// 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
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;
void wxVListBox::Init()
{
- m_current = wxNOT_FOUND;
+ m_current =
+ m_anchor = wxNOT_FOUND;
m_selStore = NULL;
}
// 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;
// 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 )
{
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() )
{
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);
}
// ----------------------------------------------------------------------------
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);
}
}