Support sort indicators in wxListCtrl header

This commit is contained in:
Maarten Bent
2021-11-28 19:19:59 +01:00
parent 9febbe2b30
commit d8ec0aa001
7 changed files with 262 additions and 1 deletions

View File

@@ -115,6 +115,13 @@ public:
virtual bool IsItemChecked(long item) const wxOVERRIDE;
virtual 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;
int GetSortIndicator() const wxOVERRIDE;
bool IsAscendingSortIndicator() const wxOVERRIDE;
void SetSingleStyle( long style, bool add = true ) ;
void SetWindowStyleFlag( long style ) wxOVERRIDE;
void RecreateWindow() {}

View File

@@ -381,6 +381,10 @@ public:
int m_colToSend;
int m_widthToSend;
bool m_enableSortCol;
bool m_sortAsc;
int m_sortCol;
virtual wxWindow *GetMainWindowOfCompositeControl() wxOVERRIDE { return GetParent(); }
virtual void OnInternalIdle() wxOVERRIDE;

View File

@@ -446,6 +446,14 @@ public:
virtual bool IsItemChecked(long WXUNUSED(item)) const { return false; }
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 int GetSortIndicator() const { return -1; }
virtual bool IsAscendingSortIndicator() const { return true; }
protected:
// Return pointer to the corresponding m_imagesXXX.
const wxWithImages* GetImages(int which) const;

View File

@@ -225,6 +225,14 @@ public:
virtual bool IsItemChecked(long item) const wxOVERRIDE;
virtual 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;
int GetSortIndicator() const wxOVERRIDE;
bool IsAscendingSortIndicator() const wxOVERRIDE;
// Gets the number of selected items in the list control
int GetSelectedItemCount() const;
@@ -418,6 +426,10 @@ 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;
@@ -445,6 +457,8 @@ private:
// in-place editor control.
void OnCharHook(wxKeyEvent& event);
// Draw the sort arrow arror in the header.
void DrawSortArrow();
// Object using for header custom drawing if necessary, may be NULL.
wxMSWListHeaderCustomDraw* m_headerCustomDraw;

View File

@@ -1420,6 +1420,72 @@ 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().
@note This does not actually sort the list, use SortItems() for this.
@param idx
The column to set the sort indicator for.
If @c -1 is given, then the currently shown sort indicator
will be removed.
@param ascending
If @true or @false show the sort indicator corresponding to
ascending or descending sort order respectively.
@since 3.1.6
*/
void ShowSortIndicator(const int idx, const bool ascending = true);
/**
Remove the sort indicator from the column being used as sort key.
@since 3.1.6
*/
int RemoveSortIndicator() const;
/**
Returns the column that shows the sort indicator.
@since 3.1.6
*/
int GetSortIndicator() const;
/**
Returns @true if the sort indicator direction is ascending,
@false when the direction is descending.
@since 3.1.6
*/
bool IsAscendingSortIndicator() const;
protected:
/**

View File

@@ -981,6 +981,10 @@ wxListHeaderWindow::wxListHeaderWindow()
m_owner = NULL;
m_resizeCursor = NULL;
m_enableSortCol = false;
m_sortAsc = true;
m_sortCol = -1;
}
bool wxListHeaderWindow::Create( wxWindow *win,
@@ -1099,6 +1103,15 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
flags |= wxCONTROL_SELECTED;
#endif
wxHeaderSortIconType sortArrow = wxHDR_SORT_ICON_NONE;
if ( !m_owner->IsVirtual() && m_enableSortCol && i == m_sortCol )
{
if ( m_sortAsc )
sortArrow = wxHDR_SORT_ICON_UP;
else
sortArrow = wxHDR_SORT_ICON_DOWN;
}
if (i == 0)
flags |= wxCONTROL_SPECIAL; // mark as first column
@@ -1107,7 +1120,8 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
this,
dc,
wxRect(x, HEADER_OFFSET_Y, cw, ch),
flags
flags,
sortArrow
);
// see if we have enough space for the column label
@@ -1320,6 +1334,12 @@ 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()
@@ -5064,6 +5084,60 @@ bool wxGenericListCtrl::IsItemChecked(long item) const
return m_mainWin->IsItemChecked(item);
}
void wxGenericListCtrl::EnableSortIndicator(const bool enable)
{
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 )
{
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();
}
}
int wxGenericListCtrl::GetSortIndicator() const
{
if ( m_headerWin )
return m_headerWin->m_sortCol;
return -1;
}
bool wxGenericListCtrl::IsAscendingSortIndicator() const
{
if ( m_headerWin )
return m_headerWin->m_sortAsc;
return true;
}
void wxGenericListCtrl::SetSingleStyle( long style, bool add )
{
wxASSERT_MSG( !(style & wxLC_VIRTUAL),

View File

@@ -278,6 +278,10 @@ void wxListCtrl::Init()
m_colCount = 0;
m_textCtrl = NULL;
m_enableSortCol = false;
m_sortAsc = true;
m_sortCol = -1;
m_hasAnyAttr = false;
m_headerCustomDraw = NULL;
@@ -1452,6 +1456,48 @@ bool wxListCtrl::IsItemChecked(long item) const
return ListView_GetCheckState(GetHwnd(), (UINT)item) != 0;
}
void wxListCtrl::EnableSortIndicator(const bool enable)
{
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
{
m_sortCol = idx;
m_sortAsc = ascending;
DrawSortArrow();
}
}
void wxListCtrl::RemoveSortIndicator()
{
m_sortCol = -1;
m_sortAsc = true;
DrawSortArrow();
}
int wxListCtrl::GetSortIndicator() const
{
return m_sortCol;
}
bool wxListCtrl::IsAscendingSortIndicator() const
{
return m_sortAsc;
}
// Gets the number of selected items in the list control
int wxListCtrl::GetSelectedItemCount() const
{
@@ -2045,6 +2091,8 @@ long wxListCtrl::DoInsertColumn(long col, const wxListItem& item)
SetColumnWidth(n, wxLIST_AUTOSIZE_USEHEADER);
}
DrawSortArrow();
return n;
}
@@ -2419,6 +2467,13 @@ 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;
@@ -3361,6 +3416,39 @@ void wxListCtrl::OnCharHook(wxKeyEvent& event)
event.Skip();
}
void wxListCtrl::DrawSortArrow()
{
if ( HasFlag(wxLC_SORT_ASCENDING) || HasFlag(wxLC_SORT_DESCENDING) )
{
m_sortCol = 0;
m_sortAsc = HasFlag(wxLC_SORT_ASCENDING);
}
LV_COLUMN lvCol;
wxZeroMemory(lvCol);
lvCol.mask = LVCF_FMT;
for ( int col = 0; col < m_colCount; ++col )
{
if ( ListView_GetColumn(GetHwnd(), col, &lvCol) )
{
if ( !IsVirtual() && m_enableSortCol && col == m_sortCol )
{
if ( m_sortAsc )
lvCol.fmt = (lvCol.fmt & ~HDF_SORTDOWN) | HDF_SORTUP;
else
lvCol.fmt = (lvCol.fmt & ~HDF_SORTUP) | HDF_SORTDOWN;
}
else
{
lvCol.fmt = lvCol.fmt & ~(HDF_SORTDOWN | HDF_SORTUP);
}
ListView_SetColumn(GetHwnd(), col, &lvCol);
}
}
}
WXLRESULT
wxListCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
{