diff --git a/src/stc/PlatWX.cpp b/src/stc/PlatWX.cpp index 11795fe591..359b5c4383 100644 --- a/src/stc/PlatWX.cpp +++ b/src/stc/PlatWX.cpp @@ -2117,24 +2117,27 @@ PRectangle Window::GetMonitorRect(Point pt) { // Do not activate the window when it is shown. bool wxSTCPopupBase::Show(bool show) { - if ( !wxWindowBase::Show(show) ) - return false; - if ( show ) { - HWND hWnd = reinterpret_cast(GetHandle()); - if ( GetName() == "wxSTCCallTip" ) - ::AnimateWindow(hWnd, 25, AW_BLEND); - else - ::ShowWindow(hWnd, SW_SHOWNA ); + // Check if the window is changing from hidden to shown. + bool changingVisibility = wxWindowBase::Show(true); - ::SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, - SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + if ( changingVisibility ) + { + HWND hWnd = reinterpret_cast(GetHandle()); + if ( GetName() == "wxSTCCallTip" ) + ::AnimateWindow(hWnd, 25, AW_BLEND); + else + ::ShowWindow(hWnd, SW_SHOWNA ); + + ::SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + } + + return changingVisibility; } else - wxPopupWindow::Show(false); - - return true; + return wxPopupWindow::Show(false); } // Do not activate in response to mouse clicks on this window. @@ -2224,7 +2227,7 @@ PRectangle Window::GetMonitorRect(Point pt) { #endif // __WXOSX_COCOA__ wxSTCPopupWindow::wxSTCPopupWindow(wxWindow* parent) - :wxSTCPopupBase(parent), m_initialPosition(wxDefaultPosition) + :wxSTCPopupBase(parent), m_lastKnownPosition(wxDefaultPosition) { #if !wxSTC_POPUP_IS_CUSTOM Bind(wxEVT_SET_FOCUS, &wxSTCPopupWindow::OnFocus, this); @@ -2275,9 +2278,7 @@ bool wxSTCPopupWindow::AcceptsFocus() const void wxSTCPopupWindow::DoSetSize(int x, int y, int width, int height, int flags) { - if ( m_initialPosition == wxDefaultPosition - && x != wxDefaultCoord && y != wxDefaultCoord ) - m_initialPosition = wxPoint(x, y); + m_lastKnownPosition = wxPoint(x, y); // convert coords to screen coords since we're a top-level window if (x != wxDefaultCoord) @@ -2291,8 +2292,8 @@ void wxSTCPopupWindow::DoSetSize(int x, int y, int width, int height, int flags) void wxSTCPopupWindow::OnParentMove(wxMoveEvent& event) { - if ( m_initialPosition != wxDefaultPosition ) - SetPosition(m_initialPosition); + if ( m_lastKnownPosition.IsFullySpecified() ) + SetPosition(m_lastKnownPosition); event.Skip(); } @@ -2700,7 +2701,7 @@ wxSTCListBox::wxSTCListBox(wxWindow* parent, wxSTCListBoxVisualData* v, int ht) m_textTopGap(0), m_imageAreaWidth(0), m_imageAreaHeight(0) { wxVListBox::Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, - wxBORDER_NONE); + wxBORDER_NONE, "AutoCompListBox"); m_imagePadding = FromDIP(1); m_textBoxToTextGap = FromDIP(3); diff --git a/src/stc/PlatWX.h b/src/stc/PlatWX.h index 714f5e4180..31a11dbf4d 100644 --- a/src/stc/PlatWX.h +++ b/src/stc/PlatWX.h @@ -150,7 +150,7 @@ protected: #endif private: - wxPoint m_initialPosition; + wxPoint m_lastKnownPosition; wxWindow* m_tlw; }; diff --git a/src/stc/stc.cpp b/src/stc/stc.cpp index 789b44caf7..65a7a74684 100644 --- a/src/stc/stc.cpp +++ b/src/stc/stc.cpp @@ -46,6 +46,8 @@ #include "wx/tokenzr.h" #include "wx/mstream.h" #include "wx/image.h" +#include "wx/vlbox.h" +#include "wx/stack.h" #if wxUSE_FFILE #include "wx/ffile.h" #elif wxUSE_FILE @@ -5251,29 +5253,89 @@ void wxStyledTextCtrl::OnContextMenu(wxContextMenuEvent& evt) { void wxStyledTextCtrl::OnMouseWheel(wxMouseEvent& evt) { + // The default action of this method is to call m_swx->DoMouseWheel. + // However, it might be necessary to do something else depending on whether + // 1) the mouse wheel captures for the STC, + // 2) the event's position is in the STC's rect, and + // 3) and an autocompletion list is currently being shown. + // This table summarizes when each action is needed. + + // InRect | MouseWheelCaptures | Autocomp Active | action + // -------+--------------------+-----------------+------------------- + // true | true | true | scroll ac list + // true | true | false | default + // true | false | true | scroll ac list + // true | false | false | default + // false | true | true | scroll ac list + // false | true | false | default + // false | false | true | forward to parent + // false | false | false | forward to parent + // if the mouse wheel is not captured, test if the mouse // pointer is over the editor window and if not, don't // handle the message but pass it on. - if ( !GetMouseWheelCaptures() ) { - if ( !GetRect().Contains(evt.GetPosition()) ) { - wxWindow* parent = GetParent(); - if (parent != NULL) { - wxMouseEvent newevt(evt); - newevt.SetPosition( - parent->ScreenToClient(ClientToScreen(evt.GetPosition()))); - parent->ProcessWindowEvent(newevt); - } - return; + if ( !GetMouseWheelCaptures() && !GetRect().Contains(evt.GetPosition()) ) + { + wxWindow* parent = GetParent(); + if ( parent != NULL ) + { + wxMouseEvent newevt(evt); + newevt.SetPosition( + parent->ScreenToClient(ClientToScreen(evt.GetPosition()))); + parent->ProcessWindowEvent(newevt); } } + else if ( AutoCompActive() ) + { + // When the autocompletion popup is active, Scintilla uses the mouse + // wheel to scroll the autocomp list instead of the editor. - m_swx->DoMouseWheel(evt.GetWheelAxis(), - evt.GetWheelRotation(), - evt.GetWheelDelta(), - evt.GetLinesPerAction(), - evt.GetColumnsPerAction(), - evt.ControlDown(), - evt.IsPageScroll()); + // First try to find the list. It will be a wxVListBox named + // "AutoCompListBox". + wxWindow* curWin = this, *acListBox = NULL; + wxStack windows; + windows.push(curWin); + + while ( !windows.empty() ) + { + curWin = windows.top(); + windows.pop(); + + if ( curWin->IsKindOf(wxCLASSINFO(wxVListBox)) && + curWin->GetName() == "AutoCompListBox") + { + acListBox = curWin; + break; + } + + wxWindowList& children = curWin->GetChildren(); + wxWindowList::iterator it; + + for ( it = children.begin(); it!=children.end(); ++it ) + { + windows.push(*it); + } + } + + // Next if the list was found, send it a copy of this event. + if ( acListBox ) + { + wxMouseEvent newevt(evt); + newevt.SetPosition( + acListBox->ScreenToClient(ClientToScreen(evt.GetPosition()))); + acListBox->ProcessWindowEvent(newevt); + } + } + else + { + m_swx->DoMouseWheel(evt.GetWheelAxis(), + evt.GetWheelRotation(), + evt.GetWheelDelta(), + evt.GetLinesPerAction(), + evt.GetColumnsPerAction(), + evt.ControlDown(), + evt.IsPageScroll()); + } } diff --git a/src/stc/stc.cpp.in b/src/stc/stc.cpp.in index 833b8c9a33..198c4ccac4 100644 --- a/src/stc/stc.cpp.in +++ b/src/stc/stc.cpp.in @@ -46,6 +46,8 @@ #include "wx/tokenzr.h" #include "wx/mstream.h" #include "wx/image.h" +#include "wx/vlbox.h" +#include "wx/stack.h" #if wxUSE_FFILE #include "wx/ffile.h" #elif wxUSE_FILE @@ -778,29 +780,89 @@ void wxStyledTextCtrl::OnContextMenu(wxContextMenuEvent& evt) { void wxStyledTextCtrl::OnMouseWheel(wxMouseEvent& evt) { + // The default action of this method is to call m_swx->DoMouseWheel. + // However, it might be necessary to do something else depending on whether + // 1) the mouse wheel captures for the STC, + // 2) the event's position is in the STC's rect, and + // 3) and an autocompletion list is currently being shown. + // This table summarizes when each action is needed. + + // InRect | MouseWheelCaptures | Autocomp Active | action + // -------+--------------------+-----------------+------------------- + // true | true | true | scroll ac list + // true | true | false | default + // true | false | true | scroll ac list + // true | false | false | default + // false | true | true | scroll ac list + // false | true | false | default + // false | false | true | forward to parent + // false | false | false | forward to parent + // if the mouse wheel is not captured, test if the mouse // pointer is over the editor window and if not, don't // handle the message but pass it on. - if ( !GetMouseWheelCaptures() ) { - if ( !GetRect().Contains(evt.GetPosition()) ) { - wxWindow* parent = GetParent(); - if (parent != NULL) { - wxMouseEvent newevt(evt); - newevt.SetPosition( - parent->ScreenToClient(ClientToScreen(evt.GetPosition()))); - parent->ProcessWindowEvent(newevt); - } - return; + if ( !GetMouseWheelCaptures() && !GetRect().Contains(evt.GetPosition()) ) + { + wxWindow* parent = GetParent(); + if ( parent != NULL ) + { + wxMouseEvent newevt(evt); + newevt.SetPosition( + parent->ScreenToClient(ClientToScreen(evt.GetPosition()))); + parent->ProcessWindowEvent(newevt); } } + else if ( AutoCompActive() ) + { + // When the autocompletion popup is active, Scintilla uses the mouse + // wheel to scroll the autocomp list instead of the editor. - m_swx->DoMouseWheel(evt.GetWheelAxis(), - evt.GetWheelRotation(), - evt.GetWheelDelta(), - evt.GetLinesPerAction(), - evt.GetColumnsPerAction(), - evt.ControlDown(), - evt.IsPageScroll()); + // First try to find the list. It will be a wxVListBox named + // "AutoCompListBox". + wxWindow* curWin = this, *acListBox = NULL; + wxStack windows; + windows.push(curWin); + + while ( !windows.empty() ) + { + curWin = windows.top(); + windows.pop(); + + if ( curWin->IsKindOf(wxCLASSINFO(wxVListBox)) && + curWin->GetName() == "AutoCompListBox") + { + acListBox = curWin; + break; + } + + wxWindowList& children = curWin->GetChildren(); + wxWindowList::iterator it; + + for ( it = children.begin(); it!=children.end(); ++it ) + { + windows.push(*it); + } + } + + // Next if the list was found, send it a copy of this event. + if ( acListBox ) + { + wxMouseEvent newevt(evt); + newevt.SetPosition( + acListBox->ScreenToClient(ClientToScreen(evt.GetPosition()))); + acListBox->ProcessWindowEvent(newevt); + } + } + else + { + m_swx->DoMouseWheel(evt.GetWheelAxis(), + evt.GetWheelRotation(), + evt.GetWheelDelta(), + evt.GetLinesPerAction(), + evt.GetColumnsPerAction(), + evt.ControlDown(), + evt.IsPageScroll()); + } }