]> git.saurik.com Git - wxWidgets.git/commitdiff
made multiple selection behave more consistently with the usual (Windows) way
authorVadim Zeitlin <vadim@wxwidgets.org>
Fri, 13 Jun 2003 13:09:30 +0000 (13:09 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Fri, 13 Jun 2003 13:09:30 +0000 (13:09 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@21106 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/vlbox.h
src/generic/vlbox.cpp

index ff1dc10de91b41bb77d127b141a1687a8c4e41a0..e2a2dc8063e0b2e0de324e09195c9513a67e96f8 100644 (file)
@@ -132,14 +132,14 @@ public:
     // delete all items from the control
     void Clear() { SetItemCount(0); }
 
-    // set the selection to the specified item, if it is -1 the selection is
-    // unset
+    // set the selection to the specified item, if it is wxNOT_FOUND the
+    // selection is unset
     //
     // this function is only valid for the single selection listboxes
     void SetSelection(int selection);
 
     // selects or deselects the specified item which must be valid (i.e. not
-    // equal to -1)
+    // equal to wxNOT_FOUND)
     //
     // return true if the items selection status has changed or false
     // otherwise
@@ -221,22 +221,37 @@ protected:
     bool DoSelectAll(bool select);
 
     // change the current item (in single selection listbox it also implicitly
-    // changes the selection); current may be -1 in which case there will be
-    // no current item any more
+    // changes the selection); current may be wxNOT_FOUND in which case there
+    // will be no current item any more
     //
     // return true if the current item changed, false otherwise
     bool DoSetCurrent(int current);
 
+    // flags for DoHandleItemClick
+    enum
+    {
+        ItemClick_Shift = 1,        // item shift-clicked
+        ItemClick_Ctrl  = 2,        //       ctrl
+        ItemClick_Kbd   = 4         // item selected from keyboard
+    };
+
     // common part of keyboard and mouse handling processing code
-    void DoHandleItemClick(int item, bool shiftDown, bool ctrlDown);
+    void DoHandleItemClick(int item, int flags);
 
 private:
-    // the current item or -1
+    // the current item or wxNOT_FOUND
     //
     // if m_selStore == NULL this is also the selected item, otherwise the
     // selections are managed by m_selStore
     int m_current;
 
+    // the anchor of the selection for the multiselection listboxes:
+    // shift-clicking an item extends the selection from m_anchor to the item
+    // clicked, for example
+    //
+    // always wxNOT_FOUND for single selection listboxes
+    int m_anchor;
+
     // the object managing our selected items if not NULL
     wxSelectionStore *m_selStore;
 
index 2f6276cd814087b23f721994eab3925c9b1ab9ee..bc846054a238b49dceae8b7b79ea47752fe1b91f 100644 (file)
@@ -54,7 +54,8 @@ END_EVENT_TABLE()
 
 void wxVListBox::Init()
 {
-    m_current = wxNOT_FOUND;
+    m_current =
+    m_anchor = wxNOT_FOUND;
     m_selStore = NULL;
 }
 
@@ -376,7 +377,7 @@ void wxVListBox::OnPaint(wxPaintEvent& event)
 // wxVListBox keyboard/mouse handling
 // ============================================================================
 
-void wxVListBox::DoHandleItemClick(int item, bool shiftDown, bool ctrlDown)
+void wxVListBox::DoHandleItemClick(int item, int flags)
 {
     // has anything worth telling the client code about happened?
     bool notify = false;
@@ -389,32 +390,44 @@ void wxVListBox::DoHandleItemClick(int item, bool shiftDown, bool ctrlDown)
         // NB: the keyboard interface we implement here corresponds to
         //     wxLB_EXTENDED rather than wxLB_MULTIPLE but this one makes more
         //     sense IMHO
-        if ( shiftDown )
+        if ( flags & ItemClick_Shift )
         {
             if ( m_current != wxNOT_FOUND )
             {
+                if ( m_anchor == wxNOT_FOUND )
+                    m_anchor = m_current;
+
                 select = false;
 
-                // only the range from old m_current to new m_current must be
-                // selected
+                // only the range from the selection anchor to new m_current
+                // must be selected
                 if ( DeselectAll() )
                     notify = true;
 
-                if ( SelectRange(m_current, item) )
+                if ( SelectRange(m_anchor, item) )
                     notify = true;
             }
             //else: treat it as ordinary click/keypress
         }
-        else if ( ctrlDown )
+        else // Shift not pressed
         {
-            select = false;
+            m_anchor = item;
 
-            Toggle(item);
+            if ( flags & ItemClick_Ctrl )
+            {
+                select = false;
 
-            // the status of the item has definitely changed
-            notify = true;
+                if ( !(flags & ItemClick_Kbd) )
+                {
+                    Toggle(item);
+
+                    // the status of the item has definitely changed
+                    notify = true;
+                }
+                //else: Ctrl-arrow pressed, don't change selection
+            }
+            //else: behave as in single selection case
         }
-        //else: behave as in single selection case
 
         if ( select )
         {
@@ -451,6 +464,9 @@ void wxVListBox::DoHandleItemClick(int item, bool shiftDown, bool ctrlDown)
 
 void wxVListBox::OnKeyDown(wxKeyEvent& event)
 {
+    // flags for DoHandleItemClick()
+    int flags = ItemClick_Kbd;
+
     int current = 0; // just to silent the stupid compiler warnings
     switch ( event.GetKeyCode() )
     {
@@ -494,12 +510,25 @@ void wxVListBox::OnKeyDown(wxKeyEvent& event)
             current = GetFirstVisibleLine();
             break;
 
+        case WXK_SPACE:
+            // hack: pressing space should work like a mouse click rather than
+            // like a keyboard arrow press, so trick DoHandleItemClick() in
+            // thinking we were clicked
+            flags &= ~ItemClick_Kbd;
+            current = m_current;
+            break;
+
         default:
             event.Skip();
             return;
     }
 
-    DoHandleItemClick(current, event.ShiftDown(), event.ControlDown());
+    if ( event.ShiftDown() )
+       flags |= ItemClick_Shift;
+    if ( event.ControlDown() )
+        flags |= ItemClick_Ctrl;
+
+    DoHandleItemClick(current, flags);
 }
 
 // ----------------------------------------------------------------------------
@@ -512,15 +541,20 @@ void wxVListBox::OnLeftDown(wxMouseEvent& event)
 
     if ( item != wxNOT_FOUND )
     {
+        int flags = 0;
+        if ( event.ShiftDown() )
+           flags |= ItemClick_Shift;
+
         // under Mac Apple-click is used in the same way as Ctrl-click
         // elsewhere
-        DoHandleItemClick(item, event.ShiftDown(),
 #ifdef __WXMAC__
-                                event.MetaDown()
+        if ( event.MetaDown() )
 #else
-                                event.ControlDown()
+        if ( event.ControlDown() )
 #endif
-                         );
+            flags |= ItemClick_Ctrl;
+
+        DoHandleItemClick(item, flags);
     }
 }