mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-02 13:01:18 +12:00
GameList: Allow sorting by more columns (#1571)
This commit is contained in:
parent
2eec6b44c3
commit
f3fe6f3455
4 changed files with 84 additions and 18 deletions
|
@ -464,5 +464,34 @@ namespace iosu
|
|||
return static_cast<IOSUModule*>(&sIOSUModuleNNPDM);
|
||||
}
|
||||
|
||||
|
||||
bool GameListStat::LastPlayDate::operator<(const LastPlayDate& b) const
|
||||
{
|
||||
const auto& a = *this;
|
||||
|
||||
if(a.year < b.year)
|
||||
return true;
|
||||
if(a.year > b.year)
|
||||
return false;
|
||||
|
||||
// same year
|
||||
if(a.month < b.month)
|
||||
return true;
|
||||
if(a.month > b.month)
|
||||
return false;
|
||||
|
||||
// same year and month
|
||||
return a.day < b.day;
|
||||
}
|
||||
|
||||
bool GameListStat::LastPlayDate::operator==(const LastPlayDate& b) const
|
||||
{
|
||||
const auto& a = *this;
|
||||
return a.year == b.year &&
|
||||
a.month == b.month &&
|
||||
a.day == b.day;
|
||||
}
|
||||
std::weak_ordering GameListStat::LastPlayDate::operator<=>(const LastPlayDate& b) const = default;
|
||||
|
||||
};
|
||||
};
|
||||
|
|
|
@ -21,11 +21,15 @@ namespace iosu
|
|||
/* Helper for UI game list */
|
||||
struct GameListStat
|
||||
{
|
||||
struct
|
||||
struct LastPlayDate
|
||||
{
|
||||
uint32 year; // if 0 -> never played
|
||||
uint32 month;
|
||||
uint32 day;
|
||||
|
||||
bool operator<(const LastPlayDate& b) const;
|
||||
bool operator==(const LastPlayDate& b) const;
|
||||
std::weak_ordering operator<=>(const LastPlayDate& b) const;
|
||||
}last_played;
|
||||
uint32 numMinutesPlayed;
|
||||
};
|
||||
|
|
|
@ -485,25 +485,57 @@ static inline int order_to_int(const std::weak_ordering &wo)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int wxGameList::SortComparator(uint64 titleId1, uint64 titleId2, SortData* sortData)
|
||||
std::weak_ordering wxGameList::SortComparator(uint64 titleId1, uint64 titleId2, SortData* sortData)
|
||||
{
|
||||
const auto isFavoriteA = GetConfig().IsGameListFavorite(titleId1);
|
||||
const auto isFavoriteB = GetConfig().IsGameListFavorite(titleId2);
|
||||
const auto& name1 = GetNameByTitleId(titleId1);
|
||||
const auto& name2 = GetNameByTitleId(titleId2);
|
||||
auto titleLastPlayed = [](uint64_t id)
|
||||
{
|
||||
iosu::pdm::GameListStat playTimeStat{};
|
||||
iosu::pdm::GetStatForGamelist(id, playTimeStat);
|
||||
return playTimeStat;
|
||||
};
|
||||
|
||||
if(sortData->dir > 0)
|
||||
return order_to_int(std::tie(isFavoriteB, name1) <=> std::tie(isFavoriteA, name2));
|
||||
else
|
||||
return order_to_int(std::tie(isFavoriteB, name2) <=> std::tie(isFavoriteA, name1));
|
||||
auto titlePlayMinutes = [](uint64_t id)
|
||||
{
|
||||
iosu::pdm::GameListStat playTimeStat;
|
||||
if (!iosu::pdm::GetStatForGamelist(id, playTimeStat))
|
||||
return 0u;
|
||||
return playTimeStat.numMinutesPlayed;
|
||||
};
|
||||
|
||||
auto titleRegion = [](uint64_t id)
|
||||
{
|
||||
return CafeTitleList::GetGameInfo(id).GetRegion();
|
||||
};
|
||||
|
||||
switch(sortData->column)
|
||||
{
|
||||
default:
|
||||
case ColumnName:
|
||||
{
|
||||
const auto isFavoriteA = GetConfig().IsGameListFavorite(titleId1);
|
||||
const auto isFavoriteB = GetConfig().IsGameListFavorite(titleId2);
|
||||
const auto nameA = GetNameByTitleId(titleId1);
|
||||
const auto nameB = GetNameByTitleId(titleId2);
|
||||
return std::tie(isFavoriteB, nameA) <=> std::tie(isFavoriteA, nameB);
|
||||
}
|
||||
case ColumnGameStarted:
|
||||
return titleLastPlayed(titleId1).last_played <=> titleLastPlayed(titleId2).last_played;
|
||||
case ColumnGameTime:
|
||||
return titlePlayMinutes(titleId1) <=> titlePlayMinutes(titleId2);
|
||||
case ColumnRegion:
|
||||
return titleRegion(titleId1) <=> titleRegion(titleId2);
|
||||
case ColumnTitleID:
|
||||
return titleId1 <=> titleId2;
|
||||
}
|
||||
// unreachable
|
||||
cemu_assert_debug(false);
|
||||
return std::weak_ordering::less;
|
||||
}
|
||||
|
||||
int wxGameList::SortFunction(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData)
|
||||
{
|
||||
const auto sort_data = (SortData*)sortData;
|
||||
const int dir = sort_data->dir;
|
||||
|
||||
return sort_data->thisptr->SortComparator((uint64)item1, (uint64)item2, sort_data);
|
||||
return sort_data->dir * order_to_int(sort_data->thisptr->SortComparator((uint64)item1, (uint64)item2, sort_data));
|
||||
}
|
||||
|
||||
void wxGameList::SortEntries(int column)
|
||||
|
@ -530,8 +562,9 @@ void wxGameList::SortEntries(int column)
|
|||
case ColumnGameTime:
|
||||
case ColumnGameStarted:
|
||||
case ColumnRegion:
|
||||
case ColumnTitleID:
|
||||
{
|
||||
SortData data{ this, column, s_direction };
|
||||
SortData data{ this, ItemColumns{column}, s_direction };
|
||||
SortItems(SortFunction, (wxIntPtr)&data);
|
||||
break;
|
||||
}
|
||||
|
@ -1049,7 +1082,7 @@ void wxGameList::OnClose(wxCloseEvent& event)
|
|||
|
||||
int wxGameList::FindInsertPosition(TitleId titleId)
|
||||
{
|
||||
SortData data{ this, s_last_column, s_direction };
|
||||
SortData data{ this, ItemColumns{s_last_column}, s_direction };
|
||||
const auto itemCount = GetItemCount();
|
||||
if (itemCount == 0)
|
||||
return 0;
|
||||
|
|
|
@ -68,7 +68,7 @@ private:
|
|||
inline static const wxColour kSecondColor{ 0xFDF9F2 };
|
||||
void UpdateItemColors(sint32 startIndex = 0);
|
||||
|
||||
enum ItemColumns
|
||||
enum ItemColumns : int
|
||||
{
|
||||
ColumnHiddenName = 0,
|
||||
ColumnIcon,
|
||||
|
@ -89,12 +89,12 @@ private:
|
|||
struct SortData
|
||||
{
|
||||
wxGameList* thisptr;
|
||||
int column;
|
||||
ItemColumns column;
|
||||
int dir;
|
||||
};
|
||||
|
||||
int FindInsertPosition(TitleId titleId);
|
||||
int SortComparator(uint64 titleId1, uint64 titleId2, SortData* sortData);
|
||||
std::weak_ordering SortComparator(uint64 titleId1, uint64 titleId2, SortData* sortData);
|
||||
static int SortFunction(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData);
|
||||
|
||||
wxTimer* m_tooltip_timer;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue