From 237d84033ec95d4214bc38a9dae06f8c54016e32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Thu, 20 Dec 2007 18:36:19 +0000 Subject: [PATCH] backported: when a window inside scrolled window receives focus, make sure the parent is scrolled so that the window with focus is visible git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@50864 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + include/wx/scrolwin.h | 4 +++ src/generic/scrlwing.cpp | 75 ++++++++++++++++++++++++++++++++++++++++ version-script.in | 1 + 4 files changed, 81 insertions(+) diff --git a/docs/changes.txt b/docs/changes.txt index 9f16059f8c..035a2646e4 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -105,6 +105,7 @@ All (GUI): - wxRichTextCtrl performance has been improved considerably. - wxNotebook RTTI corrected, so now wxDynamicCast(notebook, wxBookCtrlBase) works. +- When focus is set to wxScrolledWindow child, scroll it into view. All (Unix): diff --git a/include/wx/scrolwin.h b/include/wx/scrolwin.h index e7660e93ea..b03c73eb77 100644 --- a/include/wx/scrolwin.h +++ b/include/wx/scrolwin.h @@ -163,6 +163,10 @@ public: void HandleOnMouseWheel(wxMouseEvent& event); #endif // wxUSE_MOUSEWHEEL +#if wxABI_VERSION >= 20808 + void HandleOnChildFocus(wxChildFocusEvent& event); +#endif + // FIXME: this is needed for now for wxPlot compilation, should be removed // once it is fixed! void OnScroll(wxScrollWinEvent& event) { HandleOnScroll(event); } diff --git a/src/generic/scrlwing.cpp b/src/generic/scrlwing.cpp index 1afba80a66..42ffc4a924 100644 --- a/src/generic/scrlwing.cpp +++ b/src/generic/scrlwing.cpp @@ -245,6 +245,12 @@ bool wxScrollHelperEvtHandler::ProcessEvent(wxEvent& event) return true; } + if ( evType == wxEVT_CHILD_FOCUS ) + { + m_scrollHelper->HandleOnChildFocus((wxChildFocusEvent &)event); + return true; + } + if ( evType == wxEVT_SCROLLWIN_TOP || evType == wxEVT_SCROLLWIN_BOTTOM || evType == wxEVT_SCROLLWIN_LINEUP || @@ -1339,6 +1345,75 @@ void wxScrollHelper::HandleOnMouseWheel(wxMouseEvent& event) #endif // wxUSE_MOUSEWHEEL +void wxScrollHelper::HandleOnChildFocus(wxChildFocusEvent& event) +{ + // this event should be processed by all windows in parenthood chain, + // e.g. so that nested wxScrolledWindows work correctly + event.Skip(); + + // find the immediate child under which the window receiving focus is: + wxWindow *win = event.GetWindow(); + while ( win->GetParent() != m_targetWindow ) + { + win = win->GetParent(); + wxCHECK_RET( win, "incorrectly sent wxChildFocusEvent - not our child" ); + } + + // if the child is not fully visible, try to scroll it into view: + int stepx, stepy; + GetScrollPixelsPerUnit(&stepx, &stepy); + + // NB: we don't call CalcScrolledPosition() on win->GetPosition() here, + // because children' positions are already scrolled + wxRect winrect(win->GetPosition(), win->GetSize()); + wxSize view(m_targetWindow->GetClientSize()); + + int startx, starty; + GetViewStart(&startx, &starty); + + // first in vertical direction: + if ( stepy > 0 ) + { + int diff = 0; + + if ( winrect.GetTop() < 0 ) + { + diff = winrect.GetTop(); + } + else if ( winrect.GetBottom() > view.y ) + { + diff = winrect.GetBottom() - view.y + 1; + // round up to next scroll step if we can't get exact position, + // so that the window is fully visible: + diff += stepy - 1; + } + + starty = (starty * stepy + diff) / stepy; + } + + // then horizontal: + if ( stepx > 0 ) + { + int diff = 0; + + if ( winrect.GetLeft() < 0 ) + { + diff = winrect.GetLeft(); + } + else if ( winrect.GetRight() > view.x ) + { + diff = winrect.GetRight() - view.x + 1; + // round up to next scroll step if we can't get exact position, + // so that the window is fully visible: + diff += stepx - 1; + } + + startx = (startx * stepx + diff) / stepx; + } + + Scroll(startx, starty); +} + // ---------------------------------------------------------------------------- // wxScrolledWindow implementation // ---------------------------------------------------------------------------- diff --git a/version-script.in b/version-script.in index c96e9541c8..5969a82a8e 100644 --- a/version-script.in +++ b/version-script.in @@ -27,6 +27,7 @@ # public symbols added in 2.8.8 (please keep in alphabetical order): @WX_VERSION_TAG@.8 { global: + *wxScrollHelper*HandleOnChildFocus*; *wxWindowBase*Get*Sibling*; };