Merge branch 'listctrl-checkboxes-generic' of https://github.com/MaartenBent/wxWidgets

Implement checkboxes support for the generic version of wxListCtrl too so it's
not available under all platforms.
This commit is contained in:
Vadim Zeitlin
2016-02-06 19:18:58 +01:00
4 changed files with 134 additions and 5 deletions

View File

@@ -96,6 +96,7 @@ All (GUI):
- Allow customizing window shown by wxBusyInfo. - Allow customizing window shown by wxBusyInfo.
- Add wxAddRemoveCtrl. - Add wxAddRemoveCtrl.
- Add wxAppProgressIndicator for MSW (Chaobin Zhang) and OS X (Tobias Taschner). - Add wxAppProgressIndicator for MSW (Chaobin Zhang) and OS X (Tobias Taschner).
- Add support for using checkboxes to wxListCtrl (Maarten Bent).
- Add wxListBox::GetTopItem() and GetCountPerPage() (Andreas Falkenhahn). - Add wxListBox::GetTopItem() and GetCountPerPage() (Andreas Falkenhahn).
- Add wxTextEntry::ForceUpper(). - Add wxTextEntry::ForceUpper().
- Add wxTextEntryDialog::ForceUpper(). - Add wxTextEntryDialog::ForceUpper().
@@ -201,7 +202,6 @@ wxMSW:
- Return correct OS version under Windows 8.1 and later. - Return correct OS version under Windows 8.1 and later.
- Fix crash in wxD2DContext when using non-MSVC compiler (iwbnwif). - Fix crash in wxD2DContext when using non-MSVC compiler (iwbnwif).
- Notify shell about the changes done by wxMimeTypesManager (Maarten Bent). - Notify shell about the changes done by wxMimeTypesManager (Maarten Bent).
- Add support for using checkboxes to wxListCtrl (Maarten Bent);
wxOSX/Cocoa: wxOSX/Cocoa:

View File

@@ -101,6 +101,11 @@ public:
void SetTextColour(const wxColour& col); void SetTextColour(const wxColour& col);
long GetTopItem() const; long GetTopItem() const;
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;
void SetSingleStyle( long style, bool add = true ) ; void SetSingleStyle( long style, bool add = true ) ;
void SetWindowStyleFlag( long style ) wxOVERRIDE; void SetWindowStyleFlag( long style ) wxOVERRIDE;
void RecreateWindow() {} void RecreateWindow() {}

View File

