From 06b9c2a22f73310b69ae0ed4a5b0ede405f1dcb9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Wed, 19 Dec 2007 19:21:52 +0000 Subject: [PATCH] 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/trunk@50835 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/scrolwin.h | 1 + src/generic/scrlwing.cpp | 75 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/include/wx/scrolwin.h b/include/wx/scrolwin.h index 001eb0bca8..01c90d50cb 100644 --- a/include/wx/scrolwin.h +++ b/include/wx/scrolwin.h @@ -162,6 +162,7 @@ public: #if wxUSE_MOUSEWHEEL void HandleOnMouseWheel(wxMouseEvent& event); #endif // wxUSE_MOUSEWHEEL + void HandleOnChildFocus(wxChildFocusEvent& event); // FIXME: this is needed for now for wxPlot compilation, should be removed // once it is fixed! diff --git a/src/generic/scrlwing.cpp b/src/generic/scrlwing.cpp index 4d4c52bc70..0b6c1fcc6e 100644 --- a/src/generic/scrlwing.cpp +++ b/src/generic/scrlwing.cpp @@ -241,6 +241,12 @@ bool wxScrollHelperEvtHandler::ProcessEvent(wxEvent& event) return true; } + if ( evType == wxEVT_CHILD_FOCUS ) + { + m_scrollHelper->HandleOnChildFocus((wxChildFocusEvent &)event); + return true; + } + // reset the skipped flag (which might have been set to true in // ProcessEvent() above) to be able to test it below bool wasSkipped = event.GetSkipped(); @@ -1345,6 +1351,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 // ---------------------------------------------------------------------------- -- 2.45.2