From 81ec161949b5b5c565a36c175de8f41901f94bbf Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 21 Sep 2014 01:41:22 +0000 Subject: [PATCH] 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 --- include/wx/msw/spinctrl.h | 3 +- src/msw/spinctrl.cpp | 61 ++++++++++++++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/include/wx/msw/spinctrl.h b/include/wx/msw/spinctrl.h index 9250292de0..6c8bd49fe1 100644 --- a/include/wx/msw/spinctrl.h +++ b/include/wx/msw/spinctrl.h @@ -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; diff --git a/src/msw/spinctrl.cpp b/src/msw/spinctrl.cpp index 4610eef008..3346eb3ba0 100644 --- a/src/msw/spinctrl.cpp +++ b/src/msw/spinctrl.cpp @@ -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