Fix setting layout direction for wxSpinCtrl in wxMSW.

Position the spin control components (the button and the text) correctly for
the current layout.

Also update the layout of the text explicitly.

See #11583.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@77755 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2014-09-21 01:41:22 +00:00
parent e5755015e7
commit 81ec161949
2 changed files with 55 additions and 9 deletions

View File

@ -111,6 +111,8 @@ public:
// recognize buddy window as part of this control at wx level
virtual bool ContainsHWND(WXHWND hWnd) const { return hWnd == m_hwndBuddy; }
virtual void SetLayoutDirection(wxLayoutDirection dir) wxOVERRIDE;
protected:
virtual void DoGetPosition(int *x, int *y) const;
virtual void DoMoveWindow(int x, int y, int width, int height);
@ -137,7 +139,6 @@ protected:
// called to ensure that the value is in the correct range
virtual void NormalizeValue();
// the value of the control before the latest change (which might not have
// changed anything in fact -- this is why we need this field)
int m_oldValue;

View File

@ -521,6 +521,20 @@ void wxSpinCtrl::SetSelection(long from, long to)
::SendMessage(GetBuddyHwnd(), EM_SETSEL, (WPARAM)from, (LPARAM)to);
}
void wxSpinCtrl::SetLayoutDirection(wxLayoutDirection dir)
{
#ifndef __WXWINCE__
// Buddy text field is plain EDIT control so we need to set its layout
// direction in a specific way.
wxUpdateEditLayoutDirection(GetBuddyHwnd(), dir);
#endif // !__WXWINCE__
wxSpinButton::SetLayoutDirection(dir);
// Reposition the child windows according to the new layout.
SetSize(-1, -1, -1, -1, wxSIZE_AUTO | wxSIZE_FORCE);
}
// ----------------------------------------------------------------------------
// wxSpinButton methods
// ----------------------------------------------------------------------------
@ -759,13 +773,30 @@ void wxSpinCtrl::DoMoveWindow(int x, int y, int width, int height)
widthText = 0;
}
// 1) The buddy window
DoMoveSibling(m_hwndBuddy, x, y, widthText, height);
// Because both subcontrols are positioned relatively
// to the parent which can have different layout direction
// then our control, we need to mirror their positions manually.
if ( GetParent()->GetLayoutDirection() == GetLayoutDirection() )
{
// Logical positions: x(Text) < x(Button)
// 1) The buddy window
DoMoveSibling(m_hwndBuddy, x, y, widthText, height);
// 2) The button window
if ( widthText > 0 )
x += widthText + MARGIN_BETWEEN;
wxSpinButton::DoMoveWindow(x, y, widthBtn, height);
// 2) The button window
if ( widthText > 0 )
x += widthText + MARGIN_BETWEEN;
wxSpinButton::DoMoveWindow(x, y, widthBtn, height);
}
else
{
// Logical positions: x(Button) < x(Text)
// 1) The button window
wxSpinButton::DoMoveWindow(x, y, widthBtn, height);
// 2) The buddy window
x += widthBtn + MARGIN_BETWEEN;
DoMoveSibling(m_hwndBuddy, x, y, widthText, height);
}
}
// get total size of the control
@ -797,13 +828,27 @@ void wxSpinCtrl::DoGetClientSize(int *x, int *y) const
void wxSpinCtrl::DoGetPosition(int *x, int *y) const
{
// Because both subcontrols are mirrored manually
// (for layout direction purposes, see note)
// and leftmost control can be either spin or buddy text
// we need to get positions for both controls
// and return this with lower horizonal value.
// Note:
// Logical positions in manual mirroring:
// our layout == parent layout => x(Text) < x(Button)
// our layout != parent layout => x(Button) < x(Text)
// hack: pretend that our HWND is the text control just for a moment
int xBuddy;
WXHWND hWnd = GetHWND();
wxConstCast(this, wxSpinCtrl)->m_hWnd = m_hwndBuddy;
wxSpinButton::DoGetPosition(&xBuddy, y);
wxSpinButton::DoGetPosition(x, y);
int xText;
wxConstCast(this, wxSpinCtrl)->m_hWnd = hWnd;
wxSpinButton::DoGetPosition(&xText, y);
*x = wxMin(xBuddy, xText);
}
#endif // wxUSE_SPINCTRL