Merge branch 'virtual-list-sort-indicator'

Simplify recently added wxListCtrl sort indicators support and allow
using it with virtual list controls too.

See https://github.com/wxWidgets/wxWidgets/pull/2618
This commit is contained in:
Vadim Zeitlin
2021-12-14 19:28:20 +00:00
8 changed files with 69 additions and 125 deletions

View File

@@ -115,10 +115,7 @@ public:
bool IsItemChecked(long item) const wxOVERRIDE;
void CheckItem(long item, bool check) wxOVERRIDE;
void EnableSortIndicator(const bool enable = true) wxOVERRIDE;
bool IsSortIndicatorEnabled() const wxOVERRIDE;
void ShowSortIndicator(const int idx, const bool ascending = true) wxOVERRIDE;
void RemoveSortIndicator() wxOVERRIDE;
void ShowSortIndicator(int idx, bool ascending = true) wxOVERRIDE;
int GetSortIndicator() const wxOVERRIDE;
bool IsAscendingSortIndicator() const wxOVERRIDE;

View File

@@ -381,7 +381,6 @@ public:
int m_colToSend;
int m_widthToSend;
bool m_enableSortCol;
bool m_sortAsc;
int m_sortCol;

View File

@@ -447,12 +447,16 @@ public:
virtual void CheckItem(long WXUNUSED(item), bool WXUNUSED(check)) { }
// Sort indicator in header.
virtual void EnableSortIndicator(const bool WXUNUSED(enable) = true) { }
virtual bool IsSortIndicatorEnabled() const { return false; }
virtual void ShowSortIndicator(const int WXUNUSED(idx), const bool WXUNUSED(ascending) = true) { }
virtual void RemoveSortIndicator() { }
virtual void ShowSortIndicator(int WXUNUSED(col), bool WXUNUSED(ascending) = true) { }
void RemoveSortIndicator() { ShowSortIndicator(-1); }
virtual int GetSortIndicator() const { return -1; }
virtual bool IsAscendingSortIndicator() const { return true; }
bool GetUpdatedAscendingSortIndicator(int col) const
{
// If clicking on the same column by which we already sort, toggle the sort
// direction, otherwise use ascending sort by default.
return col == GetSortIndicator() ? !IsAscendingSortIndicator() : true;
}
protected:
// Return pointer to the corresponding m_imagesXXX.

View File

@@ -226,10 +226,7 @@ public:
void CheckItem(long item, bool check) wxOVERRIDE;
// Sort indicator in header
void EnableSortIndicator(const bool enable = true) wxOVERRIDE;
bool IsSortIndicatorEnabled() const wxOVERRIDE;
void ShowSortIndicator(const int idx, const bool ascending = true) wxOVERRIDE;
void RemoveSortIndicator() wxOVERRIDE;
void ShowSortIndicator(int idx, bool ascending = true) wxOVERRIDE;
int GetSortIndicator() const wxOVERRIDE;
bool IsAscendingSortIndicator() const wxOVERRIDE;
@@ -426,16 +423,16 @@ protected:
int m_colCount; // Windows doesn't have GetColumnCount so must
// keep track of inserted/deleted columns
bool m_enableSortCol;
bool m_sortAsc;
int m_sortCol;
// all wxMSWListItemData objects we use
wxVector<wxMSWListItemData *> m_internalData;
// true if we have any items with custom attributes
bool m_hasAnyAttr;
// m_sortAsc is only used if m_sortCol != -1
bool m_sortAsc;
int m_sortCol;
private:
// process NM_CUSTOMDRAW notification message
WXLPARAM OnCustomDraw(WXLPARAM lParam);
@@ -457,7 +454,7 @@ private:
// in-place editor control.
void OnCharHook(wxKeyEvent& event);
// Draw the sort arrow arror in the header.
// Draw the sort arrow in the header.
void DrawSortArrow();
// Object using for header custom drawing if necessary, may be NULL.

View File

