]> git.saurik.com Git - wxWidgets.git/commitdiff
Allow user code to override key events in generic wxListCtrl.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 11 Jul 2010 10:43:35 +0000 (10:43 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 11 Jul 2010 10:43:35 +0000 (10:43 +0000)
The changes of r58323 ("Restore keyboard navi") fixed the handling of cursor
keys in the generic wxListCtrl implementation but at the price of not sending
keyboard events for the cursor keys to wxListCtrl itself any more. This made
it impossible to override their handling in user code, something that used to
work in previous wx versions and still works in wxMSW.

Revert the changes of this revision now and fix the original code by simply
disabling the handling of the cursor keys in wxScrollHelperBase using a newly
added DisableKeyboardScrolling() method. This ensures that the keyboard events
for cursor keys are not used to scroll the window when they are forwarded to
wxListCtrl from wxListMainWindow.

The fix is conceptually ugly as it would be better to avoid the need for such
ad hoc functions as DisableKeyboardScrolling() but it is very simple and there
just doesn't seem to be any sane way to do it otherwise with wxScrollHelperBase.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@64877 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/scrolwin.h
interface/wx/scrolwin.h
src/generic/listctrl.cpp
src/generic/scrlwing.cpp

index 1b41c43d9bd102b3b6119897a57e63c484dde4ab..f1ca429ffffbd89dbf061859fab9bfb61377c5f7 100644 (file)
@@ -108,6 +108,17 @@ public:
     // actually scroll a non-constant distance
     virtual void EnableScrolling(bool x_scrolling, bool y_scrolling);
 
+    // Disable use of keyboard keys for scrolling. By default cursor movement
+    // keys (including Home, End, Page Up and Down) are used to scroll the
+    // window appropriately. If the derived class uses these keys for something
+    // else, e.g. changing the currently selected item, this function can be
+    // used to disable this behaviour as it's not only not necessary then but
+    // can actually be actively harmful if another object forwards a keyboard
+    // event corresponding to one of the above keys to us using
+    // ProcessWindowEvent() because the event will always be processed which
+    // can be undesirable.
+    void DisableKeyboardScrolling() { m_kbdScrollingEnabled = false; }
+
     // Get the view start
     void GetViewStart(int *x, int *y) const { DoGetViewStart(x, y); }
 
@@ -284,6 +295,8 @@ protected:
     bool                  m_xScrollingEnabled;
     bool                  m_yScrollingEnabled;
 
+    bool                  m_kbdScrollingEnabled;
+
 #if wxUSE_MOUSEWHEEL
     int m_wheelRotation;
 #endif // wxUSE_MOUSEWHEEL
index 9749ef7e8c45afeae070fe55e628dc6716e6fc7d..51fbde4e5e0711199fbca95ffe6e23b313d375fa 100644 (file)
@@ -199,6 +199,22 @@ public:
                 long style = wxHSCROLL | wxVSCROLL,
                 const wxString& name = "scrolledWindow");
 
+    /**
+        Disable use of keyboard keys for scrolling.
+
+        By default cursor movement keys (including Home, End, Page Up and Down)
+        are used to scroll the window appropriately. If the derived class uses
+        these keys for something else, e.g. changing the currently selected
+        item, this function can be used to disable this behaviour as it's not
+        only not necessary then but can actually be actively harmful if another
+        object forwards a keyboard event corresponding to one of the above keys
+        to us using ProcessWindowEvent() because the event will always be
+        processed which can be undesirable.
+
+        @since 2.9.1
+    */
+    void DisableKeyboardScrolling();
+
     /**
         Call this function to prepare the device context for drawing a scrolled
         image.
index 1efbc040eaeda8f6a2741d14ea5b9b749e0ee8f5..0a6da82812d92dbe93d837acdbb69033167c7e01 100644 (file)
@@ -2753,21 +2753,11 @@ void wxListMainWindow::OnChar( wxKeyEvent &event )
         parent->GetEventHandler()->ProcessEvent( le );
     }
 
-    if ( (event.GetKeyCode() != WXK_UP) &&
-         (event.GetKeyCode() != WXK_DOWN) &&
-         (event.GetKeyCode() != WXK_RIGHT) &&
-         (event.GetKeyCode() != WXK_LEFT) &&
-         (event.GetKeyCode() != WXK_PAGEUP) &&
-         (event.GetKeyCode() != WXK_PAGEDOWN) &&
-         (event.GetKeyCode() != WXK_END) &&
-         (event.GetKeyCode() != WXK_HOME) )
-    {
-        // propagate the char event upwards
-        wxKeyEvent ke(event);
-        ke.SetEventObject( parent );
-        if (parent->GetEventHandler()->ProcessEvent( ke ))
-            return;
-    }
+    // propagate the char event upwards
+    wxKeyEvent ke(event);
+    ke.SetEventObject( parent );
+    if (parent->GetEventHandler()->ProcessEvent( ke ))
+        return;
 
     if ( HandleAsNavigationKey(event) )
         return;
@@ -4359,6 +4349,11 @@ bool wxGenericListCtrl::Create(wxWindow *parent,
 
     SetTargetWindow( m_mainWin );
 
+    // We use the cursor keys for moving the selection, not scrolling, so call
+    // this method to ensure wxScrollHelperEvtHandler doesn't catch all
+    // keyboard events forwarded to us from wxListMainWindow.
+    DisableKeyboardScrolling();
+
     wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
     sizer->Add( m_mainWin, 1, wxGROW );
     SetSizer( sizer );
index c5329862e2e50d948be9675b2b251581ee2beef9..7dcd4ba055b40f584673f110a850730c99640c70 100644 (file)
@@ -343,6 +343,8 @@ wxScrollHelperBase::wxScrollHelperBase(wxWindow *win)
     m_xScrollingEnabled =
     m_yScrollingEnabled = true;
 
+    m_kbdScrollingEnabled = true;
+
     m_scaleX =
     m_scaleY = 1.0;
 #if wxUSE_MOUSEWHEEL
@@ -844,6 +846,12 @@ void wxScrollHelperBase::HandleOnPaint(wxPaintEvent& WXUNUSED(event))
 // this they always have the priority
 void wxScrollHelperBase::HandleOnChar(wxKeyEvent& event)
 {
+    if ( !m_kbdScrollingEnabled )
+    {
+        event.Skip();
+        return;
+    }
+
     // prepare the event this key press maps to
     wxScrollWinEvent newEvent;