66 if (ow_editor->is_lyra_preview()) {
67 ImGui::TextDisabled(
"Lyra preview: item and sprite lists unavailable");
72 static bool was_focused =
false;
74 ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows);
75 if (focused && !was_focused) {
78 was_focused = focused;
80 auto* items = ow_editor->overworld().mutable_all_items();
82 ImGui::TextDisabled(tr(
"No item list available."));
86 static char filter_buffer[64] =
"";
87 static bool current_world_only =
true;
88 static bool current_map_only =
false;
89 static int sort_mode = 0;
92 filter_buffer,
sizeof(filter_buffer));
94 ImGui::Checkbox(tr(
"World"), ¤t_world_only);
96 ImGui::Checkbox(tr(
"Map"), ¤t_map_only);
98 const char* sort_modes[] = {
"Map + Position",
"Item ID",
"Name"};
99 ImGui::SetNextItemWidth(180.0f);
100 ImGui::Combo(tr(
"Sort"), &sort_mode, sort_modes, IM_ARRAYSIZE(sort_modes));
102 const std::string lowered_filter = ToLower(std::string(filter_buffer));
103 std::vector<size_t> filtered_indices;
104 filtered_indices.reserve(items->size());
106 const int current_map = ow_editor->current_map_id();
107 const int current_world = ow_editor->current_world_id();
109 for (
size_t i = 0; i < items->size(); ++i) {
110 const auto& item = items->at(i);
114 if (current_world_only && (item.room_map_id_ / 0x40) != current_world) {
117 if (current_map_only && item.room_map_id_ != current_map) {
120 if (!MatchesItemFilter(item, lowered_filter)) {
123 filtered_indices.push_back(i);
126 auto sort_by_map_pos = [&](
size_t lhs,
size_t rhs) {
127 const auto& a = items->at(lhs);
128 const auto& b = items->at(rhs);
129 if (a.room_map_id_ != b.room_map_id_) {
130 return a.room_map_id_ < b.room_map_id_;
138 return a.id_ < b.id_;
140 auto sort_by_id = [&](
size_t lhs,
size_t rhs) {
141 const auto& a = items->at(lhs);
142 const auto& b = items->at(rhs);
143 if (a.id_ != b.id_) {
144 return a.id_ < b.id_;
146 return sort_by_map_pos(lhs, rhs);
148 auto sort_by_name = [&](
size_t lhs,
size_t rhs) {
149 const auto& a = items->at(lhs);
150 const auto& b = items->at(rhs);
151 const std::string name_a = ItemName(a);
152 const std::string name_b = ItemName(b);
153 if (name_a != name_b) {
154 return name_a < name_b;
156 return sort_by_map_pos(lhs, rhs);
161 std::sort(filtered_indices.begin(), filtered_indices.end(), sort_by_id);
164 std::sort(filtered_indices.begin(), filtered_indices.end(), sort_by_name);
168 std::sort(filtered_indices.begin(), filtered_indices.end(),
174 const bool has_selection = selected_item !=
nullptr;
176 if (!has_selection) {
177 ImGui::BeginDisabled();
180 ow_editor->DuplicateSelectedItem();
181 selected_item = ow_editor->GetSelectedItem();
184 if (ImGui::Button(
ICON_MD_DELETE " Delete", ImVec2(96.0f, 0.0f))) {
185 ow_editor->DeleteSelectedItem();
186 selected_item = ow_editor->GetSelectedItem();
188 if (!has_selection) {
189 ImGui::EndDisabled();
194 ImGui::TextDisabled(tr(
"Selected: 0x%02X @ (%d,%d)"),
195 static_cast<int>(selected_item->
id_), selected_item->
x_,
198 ImGui::TextDisabled(tr(
"No item selected"));
201 ImGui::TextDisabled(tr(
202 "Shortcuts: Ctrl+D duplicate, arrows nudge, Shift+arrows nudge by 16px"));
203 ImGui::TextDisabled(tr(
"Total: %zu | Visible: %zu"), items->size(),
204 filtered_indices.size());
206 if (ImGui::BeginTable(
"##OverworldItemListTable", 6,
207 ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg |
208 ImGuiTableFlags_Resizable |
209 ImGuiTableFlags_SizingStretchProp |
210 ImGuiTableFlags_ScrollY,
211 ImVec2(0.0f, 0.0f))) {
212 ImGui::TableSetupColumn(
"", ImGuiTableColumnFlags_WidthFixed, 30.0f);
213 ImGui::TableSetupColumn(
"ID", ImGuiTableColumnFlags_WidthFixed, 42.0f);
214 ImGui::TableSetupColumn(
"Name", ImGuiTableColumnFlags_WidthStretch, 1.0f);
215 ImGui::TableSetupColumn(
"Map", ImGuiTableColumnFlags_WidthFixed, 54.0f);
216 ImGui::TableSetupColumn(
"World XY", ImGuiTableColumnFlags_WidthFixed,
218 ImGui::TableSetupColumn(
"Game XY", ImGuiTableColumnFlags_WidthFixed, 86.0f);
219 ImGui::TableHeadersRow();
221 for (
size_t visible_row = 0; visible_row < filtered_indices.size();
223 const size_t index = filtered_indices[visible_row];
224 const auto& item = items->at(index);
225 const bool is_selected =
226 selected_item && ItemIdentityMatches(item, *selected_item);
228 ImGui::TableNextRow();
230 ImGui::TableNextColumn();
231 if (ImGui::SmallButton(
232 absl::StrFormat(
"%s##select_item_%zu",
237 ow_editor->SelectItemByIdentity(item);
238 selected_item = ow_editor->GetSelectedItem();
241 ImGui::TableNextColumn();
242 ImGui::Text(tr(
"0x%02X"),
static_cast<int>(item.id_));
244 ImGui::TableNextColumn();
245 ImGui::TextUnformatted(ItemName(item).c_str());
247 ImGui::TableNextColumn();
248 if (item.room_map_id_ == current_map) {
249 ImGui::TextColored(ImVec4(0.45f, 0.85f, 0.50f, 1.0f),
"%02X",
250 static_cast<int>(item.room_map_id_));
252 ImGui::Text(
"%02X",
static_cast<int>(item.room_map_id_));
255 ImGui::TableNextColumn();
256 ImGui::Text(
"%4d, %4d", item.x_, item.y_);
258 ImGui::TableNextColumn();
259 ImGui::Text(
"%2d, %2d", item.game_x_, item.game_y_);