@@ -200,6 +200,8 @@ public:
// is this item selected? [NB: not used in virtual mode] // is this item selected? [NB: not used in virtual mode]
bool m_highlighted; bool m_highlighted;
bool m_checked;
// back pointer to the list ctrl // back pointer to the list ctrl
wxListMainWindow *m_owner; wxListMainWindow *m_owner;
@@ -249,6 +251,9 @@ public:
void SetImage( int index, int image ); void SetImage( int index, int image );
int GetImage( int index ) const; int GetImage( int index ) const;
void Check(bool check) { m_checked = check; }
bool IsChecked() { return m_checked; }
bool HasImage() const { return GetImage() != -1; } bool HasImage() const { return GetImage() != -1; }
bool HasText() const { return !GetText(0).empty(); } bool HasText() const { return !GetText(0).empty(); }
@@ -636,6 +641,11 @@ public:
bool GetItemPosition( long item, wxPoint& pos ) const; bool GetItemPosition( long item, wxPoint& pos ) const;
int GetSelectedItemCount() const; int GetSelectedItemCount() const;
bool HasCheckboxes() const;
bool EnableCheckboxes(bool enable = true);
bool IsItemChecked(long item) const;
void CheckItem(long item, bool check);
wxString GetItemText(long item, int col = 0) const wxString GetItemText(long item, int col = 0) const
{ {
wxListItem info; wxListItem info;
@@ -779,6 +789,8 @@ protected:
m_lineBeforeLastClicked, m_lineBeforeLastClicked,
m_lineSelectSingleOnUp; m_lineSelectSingleOnUp;
bool m_hasCheckboxes;
protected: protected:
wxWindow *GetMainWindowOfCompositeControl() wxOVERRIDE { return GetParent(); } wxWindow *GetMainWindowOfCompositeControl() wxOVERRIDE { return GetParent(); }
@@ -838,6 +850,10 @@ private:
// Compute the minimal width needed to fully display the column header. // Compute the minimal width needed to fully display the column header.
int ComputeMinHeaderWidth(const wxListHeaderData* header) const; int ComputeMinHeaderWidth(const wxListHeaderData* header) const;
// Check if the given point is inside the checkbox of this item.
//
// Always returns false if there are no checkboxes.
bool IsInsideCheckbox(long item, int x, int y);
// the height of one line using the current font // the height of one line using the current font
wxCoord m_lineHeight; wxCoord m_lineHeight;

View File

@@ -46,7 +46,7 @@
#endif #endif
#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__) #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
#define "wx/msw/wrapwin.h" #include "wx/msw/wrapwin.h"
#endif #endif
// NOTE: If using the wxListBox visual attributes works everywhere then this can // NOTE: If using the wxListBox visual attributes works everywhere then this can
@@ -102,6 +102,8 @@ static const int IMAGE_MARGIN_IN_REPORT_MODE = 5;
// the space between the image and the text in the report mode in header // the space between the image and the text in the report mode in header
static const int HEADER_IMAGE_MARGIN_IN_REPORT_MODE = 2; static const int HEADER_IMAGE_MARGIN_IN_REPORT_MODE = 2;
// space after a checkbox
static const int MARGIN_AROUND_CHECKBOX = 5;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -410,6 +412,7 @@ wxListLineData::wxListLineData( wxListMainWindow *owner )
m_gi = new GeometryInfo; m_gi = new GeometryInfo;
m_highlighted = false; m_highlighted = false;
m_checked = false;
InitItems( GetMode() == wxLC_REPORT ? m_owner->GetColumnCount() : 1 ); InitItems( GetMode() == wxLC_REPORT ? m_owner->GetColumnCount() : 1 );
} }
@@ -794,6 +797,21 @@ void wxListLineData::DrawInReportMode( wxDC *dc,
x += 2; x += 2;
#endif #endif
if ( m_owner->HasCheckboxes() )
{
wxSize cbSize = wxRendererNative::Get().GetCheckBoxSize(m_owner);
int yOffset = (rect.height - cbSize.GetHeight()) / 2;
wxRect rr(wxPoint(x, rect.y + yOffset), cbSize);
rr.x += MARGIN_AROUND_CHECKBOX;
int flags = 0;
if (m_checked)
flags |= wxCONTROL_CHECKED;
wxRendererNative::Get().DrawCheckBox(m_owner, *dc, rr, flags);
x += cbSize.GetWidth() + (2 * MARGIN_AROUND_CHECKBOX);
}
size_t col = 0; size_t col = 0;
for ( wxListItemDataList::compatibility_iterator node = m_items.GetFirst(); for ( wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
node; node;
@@ -802,6 +820,8 @@ void wxListLineData::DrawInReportMode( wxDC *dc,
wxListItemData *item = node->GetData(); wxListItemData *item = node->GetData();
int width = m_owner->GetColumnWidth(col); int width = m_owner->GetColumnWidth(col);
if (col == 0 && m_owner->HasCheckboxes())
width -= x;
int xOld = x; int xOld = x;
x += width; x += width;
@@ -1588,6 +1608,8 @@ void wxListMainWindow::Init()
m_lineLastClicked = m_lineLastClicked =
m_lineSelectSingleOnUp = m_lineSelectSingleOnUp =
m_lineBeforeLastClicked = (size_t)-1; m_lineBeforeLastClicked = (size_t)-1;
m_hasCheckboxes = false;
} }
wxListMainWindow::wxListMainWindow() wxListMainWindow::wxListMainWindow()
@@ -2557,7 +2579,11 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
bool cmdModifierDown = event.CmdDown(); bool cmdModifierDown = event.CmdDown();
if ( IsSingleSel() || !(cmdModifierDown || event.ShiftDown()) ) if ( IsSingleSel() || !(cmdModifierDown || event.ShiftDown()) )
{ {
if ( IsSingleSel() || !IsHighlighted(current) ) if (IsInsideCheckbox(current, x, y))
{
CheckItem(current, !IsItemChecked(current));
}
else if (IsSingleSel() || !IsHighlighted(current))
{ {
HighlightAll(false); HighlightAll(false);
@@ -3673,6 +3699,58 @@ bool wxListMainWindow::GetItemPosition(long item, wxPoint& pos) const
return true; return true;
} }
// ----------------------------------------------------------------------------
// checkboxes
// ----------------------------------------------------------------------------
bool wxListMainWindow::HasCheckboxes() const
{
return m_hasCheckboxes;
}
bool wxListMainWindow::EnableCheckboxes(bool enable)
{
m_hasCheckboxes = enable;
m_dirty = true;
m_headerWidth = 0;
Refresh();
return true;
}
void wxListMainWindow::CheckItem(long item, bool state)
{
wxListLineData *line = GetLine((size_t)item);
line->Check(state);
RefreshLine(item);
SendNotify(item, state ? wxEVT_LIST_ITEM_CHECKED
: wxEVT_LIST_ITEM_UNCHECKED);
}
bool wxListMainWindow::IsItemChecked(long item) const
{
wxListLineData *line = GetLine((size_t)item);
return line->IsChecked();
}
bool wxListMainWindow::IsInsideCheckbox(long item, int x, int y)
{
if ( HasCheckboxes() )
{
wxRect lineRect = GetLineRect(item);
wxSize cbSize = wxRendererNative::Get().GetCheckBoxSize(this);
int yOffset = (lineRect.height - cbSize.GetHeight()) / 2;
wxRect rr(wxPoint(MARGIN_AROUND_CHECKBOX, lineRect.y + yOffset), cbSize);
return rr.Contains(wxPoint(x, y));
}
return false;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// geometry calculation // geometry calculation
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -4691,6 +4769,36 @@ void wxGenericListCtrl::OnScroll(wxScrollWinEvent& event)
event.Skip(); event.Skip();
} }
bool wxGenericListCtrl::HasCheckboxes() const
{
if (!InReportView())
return false;
return m_mainWin->HasCheckboxes();
}
bool wxGenericListCtrl::EnableCheckboxes(bool enable)
{
if (!InReportView())
return false;
return m_mainWin->EnableCheckboxes(enable);
}
void wxGenericListCtrl::CheckItem(long item, bool state)
{
if (InReportView())
m_mainWin->CheckItem(item, state);
}
bool wxGenericListCtrl::IsItemChecked(long item) const
{
if (!InReportView())
return false;
return m_mainWin->IsItemChecked(item);
}
void wxGenericListCtrl::SetSingleStyle( long style, bool add ) void wxGenericListCtrl::SetSingleStyle( long style, bool add )
{ {
wxASSERT_MSG( !(style & wxLC_VIRTUAL), wxASSERT_MSG( !(style & wxLC_VIRTUAL),