about summary refs log tree commit diff stats
path: root/src/items_pane.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/items_pane.cpp')
-rw-r--r--src/items_pane.cpp145
1 files changed, 145 insertions, 0 deletions
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 @@
1#include "items_pane.h"
2
3#include <map>
4
5namespace {
6
7enum SortInstruction {
8 SI_NONE = 0,
9 SI_ASC = 1 << 0,
10 SI_DESC = 1 << 1,
11 SI_NAME = 1 << 2,
12 SI_AMOUNT = 1 << 3,
13 SI_ORDER = 1 << 4,
14};
15
16inline SortInstruction operator|(SortInstruction lhs, SortInstruction rhs) {
17 return static_cast<SortInstruction>(static_cast<int>(lhs) |
18 static_cast<int>(rhs));
19}
20
21template <typename T>
22int ItemCompare(const T& lhs, const T& rhs, bool ascending) {
23 if (lhs < rhs) {
24 return ascending ? -1 : 1;
25 } else if (lhs > rhs) {
26 return ascending ? 1 : -1;
27 } else {
28 return 0;
29 }
30}
31
32int wxCALLBACK RowCompare(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData) {
33 const ItemState& lhs = *reinterpret_cast<const ItemState*>(item1);
34 const ItemState& rhs = *reinterpret_cast<const ItemState*>(item2);
35 SortInstruction instruction = static_cast<SortInstruction>(sortData);
36
37 bool ascending = (instruction & SI_ASC) != 0;
38 if ((instruction & SI_NAME) != 0) {
39 return ItemCompare(lhs.name, rhs.name, ascending);
40 } else if ((instruction & SI_AMOUNT) != 0) {
41 return ItemCompare(lhs.amount, rhs.amount, ascending);
42 } else if ((instruction & SI_ORDER) != 0) {
43 return ItemCompare(lhs.index, rhs.index, ascending);
44 } else {
45 return 0;
46 }
47}
48
49} // namespace
50
51ItemsPane::ItemsPane(wxWindow* parent)
52 : wxListView(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
53 wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_HRULES) {
54 AppendColumn("Item", wxLIST_FORMAT_LEFT, wxLIST_AUTOSIZE_USEHEADER);
55 AppendColumn("Amount", wxLIST_FORMAT_LEFT, wxLIST_AUTOSIZE_USEHEADER);
56 AppendColumn("Order", wxLIST_FORMAT_LEFT, wxLIST_AUTOSIZE_USEHEADER);
57
58 Bind(wxEVT_LIST_COL_CLICK, &ItemsPane::OnColClick, this);
59 Bind(wxEVT_DPI_CHANGED, &ItemsPane::OnDPIChanged, this);
60}
61
62void ItemsPane::ResetIndicators() {
63 DeleteAllItems();
64 items_.clear();
65}
66
67void ItemsPane::UpdateIndicators(const std::vector<ItemState>& items) {
68 std::map<std::string, ItemState> items_by_name;
69
70 for (const ItemState& item : items) {
71 items_by_name[item.name] = item;
72 }
73
74 for (int i = 0; i < GetItemCount(); i++) {
75 std::string item_name = GetItemText(i).utf8_string();
76 auto it = items_by_name.find(item_name);
77
78 if (it != items_by_name.end()) {
79 SetItem(i, 1, std::to_string(it->second.amount));
80 SetItem(i, 2, std::to_string(it->second.index));
81
82 *reinterpret_cast<ItemState*>(GetItemData(i)) = it->second;
83
84 items_by_name.erase(item_name);
85 }
86 }
87
88 for (const auto& [name, item] : items_by_name) {
89 int i = InsertItem(GetItemCount(), name);
90 SetItem(i, 1, std::to_string(item.amount));
91 SetItem(i, 2, std::to_string(item.index));
92
93 auto item_ptr = std::make_unique<ItemState>(item);
94 SetItemPtrData(i, reinterpret_cast<wxUIntPtr>(item_ptr.get()));
95 items_.push_back(std::move(item_ptr));
96 }
97
98 SetColumnWidth(0, wxLIST_AUTOSIZE);
99 SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER);
100 SetColumnWidth(2, wxLIST_AUTOSIZE_USEHEADER);
101
102 if (GetSortIndicator() != -1) {
103 DoSort(GetSortIndicator(), IsAscendingSortIndicator());
104 }
105}
106
107void ItemsPane::OnColClick(wxListEvent& event) {
108 int col = event.GetColumn();
109 if (col == -1) {
110 return;
111 }
112
113 bool ascending = GetUpdatedAscendingSortIndicator(col);
114
115 DoSort(col, ascending);
116}
117
118void ItemsPane::OnDPIChanged(wxDPIChangedEvent& event) {
119 SetColumnWidth(0, wxLIST_AUTOSIZE);
120 SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER);
121 SetColumnWidth(2, wxLIST_AUTOSIZE_USEHEADER);
122
123 event.Skip();
124}
125
126void ItemsPane::DoSort(int col, bool ascending) {
127 SortInstruction instruction = SI_NONE;
128 if (ascending) {
129 instruction = instruction | SI_ASC;
130 } else {
131 instruction = instruction | SI_DESC;
132 }
133
134 if (col == 0) {
135 instruction = instruction | SI_NAME;
136 } else if (col == 1) {
137 instruction = instruction | SI_AMOUNT;
138 } else if (col == 2) {
139 instruction = instruction | SI_ORDER;
140 }
141
142 if (SortItems(RowCompare, instruction)) {
143 ShowSortIndicator(col, ascending);
144 }
145}