MGR: Continue fixing detection of list selection and list deselection; deselecting by clicking on empty part of list control (below or on its right) does not generate any list events if the selected item has been scrolled out of view, so we must use mouse click events within the wxListCtrl.

This commit is contained in:
Charlie Fenton 2014-05-21 19:11:22 -07:00
parent 85baaa560a
commit e6279e3ea8
7 changed files with 62 additions and 29 deletions

View File

@ -34,7 +34,6 @@
IMPLEMENT_DYNAMIC_CLASS(CBOINCBaseView, wxPanel)
CBOINCBaseView::CBOINCBaseView() {}
CBOINCBaseView::CBOINCBaseView(wxNotebook* pNotebook) :
@ -337,8 +336,9 @@ bool CBOINCBaseView::OnRestoreState(wxConfigBase* pConfig) {
}
// We don't currently use this because selecting an item
// triggers an EVT_LIST_CACHE_HINT; see OnCacheHint() below.
// We don't use this because multiple selection virtual
// wxListCtrl does not generate selection events for
// shift-click; see OnCheckSelectionChanged() below.
void CBOINCBaseView::OnListSelected(wxListEvent& event) {
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseView::OnListSelected - Function Begin"));
@ -352,8 +352,9 @@ void CBOINCBaseView::OnListSelected(wxListEvent& event) {
}
// We don't currently use this because selecting an item
// triggers an EVT_LIST_CACHE_HINT; see OnCacheHint() below.
// We don't use this because multiple selection virtual
// wxListCtrl does generates deselection events only for
// control-click; see OnCheckSelectionChanged() below.
void CBOINCBaseView::OnListDeselected(wxListEvent& event) {
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseView::OnListDeselected - Function Begin"));
@ -367,13 +368,14 @@ void CBOINCBaseView::OnListDeselected(wxListEvent& event) {
}
// Work around bugs (features?) in virtual list control:
// * It does not send deselection events.
// * It (apparently intentionally) does not send selection
// events if you add to selection using Shift_Click.
// Work around features in multiple selection virtual wxListCtrl:
// * It does not send deselection events (except ctrl-click).
// * It does not send selection events if you add to selection
// using Shift_Click.
//
// We currently handle all selections and deselections here.
void CBOINCBaseView::OnCacheHint(wxListEvent& event) {
// We currently handle all selections and deselections here. This
// is called due to an event posted by CBOINCListCtrl::OnMouseUp().
void CBOINCBaseView::OnCheckSelectionChanged(CCheckSelectionChangedEvent& ) {
int newSelectionCount = m_pListPane->GetSelectedItemCount();
long currentSelection = m_pListPane->GetFirstSelected();
@ -388,7 +390,6 @@ void CBOINCBaseView::OnCacheHint(wxListEvent& event) {
m_iPreviousSelectionCount = newSelectionCount;
m_lPreviousFirstSelection = currentSelection;
event.Skip();
}

View File

@ -22,11 +22,13 @@
#pragma interface "BOINCBaseView.cpp"
#endif
#define DEFAULT_TASK_FLAGS wxTAB_TRAVERSAL | wxADJUST_MINSIZE | wxFULL_REPAINT_ON_RESIZE
#define DEFAULT_LIST_FLAGS wxLC_REPORT | wxLC_VIRTUAL | wxLC_HRULES
class CBOINCTaskCtrl;
class CBOINCListCtrl;
class CCheckSelectionChangedEvent;
struct PROJECT;
@ -146,7 +148,7 @@ protected:
virtual void OnListRender( wxTimerEvent& event );
virtual void OnListSelected( wxListEvent& event );
virtual void OnListDeselected( wxListEvent& event );
virtual void OnCacheHint(wxListEvent& event);
virtual void OnCheckSelectionChanged(CCheckSelectionChangedEvent& event);
virtual wxString OnListGetItemText( long item, long column ) const;
virtual int OnListGetItemImage( long item ) const;
@ -202,6 +204,5 @@ protected:
CBOINCListCtrl* m_pListPane;
};
#endif

View File

@ -25,18 +25,23 @@
#include "Events.h"
DEFINE_EVENT_TYPE(wxEVT_CHECK_SELECTION_CHANGED)
#if USE_NATIVE_LISTCONTROL
DEFINE_EVENT_TYPE(wxEVT_DRAW_PROGRESSBAR)
BEGIN_EVENT_TABLE(CBOINCListCtrl, LISTCTRL_BASE)
EVT_DRAW_PROGRESSBAR(CBOINCListCtrl::OnDrawProgressBar)
EVT_LEFT_DOWN(CBOINCListCtrl::OnMouseClick)
EVT_LEFT_UP(CBOINCListCtrl::OnMouseClick)
END_EVENT_TABLE()
#else
BEGIN_EVENT_TABLE(CBOINCListCtrl, LISTCTRL_BASE)
EVT_SIZE(CBOINCListCtrl::OnSize)
EVT_LEFT_DOWN(CBOINCListCtrl::OnMouseClick)
END_EVENT_TABLE()
#endif
@ -383,6 +388,27 @@ void MyEvtHandler::OnPaint(wxPaintEvent & event)
#endif
// Work around features in multiple selection virtual wxListCtrl:
// * It does not send deselection events (except ctrl-click).
// * It does not send selection events if you add to selection
// using Shift_Click.
//
// Post a special event. This will allow this mouse event to
// propogate through the chain to complete any selection or
// deselection operatiion, then the special event will trigger
// CBOINCBaseView::OnCheckSelectionChanged() to respond to the
// selection change, if any.
// On Windows, selection occurs on mouse down but deselection
// occurs on mouse up, so we must check after both events.
//
void CBOINCListCtrl::OnMouseClick(wxMouseEvent& event) {
CCheckSelectionChangedEvent newEvent(wxEVT_CHECK_SELECTION_CHANGED, this);
m_pParentView->GetEventHandler()->AddPendingEvent(newEvent);
event.Skip();
}
// To reduce flicker, refresh only changed columns (except
// on Mac, which is double-buffered to eliminate flicker.)
void CBOINCListCtrl::RefreshCell(int row, int col) {

View File

@ -96,6 +96,7 @@ private:
void SetupMacAccessibilitySupport();
void RemoveMacAccessibilitySupport();
void OnSize( wxSizeEvent &event );
void OnMouseClick(wxMouseEvent& event);
void* m_fauxHeaderView;
void* m_fauxBodyView;
@ -117,12 +118,28 @@ public:
virtual wxEvent * Clone() const { return new CDrawProgressBarEvent(*this); }
};
class CCheckSelectionChangedEvent : public wxEvent
{
public:
CCheckSelectionChangedEvent(wxEventType evtType, CBOINCListCtrl* myCtrl)
: wxEvent(-1, evtType)
{
SetEventObject(myCtrl);
}
virtual wxEvent * Clone() const { return new CCheckSelectionChangedEvent(*this); }
};
BEGIN_DECLARE_EVENT_TYPES()
DECLARE_EVENT_TYPE( wxEVT_DRAW_PROGRESSBAR, 12000 )
DECLARE_EVENT_TYPE( wxEVT_CHECK_SELECTION_CHANGED, 12002 )
END_DECLARE_EVENT_TYPES()
#define EVT_DRAW_PROGRESSBAR(fn) DECLARE_EVENT_TABLE_ENTRY(wxEVT_DRAW_PROGRESSBAR, -1, -1, (wxObjectEventFunction) (wxEventFunction) &fn, NULL),
#define EVT_CHECK_SELECTION_CHANGED(fn) DECLARE_EVENT_TABLE_ENTRY(wxEVT_CHECK_SELECTION_CHANGED, -1, -1, (wxObjectEventFunction) (wxEventFunction) &fn, NULL),
// Define a custom event handler
class MyEvtHandler : public wxEvtHandler

View File

@ -82,11 +82,7 @@ BEGIN_EVENT_TABLE (CViewProjects, CBOINCBaseView)
EVT_BUTTON(ID_TASK_PROJECT_DETACH, CViewProjects::OnProjectDetach)
EVT_BUTTON(ID_TASK_PROJECT_SHOW_PROPERTIES, CViewProjects::OnShowItemProperties)
EVT_CUSTOM_RANGE(wxEVT_COMMAND_BUTTON_CLICKED, ID_TASK_PROJECT_WEB_PROJDEF_MIN, ID_TASK_PROJECT_WEB_PROJDEF_MAX, CViewProjects::OnProjectWebsiteClicked)
// We currently handle EVT_LIST_CACHE_HINT instead of EVT_LIST_ITEM_SELECTED
// or EVT_LIST_ITEM_DESELECTED. See CBOINCBaseView::OnCacheHint() for info.
// EVT_LIST_ITEM_SELECTED(ID_LIST_PROJECTSVIEW, CViewProjects::OnListSelected)
// EVT_LIST_ITEM_DESELECTED(ID_LIST_PROJECTSVIEW, CViewProjects::OnListDeselected)
EVT_LIST_CACHE_HINT(ID_LIST_PROJECTSVIEW, CViewProjects::OnCacheHint)
EVT_CHECK_SELECTION_CHANGED(CViewProjects::OnCheckSelectionChanged)
EVT_LIST_COL_CLICK(ID_LIST_PROJECTSVIEW, CViewProjects::OnColClick)
EVT_LIST_COL_END_DRAG(ID_LIST_PROJECTSVIEW, CViewProjects::OnColResize)
END_EVENT_TABLE ()

View File

@ -68,11 +68,7 @@ IMPLEMENT_DYNAMIC_CLASS(CViewTransfers, CBOINCBaseView)
BEGIN_EVENT_TABLE (CViewTransfers, CBOINCBaseView)
EVT_BUTTON(ID_TASK_TRANSFERS_RETRYNOW, CViewTransfers::OnTransfersRetryNow)
EVT_BUTTON(ID_TASK_TRANSFERS_ABORT, CViewTransfers::OnTransfersAbort)
// We currently handle EVT_LIST_CACHE_HINT instead of EVT_LIST_ITEM_SELECTED
// or EVT_LIST_ITEM_DESELECTED. See CBOINCBaseView::OnCacheHint() for info.
// EVT_LIST_ITEM_SELECTED(ID_LIST_TRANSFERSVIEW, CViewTransfers::OnListSelected)
// EVT_LIST_ITEM_DESELECTED(ID_LIST_TRANSFERSVIEW, CViewTransfers::OnListDeselected)
EVT_LIST_CACHE_HINT(ID_LIST_TRANSFERSVIEW, CViewTransfers::OnCacheHint)
EVT_CHECK_SELECTION_CHANGED(CViewTransfers::OnCheckSelectionChanged)
EVT_LIST_COL_CLICK(ID_LIST_TRANSFERSVIEW, CViewTransfers::OnColClick)
EVT_LIST_COL_END_DRAG(ID_LIST_TRANSFERSVIEW, CViewTransfers::OnColResize)
END_EVENT_TABLE ()

View File

@ -89,11 +89,7 @@ BEGIN_EVENT_TABLE (CViewWork, CBOINCBaseView)
EVT_BUTTON(ID_TASK_SHOW_PROPERTIES, CViewWork::OnShowItemProperties)
EVT_BUTTON(ID_TASK_ACTIVE_ONLY, CViewWork::OnActiveTasksOnly)
EVT_CUSTOM_RANGE(wxEVT_COMMAND_BUTTON_CLICKED, ID_TASK_PROJECT_WEB_PROJDEF_MIN, ID_TASK_PROJECT_WEB_PROJDEF_MAX, CViewWork::OnProjectWebsiteClicked)
// We currently handle EVT_LIST_CACHE_HINT instead of EVT_LIST_ITEM_SELECTED
// or EVT_LIST_ITEM_DESELECTED. See CBOINCBaseView::OnCacheHint() for info.
// EVT_LIST_ITEM_SELECTED(ID_LIST_WORKVIEW, CViewWork::OnListSelected)
// EVT_LIST_ITEM_DESELECTED(ID_LIST_WORKVIEW, CViewWork::OnListDeselected)
EVT_LIST_CACHE_HINT(ID_LIST_WORKVIEW, CViewWork::OnCacheHint)
EVT_CHECK_SELECTION_CHANGED(CViewWork::OnCheckSelectionChanged)
EVT_LIST_COL_CLICK(ID_LIST_WORKVIEW, CViewWork::OnColClick)
EVT_LIST_COL_END_DRAG(ID_LIST_WORKVIEW, CViewWork::OnColResize)
END_EVENT_TABLE ()