Merge branch listctrl-with-checkboxes
Add support for native checkboxes to wxMSW wxListCtrl. Closes https://github.com/wxWidgets/wxWidgets/pull/153
This commit is contained in:
@@ -199,6 +199,7 @@ wxMSW:
|
||||
- Return correct OS version under Windows 8.1 and later.
|
||||
- Fix crash in wxD2DContext when using non-MSVC compiler (iwbnwif).
|
||||
- Notify shell about the changes done by wxMimeTypesManager (Maarten Bent).
|
||||
- Add support for using checkboxes to wxListCtrl (Maarten Bent);
|
||||
|
||||
wxOSX/Cocoa:
|
||||
|
||||
|
@@ -460,6 +460,12 @@ public:
|
||||
void SetAlternateRowColour(const wxColour& colour);
|
||||
wxColour GetAlternateRowColour() const { return m_alternateRowColour.GetBackgroundColour(); }
|
||||
|
||||
// Checkboxes support: only implemented in wxMSW currently.
|
||||
virtual bool HasCheckboxes() const { return false; }
|
||||
virtual bool EnableCheckboxes(bool WXUNUSED(enable) = true) { return false; }
|
||||
virtual bool IsItemChecked(long WXUNUSED(item)) const { return false; }
|
||||
virtual void CheckItem(long WXUNUSED(item), bool WXUNUSED(check)) { }
|
||||
|
||||
protected:
|
||||
// Real implementations methods to which our public forwards.
|
||||
virtual long DoInsertColumn(long col, const wxListItem& info) = 0;
|
||||
@@ -563,6 +569,8 @@ wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_LIST_COL_BEGIN_DRAG, wxListEve
|
||||
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_LIST_COL_DRAGGING, wxListEvent );
|
||||
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_LIST_COL_END_DRAG, wxListEvent );
|
||||
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_LIST_ITEM_FOCUSED, wxListEvent );
|
||||
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_LIST_ITEM_CHECKED, wxListEvent );
|
||||
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_LIST_ITEM_UNCHECKED, wxListEvent );
|
||||
|
||||
typedef void (wxEvtHandler::*wxListEventFunction)(wxListEvent&);
|
||||
|
||||
@@ -593,6 +601,8 @@ typedef void (wxEvtHandler::*wxListEventFunction)(wxListEvent&);
|
||||
#define EVT_LIST_ITEM_MIDDLE_CLICK(id, fn) wx__DECLARE_LISTEVT(ITEM_MIDDLE_CLICK, id, fn)
|
||||
#define EVT_LIST_ITEM_ACTIVATED(id, fn) wx__DECLARE_LISTEVT(ITEM_ACTIVATED, id, fn)
|
||||
#define EVT_LIST_ITEM_FOCUSED(id, fn) wx__DECLARE_LISTEVT(ITEM_FOCUSED, id, fn)
|
||||
#define EVT_LIST_ITEM_CHECKED(id, fn) wx__DECLARE_LISTEVT(ITEM_CHECKED, id, fn)
|
||||
#define EVT_LIST_ITEM_UNCHECKED(id, fn) wx__DECLARE_LISTEVT(ITEM_UNCHECKED, id, fn)
|
||||
|
||||
#define EVT_LIST_CACHE_HINT(id, fn) wx__DECLARE_LISTEVT(CACHE_HINT, id, fn)
|
||||
|
||||
|
@@ -216,6 +216,12 @@ public:
|
||||
void SetItemFont( long item, const wxFont &f);
|
||||
wxFont GetItemFont( long item ) const;
|
||||
|
||||
// Checkbox state of an item
|
||||
virtual bool HasCheckboxes() const wxOVERRIDE;
|
||||
virtual bool EnableCheckboxes(bool enable = true) wxOVERRIDE;
|
||||
virtual bool IsItemChecked(long item) const wxOVERRIDE;
|
||||
virtual void CheckItem(long item, bool check) wxOVERRIDE;
|
||||
|
||||
// Gets the number of selected items in the list control
|
||||
int GetSelectedItemCount() const;
|
||||
|
||||
|
@@ -256,6 +256,12 @@ enum
|
||||
@event{EVT_LIST_CACHE_HINT(id, func)}
|
||||
Prepare cache for a virtual list control.
|
||||
Processes a @c wxEVT_LIST_CACHE_HINT event type.
|
||||
@event{EVT_LIST_ITEM_CHECKED(id, func)}
|
||||
The item has been checked.
|
||||
Processes a @c wxEVT_LIST_ITEM_CHECKED event type (new since wxWidgets 3.1.0).
|
||||
@event{EVT_LIST_ITEM_UNCHECKED(id, func)}
|
||||
The item has been unchecked.
|
||||
Processes a @c wxEVT_LIST_ITEM_UNCHECKED event type (new since wxWidgets 3.1.0).
|
||||
@endEventTable
|
||||
|
||||
@note Under wxMSW this control uses wxSystemThemedControl for an explorer
|
||||
@@ -1221,6 +1227,52 @@ public:
|
||||
*/
|
||||
bool SortItems(wxListCtrlCompare fnSortCallBack, wxIntPtr data);
|
||||
|
||||
/**
|
||||
Returns true if checkboxes are enabled for list items.
|
||||
|
||||
@see EnableCheckboxes()
|
||||
|
||||
@since 3.1.0
|
||||
*/
|
||||
bool HasCheckboxes() const;
|
||||
|
||||
/**
|
||||
Enable or disable checkboxes for list items.
|
||||
|
||||
This method is only implemented for wxMSW native control currently, it
|
||||
will always simply return false in the other ports.
|
||||
|
||||
@param enable If @true, enable checkboxes, otherwise disable checkboxes.
|
||||
@return @true if checkboxes are supported, @false otherwise.
|
||||
|
||||
@since 3.1.0
|
||||
*/
|
||||
void EnableCheckboxes(bool enable = true);
|
||||
|
||||
/**
|
||||
Return true if the checkbox for the given wxListItem is checked.
|
||||
|
||||
Always returns false if checkboxes support hadn't been enabled.
|
||||
|
||||
@param item Item (zero-based) index.
|
||||
|
||||
@since 3.1.0
|
||||
*/
|
||||
bool IsItemChecked(long item) const;
|
||||
|
||||
/**
|
||||
Check or uncheck a wxListItem in a control using checkboxes.
|
||||
|
||||
This method only works if checkboxes support had been successfully
|
||||
enabled using EnableCheckboxes().
|
||||
|
||||
@param item Item (zero-based) index.
|
||||
@param check If @true, check the item, otherwise uncheck.
|
||||
|
||||
@since 3.1.0
|
||||
*/
|
||||
void CheckItem(long item, bool check);
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
@@ -1343,6 +1395,10 @@ protected:
|
||||
A column has been resized by the user.
|
||||
@event{EVT_LIST_CACHE_HINT(id, func)}
|
||||
Prepare cache for a virtual list control
|
||||
@event{EVT_LIST_ITEM_CHECKED(id, func)}
|
||||
The item has been checked (new since wxWidgets 3.1.0).
|
||||
@event{EVT_LIST_ITEM_UNCHECKED(id, func)}
|
||||
The item has been unchecked (new since wxWidgets 3.1.0).
|
||||
@endEventTable
|
||||
|
||||
|
||||
@@ -1456,6 +1512,8 @@ wxEventType wxEVT_LIST_COL_BEGIN_DRAG;
|
||||
wxEventType wxEVT_LIST_COL_DRAGGING;
|
||||
wxEventType wxEVT_LIST_COL_END_DRAG;
|
||||
wxEventType wxEVT_LIST_ITEM_FOCUSED;
|
||||
wxEventType wxEVT_LIST_ITEM_CHECKED;
|
||||
wxEventType wxEVT_LIST_ITEM_UNCHECKED;
|
||||
|
||||
|
||||
/**
|
||||
|
@@ -154,11 +154,15 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
||||
EVT_MENU(LIST_MAC_USE_GENERIC, MyFrame::OnToggleMacUseGeneric)
|
||||
#endif // __WXOSX__
|
||||
EVT_MENU(LIST_FIND, MyFrame::OnFind)
|
||||
EVT_MENU(LIST_TOGGLE_CHECKBOX, MyFrame::OnToggleItemCheckbox)
|
||||
EVT_MENU(LIST_GET_CHECKBOX, MyFrame::OnGetItemCheckbox)
|
||||
EVT_MENU(LIST_TOGGLE_CHECKBOXES, MyFrame::OnToggleCheckboxes)
|
||||
|
||||
EVT_UPDATE_UI(LIST_SHOW_COL_INFO, MyFrame::OnUpdateUIEnableInReport)
|
||||
EVT_UPDATE_UI(LIST_TOGGLE_HEADER, MyFrame::OnUpdateUIEnableInReport)
|
||||
|
||||
EVT_UPDATE_UI(LIST_TOGGLE_MULTI_SEL, MyFrame::OnUpdateToggleMultiSel)
|
||||
EVT_UPDATE_UI(LIST_TOGGLE_CHECKBOXES, MyFrame::OnUpdateToggleCheckboxes)
|
||||
EVT_UPDATE_UI(LIST_TOGGLE_HEADER, MyFrame::OnUpdateToggleHeader)
|
||||
EVT_UPDATE_UI(LIST_ROW_LINES, MyFrame::OnUpdateRowLines)
|
||||
wxEND_EVENT_TABLE()
|
||||
@@ -261,6 +265,12 @@ MyFrame::MyFrame(const wxChar *title)
|
||||
menuList->AppendCheckItem(LIST_TOGGLE_HEADER, "Toggle &header\tCtrl-H");
|
||||
menuList->Check(LIST_TOGGLE_HEADER, true);
|
||||
menuList->AppendCheckItem(LIST_TOGGLE_BELL, "Toggle &bell on no match");
|
||||
menuList->AppendSeparator();
|
||||
menuList->AppendCheckItem(LIST_TOGGLE_CHECKBOXES,
|
||||
wxT("&Enable Checkboxes"));
|
||||
menuList->Check(LIST_TOGGLE_CHECKBOXES, true);
|
||||
menuList->Append(LIST_TOGGLE_CHECKBOX, wxT("Toggle the item checkbox state"));
|
||||
menuList->Append(LIST_GET_CHECKBOX, wxT("Get the item checkbox state"));
|
||||
|
||||
wxMenu *menuCol = new wxMenu;
|
||||
menuCol->Append(LIST_SET_FG_COL, wxT("&Foreground colour..."));
|
||||
@@ -835,6 +845,27 @@ void MyFrame::OnUpdateToggleMultiSel(wxUpdateUIEvent& event)
|
||||
event.Check(!m_listCtrl->HasFlag(wxLC_SINGLE_SEL));
|
||||
}
|
||||
|
||||
void MyFrame::OnToggleCheckboxes(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
if ( !m_listCtrl->EnableCheckboxes(!m_listCtrl->HasCheckboxes()) )
|
||||
{
|
||||
wxLogMessage("Failed to toggle checkboxes (not supported?)");
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogMessage("Checkboxes are now %s",
|
||||
m_listCtrl->HasCheckboxes() ? "enabled" : "disabled");
|
||||
}
|
||||
}
|
||||
|
||||
void MyFrame::OnUpdateToggleCheckboxes(wxUpdateUIEvent& event)
|
||||
{
|
||||
bool cbEnabled = m_listCtrl->HasCheckboxes();
|
||||
event.Check(cbEnabled);
|
||||
GetMenuBar()->Enable(LIST_TOGGLE_CHECKBOX, cbEnabled);
|
||||
GetMenuBar()->Enable(LIST_GET_CHECKBOX, cbEnabled);
|
||||
}
|
||||
|
||||
void MyFrame::OnUpdateToggleHeader(wxUpdateUIEvent& event)
|
||||
{
|
||||
event.Check(!m_listCtrl->HasFlag(wxLC_NO_HEADER));
|
||||
@@ -893,6 +924,33 @@ void MyFrame::OnEdit(wxCommandEvent& WXUNUSED(event))
|
||||
}
|
||||
}
|
||||
|
||||
void MyFrame::OnToggleItemCheckbox(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
long item = m_listCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
|
||||
while (item != -1)
|
||||
{
|
||||
bool checked = m_listCtrl->IsItemChecked(item);
|
||||
m_listCtrl->CheckItem(item, !checked);
|
||||
|
||||
item = m_listCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
|
||||
wxLIST_STATE_SELECTED);
|
||||
}
|
||||
}
|
||||
|
||||
void MyFrame::OnGetItemCheckbox(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
long item = m_listCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
|
||||
while (item != -1)
|
||||
{
|
||||
bool checked = m_listCtrl->IsItemChecked(item);
|
||||
|
||||
wxLogMessage(wxT("Item %ld is %s"), item, checked ? wxT("checked") : wxT("unchecked"));
|
||||
|
||||
item = m_listCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
|
||||
wxLIST_STATE_SELECTED);
|
||||
}
|
||||
}
|
||||
|
||||
void MyFrame::OnDelete(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
if ( m_listCtrl->GetItemCount() )
|
||||
@@ -935,6 +993,8 @@ wxBEGIN_EVENT_TABLE(MyListCtrl, wxListCtrl)
|
||||
EVT_LIST_KEY_DOWN(LIST_CTRL, MyListCtrl::OnListKeyDown)
|
||||
EVT_LIST_ITEM_ACTIVATED(LIST_CTRL, MyListCtrl::OnActivated)
|
||||
EVT_LIST_ITEM_FOCUSED(LIST_CTRL, MyListCtrl::OnFocused)
|
||||
EVT_LIST_ITEM_CHECKED(LIST_CTRL, MyListCtrl::OnChecked)
|
||||
EVT_LIST_ITEM_UNCHECKED(LIST_CTRL, MyListCtrl::OnUnChecked)
|
||||
|
||||
EVT_LIST_ITEM_RIGHT_CLICK(LIST_CTRL, MyListCtrl::OnItemRightClick)
|
||||
|
||||
@@ -1127,6 +1187,20 @@ void MyListCtrl::OnItemRightClick(wxListEvent& event)
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void MyListCtrl::OnChecked(wxListEvent& event)
|
||||
{
|
||||
LogEvent(event, wxT("OnChecked"));
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void MyListCtrl::OnUnChecked(wxListEvent& event)
|
||||
{
|
||||
LogEvent(event, wxT("OnUnChecked"));
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void MyListCtrl::OnListKeyDown(wxListEvent& event)
|
||||
{
|
||||
long item;
|
||||
|
@@ -62,6 +62,8 @@ public:
|
||||
void OnActivated(wxListEvent& event);
|
||||
void OnFocused(wxListEvent& event);
|
||||
void OnItemRightClick(wxListEvent& event);
|
||||
void OnChecked(wxListEvent& event);
|
||||
void OnUnChecked(wxListEvent& event);
|
||||
void OnCacheHint(wxListEvent& event);
|
||||
|
||||
void OnChar(wxKeyEvent& event);
|
||||
@@ -147,9 +149,13 @@ protected:
|
||||
void OnToggleMacUseGeneric(wxCommandEvent& event);
|
||||
#endif // __WXOSX__
|
||||
void OnFind(wxCommandEvent& event);
|
||||
void OnToggleItemCheckbox(wxCommandEvent& event);
|
||||
void OnGetItemCheckbox(wxCommandEvent& event);
|
||||
void OnToggleCheckboxes(wxCommandEvent& event);
|
||||
|
||||
void OnUpdateUIEnableInReport(wxUpdateUIEvent& event);
|
||||
void OnUpdateToggleMultiSel(wxUpdateUIEvent& event);
|
||||
void OnUpdateToggleCheckboxes(wxUpdateUIEvent& event);
|
||||
void OnUpdateToggleHeader(wxUpdateUIEvent& event);
|
||||
void OnUpdateRowLines(wxUpdateUIEvent& event);
|
||||
|
||||
@@ -218,6 +224,9 @@ enum
|
||||
LIST_TOGGLE_MULTI_SEL,
|
||||
LIST_TOGGLE_HEADER,
|
||||
LIST_TOGGLE_BELL,
|
||||
LIST_TOGGLE_CHECKBOX,
|
||||
LIST_GET_CHECKBOX,
|
||||
LIST_TOGGLE_CHECKBOXES,
|
||||
LIST_TOGGLE_FIRST,
|
||||
LIST_SHOW_COL_INFO,
|
||||
LIST_SHOW_SEL_INFO,
|
||||
|
@@ -52,6 +52,8 @@ wxDEFINE_EVENT( wxEVT_LIST_ITEM_RIGHT_CLICK, wxListEvent );
|
||||
wxDEFINE_EVENT( wxEVT_LIST_ITEM_MIDDLE_CLICK, wxListEvent );
|
||||
wxDEFINE_EVENT( wxEVT_LIST_ITEM_ACTIVATED, wxListEvent );
|
||||
wxDEFINE_EVENT( wxEVT_LIST_ITEM_FOCUSED, wxListEvent );
|
||||
wxDEFINE_EVENT( wxEVT_LIST_ITEM_CHECKED, wxListEvent );
|
||||
wxDEFINE_EVENT( wxEVT_LIST_ITEM_UNCHECKED, wxListEvent );
|
||||
wxDEFINE_EVENT( wxEVT_LIST_CACHE_HINT, wxListEvent );
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@@ -1211,6 +1211,30 @@ wxFont wxListCtrl::GetItemFont( long item ) const
|
||||
return f;
|
||||
}
|
||||
|
||||
bool wxListCtrl::HasCheckboxes() const
|
||||
{
|
||||
const DWORD currStyle = ListView_GetExtendedListViewStyle(GetHwnd());
|
||||
return (currStyle & LVS_EX_CHECKBOXES) != 0;
|
||||
}
|
||||
|
||||
bool wxListCtrl::EnableCheckboxes(bool enable)
|
||||
{
|
||||
LPARAM newStyle = enable ? LVS_EX_CHECKBOXES : 0;
|
||||
ListView_SetExtendedListViewStyleEx(GetHwnd(), LVS_EX_CHECKBOXES, newStyle);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void wxListCtrl::CheckItem(long item, bool state)
|
||||
{
|
||||
ListView_SetCheckState(GetHwnd(), (UINT)item, (BOOL)state);
|
||||
}
|
||||
|
||||
bool wxListCtrl::IsItemChecked(long item) const
|
||||
{
|
||||
return ListView_GetCheckState(GetHwnd(), (UINT)item) != 0;
|
||||
}
|
||||
|
||||
// Gets the number of selected items in the list control
|
||||
int wxListCtrl::GetSelectedItemCount() const
|
||||
{
|
||||
@@ -2216,6 +2240,31 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
|
||||
? wxEVT_LIST_ITEM_SELECTED
|
||||
: wxEVT_LIST_ITEM_DESELECTED;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if ( eventType == wxEVT_NULL )
|
||||
|
Reference in New Issue
Block a user