@@ -1420,39 +1420,19 @@ public:
*/
void ExtendRulesAndAlternateColour(bool extend = true);
/**
Enable or disable showing a sort indicator in the header bar.
Sort indicators are only shown in report view.
When clicking on the header of a column, this column will get the sort-
indicator in ascending order, or toggle it in the opposite order. To
sort the list, call SortItems() in EVT_LIST_COL_CLICK.
@note In wxMSW, this will disable the header icon of the column.
@param enable
If @true, enable showing a sort indicator, otherwise disable.
@since 3.1.6
*/
void EnableSortIndicator(const bool enable);
/**
Returns true if a sort indicator is enabled.
@see EnableSortIndicator()
@since 3.1.6
*/
bool IsSortIndicatorEnabled() const;
/**
Show the sort indicator of a specific column in a specific direction.
Sort indicators have to be enabled using EnableSortIndicator().
Sort indicators are only shown in report view and in the native wxMSW
version override any column icon, i.e. if the sort indicator is shown
for a column, no (other) icon is shown.
This function should typically be called from EVT_LIST_COL_CLICK
handler.
@note This does not actually sort the list, use SortItems() for this.
@param idx
@param col
The column to set the sort indicator for.
If @c -1 is given, then the currently shown sort indicator
will be removed.
@@ -1462,7 +1442,7 @@ public:
@since 3.1.6
*/
void ShowSortIndicator(const int idx, const bool ascending = true);
void ShowSortIndicator(int col, bool ascending = true);
/**
Remove the sort indicator from the column being used as sort key.
@@ -1474,10 +1454,37 @@ public:
/**
Returns the column that shows the sort indicator.
Can return @c -1 if there is no sort indicator currently shown.
@since 3.1.6
*/
int GetSortIndicator() const;
/**
Returns the new value to use for sort indicator after clicking a
column.
This helper function can be useful in the EVT_LIST_COL_CLICK handler
when it updates the sort indicator after the user clicked on a column.
For example:
@code
void MyListCtrl::OnColClick(wxListEvent& event)
{
int col = event.GetColumn();
if ( col == -1 )
return; // clicked outside any column.
const bool ascending = GetUpdatedAscendingSortIndicator(col);
SortItems(MyCompareFunction, ascending);
ShowSortIndicator(col, ascending);
}
@endcode
@since 3.1.6
*/
bool GetUpdatedAscendingSortIndicator(int col) const;
/**
Returns @true if the sort indicator direction is ascending,
@false when the direction is descending.

View File

@@ -461,8 +461,6 @@ void MyFrame::RecreateList(long flags, bool withText)
flags |
wxBORDER_THEME | wxLC_EDIT_LABELS);
m_listCtrl->EnableSortIndicator();
if ( old )
{
wxSizer* const sizer = m_panel->GetSizer();
@@ -1091,10 +1089,11 @@ void MyListCtrl::OnColClick(wxListEvent& event)
return; // clicked outside any column.
}
if ( IsSortIndicatorEnabled() )
// sort on item data (SetItemData)
const bool ascending = GetUpdatedAscendingSortIndicator(col);
if ( SortItems(MyCompareFunction, ascending) )
{
// sort on item data (SetItemData), disable when sorting fails
EnableSortIndicator( SortItems(MyCompareFunction, IsAscendingSortIndicator()) );
ShowSortIndicator(col, ascending);
}
// set or unset image

View File

@@ -982,7 +982,6 @@ wxListHeaderWindow::wxListHeaderWindow()
m_owner = NULL;
m_resizeCursor = NULL;
m_enableSortCol = false;
m_sortAsc = true;
m_sortCol = -1;
}
@@ -1104,7 +1103,7 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
#endif
wxHeaderSortIconType sortArrow = wxHDR_SORT_ICON_NONE;
if ( !m_owner->IsVirtual() && m_enableSortCol && i == m_sortCol )
if ( i == m_sortCol )
{
if ( m_sortAsc )
sortArrow = wxHDR_SORT_ICON_UP;
@@ -1334,12 +1333,6 @@ void wxListHeaderWindow::OnMouse( wxMouseEvent &event )
colItem.SetState(state & ~wxLIST_STATE_SELECTED);
m_owner->SetColumn(i, colItem);
}
if ( m_sortCol != m_column )
m_sortAsc = true;
else
m_sortAsc = !m_sortAsc;
m_sortCol = m_column;
}
SendListEvent( event.LeftDown()
@@ -5084,41 +5077,15 @@ bool wxGenericListCtrl::IsItemChecked(long item) const
return m_mainWin->IsItemChecked(item);
}
void wxGenericListCtrl::EnableSortIndicator(const bool enable)
void wxGenericListCtrl::ShowSortIndicator(int idx, bool ascending)
{
if ( m_headerWin )
{
m_headerWin->m_enableSortCol = enable;
Refresh();
}
}
bool wxGenericListCtrl::IsSortIndicatorEnabled() const
{
return m_headerWin && m_headerWin->m_enableSortCol;
}
void wxGenericListCtrl::ShowSortIndicator(const int idx, const bool ascending)
{
if ( idx == -1 )
{
RemoveSortIndicator();
}
else if ( m_headerWin )
if ( m_headerWin &&
(idx != m_headerWin->m_sortCol ||
(idx != -1 && ascending != m_headerWin->m_sortAsc)) )
{
m_headerWin->m_sortCol = idx;
m_headerWin->m_sortAsc = ascending;
Refresh();
}
}
void wxGenericListCtrl::RemoveSortIndicator()
{
if ( m_headerWin )
{
m_headerWin->m_sortCol = -1;
m_headerWin->m_sortAsc = true;
Refresh();
m_headerWin->Refresh();
}
}

View File

@@ -278,7 +278,6 @@ void wxListCtrl::Init()
m_colCount = 0;
m_textCtrl = NULL;
m_enableSortCol = false;
m_sortAsc = true;
m_sortCol = -1;
@@ -1456,38 +1455,17 @@ bool wxListCtrl::IsItemChecked(long item) const
return ListView_GetCheckState(GetHwnd(), (UINT)item) != 0;
}
void wxListCtrl::EnableSortIndicator(const bool enable)
void wxListCtrl::ShowSortIndicator(int idx, bool ascending)
{
m_enableSortCol = enable;
DrawSortArrow();
}
bool wxListCtrl::IsSortIndicatorEnabled() const
{
return m_enableSortCol;
}
void wxListCtrl::ShowSortIndicator(const int idx, const bool ascending)
{
if ( idx == -1 )
{
RemoveSortIndicator();
}
else
if ( idx != m_sortCol || (idx != -1 && ascending != m_sortAsc) )
{
m_sortCol = idx;
m_sortAsc = ascending;
DrawSortArrow();
}
}
void wxListCtrl::RemoveSortIndicator()
{
m_sortCol = -1;
m_sortAsc = true;
DrawSortArrow();
}
int wxListCtrl::GetSortIndicator() const
{
return m_sortCol;
@@ -2091,7 +2069,10 @@ long wxListCtrl::DoInsertColumn(long col, const wxListItem& item)
SetColumnWidth(n, wxLIST_AUTOSIZE_USEHEADER);
}
DrawSortArrow();
// Update the sort indicator if the index of the column for which it was
// set changed. Note that this condition works even if m_sortCol == -1.
if ( col <= m_sortCol )
DrawSortArrow();
return n;
}
@@ -2467,13 +2448,6 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
break;
case LVN_COLUMNCLICK:
if ( m_sortCol != nmLV->iSubItem )
m_sortAsc = true;
else
m_sortAsc = !m_sortAsc;
m_sortCol = nmLV->iSubItem;
DrawSortArrow();
eventType = wxEVT_LIST_COL_CLICK;
event.m_itemIndex = -1;
event.m_col = nmLV->iSubItem;
@@ -3432,7 +3406,7 @@ void wxListCtrl::DrawSortArrow()
{
if ( ListView_GetColumn(GetHwnd(), col, &lvCol) )
{
if ( !IsVirtual() && m_enableSortCol && col == m_sortCol )
if ( col == m_sortCol )
{
if ( m_sortAsc )
lvCol.fmt = (lvCol.fmt & ~HDF_SORTDOWN) | HDF_SORTUP;