yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
overworld_toolbar.cc
Go to the documentation of this file.
2#include "util/i18n/tr.h"
3
4#include <string>
5
6#include "absl/strings/str_format.h"
14#include "zelda3/common.h"
16
17namespace yaze::editor {
18
19namespace {
20
23 const char* label;
24 const char* tooltip;
25};
26
28 {EntityEditMode::ENTRANCES, "Entrances",
29 "Entrances (3)\nOnly entrances respond to hover and drag"},
30 {EntityEditMode::EXITS, "Exits",
31 "Exits (4)\nOnly exits respond to hover and drag"},
32 {EntityEditMode::ITEMS, "Items",
33 "Items (5)\nOnly items respond to hover and drag.\n"
34 "Arrows nudge the selected item (Shift = 16px), Cmd/Ctrl+D duplicates"},
35 {EntityEditMode::SPRITES, "Sprites",
36 "Sprites (6)\nOnly sprites respond to hover and drag"},
37};
38
39bool ToolButton(const char* label, const char* tooltip, bool active,
40 const char* automation_id = nullptr) {
41 const bool clicked = gui::ToggleButton(label, active);
42 if (automation_id) {
44 std::string("OverworldToolbar/button:") + automation_id, "button",
45 ImGui::GetItemID());
46 }
47 if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
48 ImGui::SetTooltip("%s", tooltip);
49 }
50 return clicked;
51}
52
54 ImGui::SameLine(0, 6.0f);
55 const ImVec2 pos = ImGui::GetCursorScreenPos();
56 const float height = ImGui::GetFrameHeight();
57 ImGui::GetWindowDrawList()->AddLine(ImVec2(pos.x, pos.y + 3.0f),
58 ImVec2(pos.x, pos.y + height - 3.0f),
59 ImGui::GetColorU32(ImGuiCol_Separator));
60 ImGui::Dummy(ImVec2(1.0f, 0.0f));
61 ImGui::SameLine(0, 6.0f);
62}
63
64} // namespace
65
66std::string OverworldToolbar::WithHint(const char* text,
67 const char* shortcut_name) const {
68 if (!shortcuts || !shortcut_name) {
69 return text;
70 }
71 const std::string keys = shortcuts->GetDisplayString(shortcut_name);
72 if (keys.empty()) {
73 return text;
74 }
75 // Put the hint on the first line: "Zoom In (=)\n<details>".
76 std::string result = text;
77 const size_t newline = result.find('\n');
78 const std::string hint = " (" + keys + ")";
79 if (newline == std::string::npos) {
80 return result + hint;
81 }
82 return result.insert(newline, hint);
83}
84
86 const auto toggle = [&](const char* icon, const char* label,
87 const char* shortcut, const std::function<bool()>& on,
88 const std::function<void()>& flip) {
89 if (!on || !flip) {
90 return;
91 }
92 const std::string tip = WithHint(label, shortcut);
93 if (in_menu) {
94 const std::string keys =
95 shortcuts && shortcut ? shortcuts->GetDisplayString(shortcut) : "";
96 const std::string title =
97 std::string(label).substr(0, std::string(label).find('\n'));
98 const std::string item = absl::StrFormat("%s %s", icon, title);
99 if (ImGui::MenuItem(item.c_str(), keys.empty() ? nullptr : keys.c_str(),
100 on())) {
101 flip();
102 }
103 if (ImGui::IsItemHovered()) {
104 ImGui::SetTooltip("%s", tip.c_str());
105 }
106 return;
107 }
108 if (gui::ToolbarIconButton(icon, tip.c_str(), on())) {
109 flip();
110 }
111 ImGui::SameLine(0, 2);
112 };
113 const auto action = [&](const char* icon, const char* label,
114 const char* shortcut,
115 const std::function<void()>& run) {
116 if (!run) {
117 return;
118 }
119 if (in_menu) {
120 const std::string keys =
121 shortcuts && shortcut ? shortcuts->GetDisplayString(shortcut) : "";
122 const std::string title =
123 std::string(label).substr(0, std::string(label).find('\n'));
124 const std::string item = absl::StrFormat("%s %s", icon, title);
125 if (ImGui::MenuItem(item.c_str(),
126 keys.empty() ? nullptr : keys.c_str())) {
127 run();
128 }
129 if (ImGui::IsItemHovered()) {
130 ImGui::SetTooltip("%s", WithHint(label, shortcut).c_str());
131 }
132 return;
133 }
134 const std::string tip = WithHint(label, shortcut);
135 if (gui::ToolbarIconButton(icon, tip.c_str())) {
136 run();
137 }
138 ImGui::SameLine(0, 2);
139 };
140
141 toggle(ICON_MD_GRID_4X4, "Grid", "overworld.toggle_grid", is_grid_visible,
143 toggle(ICON_MD_PLACE, "Entities\nShow entrances, exits, items and sprites",
144 "overworld.toggle_entities", are_entities_visible, on_toggle_entities);
145 toggle(ICON_MD_VISIBILITY, "Overlay preview\nDraw this map's overlay",
147 if (in_menu) {
148 ImGui::Separator();
149 }
150 action(ICON_MD_ZOOM_OUT, "Zoom out\nCmd/Ctrl+wheel zooms at the cursor",
151 "overworld.zoom_out", on_zoom_out);
152 if (!in_menu && get_zoom) {
153 ImGui::AlignTextToFramePadding();
154 ImGui::TextDisabled("%3.0f%%", get_zoom() * 100.0f);
155 ImGui::SameLine(0, 2);
156 }
157 action(ICON_MD_ZOOM_IN, "Zoom in\nCmd/Ctrl+wheel zooms at the cursor",
158 "overworld.zoom_in", on_zoom_in);
159 action(ICON_MD_FIT_SCREEN, "Zoom to fit world", "overworld.zoom_fit",
161 action(ICON_MD_CENTER_FOCUS_STRONG, "Center on selected map",
162 "overworld.center_map", on_center_map);
163}
164
165void OverworldToolbar::Draw(int& current_world, int& current_map,
166 bool& current_map_lock, EditingMode& current_mode,
167 EntityEditMode& entity_edit_mode,
168 WorkspaceWindowManager* window_manager, Rom* rom,
169 zelda3::Overworld* overworld,
170 project::YazeProject* project, int game_state,
171 const std::function<void()>& draw_appearance) {
172 if (!overworld || !overworld->is_loaded() || !window_manager || !rom) {
173 return;
174 }
175 const bool project_terrain = !overworld->is_lyra_preview() && project &&
176 !project->lyra_terrain_file.empty() &&
177 current_map >= 0xA0 && current_map < 0xC0;
178 if (!project_terrain && !overworld->overworld_map(current_map)) {
179 return;
180 }
181
182 const float avail = ImGui::GetContentRegionAvail().x;
183 const float right_edge = ImGui::GetCursorScreenPos().x + avail;
184 const bool tiny = avail < ImGui::GetFontSize() * 38.0f;
185
186 gui::StyleVarGuard toolbar_style_guard(
187 {{ImGuiStyleVar_FramePadding, ImVec2(4.0f, 3.0f)},
188 {ImGuiStyleVar_ItemSpacing, ImVec2(4.0f, 4.0f)}});
189 ImGui::PushID("OverworldToolbar");
190
191 // --- World -----------------------------------------------------------------
192 static constexpr const char* kWorldButtons[] = {"LW", "DW", "SW"};
193 static constexpr const char* kWorldShortcuts[] = {"overworld.world_light",
194 "overworld.world_dark",
195 "overworld.world_special"};
196 for (int world_index = 0; !tiny && world_index < 3; ++world_index) {
197 if (world_index > 0) {
198 ImGui::SameLine(0, 2);
199 }
200 if (gui::ToggleButton(kWorldButtons[world_index],
201 current_world == world_index, ImVec2(30.0f, 0.0f)) &&
203 on_world_changed(world_index);
204 }
206 absl::StrFormat("OverworldToolbar/world:%d", world_index), "button",
207 ImGui::GetItemID());
208 if (ImGui::IsItemHovered()) {
209 ImGui::SetTooltip(
210 "%s", WithHint(kWorldNames[world_index], kWorldShortcuts[world_index])
211 .c_str());
212 }
213 }
214
215 // --- Map -------------------------------------------------------------------
216 if (!tiny)
217 GroupSeparator();
218 const auto metadata = BuildOverworldMapMetadata(*overworld, rom, project,
219 current_map, game_state);
220 if (ImGui::Button(metadata.map_id_label.c_str()) && on_open_map_properties) {
222 }
223 if (current_map >= 0xA0 && current_map < 0xC0) {
224 ImGui::SameLine(0, 2);
225 ImGui::TextColored(ImVec4(1.0f, 0.85f, 0.3f, 1.0f), ICON_MD_INFO);
226 if (ImGui::IsItemHovered()) {
227 ImGui::SetTooltip(
228 "Tail Map ($A0-$BF) • Entity Limits:\n"
229 "• Items: Disabled (SRAM event storage $7EF000-$7EF4FF unallocated)\n"
230 "• Exits: 1 free slot (full links need exit table v2)\n"
231 "• Entrances: Trigger table v2 in development (Phase P2)\n"
232 "• Sprites: Draft state (actor compilation needed for ROM)");
233 }
234 }
235 if (ImGui::IsItemHovered()) {
236 ImGui::SetTooltip(
237 "%s\n%s\nClick this button or double-click the canvas map for "
238 "properties.\n"
239 "%s / %s: adjacent map",
240 metadata.map_title.c_str(), metadata.area_size_label.c_str(),
241 WithHint("Previous", "overworld.map_left").c_str(),
242 WithHint("Next", "overworld.map_right").c_str());
243 }
244 ImGui::SameLine(0, 2);
245 const std::string pin_tip =
246 current_map_lock
247 ? WithHint("Unpin map\nResume following the cursor",
248 "overworld.toggle_lock")
249 : WithHint("Pin map\nKeep properties on this map while navigating",
250 "overworld.toggle_lock");
252 current_map_lock ? ICON_MD_PUSH_PIN : ICON_MD_GPS_FIXED,
253 pin_tip.c_str(),
254 ImVec2(ImGui::GetFrameHeight(), ImGui::GetFrameHeight()),
255 current_map_lock)) {
256 current_map_lock = !current_map_lock;
257 }
258
259 // Keep frequent map properties visible even when secondary tools overflow.
260 ImGui::BeginDisabled(project_terrain);
261 ImGui::SameLine(0, 4);
262 const std::string story_label = absl::StrFormat("Story %d", game_state);
263 ImGui::SetNextItemWidth(ImGui::CalcTextSize("Story 0").x +
264 ImGui::GetFrameHeight() + 8.0f);
265 const bool story_open = ImGui::BeginCombo("##Story", story_label.c_str());
267 "OverworldToolbar/combo:Story", "combobox", ImGui::GetItemID());
268 if (ImGui::IsItemHovered()) {
269 ImGui::SetTooltip(
270 "Story part to preview. Changes the active sprite set, "
271 "sprite graphics and sprite palettes. "
272 "Shared item placements stay the same.");
273 }
274 if (story_open) {
275 for (int state = 0; state < 3; ++state) {
276 const std::string label =
277 absl::StrFormat("%d — %s", state, kGameStateNames[state]);
278 if (ImGui::Selectable(label.c_str(), game_state == state) &&
280 on_story_changed(state);
281 }
283 absl::StrFormat("OverworldToolbar/story:%d", state), "selectable",
284 ImGui::GetItemID());
285 }
286 ImGui::EndCombo();
287 }
288 if (draw_appearance) {
289 ImGui::SameLine(0, 4);
290 draw_appearance();
291 }
292 ImGui::EndDisabled();
293
294 const char* entity_label = "Entities";
295 for (const auto& button : kEntityModeButtons) {
296 if (entity_edit_mode == button.mode) {
297 entity_label = button.label;
298 }
299 }
300 const auto button_width = [](const char* label) {
301 return ImGui::CalcTextSize(label, nullptr, true).x +
302 ImGui::GetStyle().FramePadding.x * 2.0f;
303 };
304 // Match the actual buttons and gaps below. Shorten secondary labels before
305 // moving tools into overflow; input fields do not imply a narrow toolbar.
306 const float drawing_width =
307 button_width(ICON_MD_MOUSE) + button_width(ICON_MD_DRAW) +
308 button_width(ICON_MD_FORMAT_COLOR_FILL) +
309 button_width(ICON_MD_GRASS " Insert Item") + 3.0f * 2.0f;
310 const auto tools_width = [&](bool compact_labels) {
311 return 3.0f * 13.0f + drawing_width +
312 button_width(compact_labels ? ICON_MD_PLACE : entity_label) +
313 button_width(compact_labels ? ICON_MD_VISIBILITY : "View") + 2.0f +
314 button_width(compact_labels ? ICON_MD_WINDOW : "Windows");
315 };
316 const float remaining = right_edge - ImGui::GetItemRectMax().x;
317 const bool compact = tools_width(false) > remaining;
318 // Tiny docks also need access to the world selector through this popup.
319 const bool overflow = tiny || tools_width(true) > remaining;
320 if (overflow) {
321 ImGui::SameLine(0, 4);
322 if (ToolButton(ICON_MD_MORE_HORIZ, "Drawing tools and map options", false,
323 "Tools")) {
324 ImGui::OpenPopup("ToolsOverflow");
325 }
326 if (!ImGui::BeginPopup("ToolsOverflow")) {
327 ImGui::PopID();
328 return;
329 }
330 if (tiny) {
331 for (int world = 0; world < 3; ++world) {
332 if (ImGui::MenuItem(kWorldNames[world], nullptr,
333 current_world == world) &&
335 on_world_changed(world);
336 }
337 }
338 ImGui::Separator();
339 }
340 } else {
341 GroupSeparator();
342 }
343 // --- Tool ------------------------------------------------------------------
344 const auto set_mode = [&](EditingMode mode) {
345 if (on_set_mode) {
346 on_set_mode(mode);
347 } else {
348 current_mode = mode;
349 }
350 };
351 if (ToolButton(ICON_MD_MOUSE,
352 "Select (1)\nLeft-drag empty map: pan Middle-drag: pan\n"
353 "Drag entities to move them Right-click: map menu\n"
354 "Double-click a map: Map Properties",
355 current_mode == EditingMode::MOUSE, "Select")) {
356 set_mode(EditingMode::MOUSE);
357 }
358 ImGui::SameLine(0, 2);
359 const std::string brush_tip = WithHint(
360 "Brush (2)\nLeft-drag: paint the selected tile16\n"
361 "Right-click: sample tile16 (or I) Right-drag: capture a brush\n"
362 "[ / ]: previous / next tile16 Shift+Right-click: map menu",
363 "overworld.brush_toggle");
364 if (ToolButton(ICON_MD_DRAW, brush_tip.c_str(),
365 current_mode == EditingMode::DRAW_TILE, "Paint")) {
366 set_mode(EditingMode::DRAW_TILE);
367 }
368 ImGui::SameLine(0, 2);
369 const std::string fill_tip = WithHint(
370 "Fill screen\nClick fills the 32x32 screen under the cursor\n"
371 "Right-click: sample tile16 Shift+Right-click: map menu",
372 "overworld.fill");
373 if (ToolButton(ICON_MD_FORMAT_COLOR_FILL, fill_tip.c_str(),
374 current_mode == EditingMode::FILL_TILE, "Fill")) {
375 set_mode(EditingMode::FILL_TILE);
376 }
377 ImGui::BeginDisabled(project_terrain);
378 ImGui::SameLine(0, 2);
379 if (ToolButton(ICON_MD_GRASS " Insert Item",
380 "Pick an item from the list, then click the map to place it",
381 false, "Insert Item")) {
382 if (on_insert_item) {
384 }
385 }
386
387 // --- Entity modes ------------------------------------------------------------
388 GroupSeparator();
389 if (ImGui::Button(compact ? ICON_MD_PLACE : entity_label)) {
390 ImGui::OpenPopup("EntityTools");
391 }
393 "OverworldToolbar/button:Entities", "button", ImGui::GetItemID());
394 if (ImGui::IsItemHovered()) {
395 ImGui::SetTooltip(
396 "Choose which entities respond to hover and drag.\n"
397 "Entrances (3), exits (4), items (5), sprites (6).");
398 }
399 if (ImGui::BeginPopup("EntityTools")) {
400 const auto choose = [&](EntityEditMode mode) {
401 if (on_set_entity_mode) {
402 on_set_entity_mode(mode);
403 } else {
404 entity_edit_mode = mode;
405 }
406 };
407 if (ImGui::MenuItem("All entities", nullptr,
408 entity_edit_mode == EntityEditMode::NONE)) {
409 choose(EntityEditMode::NONE);
410 }
411 for (const auto& button : kEntityModeButtons) {
412 const bool disabled_for_tail =
413 (current_map >= 0xA0 && current_map < 0xC0) &&
414 button.mode == EntityEditMode::ITEMS;
415 if (disabled_for_tail) {
416 ImGui::BeginDisabled();
417 }
418 if (ImGui::MenuItem(button.label, nullptr,
419 entity_edit_mode == button.mode)) {
420 choose(button.mode);
421 }
422 if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
423 if (disabled_for_tail) {
424 ImGui::SetTooltip(
425 "Items unavailable on Tail Maps (SRAM event storage "
426 "unallocated)");
427 } else {
428 ImGui::SetTooltip("%s", button.tooltip);
429 }
430 }
431 if (disabled_for_tail) {
432 ImGui::EndDisabled();
433 }
434 }
435 ImGui::EndPopup();
436 }
437 ImGui::EndDisabled();
438
439 // Secondary display controls stay in a named menu, leaving space for tools.
440 GroupSeparator();
441 const size_t session_id = window_manager->GetActiveSessionId();
442 if (ToolButton(compact ? ICON_MD_VISIBILITY : "View",
443 "Grid, entities, overlay and zoom", false, "View")) {
444 ImGui::OpenPopup("OverworldViewMenu");
445 }
446 if (ImGui::BeginPopup("OverworldViewMenu")) {
447 DrawViewControls(/*in_menu=*/true);
448 ImGui::EndPopup();
449 }
450 ImGui::SameLine(0, 2);
451 if (ToolButton(compact ? ICON_MD_WINDOW : "Windows",
452 "Open overworld editing windows", false, "Windows")) {
453 ImGui::OpenPopup("OverworldWindowsPopup");
454 }
455 if (ImGui::BeginPopup("OverworldWindowsPopup")) {
456 const auto item = [&](const char* label, const char* panel_id,
457 const char* shortcut_name) {
458 const std::string keys = shortcuts && shortcut_name
459 ? shortcuts->GetDisplayString(shortcut_name)
460 : "";
461 if (ImGui::MenuItem(label, keys.empty() ? nullptr : keys.c_str(),
462 window_manager->IsWindowOpen(panel_id))) {
463 const bool opening = !window_manager->IsWindowOpen(panel_id);
464 window_manager->ToggleWindow(session_id, panel_id);
465 if (opening && panel_id == OverworldPanelIds::kItemList &&
468 }
469 }
470 };
471 item(ICON_MD_TUNE " Map Properties", OverworldPanelIds::kMapProperties,
472 nullptr);
474 nullptr);
475 item(ICON_MD_EDIT " Tile16 Editor", OverworldPanelIds::kTile16Editor,
476 "overworld.toggle_tile16_editor");
478 nullptr);
479 item(ICON_MD_IMAGE " Area Graphics", OverworldPanelIds::kAreaGraphics,
480 nullptr);
481 item(ICON_MD_LAYERS " GFX Groups", OverworldPanelIds::kGfxGroups, nullptr);
483 "overworld.toggle_item_list");
484 item(ICON_MD_AUTO_FIX_HIGH " Scratch Workspace",
486 item(ICON_MD_ANALYTICS " Usage Statistics", OverworldPanelIds::kUsageStats,
487 nullptr);
488 const auto rom_version = zelda3::OverworldVersionHelper::GetVersion(*rom);
489 if (rom_version == zelda3::OverworldVersion::kVanilla &&
491 ImGui::Separator();
492 if (ImGui::MenuItem(ICON_MD_UPGRADE
493 " Upgrade to ZSCustomOverworld v3...")) {
495 }
496 }
497 ImGui::EndPopup();
498 }
499 if (overflow) {
500 ImGui::EndPopup();
501 }
502 ImGui::PopID();
503}
504
505} // namespace yaze::editor
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:52
ShortcutManager * shortcuts
Used for shortcut hints in tooltips (GetDisplayString).
std::function< bool()> are_entities_visible
std::function< void()> on_insert_item
std::function< void()> on_zoom_fit
std::function< void()> on_center_map
std::function< void(int)> on_upgrade_rom_version
std::string WithHint(const char *text, const char *shortcut_name) const
"Label (Shortcut)" when the shortcut is bound, else "Label".
void Draw(int &current_world, int &current_map, bool &current_map_lock, EditingMode &current_mode, EntityEditMode &entity_edit_mode, WorkspaceWindowManager *window_manager, Rom *rom, zelda3::Overworld *overworld, project::YazeProject *project, int game_state, const std::function< void()> &draw_appearance={})
std::function< float()> get_zoom
std::function< void(int)> on_story_changed
std::function< bool()> is_overlay_preview_enabled
std::function< void(int)> on_world_changed
std::function< void()> on_zoom_in
std::function< void()> on_open_map_properties
std::function< void()> on_zoom_out
std::function< void()> on_toggle_grid
std::function< void()> on_toggle_entities
std::function< bool()> is_grid_visible
std::function< void()> on_toggle_overlay_preview
std::function< void(EntityEditMode)> on_set_entity_mode
std::function< void(EditingMode)> on_set_mode
std::string GetDisplayString(const std::string &name) const
Live, platform-formatted binding for a shortcut name.
Central registry for all editor cards with session awareness and dependency injection.
bool IsWindowOpen(size_t session_id, const std::string &base_window_id) const
bool ToggleWindow(size_t session_id, const std::string &base_window_id)
RAII guard for ImGui style vars.
Definition style_guard.h:71
void RegisterWidget(const std::string &full_path, const std::string &type, ImGuiID imgui_id, const std::string &description="", const WidgetMetadata &metadata=WidgetMetadata())
static WidgetIdRegistry & Instance()
static OverworldVersion GetVersion(const Rom &rom)
Detect ROM version from ASM marker byte.
bool is_lyra_preview() const
Definition overworld.h:444
auto is_loaded() const
Definition overworld.h:836
auto overworld_map(int i) const
Definition overworld.h:770
#define ICON_MD_GRID_VIEW
Definition icons.h:897
#define ICON_MD_CENTER_FOCUS_STRONG
Definition icons.h:386
#define ICON_MD_INFO
Definition icons.h:993
#define ICON_MD_FIT_SCREEN
Definition icons.h:781
#define ICON_MD_GPS_FIXED
Definition icons.h:883
#define ICON_MD_UPGRADE
Definition icons.h:2047
#define ICON_MD_PLACE
Definition icons.h:1477
#define ICON_MD_DRAW
Definition icons.h:625
#define ICON_MD_TUNE
Definition icons.h:2022
#define ICON_MD_ZOOM_OUT
Definition icons.h:2196
#define ICON_MD_VISIBILITY
Definition icons.h:2101
#define ICON_MD_GRASS
Definition icons.h:891
#define ICON_MD_FORMAT_COLOR_FILL
Definition icons.h:830
#define ICON_MD_EDIT
Definition icons.h:645
#define ICON_MD_MORE_HORIZ
Definition icons.h:1241
#define ICON_MD_AUTO_FIX_HIGH
Definition icons.h:218
#define ICON_MD_GRID_ON
Definition icons.h:896
#define ICON_MD_LIST
Definition icons.h:1094
#define ICON_MD_LAYERS
Definition icons.h:1068
#define ICON_MD_WINDOW
Definition icons.h:2176
#define ICON_MD_IMAGE
Definition icons.h:982
#define ICON_MD_ZOOM_IN
Definition icons.h:2194
#define ICON_MD_GRID_4X4
Definition icons.h:893
#define ICON_MD_MOUSE
Definition icons.h:1251
#define ICON_MD_PUSH_PIN
Definition icons.h:1529
#define ICON_MD_ANALYTICS
Definition icons.h:154
bool ToolButton(const char *label, const char *tooltip, bool active, const char *automation_id=nullptr)
Editors are the view controllers for the application.
constexpr const char * kWorldNames[]
OverworldMapMetadata BuildOverworldMapMetadata(const zelda3::Overworld &overworld, const Rom *rom, const project::YazeProject *project, int map_id, int game_state)
constexpr const char * kGameStateNames[]
Definition ui_constants.h:8
bool ThemedIconButton(const char *icon, const char *tooltip, const ImVec2 &size, bool is_active, bool is_disabled, const char *panel_id, const char *anim_id)
Draw a standard icon button with theme-aware colors.
bool ToggleButton(const char *label, bool active, const ImVec2 &size)
bool ToolbarIconButton(const char *icon, const char *tooltip, bool is_active)
Convenience wrapper for toolbar-sized icon buttons.
@ kVanilla
0xFF in ROM, no ZScream ASM applied
static constexpr const char * kMapProperties
static constexpr const char * kTile8Selector
static constexpr const char * kAreaGraphics
static constexpr const char * kItemList
static constexpr const char * kScratchSpace
static constexpr const char * kTile16Editor
static constexpr const char * kTile16Selector
static constexpr const char * kGfxGroups
static constexpr const char * kUsageStats
Modern project structure with comprehensive settings consolidation.
Definition project.h:290
std::string lyra_terrain_file
Definition project.h:342