Skip to content

UI: improve wxListView sorting #1597

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 21 additions & 21 deletions src/gui/components/wxDownloadManagerList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ wxDownloadManagerList::wxDownloadManagerList(wxWindow* parent, wxWindowID id)
Bind(wxEVT_REMOVE_ITEM, &wxDownloadManagerList::OnRemoveItem, this);
Bind(wxEVT_REMOVE_ENTRY, &wxDownloadManagerList::OnRemoveEntry, this);
Bind(wxEVT_CLOSE_WINDOW, &wxDownloadManagerList::OnClose, this);

ShowSortIndicator(ColumnName);
}

boost::optional<const wxDownloadManagerList::TitleEntry&> wxDownloadManagerList::GetSelectedTitleEntry() const
Expand Down Expand Up @@ -217,16 +219,7 @@ void wxDownloadManagerList::OnColumnClick(wxListEvent& event)
{
const int column = event.GetColumn();

if (column == m_sort_by_column)
{
m_sort_less = !m_sort_less;
}
else
{
m_sort_by_column = column;
m_sort_less = true;
}
SortEntries();
SortEntries(column);
event.Skip();
}

Expand Down Expand Up @@ -620,24 +613,31 @@ bool wxDownloadManagerList::SortFunc(std::span<int> sortColumnOrder, const Type_

#include <boost/container/small_vector.hpp>

void wxDownloadManagerList::SortEntries()
void wxDownloadManagerList::SortEntries(int column)
{
boost::container::small_vector<int, 12> s_SortColumnOrder{ ColumnName, ColumnType, ColumnVersion, ColumnTitleId, ColumnProgress };

if (m_sort_by_column != -1)
bool ascending;
if (column == -1)
{
// prioritize column by moving it to first position in the column sort order list
s_SortColumnOrder.erase(std::remove(s_SortColumnOrder.begin(), s_SortColumnOrder.end(), m_sort_by_column), s_SortColumnOrder.end());
s_SortColumnOrder.insert(s_SortColumnOrder.begin(), m_sort_by_column);
column = GetSortIndicator();
if (column == -1)
column = ColumnName;
ascending = IsAscendingSortIndicator();
}
else
ascending = GetUpdatedAscendingSortIndicator(column);

// prioritize column by moving it to first position in the column sort order list
s_SortColumnOrder.erase(std::remove(s_SortColumnOrder.begin(), s_SortColumnOrder.end(), column), s_SortColumnOrder.end());
s_SortColumnOrder.insert(s_SortColumnOrder.begin(), column);

std::sort(m_sorted_data.begin(), m_sorted_data.end(),
[this, &s_SortColumnOrder](const Type_t& v1, const Type_t& v2) -> bool
{
const bool result = SortFunc({ s_SortColumnOrder.data(), s_SortColumnOrder.size() }, v1, v2);
return m_sort_less ? result : !result;
});

[this, &s_SortColumnOrder, ascending](const Type_t& v1, const Type_t& v2) -> bool {
return ascending ? SortFunc(s_SortColumnOrder, v1, v2) : SortFunc(s_SortColumnOrder, v2, v1);
});

ShowSortIndicator(column, ascending);
RefreshPage();
}

Expand Down
5 changes: 1 addition & 4 deletions src/gui/components/wxDownloadManagerList.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class wxDownloadManagerList : public wxListView
// error state?
};

void SortEntries();
void SortEntries(int column = -1);
void RefreshPage();
void Filter(const wxString& filter);
void Filter2(bool showTitles, bool showUpdates, bool showInstalled);
Expand Down Expand Up @@ -138,9 +138,6 @@ class wxDownloadManagerList : public wxListView
std::vector<ItemDataPtr> m_data;
std::vector<std::reference_wrapper<ItemData>> m_sorted_data;

int m_sort_by_column = ItemColumn::ColumnName;
bool m_sort_less = true;

bool m_filterShowTitles = true;
bool m_filterShowUpdates = true;
bool m_filterShowInstalled = true;
Expand Down
28 changes: 13 additions & 15 deletions src/gui/components/wxGameList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ wxGameList::wxGameList(wxWindow* parent, wxWindowID id)
// start async worker (for icon loading)
m_async_worker_active = true;
m_async_worker_thread = std::thread(&wxGameList::AsyncWorkerThread, this);

ShowSortIndicator(ColumnName);
}

wxGameList::~wxGameList()
Expand Down Expand Up @@ -540,21 +542,16 @@ int wxGameList::SortFunction(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData)

