]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/vlbox.cpp
Added support for delayed deactivation of windows (for MDI)
[wxWidgets.git] / src / generic / vlbox.cpp
index e15de81c6a40a8b7284bc25b12ee8987ff711f92..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;
 }
 
@@ -188,6 +189,10 @@ bool wxVListBox::DoSelectAll(bool select)
 
 bool wxVListBox::DoSetCurrent(int current)
 {
+    wxASSERT_MSG( current == wxNOT_FOUND ||
+                    (current >= 0 && (size_t)current < GetItemCount()),
+                  _T("wxVListBox::DoSetCurrent(): invalid item index") );
+
     if ( current == m_current )
     {
         // nothing to do
@@ -239,6 +244,10 @@ void wxVListBox::SendSelectedEvent()
 
 void wxVListBox::SetSelection(int selection)
 {
+    wxCHECK_RET( selection == wxNOT_FOUND ||
+                  (selection >= 0 && (size_t)selection < GetItemCount()),
+                  _T("wxVListBox::SetSelection(): invalid item index") );
+
     wxASSERT_MSG( !HasMultipleSelection(),
                   _T("SetSelection() is invalid with multiselection listbox") );
 
@@ -368,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;
@@ -381,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;
+
+            if ( flags & ItemClick_Ctrl )
+            {
+                select = false;
 
-            Toggle(item);
+                if ( !(flags & ItemClick_Kbd) )
+                {
+                    Toggle(item);
 
-            // the status of the item has definitely changed
-            notify = true;
+                    // 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 )
         {
@@ -443,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() )
     {
@@ -486,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);
 }
 
 // ----------------------------------------------------------------------------
@@ -502,13 +539,23 @@ void wxVListBox::OnLeftDown(wxMouseEvent& event)
 {
     int item = HitTest(event.GetPosition());
 
-    DoHandleItemClick(item, event.ShiftDown(),
+    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
 #ifdef __WXMAC__
-                            event.MetaDown()
+        if ( event.MetaDown() )
 #else
-                            event.ControlDown()
+        if ( event.ControlDown() )
 #endif
-                     );
+            flags |= ItemClick_Ctrl;
+
+        DoHandleItemClick(item, flags);
+    }
 }
 
 void wxVListBox::OnLeftDClick(wxMouseEvent& event)