From 97f02b39ba00ebefdb309750826dd13e0c8c1ccf Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Sat, 8 Mar 2025 14:46:22 -0500 Subject: Added items pane --- src/items_pane.cpp | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 src/items_pane.cpp (limited to 'src/items_pane.cpp') diff --git a/src/items_pane.cpp b/src/items_pane.cpp new file mode 100644 index 0000000..055eec0 --- /dev/null +++ b/src/items_pane.cpp @@ -0,0 +1,145 @@ +#include "items_pane.h" + +#include + +namespace { + +enum SortInstruction { + SI_NONE = 0, + SI_ASC = 1 << 0, + SI_DESC = 1 << 1, + SI_NAME = 1 << 2, + SI_AMOUNT = 1 << 3, + SI_ORDER = 1 << 4, +}; + +inline SortInstruction operator|(SortInstruction lhs, SortInstruction rhs) { + return static_cast(static_cast(lhs) | + static_cast(rhs)); +} + +template +int ItemCompare(const T& lhs, const T& rhs, bool ascending) { + if (lhs < rhs) { + return ascending ? -1 : 1; + } else if (lhs > rhs) { + return ascending ? 1 : -1; + } else { + return 0; + } +} + +int wxCALLBACK RowCompare(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData) { + const ItemState& lhs = *reinterpret_cast(item1); + const ItemState& rhs = *reinterpret_cast(item2); + SortInstruction instruction = static_cast(sortData); + + bool ascending = (instruction & SI_ASC) != 0; + if ((instruction & SI_NAME) != 0) { + return ItemCompare(lhs.name, rhs.name, ascending); + } else if ((instruction & SI_AMOUNT) != 0) { + return ItemCompare(lhs.amount, rhs.amount, ascending); + } else if ((instruction & SI_ORDER) != 0) { + return ItemCompare(lhs.index, rhs.index, ascending); + } else { + return 0; + } +} + +} // namespace + +ItemsPane::ItemsPane(wxWindow* parent) + : wxListView(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, + wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_HRULES) { + AppendColumn("Item", wxLIST_FORMAT_LEFT, wxLIST_AUTOSIZE_USEHEADER); + AppendColumn("Amount", wxLIST_FORMAT_LEFT, wxLIST_AUTOSIZE_USEHEADER); + AppendColumn("Order", wxLIST_FORMAT_LEFT, wxLIST_AUTOSIZE_USEHEADER); + + Bind(wxEVT_LIST_COL_CLICK, &ItemsPane::OnColClick, this); + Bind(wxEVT_DPI_CHANGED, &ItemsPane::OnDPIChanged, this); +} + +void ItemsPane::ResetIndicators() { + DeleteAllItems(); + items_.clear(); +} + +void ItemsPane::UpdateIndicators(const std::vector& items) { + std::map items_by_name; + + for (const ItemState& item : items) { + items_by_name[item.name] = item; + } + + for (int i = 0; i < GetItemCount(); i++) { + std::string item_name = GetItemText(i).utf8_string(); + auto it = items_by_name.find(item_name); + + if (it != items_by_name.end()) { + SetItem(i, 1, std::to_string(it->second.amount)); + SetItem(i, 2, std::to_string(it->second.index)); + + *reinterpret_cast(GetItemData(i)) = it->second; + + items_by_name.erase(item_name); + } + } + + for (const auto& [name, item] : items_by_name) { + int i = InsertItem(GetItemCount(), name); + SetItem(i, 1, std::to_string(item.amount)); + SetItem(i, 2, std::to_string(item.index)); + + auto item_ptr = std::make_unique(item); + SetItemPtrData(i, reinterpret_cast(item_ptr.get())); + items_.push_back(std::move(item_ptr)); + } + + SetColumnWidth(0, wxLIST_AUTOSIZE); + SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER); + SetColumnWidth(2, wxLIST_AUTOSIZE_USEHEADER); + + if (GetSortIndicator() != -1) { + DoSort(GetSortIndicator(), IsAscendingSortIndicator()); + } +} + +void ItemsPane::OnColClick(wxListEvent& event) { + int col = event.GetColumn(); + if (col == -1) { + return; + } + + bool ascending = GetUpdatedAscendingSortIndicator(col); + + DoSort(col, ascending); +} + +void ItemsPane::OnDPIChanged(wxDPIChangedEvent& event) { + SetColumnWidth(0, wxLIST_AUTOSIZE); + SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER); + SetColumnWidth(2, wxLIST_AUTOSIZE_USEHEADER); + + event.Skip(); +} + +void ItemsPane::DoSort(int col, bool ascending) { + SortInstruction instruction = SI_NONE; + if (ascending) { + instruction = instruction | SI_ASC; + } else { + instruction = instruction | SI_DESC; + } + + if (col == 0) { + instruction = instruction | SI_NAME; + } else if (col == 1) { + instruction = instruction | SI_AMOUNT; + } else if (col == 2) { + instruction = instruction | SI_ORDER; + } + + if (SortItems(RowCompare, instruction)) { + ShowSortIndicator(col, ascending); + } +} -- cgit 1.4.1