void wxGameList::SortEntries(int column)
{
bool ascending;
if (column == -1)
column = s_last_column;
else
{
if (s_last_column == column)
{
s_last_column = 0;
s_direction = -1;
}
else
{
s_last_column = column;
s_direction = 1;
}
column = GetSortIndicator();
if (column == -1)
column = ColumnName;
ascending = IsAscendingSortIndicator();
}
else
ascending = GetUpdatedAscendingSortIndicator(column);

switch (column)
{
Expand All @@ -564,8 +561,9 @@ void wxGameList::SortEntries(int column)
case ColumnRegion:
case ColumnTitleID:
{
SortData data{ this, ItemColumns{column}, s_direction };
SortData data{this, ItemColumns{column}, ascending ? 1 : -1};
SortItems(SortFunction, (wxIntPtr)&data);
ShowSortIndicator(column, ascending);
break;
}
}
Expand All @@ -577,7 +575,7 @@ void wxGameList::OnKeyDown(wxListEvent& event)
if (m_style != Style::kList)
return;

const auto keycode = std::tolower(event.m_code);
const auto keycode = event.GetKeyCode();
if (keycode == WXK_LEFT)
{
const auto item_count = GetItemCount();
Expand Down Expand Up @@ -1082,7 +1080,7 @@ void wxGameList::OnClose(wxCloseEvent& event)

int wxGameList::FindInsertPosition(TitleId titleId)
{
SortData data{ this, ItemColumns{s_last_column}, s_direction };
SortData data{this, ItemColumns(GetSortIndicator()), IsAscendingSortIndicator()};
const auto itemCount = GetItemCount();
if (itemCount == 0)
return 0;
Expand Down
2 changes: 0 additions & 2 deletions src/gui/components/wxGameList.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,6 @@ class wxGameList : public wxListView
ColumnCounts,
};

int s_last_column = ColumnName;
int s_direction = 1;
void SortEntries(int column = -1);
struct SortData
{
Expand Down
42 changes: 19 additions & 23 deletions src/gui/components/wxTitleManagerList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ wxTitleManagerList::wxTitleManagerList(wxWindow* parent, wxWindowID id)

m_callbackIdTitleList = CafeTitleList::RegisterCallback([](CafeTitleListCallbackEvent* evt, void* ctx) { ((wxTitleManagerList*)ctx)->HandleTitleListCallback(evt); }, this);
m_callbackIdSaveList = CafeSaveList::RegisterCallback([](CafeSaveListCallbackEvent* evt, void* ctx) { ((wxTitleManagerList*)ctx)->HandleSaveListCallback(evt); }, this);

ShowSortIndicator(ColumnTitleId);
}

wxTitleManagerList::~wxTitleManagerList()
Expand Down Expand Up @@ -1173,54 +1175,48 @@ bool wxTitleManagerList::SortFunc(int column, const Type_t& v1, const Type_t& v2
{
if(entry1.version == entry2.version)
return SortFunc(ColumnTitleId, v1, v2);
return std::underlying_type_t<EntryType>(entry1.version) < std::underlying_type_t<EntryType>(entry2.version);

return entry1.version < entry2.version;
}
else if (column == ColumnRegion)
{
if(entry1.region == entry2.region)
return SortFunc(ColumnTitleId, v1, v2);
return std::underlying_type_t<EntryType>(entry1.region) < std::underlying_type_t<EntryType>(entry2.region);

return std::underlying_type_t<CafeConsoleRegion>(entry1.region) < std::underlying_type_t<CafeConsoleRegion>(entry2.region);
}
else if (column == ColumnFormat)
{
if(entry1.format == entry2.format)
return SortFunc(ColumnType, v1, v2);

return std::underlying_type_t<EntryType>(entry1.format) < std::underlying_type_t<EntryType>(entry2.format);
return std::underlying_type_t<EntryFormat>(entry1.format) < std::underlying_type_t<EntryFormat>(entry2.format);
}

return false;
}
void wxTitleManagerList::SortEntries(int column)
{
if(column == -1)
bool ascending;
if (column == -1)
{
column = m_last_column_sorted;
m_last_column_sorted = -1;
column = GetSortIndicator();
if (column == -1)
column = ColumnTitleId;
ascending = IsAscendingSortIndicator();
}

else
ascending = GetUpdatedAscendingSortIndicator(column);

if (column != ColumnTitleId && column != ColumnName && column != ColumnType && column != ColumnVersion && column != ColumnRegion && column != ColumnFormat)
return;

if (m_last_column_sorted != column)
{
m_last_column_sorted = column;
m_sort_less = true;
}
else
m_sort_less = !m_sort_less;

std::sort(m_sorted_data.begin(), m_sorted_data.end(),
[this, column](const Type_t& v1, const Type_t& v2) -> bool
{
const bool result = SortFunc(column, v1, v2);
return m_sort_less ? result : !result;
});

[this, column, ascending](const Type_t& v1, const Type_t& v2) -> bool {
return ascending ? SortFunc(column, v1, v2) : SortFunc(column, v2, v1);
});

ShowSortIndicator(column, ascending);
RefreshPage();
}

Expand Down
2 changes: 0 additions & 2 deletions src/gui/components/wxTitleManagerList.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,6 @@ class wxTitleManagerList : public wxListView
std::vector<ItemDataPtr> m_data;
std::vector<std::reference_wrapper<ItemData>> m_sorted_data;

int m_last_column_sorted = -1;
bool m_sort_less = true;
using Type_t = std::reference_wrapper<const ItemData>;
bool SortFunc(int column, const Type_t& v1, const Type_t& v2);

Expand Down
2 changes: 1 addition & 1 deletion src/gui/helpers/wxLogEvent.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class wxLogEvent : public wxCommandEvent
: wxCommandEvent(EVT_LOG), m_filter(filter), m_message(message) { }

wxLogEvent(const wxLogEvent& event)
: wxCommandEvent(event), m_filter(event.m_filter), m_message(event.m_message) { }
: wxCommandEvent(event), m_filter(event.GetFilter()), m_message(event.GetMessage()) { }

wxEvent* Clone() const { return new wxLogEvent(*this); }

Expand Down
Loading