From 970b97a267e1e60f4e269fb15317d9364526ac21 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 13 Jun 2003 13:09:30 +0000 Subject: [PATCH] made multiple selection behave more consistently with the usual (Windows) way git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@21106 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/vlbox.h | 29 +++++++++++++----- src/generic/vlbox.cpp | 68 ++++++++++++++++++++++++++++++++----------- 2 files changed, 73 insertions(+), 24 deletions(-) diff --git a/include/wx/vlbox.h b/include/wx/vlbox.h index ff1dc10de9..e2a2dc8063 100644 --- a/include/wx/vlbox.h +++ b/include/wx/vlbox.h @@ -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; diff --git a/src/generic/vlbox.cpp b/src/generic/vlbox.cpp index 2f6276cd81..bc846054a2 100644 --- a/src/generic/vlbox.cpp +++ b/src/generic/vlbox.cpp @@ -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); } } -- 2.45.2