yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
popup_manager.cc
Go to the documentation of this file.
1#include "popup_manager.h"
2
3#include <functional>
4
5#include "absl/strings/str_format.h"
10#include "app/gui/core/style.h"
11#include "imgui/misc/cpp/imgui_stdlib.h"
12#include "util/file_util.h"
13#include "util/hex.h"
14#include "yaze.h"
15
16namespace yaze {
17namespace editor {
18
19using namespace ImGui;
20
22 : editor_manager_(editor_manager), status_(absl::OkStatus()) {}
23
25 // ============================================================================
26 // POPUP REGISTRATION
27 // ============================================================================
28 // All popups must be registered here BEFORE any menu callbacks can trigger
29 // them. This method is called in EditorManager constructor BEFORE
30 // MenuOrchestrator and UICoordinator are created, ensuring safe
31 // initialization order.
32 //
33 // Popup Registration Format:
34 // popups_[PopupID::kConstant] = {
35 // .name = PopupID::kConstant,
36 // .type = PopupType::kXxx,
37 // .is_visible = false,
38 // .allow_resize = false/true,
39 // .draw_function = [this]() { DrawXxxPopup(); }
40 // };
41 // ============================================================================
42
43 // File Operations
45 false, false, [this]() {
47 }};
49 PopupID::kNewProject, PopupType::kFileOperation, false, false, [this]() {
51 }};
53 PopupType::kFileOperation, false, false,
54 [this]() {
56 }};
57
58 // Information
60 [this]() {
62 }};
64 false, [this]() {
66 }};
68 PopupID::kSupportedFeatures, PopupType::kInfo, false, false, [this]() {
70 }};
72 false, false, [this]() {
74 }};
75
76 // Help Documentation
78 PopupID::kGettingStarted, PopupType::kHelp, false, false, [this]() {
80 }};
82 PopupID::kAsarIntegration, PopupType::kHelp, false, false, [this]() {
84 }};
86 PopupID::kBuildInstructions, PopupType::kHelp, false, false, [this]() {
88 }};
90 false, [this]() {
92 }};
94 PopupID::kTroubleshooting, PopupType::kHelp, false, false, [this]() {
96 }};
98 false, false, [this]() {
100 }};
102 false, [this]() {
104 }};
105
106 // Settings
109 true, // Resizable
110 [this]() {
112 }};
114 PopupID::kFeatureFlags, PopupType::kSettings, false, true, // Resizable
115 [this]() {
117 }};
118
119 // Workspace
121 false, false, [this]() {
123 }};
125 PopupType::kWarning, false, false,
126 [this]() {
128 }};
131 false, [this]() {
133 }};
134
136 PopupID::kLayoutPresets, PopupType::kSettings, false, false, [this]() {
138 }};
139
141 PopupID::kSessionManager, PopupType::kSettings, false, true, [this]() {
143 }};
144
145 // Debug/Testing
147 false, true, // Resizable
148 [this]() {
150 }};
151}
152
154 // Draw status popup if needed
156
157 // Draw all registered popups
158 for (auto& [name, params] : popups_) {
159 if (params.is_visible) {
160 OpenPopup(name.c_str());
161
162 // Use allow_resize flag from popup definition
163 ImGuiWindowFlags popup_flags = params.allow_resize
164 ? ImGuiWindowFlags_None
165 : ImGuiWindowFlags_AlwaysAutoResize;
166
167 if (BeginPopupModal(name.c_str(), nullptr, popup_flags)) {
168 params.draw_function();
169 EndPopup();
170 }
171 }
172 }
173}
174
175void PopupManager::Show(const char* name) {
176 if (!name) {
177 return; // Safety check for null pointer
178 }
179
180 std::string name_str(name);
181 auto it = popups_.find(name_str);
182 if (it != popups_.end()) {
183 it->second.is_visible = true;
184 } else {
185 // Log warning for unregistered popup
186 printf(
187 "[PopupManager] Warning: Popup '%s' not registered. Available popups: ",
188 name);
189 for (const auto& [key, _] : popups_) {
190 printf("'%s' ", key.c_str());
191 }
192 printf("\n");
193 }
194}
195
196void PopupManager::Hide(const char* name) {
197 if (!name) {
198 return; // Safety check for null pointer
199 }
200
201 std::string name_str(name);
202 auto it = popups_.find(name_str);
203 if (it != popups_.end()) {
204 it->second.is_visible = false;
205 CloseCurrentPopup();
206 }
207}
208
209bool PopupManager::IsVisible(const char* name) const {
210 if (!name) {
211 return false; // Safety check for null pointer
212 }
213
214 std::string name_str(name);
215 auto it = popups_.find(name_str);
216 if (it != popups_.end()) {
217 return it->second.is_visible;
218 }
219 return false;
220}
221
222void PopupManager::SetStatus(const absl::Status& status) {
223 if (!status.ok()) {
224 show_status_ = true;
225 prev_status_ = status;
226 status_ = status;
227 }
228}
229
230bool PopupManager::BeginCentered(const char* name) {
231 ImGuiIO const& io = GetIO();
232 ImVec2 pos(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.5f);
233 SetNextWindowPos(pos, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
234 ImGuiWindowFlags flags =
235 ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration |
236 ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings;
237 return Begin(name, nullptr, flags);
238}
239
241 if (show_status_ && BeginCentered("StatusWindow")) {
242 Text("%s", ICON_MD_ERROR);
243 Text("%s", prev_status_.ToString().c_str());
244 Spacing();
245 NextColumn();
246 Columns(1);
247 Separator();
248 NewLine();
249 SameLine(128);
250 if (Button("OK", gui::kDefaultModalSize) || IsKeyPressed(ImGuiKey_Space)) {
251 show_status_ = false;
252 status_ = absl::OkStatus();
253 }
254 SameLine();
255 if (Button(ICON_MD_CONTENT_COPY, ImVec2(50, 0))) {
256 SetClipboardText(prev_status_.ToString().c_str());
257 }
258 End();
259 }
260}
261
263 Text("Yet Another Zelda3 Editor - v%s", editor_manager_->version().c_str());
264 Text("Written by: scawful");
265 Spacing();
266 Text("Special Thanks: Zarby89, JaredBrian");
267 Separator();
268
269 if (Button("Close", gui::kDefaultModalSize)) {
270 Hide("About");
271 }
272}
273
275 auto* current_rom = editor_manager_->GetCurrentRom();
276 if (!current_rom)
277 return;
278
279 Text("Title: %s", current_rom->title().c_str());
280 Text("ROM Size: %s", util::HexLongLong(current_rom->size()).c_str());
281
282 if (Button("Close", gui::kDefaultModalSize) ||
283 IsKeyPressed(ImGuiKey_Escape)) {
284 Hide("ROM Information");
285 }
286}
287
289 using namespace ImGui;
290
291 Text("%s Save ROM to new location", ICON_MD_SAVE_AS);
292 Separator();
293
294 static std::string save_as_filename = "";
295 if (editor_manager_->GetCurrentRom() && save_as_filename.empty()) {
296 save_as_filename = editor_manager_->GetCurrentRom()->title();
297 }
298
299 InputText("Filename", &save_as_filename);
300 Separator();
301
302 if (Button(absl::StrFormat("%s Browse...", ICON_MD_FOLDER_OPEN).c_str(),
304 auto file_path =
305 util::FileDialogWrapper::ShowSaveFileDialog(save_as_filename, "sfc");
306 if (!file_path.empty()) {
307 save_as_filename = file_path;
308 }
309 }
310
311 SameLine();
312 if (Button(absl::StrFormat("%s Save", ICON_MD_SAVE).c_str(),
314 if (!save_as_filename.empty()) {
315 // Ensure proper file extension
316 std::string final_filename = save_as_filename;
317 if (final_filename.find(".sfc") == std::string::npos &&
318 final_filename.find(".smc") == std::string::npos) {
319 final_filename += ".sfc";
320 }
321
322 auto status = editor_manager_->SaveRomAs(final_filename);
323 if (status.ok()) {
324 save_as_filename = "";
326 }
327 }
328 }
329
330 SameLine();
331 if (Button(absl::StrFormat("%s Cancel", ICON_MD_CANCEL).c_str(),
333 save_as_filename = "";
335 }
336}
337
339 using namespace ImGui;
340
341 static std::string project_name = "";
342 static std::string project_filepath = "";
343 static std::string rom_filename = "";
344 static std::string labels_filename = "";
345 static std::string code_folder = "";
346
347 InputText("Project Name", &project_name);
348
349 if (Button(absl::StrFormat("%s Destination Folder", ICON_MD_FOLDER).c_str(),
352 }
353 SameLine();
354 Text("%s", project_filepath.empty() ? "(Not set)" : project_filepath.c_str());
355
356 if (Button(absl::StrFormat("%s ROM File", ICON_MD_VIDEOGAME_ASSET).c_str(),
360 }
361 SameLine();
362 Text("%s", rom_filename.empty() ? "(Not set)" : rom_filename.c_str());
363
364 if (Button(absl::StrFormat("%s Labels File", ICON_MD_LABEL).c_str(),
367 }
368 SameLine();
369 Text("%s", labels_filename.empty() ? "(Not set)" : labels_filename.c_str());
370
371 if (Button(absl::StrFormat("%s Code Folder", ICON_MD_CODE).c_str(),
374 }
375 SameLine();
376 Text("%s", code_folder.empty() ? "(Not set)" : code_folder.c_str());
377
378 Separator();
379
380 if (Button(absl::StrFormat("%s Choose Project File Location", ICON_MD_SAVE)
381 .c_str(),
383 auto project_file_path =
385 if (!project_file_path.empty()) {
386 if (project_file_path.find(".yaze") == std::string::npos) {
387 project_file_path += ".yaze";
388 }
389 project_filepath = project_file_path;
390 }
391 }
392
393 if (Button(absl::StrFormat("%s Create Project", ICON_MD_ADD).c_str(),
395 if (!project_filepath.empty() && !project_name.empty()) {
396 auto status = editor_manager_->CreateNewProject();
397 if (status.ok()) {
398 // Clear fields
399 project_name = "";
400 project_filepath = "";
401 rom_filename = "";
402 labels_filename = "";
403 code_folder = "";
405 }
406 }
407 }
408 SameLine();
409 if (Button(absl::StrFormat("%s Cancel", ICON_MD_CANCEL).c_str(),
411 // Clear fields
412 project_name = "";
413 project_filepath = "";
414 rom_filename = "";
415 labels_filename = "";
416 code_folder = "";
418 }
419}
420
422 if (CollapsingHeader(
423 absl::StrFormat("%s Overworld Editor", ICON_MD_LAYERS).c_str(),
424 ImGuiTreeNodeFlags_DefaultOpen)) {
425 BulletText("LW/DW/SW Tilemap Editing");
426 BulletText("LW/DW/SW Map Properties");
427 BulletText("Create/Delete/Update Entrances");
428 BulletText("Create/Delete/Update Exits");
429 BulletText("Create/Delete/Update Sprites");
430 BulletText("Create/Delete/Update Items");
431 BulletText("Multi-session map editing support");
432 }
433
434 if (CollapsingHeader(
435 absl::StrFormat("%s Dungeon Editor", ICON_MD_CASTLE).c_str())) {
436 BulletText("View Room Header Properties");
437 BulletText("View Entrance Properties");
438 BulletText("Enhanced room navigation");
439 }
440
441 if (CollapsingHeader(
442 absl::StrFormat("%s Graphics & Themes", ICON_MD_PALETTE).c_str())) {
443 BulletText("View Decompressed Graphics Sheets");
444 BulletText("View/Update Graphics Groups");
445 BulletText(
446 "5+ Built-in themes (Classic, Cyberpunk, Sunset, Forest, Midnight)");
447 BulletText("Custom theme creation and editing");
448 BulletText("Theme import/export functionality");
449 BulletText("Animated background grid effects");
450 }
451
452 if (CollapsingHeader(
453 absl::StrFormat("%s Palettes", ICON_MD_COLOR_LENS).c_str())) {
454 BulletText("View Palette Groups");
455 BulletText("Enhanced palette editing tools");
456 BulletText("Color conversion utilities");
457 }
458
459 if (CollapsingHeader(
460 absl::StrFormat("%s Project Management", ICON_MD_FOLDER).c_str())) {
461 BulletText("Multi-session workspace support");
462 BulletText("Enhanced project creation and management");
463 BulletText("ZScream project format compatibility");
464 BulletText("Workspace settings and feature flags");
465 }
466
467 if (CollapsingHeader(
468 absl::StrFormat("%s Development Tools", ICON_MD_BUILD).c_str())) {
469 BulletText("Asar 65816 assembler integration");
470 BulletText("Enhanced CLI tools with TUI interface");
471 BulletText("Memory editor with advanced features");
472 BulletText("Hex editor with search and navigation");
473 BulletText("Assembly validation and symbol extraction");
474 }
475
476 if (CollapsingHeader(
477 absl::StrFormat("%s Save Capabilities", ICON_MD_SAVE).c_str())) {
478 BulletText("All Overworld editing features");
479 BulletText("Hex Editor changes");
480 BulletText("Theme configurations");
481 BulletText("Project settings and workspace layouts");
482 BulletText("Custom assembly patches");
483 }
484
485 if (Button("Close", gui::kDefaultModalSize)) {
486 Hide("Supported Features");
487 }
488}
489
491 Text("File -> Open");
492 Text("Select a ROM file to open");
493 Text("Supported ROMs (headered or unheadered):");
494 Text("The Legend of Zelda: A Link to the Past");
495 Text("US Version 1.0");
496 Text("JP Version 1.0");
497 Spacing();
498 TextWrapped("ROM files are not bundled. Use a clean, legally obtained copy.");
499
500 if (Button("Close", gui::kDefaultModalSize)) {
501 Hide("Open a ROM");
502 }
503}
504
506 Text("Project Menu");
507 Text("Create a new project or open an existing one.");
508 Text("Save the project to save the current state of the project.");
509 TextWrapped(
510 "To save a project, you need to first open a ROM and initialize your "
511 "code path and labels file. Label resource manager can be found in "
512 "the View menu. Code path is set in the Code editor after opening a "
513 "folder.");
514
515 if (Button("Close", gui::kDefaultModalSize)) {
516 Hide("Manage Project");
517 }
518}
519
521 TextWrapped("Welcome to YAZE v%s!", YAZE_VERSION_STRING);
522 TextWrapped(
523 "YAZE lets you modify 'The Legend of Zelda: A Link to the Past' (US or "
524 "JP) ROMs with modern tooling.");
525 Spacing();
526 TextWrapped("Release Highlights:");
527 BulletText(
528 "AI-assisted workflows via z3ed agent and in-app panels "
529 "(Ollama/Gemini/OpenAI/Anthropic)");
530 BulletText("Web/WASM preview with collaboration server support");
531 BulletText("Music editor updates with SPC parsing and playback");
532 Spacing();
533 TextWrapped("General Tips:");
534 BulletText("Open a clean ROM and save a backup before editing");
535 BulletText("Use Help (F1) for context-aware guidance");
536 BulletText(
537 "Configure AI providers (Ollama/Gemini/OpenAI/Anthropic) in Settings > "
538 "Agent");
539
540 if (Button("Close", gui::kDefaultModalSize)) {
541 Hide("Getting Started");
542 }
543}
544
546 TextWrapped("Asar 65816 Assembly Integration");
547 TextWrapped(
548 "YAZE v0.5.0 includes full Asar assembler support for ROM patching.");
549 Spacing();
550 TextWrapped("Features:");
551 BulletText("Cross-platform ROM patching with assembly code");
552 BulletText("Symbol export with addresses and opcodes");
553 BulletText("Assembly validation with detailed error reporting");
554 BulletText("Memory-safe patch application with size checks");
555
556 if (Button("Close", gui::kDefaultModalSize)) {
557 Hide("Asar Integration");
558 }
559}
560
562 TextWrapped("Build Instructions");
563 TextWrapped("YAZE uses modern CMake for cross-platform builds.");
564 Spacing();
565 TextWrapped("Quick Start (examples):");
566 BulletText("cmake --preset mac-dbg | lin-dbg | win-dbg");
567 BulletText("cmake --build --preset <preset> --target yaze");
568 Spacing();
569 TextWrapped("AI Builds:");
570 BulletText("cmake --preset mac-ai | lin-ai | win-ai");
571 BulletText("cmake --build --preset <preset> --target yaze z3ed");
572 Spacing();
573 TextWrapped("Docs: docs/public/build/quick-reference.md");
574
575 if (Button("Close", gui::kDefaultModalSize)) {
576 Hide("Build Instructions");
577 }
578}
579
581 TextWrapped("Command Line Interface (z3ed)");
582 TextWrapped("Scriptable ROM editing and AI agent workflows.");
583 Spacing();
584 TextWrapped("Commands:");
585 BulletText("z3ed rom-info --rom=zelda3.sfc");
586 BulletText("z3ed agent simple-chat --rom=zelda3.sfc --ai_provider=openai");
587 BulletText("z3ed --tui");
588 BulletText("z3ed patch apply-asar patch.asm --rom=zelda3.sfc");
589
590 if (Button("Close", gui::kDefaultModalSize)) {
591 Hide("CLI Usage");
592 }
593}
594
596 TextWrapped("Troubleshooting");
597 TextWrapped("Common issues and solutions:");
598 Spacing();
599 BulletText("ROM won't load: Check file format (SFC/SMC supported)");
600 BulletText(
601 "AI agent missing: Start Ollama or set GEMINI_API_KEY/OPENAI_API_KEY/"
602 "ANTHROPIC_API_KEY");
603 BulletText("Graphics issues: Try disabling experimental features");
604 BulletText("Performance: Enable hardware acceleration in display settings");
605 BulletText("Crashes: Check ROM file integrity and available memory");
606
607 if (Button("Close", gui::kDefaultModalSize)) {
608 Hide("Troubleshooting");
609 }
610}
611
613 TextWrapped("Contributing to YAZE");
614 TextWrapped("YAZE is open source and welcomes contributions!");
615 Spacing();
616 TextWrapped("How to contribute:");
617 BulletText("Fork the repository on GitHub");
618 BulletText("Create feature branches for new work");
619 BulletText("Follow C++ coding standards");
620 BulletText("Include tests for new features");
621 BulletText("Submit pull requests for review");
622
623 if (Button("Close", gui::kDefaultModalSize)) {
624 Hide("Contributing");
625 }
626}
627
629 TextWrapped("What's New in YAZE v%s", YAZE_VERSION_STRING);
630 Spacing();
631
632 if (CollapsingHeader(
633 absl::StrFormat("%s User Interface & Theming", ICON_MD_PALETTE)
634 .c_str(),
635 ImGuiTreeNodeFlags_DefaultOpen)) {
636 BulletText("Refreshed welcome screen and onboarding tips");
637 BulletText("Context-aware help panels and updated popups");
638 BulletText("Improved panel layouts and session workflows");
639 BulletText("Theme polish and icon refreshes");
640 }
641
642 if (CollapsingHeader(
643 absl::StrFormat("%s Development & Build System", ICON_MD_BUILD)
644 .c_str(),
645 ImGuiTreeNodeFlags_DefaultOpen)) {
646 BulletText("Asar 65816 assembler integration for ROM patching");
647 BulletText("z3ed CLI + TUI for scripting, test/doctor, and automation");
648 BulletText("Modern CMake presets for desktop, AI, and web builds");
649 BulletText("Cross-platform CI/CD hardening (Windows, macOS, Linux)");
650 BulletText("Quality release packaging for macOS/Windows/Linux");
651 }
652
653 if (CollapsingHeader(
654 absl::StrFormat("%s Core Improvements", ICON_MD_SETTINGS).c_str())) {
655 BulletText("Improved ROM validation and project metadata handling");
656 BulletText("Stronger error reporting and status feedback");
657 BulletText("Performance and stability improvements across editors");
658 BulletText("Expanded logging and diagnostics tooling");
659 }
660
661 if (CollapsingHeader(
662 absl::StrFormat("%s Editor Features", ICON_MD_EDIT).c_str())) {
663 BulletText("Music editor updates with SPC parsing/playback");
664 BulletText(
665 "AI agent-assisted editing workflows (Ollama/Gemini/OpenAI/"
666 "Anthropic)");
667 BulletText("Expanded overworld/dungeon tooling and palettes");
668 BulletText("Web/WASM preview with collaboration hooks");
669 }
670
671 Spacing();
672 if (Button(
673 absl::StrFormat("%s View Release Notes", ICON_MD_DESCRIPTION).c_str(),
674 ImVec2(-1, 30))) {
675 // Close this popup and show theme settings
677 // Could trigger release notes panel opening here
678 }
679
680 if (Button("Close", gui::kDefaultModalSize)) {
682 }
683}
684
686 TextWrapped("Workspace Management");
687 TextWrapped(
688 "YAZE supports multiple ROM sessions and flexible workspace layouts.");
689 Spacing();
690
691 TextWrapped("Session Management:");
692 BulletText("Ctrl+Shift+N: Create new session");
693 BulletText("Ctrl+Shift+W: Close current session");
694 BulletText("Ctrl+Tab: Quick session switcher");
695 BulletText("Each session maintains its own ROM and editor state");
696
697 Spacing();
698 TextWrapped("Layout Management:");
699 BulletText("Drag window tabs to dock/undock");
700 BulletText("Ctrl+Shift+S: Save current layout");
701 BulletText("Ctrl+Shift+O: Load saved layout");
702 BulletText("F11: Maximize current window");
703
704 Spacing();
705 TextWrapped("Preset Layouts:");
706 BulletText("Developer: Code, memory, testing tools");
707 BulletText("Designer: Graphics, palettes, sprites");
708 BulletText("Modder: All gameplay editing tools");
709
710 if (Button("Close", gui::kDefaultModalSize)) {
711 Hide("Workspace Help");
712 }
713}
714
716 TextColored(ImVec4(1.0f, 0.5f, 0.0f, 1.0f), "%s Warning", ICON_MD_WARNING);
717 TextWrapped("You have reached the recommended session limit.");
718 TextWrapped("Having too many sessions open may impact performance.");
719 Spacing();
720 TextWrapped("Consider closing unused sessions or saving your work.");
721
722 if (Button("Understood", gui::kDefaultModalSize)) {
723 Hide("Session Limit Warning");
724 }
725 SameLine();
726 if (Button("Open Session Manager", gui::kDefaultModalSize)) {
727 Hide("Session Limit Warning");
728 // This would trigger the session manager to open
729 }
730}
731
733 TextColored(ImVec4(1.0f, 0.5f, 0.0f, 1.0f), "%s Confirm Reset",
735 TextWrapped("This will reset your current workspace layout to default.");
736 TextWrapped("Any custom window arrangements will be lost.");
737 Spacing();
738 TextWrapped("Do you want to continue?");
739
740 if (Button("Reset Layout", gui::kDefaultModalSize)) {
741 Hide("Layout Reset Confirm");
742 // This would trigger the actual reset
743 }
744 SameLine();
745 if (Button("Cancel", gui::kDefaultModalSize)) {
746 Hide("Layout Reset Confirm");
747 }
748}
749
751 TextColored(ImVec4(0.4f, 0.8f, 1.0f, 1.0f), "%s Layout Presets",
753 Separator();
754 Spacing();
755
756 TextWrapped("Choose a workspace preset to quickly configure your layout:");
757 Spacing();
758
759 // Get named presets from LayoutPresets
760 struct PresetInfo {
761 const char* name;
762 const char* icon;
763 const char* description;
764 std::function<PanelLayoutPreset()> getter;
765 };
766
767 PresetInfo presets[] = {
768 {"Minimal", ICON_MD_CROP_FREE,
769 "Essential cards only - maximum editing space",
770 []() {
772 }},
773 {"Developer", ICON_MD_BUG_REPORT,
774 "Debug and development focused - CPU/Memory/Breakpoints",
775 []() {
777 }},
778 {"Designer", ICON_MD_PALETTE,
779 "Visual and artistic focused - Graphics/Palettes/Sprites",
780 []() {
782 }},
783 {"Modder", ICON_MD_BUILD,
784 "Full-featured - All tools available for comprehensive editing",
785 []() {
787 }},
788 {"Overworld Expert", ICON_MD_MAP,
789 "Complete overworld editing toolkit with all map tools",
790 []() {
792 }},
793 {"Dungeon Expert", ICON_MD_DOOR_SLIDING,
794 "Complete dungeon editing toolkit with room tools",
795 []() {
797 }},
798 {"Testing", ICON_MD_SCIENCE, "Quality assurance and ROM testing layout",
799 []() {
801 }},
802 {"Audio", ICON_MD_MUSIC_NOTE, "Music and sound editing layout",
803 []() {
805 }},
806 };
807
808 constexpr int kPresetCount = 8;
809
810 // Draw preset buttons in a grid
811 float button_width = 200.0f;
812 float button_height = 50.0f;
813
814 for (int i = 0; i < kPresetCount; i++) {
815 if (i % 2 != 0)
816 SameLine();
817
818 PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f));
819 if (Button(
820 absl::StrFormat("%s %s", presets[i].icon, presets[i].name).c_str(),
821 ImVec2(button_width, button_height))) {
822 // Apply the preset
823 auto preset = presets[i].getter();
824 auto& panel_manager = editor_manager_->panel_manager();
825 // Hide all panels first
826 panel_manager.HideAll();
827 // Show preset panels
828 for (const auto& panel_id : preset.default_visible_panels) {
829 panel_manager.ShowPanel(panel_id);
830 }
832 }
833 PopStyleVar();
834
835 if (IsItemHovered()) {
836 BeginTooltip();
837 TextUnformatted(presets[i].description);
838 EndTooltip();
839 }
840 }
841
842 Spacing();
843 Separator();
844 Spacing();
845
846 // Reset current editor to defaults
847 if (Button(
848 absl::StrFormat("%s Reset Current Editor", ICON_MD_REFRESH).c_str(),
849 ImVec2(-1, 0))) {
850 auto& panel_manager = editor_manager_->card_registry();
851 auto* current_editor = editor_manager_->GetCurrentEditor();
852 if (current_editor) {
853 auto current_type = current_editor->type();
854 panel_manager.ResetToDefaults(0, current_type);
855 }
857 }
858
859 Spacing();
860 if (Button("Close", ImVec2(-1, 0))) {
862 }
863}
864
866 TextColored(ImVec4(0.4f, 0.8f, 1.0f, 1.0f), "%s Session Manager",
868 Separator();
869 Spacing();
870
871 size_t session_count = editor_manager_->GetActiveSessionCount();
872 size_t active_session = editor_manager_->GetCurrentSessionId();
873
874 Text("Active Sessions: %zu", session_count);
875 Spacing();
876
877 // Session table
878 if (BeginTable("SessionTable", 4,
879 ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
880 TableSetupColumn("#", ImGuiTableColumnFlags_WidthFixed, 30.0f);
881 TableSetupColumn("ROM", ImGuiTableColumnFlags_WidthStretch);
882 TableSetupColumn("Status", ImGuiTableColumnFlags_WidthFixed, 80.0f);
883 TableSetupColumn("Actions", ImGuiTableColumnFlags_WidthFixed, 120.0f);
884 TableHeadersRow();
885
886 for (size_t i = 0; i < session_count; i++) {
887 TableNextRow();
888
889 // Session number
890 TableSetColumnIndex(0);
891 Text("%zu", i + 1);
892
893 // ROM name (simplified - show current ROM for active session)
894 TableSetColumnIndex(1);
895 if (i == active_session) {
896 auto* rom = editor_manager_->GetCurrentRom();
897 if (rom && rom->is_loaded()) {
898 TextUnformatted(rom->filename().c_str());
899 } else {
900 TextDisabled("(No ROM loaded)");
901 }
902 } else {
903 TextDisabled("Session %zu", i + 1);
904 }
905
906 // Status indicator
907 TableSetColumnIndex(2);
908 if (i == active_session) {
909 TextColored(ImVec4(0.2f, 0.8f, 0.2f, 1.0f), "%s Active",
911 } else {
912 TextDisabled("Inactive");
913 }
914
915 // Actions
916 TableSetColumnIndex(3);
917 PushID(static_cast<int>(i));
918
919 if (i != active_session) {
920 if (SmallButton("Switch")) {
922 }
923 SameLine();
924 }
925
926 BeginDisabled(session_count <= 1);
927 if (SmallButton("Close")) {
929 }
930 EndDisabled();
931
932 PopID();
933 }
934
935 EndTable();
936 }
937
938 Spacing();
939 Separator();
940 Spacing();
941
942 // New session button
943 if (Button(absl::StrFormat("%s New Session", ICON_MD_ADD).c_str(),
944 ImVec2(-1, 0))) {
946 }
947
948 Spacing();
949 if (Button("Close", ImVec2(-1, 0))) {
951 }
952}
953
955 // Set a comfortable default size with natural constraints
956 SetNextWindowSize(ImVec2(900, 700), ImGuiCond_FirstUseEver);
957 SetNextWindowSizeConstraints(ImVec2(600, 400), ImVec2(FLT_MAX, FLT_MAX));
958
959 Text("%s Display & Theme Settings", ICON_MD_DISPLAY_SETTINGS);
960 TextWrapped("Customize your YAZE experience - accessible anytime!");
961 Separator();
962
963 // Create a child window for scrollable content to avoid table conflicts
964 // Use remaining space minus the close button area
965 float available_height =
966 GetContentRegionAvail().y - 60; // Reserve space for close button
967 if (BeginChild("DisplaySettingsContent", ImVec2(0, available_height), true,
968 ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
969 // Use the popup-safe version to avoid table conflicts
971
972 Separator();
973 gui::TextWithSeparators("Font Manager");
975
976 // Global font scale (moved from the old display settings window)
977 ImGuiIO& io = GetIO();
978 Separator();
979 Text("Global Font Scale");
980 static float font_global_scale = io.FontGlobalScale;
981 if (SliderFloat("##global_scale", &font_global_scale, 0.5f, 1.8f, "%.2f")) {
982 if (editor_manager_) {
983 editor_manager_->SetFontGlobalScale(font_global_scale);
984 } else {
985 io.FontGlobalScale = font_global_scale;
986 }
987 }
988 }
989 EndChild();
990
991 Separator();
992 if (Button("Close", gui::kDefaultModalSize)) {
993 Hide("Display Settings");
994 }
995}
996
998 using namespace ImGui;
999
1000 // Display feature flags editor using the existing FlagsMenu system
1001 Text("Feature Flags Configuration");
1002 Separator();
1003
1004 BeginChild("##FlagsContent", ImVec2(0, -30), true);
1005
1006 // Use the feature flags menu system
1007 static gui::FlagsMenu flags_menu;
1008
1009 if (BeginTabBar("FlagCategories")) {
1010 if (BeginTabItem("Overworld")) {
1011 flags_menu.DrawOverworldFlags();
1012 EndTabItem();
1013 }
1014 if (BeginTabItem("Dungeon")) {
1015 flags_menu.DrawDungeonFlags();
1016 EndTabItem();
1017 }
1018 if (BeginTabItem("Resources")) {
1019 flags_menu.DrawResourceFlags();
1020 EndTabItem();
1021 }
1022 if (BeginTabItem("System")) {
1023 flags_menu.DrawSystemFlags();
1024 EndTabItem();
1025 }
1026 EndTabBar();
1027 }
1028
1029 EndChild();
1030
1031 Separator();
1032 if (Button("Close", gui::kDefaultModalSize)) {
1034 }
1035}
1036
1038 using namespace ImGui;
1039
1040 Text("Data Integrity Check Results");
1041 Separator();
1042
1043 BeginChild("##IntegrityContent", ImVec2(0, -30), true);
1044
1045 // Placeholder for data integrity results
1046 // In a full implementation, this would show test results
1047 Text("ROM Data Integrity:");
1048 Separator();
1049 TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f), "✓ ROM header valid");
1050 TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f), "✓ Checksum valid");
1051 TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f), "✓ Graphics data intact");
1052 TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f), "✓ Map data intact");
1053
1054 Spacing();
1055 Text("No issues detected.");
1056
1057 EndChild();
1058
1059 Separator();
1060 if (Button("Close", gui::kDefaultModalSize)) {
1062 }
1063}
1064
1065} // namespace editor
1066} // namespace yaze
The EditorManager controls the main editor window and manages the various editor classes.
absl::Status SaveRomAs(const std::string &filename)
void SwitchToSession(size_t index)
absl::Status CreateNewProject(const std::string &template_name="Basic ROM Hack")
void SetFontGlobalScale(float scale)
auto GetCurrentEditor() const -> Editor *
auto GetCurrentRom() const -> Rom *
void RemoveSession(size_t index)
static PanelLayoutPreset GetDungeonExpertPreset()
Get the "dungeon expert" workspace preset.
static PanelLayoutPreset GetTestingPreset()
Get the "testing" workspace preset (QA focused)
static PanelLayoutPreset GetDesignerPreset()
Get the "designer" workspace preset (visual-focused)
static PanelLayoutPreset GetAudioPreset()
Get the "audio" workspace preset (music focused)
static PanelLayoutPreset GetModderPreset()
Get the "modder" workspace preset (full-featured)
static PanelLayoutPreset GetOverworldExpertPreset()
Get the "overworld expert" workspace preset.
static PanelLayoutPreset GetMinimalPreset()
Get the "minimal" workspace preset (minimal cards)
static PanelLayoutPreset GetDeveloperPreset()
Get the "developer" workspace preset (debug-focused)
void HideAll(size_t session_id)
void SetStatus(const absl::Status &status)
bool IsVisible(const char *name) const
void Show(const char *name)
void Hide(const char *name)
PopupManager(EditorManager *editor_manager)
std::unordered_map< std::string, PopupParams > popups_
EditorManager * editor_manager_
bool BeginCentered(const char *name)
static std::string ShowSaveFileDialog(const std::string &default_name="", const std::string &default_extension="")
ShowSaveFileDialog opens a save file dialog and returns the selected filepath. Uses global feature fl...
static std::string ShowOpenFileDialog()
ShowOpenFileDialog opens a file dialog and returns the selected filepath. Uses global feature flag to...
static std::string ShowOpenFolderDialog()
ShowOpenFolderDialog opens a file dialog and returns the selected folder path. Uses global feature fl...
#define YAZE_VERSION_STRING
Definition yaze.h:43
#define ICON_MD_FOLDER_OPEN
Definition icons.h:813
#define ICON_MD_SETTINGS
Definition icons.h:1699
#define ICON_MD_CANCEL
Definition icons.h:364
#define ICON_MD_WARNING
Definition icons.h:2123
#define ICON_MD_DOOR_SLIDING
Definition icons.h:614
#define ICON_MD_SAVE_AS
Definition icons.h:1646
#define ICON_MD_REFRESH
Definition icons.h:1572
#define ICON_MD_MAP
Definition icons.h:1173
#define ICON_MD_CODE
Definition icons.h:434
#define ICON_MD_LABEL
Definition icons.h:1053
#define ICON_MD_VIDEOGAME_ASSET
Definition icons.h:2076
#define ICON_MD_BUG_REPORT
Definition icons.h:327
#define ICON_MD_EDIT
Definition icons.h:645
#define ICON_MD_CASTLE
Definition icons.h:380
#define ICON_MD_ERROR
Definition icons.h:686
#define ICON_MD_MUSIC_NOTE
Definition icons.h:1264
#define ICON_MD_LAYERS
Definition icons.h:1068
#define ICON_MD_DISPLAY_SETTINGS
Definition icons.h:587
#define ICON_MD_ADD
Definition icons.h:86
#define ICON_MD_SCIENCE
Definition icons.h:1656
#define ICON_MD_CHECK_CIRCLE
Definition icons.h:400
#define ICON_MD_DESCRIPTION
Definition icons.h:539
#define ICON_MD_BUILD
Definition icons.h:328
#define ICON_MD_DASHBOARD
Definition icons.h:517
#define ICON_MD_SAVE
Definition icons.h:1644
#define ICON_MD_TAB
Definition icons.h:1930
#define ICON_MD_FOLDER
Definition icons.h:809
#define ICON_MD_PALETTE
Definition icons.h:1370
#define ICON_MD_CONTENT_COPY
Definition icons.h:465
#define ICON_MD_COLOR_LENS
Definition icons.h:440
#define ICON_MD_CROP_FREE
Definition icons.h:495
Definition input.cc:22
constexpr const char * kRomInfo
constexpr const char * kLayoutPresets
constexpr const char * kAbout
constexpr const char * kSessionManager
constexpr const char * kTroubleshooting
constexpr const char * kWhatsNew
constexpr const char * kSupportedFeatures
constexpr const char * kDataIntegrity
constexpr const char * kManageProject
constexpr const char * kNewProject
constexpr const char * kSaveAs
constexpr const char * kDisplaySettings
constexpr const char * kSessionLimitWarning
constexpr const char * kCLIUsage
constexpr const char * kLayoutResetConfirm
constexpr const char * kAsarIntegration
constexpr const char * kOpenRomHelp
constexpr const char * kFeatureFlags
constexpr const char * kGettingStarted
constexpr const char * kContributing
constexpr const char * kBuildInstructions
constexpr const char * kWorkspaceHelp
void DrawFontManager()
Definition style.cc:1323
void DrawDisplaySettingsForPopup(ImGuiStyle *ref)
Definition style.cc:868
constexpr ImVec2 kDefaultModalSize
Definition input.h:21
void TextWithSeparators(const absl::string_view &text)
Definition style.cc:1317
std::string HexLongLong(uint64_t qword, HexStringParams params)
Definition hex.cc:63
FileDialogOptions MakeRomFileDialogOptions(bool include_all_files)
Definition file_util.cc:87
Defines default panel visibility for an editor type.
Yet Another Zelda3 Editor (YAZE) - Public C API.