diff --git a/interface/wx/listctrl.h b/interface/wx/listctrl.h index fc7b0a101c..766d3a646f 100644 --- a/interface/wx/listctrl.h +++ b/interface/wx/listctrl.h @@ -1442,7 +1442,7 @@ protected: control itself when this event is generated, see @ref overview_events_with_mouse_capture "event handling overview". @event{EVT_LIST_ITEM_DESELECTED(id, func)} - The item has been deselected. + The item has been deselected. GetIndex() may be -1 with virtual lists. @event{EVT_LIST_ITEM_ACTIVATED(id, func)} The item has been activated (ENTER or double click). @event{EVT_LIST_ITEM_FOCUSED(id, func)} diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp index 141531cc75..b4363d0769 100644 --- a/src/generic/listctrl.cpp +++ b/src/generic/listctrl.cpp @@ -2447,7 +2447,8 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event ) else m_dragCount = 0; - // The only mouse event that can be generated without any valid item is + // The only mouse events that can be generated without any valid item are + // wxEVT_LIST_ITEM_DESELECTED for virtual lists, and // wxEVT_LIST_ITEM_RIGHT_CLICK as it can be useful to have a global // popup menu for the list control itself which should be shown even when // the user clicks outside of any item. @@ -2467,6 +2468,10 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event ) { // reset the selection and bail out HighlightAll(false); + // generate a DESELECTED event for + // virtual multi-selection lists + if ( IsVirtual() && !IsSingleSel() ) + SendNotify( m_lineLastClicked, wxEVT_LIST_ITEM_DESELECTED ); } return; diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp index dc9297fefe..e0c492a810 100644 --- a/src/msw/listctrl.cpp +++ b/src/msw/listctrl.cpp @@ -2470,74 +2470,78 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) case LVN_ITEMCHANGED: // we translate this catch all message into more interesting // (and more easy to process) wxWidgets events - - // first of all, we deal with the state change events only and - // only for valid items (item == -1 for the virtual list - // control) - if ( nmLV->uChanged & LVIF_STATE && iItem != -1 ) { // temp vars for readability const UINT stOld = nmLV->uOldState; const UINT stNew = nmLV->uNewState; - event.m_item.SetId(iItem); - event.m_item.SetMask(wxLIST_MASK_TEXT | - wxLIST_MASK_IMAGE | - wxLIST_MASK_DATA); - GetItem(event.m_item); - - // has the focus changed? - if ( !(stOld & LVIS_FOCUSED) && (stNew & LVIS_FOCUSED) ) + // first of all, we deal with the state change events only and + // only for valid items (item == -1 for the virtual list + // control) + if ( nmLV->uChanged & LVIF_STATE && + (iItem != -1 || (stNew & LVIS_SELECTED) != (stOld & LVIS_SELECTED))) { - eventType = wxEVT_LIST_ITEM_FOCUSED; - event.m_itemIndex = iItem; - } - if ( (stNew & LVIS_SELECTED) != (stOld & LVIS_SELECTED) ) - { - if ( eventType != wxEVT_NULL ) + event.m_item.SetId(iItem); + event.m_item.SetMask(wxLIST_MASK_TEXT | + wxLIST_MASK_IMAGE | + wxLIST_MASK_DATA); + if (iItem != -1) + GetItem(event.m_item); + + // has the focus changed? + if ( !(stOld & LVIS_FOCUSED) && (stNew & LVIS_FOCUSED) ) { - // focus and selection have both changed: send the - // focus event from here and the selection one - // below - event.SetEventType(eventType); - (void)HandleWindowEvent(event); - } - else // no focus event to send - { - // then need to set m_itemIndex as it wasn't done - // above + eventType = wxEVT_LIST_ITEM_FOCUSED; event.m_itemIndex = iItem; } - eventType = stNew & LVIS_SELECTED - ? wxEVT_LIST_ITEM_SELECTED - : wxEVT_LIST_ITEM_DESELECTED; - } + if ( (stNew & LVIS_SELECTED) != (stOld & LVIS_SELECTED) ) + { + if ( eventType != wxEVT_NULL ) + { + // focus and selection have both changed: send the + // focus event from here and the selection one + // below + event.SetEventType(eventType); + (void)HandleWindowEvent(event); + } + else // no focus event to send + { + // then need to set m_itemIndex as it wasn't done + // above + event.m_itemIndex = iItem; + } - if ( (stNew & LVIS_STATEIMAGEMASK) != (stOld & LVIS_STATEIMAGEMASK) ) - { - if ( stOld == INDEXTOSTATEIMAGEMASK(0) ) - { - // item does not yet have a state - // occurs when checkboxes are enabled and when a new item is added - eventType = wxEVT_NULL; - } - else if ( stNew == INDEXTOSTATEIMAGEMASK(1) ) - { - eventType = wxEVT_LIST_ITEM_UNCHECKED; - } - else if ( stNew == INDEXTOSTATEIMAGEMASK(2) ) - { - eventType = wxEVT_LIST_ITEM_CHECKED; - } - else - { - eventType = wxEVT_NULL; - wxLogDebug(wxS("Unknown LVIS_STATEIMAGE state: %u"), stNew); + eventType = stNew & LVIS_SELECTED + ? wxEVT_LIST_ITEM_SELECTED + : wxEVT_LIST_ITEM_DESELECTED; } - event.m_itemIndex = iItem; + if ( (stNew & LVIS_STATEIMAGEMASK) != (stOld & LVIS_STATEIMAGEMASK) ) + { + if ( stOld == INDEXTOSTATEIMAGEMASK(0) ) + { + // item does not yet have a state + // occurs when checkboxes are enabled and when a new item is added + eventType = wxEVT_NULL; + } + else if ( stNew == INDEXTOSTATEIMAGEMASK(1) ) + { + eventType = wxEVT_LIST_ITEM_UNCHECKED; + } + else if ( stNew == INDEXTOSTATEIMAGEMASK(2) ) + { + eventType = wxEVT_LIST_ITEM_CHECKED; + } + else + { + eventType = wxEVT_NULL; + wxLogDebug(wxS("Unknown LVIS_STATEIMAGE state: %u"), stNew); + } + + event.m_itemIndex = iItem; + } } }