X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/be465555381c323bdf854da04ca943e15cbb2d2d..cda66071f17f062779a7009065e5ff7dd958440b:/src/generic/vlbox.cpp?ds=sidebyside diff --git a/src/generic/vlbox.cpp b/src/generic/vlbox.cpp index e15de81c6a..938b9d331c 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; } @@ -68,11 +69,12 @@ bool wxVListBox::Create(wxWindow *parent, if ( !wxVScrolledWindow::Create(parent, id, pos, size, style, name) ) return false; - SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX)); - if ( style & wxLB_MULTIPLE ) m_selStore = new wxSelectionStore; + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX)); + m_colBgSel = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT); + return true; } @@ -188,6 +190,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,8 +245,15 @@ void wxVListBox::SendSelectedEvent() void wxVListBox::SetSelection(int selection) { - wxASSERT_MSG( !HasMultipleSelection(), - _T("SetSelection() is invalid with multiselection listbox") ); + wxCHECK_RET( selection == wxNOT_FOUND || + (selection >= 0 && (size_t)selection < GetItemCount()), + _T("wxVListBox::SetSelection(): invalid item index") ); + + if ( HasMultipleSelection() ) + { + Select(selection); + m_anchor = selection; + } DoSetCurrent(selection); } @@ -273,7 +286,7 @@ int wxVListBox::GetNextSelected(unsigned long& cookie) const } // ---------------------------------------------------------------------------- -// wxVListBox painting +// wxVListBox appearance parameters // ---------------------------------------------------------------------------- void wxVListBox::SetMargins(const wxPoint& pt) @@ -286,6 +299,15 @@ void wxVListBox::SetMargins(const wxPoint& pt) } } +void wxVListBox::SetSelectionBackground(const wxColour& col) +{ + m_colBgSel = col; +} + +// ---------------------------------------------------------------------------- +// wxVListBox painting +// ---------------------------------------------------------------------------- + wxCoord wxVListBox::OnGetLineHeight(size_t line) const { return OnMeasureItem(line) + 2*m_ptMargins.y; @@ -328,10 +350,7 @@ void wxVListBox::OnPaint(wxPaintEvent& event) { if ( isSelected ) { - wxBrush brush(wxSystemSettings:: - GetColour(wxSYS_COLOUR_HIGHLIGHT), - wxSOLID); - dc.SetBrush(brush); + dc.SetBrush(wxBrush(m_colBgSel, wxSOLID)); } else // !selected { @@ -368,7 +387,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 +400,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 ) { @@ -443,6 +474,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 +520,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 +549,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)