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
This commit is contained in:
Vadim Zeitlin 2003-06-13 13:09:30 +00:00
parent b0126f6094
commit 970b97a267
2 changed files with 73 additions and 24 deletions

View File

@ -132,14 +132,14 @@ public:
// delete all items from the control // delete all items from the control
void Clear() { SetItemCount(0); } void Clear() { SetItemCount(0); }
// set the selection to the specified item, if it is -1 the selection is // set the selection to the specified item, if it is wxNOT_FOUND the
// unset // selection is unset
// //
// this function is only valid for the single selection listboxes // this function is only valid for the single selection listboxes
void SetSelection(int selection); void SetSelection(int selection);
// selects or deselects the specified item which must be valid (i.e. not // 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 // return true if the items selection status has changed or false
// otherwise // otherwise
@ -221,22 +221,37 @@ protected:
bool DoSelectAll(bool select); bool DoSelectAll(bool select);
// change the current item (in single selection listbox it also implicitly // change the current item (in single selection listbox it also implicitly
// changes the selection); current may be -1 in which case there will be // changes the selection); current may be wxNOT_FOUND in which case there
// no current item any more // will be no current item any more
// //
// return true if the current item changed, false otherwise // return true if the current item changed, false otherwise
bool DoSetCurrent(int current); 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 // common part of keyboard and mouse handling processing code
void DoHandleItemClick(int item, bool shiftDown, bool ctrlDown); void DoHandleItemClick(int item, int flags);
private: private:
// the current item or -1 // the current item or wxNOT_FOUND
// //
// if m_selStore == NULL this is also the selected item, otherwise the // if m_selStore == NULL this is also the selected item, otherwise the
// selections are managed by m_selStore // selections are managed by m_selStore
int m_current; 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 // the object managing our selected items if not NULL
wxSelectionStore *m_selStore; wxSelectionStore *m_selStore;

View File

@ -54,7 +54,8 @@ END_EVENT_TABLE()
void wxVListBox::Init() void wxVListBox::Init()
{ {
m_current = wxNOT_FOUND; m_current =
m_anchor = wxNOT_FOUND;
m_selStore = NULL; m_selStore = NULL;
} }
@ -376,7 +377,7 @@ void wxVListBox::OnPaint(wxPaintEvent& event)
// wxVListBox keyboard/mouse handling // 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? // has anything worth telling the client code about happened?
bool notify = false; 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 // NB: the keyboard interface we implement here corresponds to
// wxLB_EXTENDED rather than wxLB_MULTIPLE but this one makes more // wxLB_EXTENDED rather than wxLB_MULTIPLE but this one makes more
// sense IMHO // sense IMHO
if ( shiftDown ) if ( flags & ItemClick_Shift )
{ {
if ( m_current != wxNOT_FOUND ) if ( m_current != wxNOT_FOUND )
{ {
if ( m_anchor == wxNOT_FOUND )
m_anchor = m_current;
select = false; select = false;
// only the range from old m_current to new m_current must be // only the range from the selection anchor to new m_current
// selected // must be selected
if ( DeselectAll() ) if ( DeselectAll() )
notify = true; notify = true;
if ( SelectRange(m_current, item) ) if ( SelectRange(m_anchor, item) )
notify = true; notify = true;
} }
//else: treat it as ordinary click/keypress //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 if ( !(flags & ItemClick_Kbd) )
notify = true; {
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 ) if ( select )
{ {
@ -451,6 +464,9 @@ void wxVListBox::DoHandleItemClick(int item, bool shiftDown, bool ctrlDown)
void wxVListBox::OnKeyDown(wxKeyEvent& event) void wxVListBox::OnKeyDown(wxKeyEvent& event)
{ {
// flags for DoHandleItemClick()
int flags = ItemClick_Kbd;
int current = 0; // just to silent the stupid compiler warnings int current = 0; // just to silent the stupid compiler warnings
switch ( event.GetKeyCode() ) switch ( event.GetKeyCode() )
{ {
@ -494,12 +510,25 @@ void wxVListBox::OnKeyDown(wxKeyEvent& event)
current = GetFirstVisibleLine(); current = GetFirstVisibleLine();
break; 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: default:
event.Skip(); event.Skip();
return; 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 ) 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 // under Mac Apple-click is used in the same way as Ctrl-click
// elsewhere // elsewhere
DoHandleItemClick(item, event.ShiftDown(),
#ifdef __WXMAC__ #ifdef __WXMAC__
event.MetaDown() if ( event.MetaDown() )
#else #else
event.ControlDown() if ( event.ControlDown() )
#endif #endif
); flags |= ItemClick_Ctrl;
DoHandleItemClick(item, flags);
} }
} }