5#include "absl/strings/str_format.h"
11#include "imgui/misc/cpp/imgui_stdlib.h"
20 : editor_manager_(editor_manager), status_(absl::OkStatus()) {}
43 false,
false, [
this]() {
70 false,
false, [
this]() {
96 false,
false, [
this]() {
119 false,
false, [
this]() {
154 for (
auto& [name, params] :
popups_) {
155 if (params.is_visible) {
156 OpenPopup(name.c_str());
159 ImGuiWindowFlags popup_flags = params.allow_resize
160 ? ImGuiWindowFlags_None
161 : ImGuiWindowFlags_AlwaysAutoResize;
163 if (BeginPopupModal(name.c_str(),
nullptr, popup_flags)) {
164 params.draw_function();
176 std::string name_str(name);
177 auto it =
popups_.find(name_str);
179 it->second.is_visible =
true;
183 "[PopupManager] Warning: Popup '%s' not registered. Available popups: ",
185 for (
const auto& [key, _] :
popups_) {
186 printf(
"'%s' ", key.c_str());
197 std::string name_str(name);
198 auto it =
popups_.find(name_str);
200 it->second.is_visible =
false;
210 std::string name_str(name);
211 auto it =
popups_.find(name_str);
213 return it->second.is_visible;
227 ImGuiIO
const& io = GetIO();
228 ImVec2 pos(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.5f);
229 SetNextWindowPos(pos, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
230 ImGuiWindowFlags flags =
231 ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration |
232 ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings;
233 return Begin(name,
nullptr, flags);
260 Text(
"Written by: scawful");
262 Text(
"Special Thanks: Zarby89, JaredBrian");
275 Text(
"Title: %s", current_rom->title().c_str());
279 IsKeyPressed(ImGuiKey_Escape)) {
280 Hide(
"ROM Information");
285 using namespace ImGui;
290 static std::string save_as_filename =
"";
295 InputText(
"Filename", &save_as_filename);
302 if (!file_path.empty()) {
303 save_as_filename = file_path;
308 if (Button(absl::StrFormat(
"%s Save",
ICON_MD_SAVE).c_str(),
310 if (!save_as_filename.empty()) {
312 std::string final_filename = save_as_filename;
313 if (final_filename.find(
".sfc") == std::string::npos &&
314 final_filename.find(
".smc") == std::string::npos) {
315 final_filename +=
".sfc";
320 save_as_filename =
"";
329 save_as_filename =
"";
335 using namespace ImGui;
337 static std::string project_name =
"";
338 static std::string project_filepath =
"";
339 static std::string rom_filename =
"";
340 static std::string labels_filename =
"";
341 static std::string code_folder =
"";
343 InputText(
"Project Name", &project_name);
345 if (Button(absl::StrFormat(
"%s Destination Folder",
ICON_MD_FOLDER).c_str(),
350 Text(
"%s", project_filepath.empty() ?
"(Not set)" : project_filepath.c_str());
357 Text(
"%s", rom_filename.empty() ?
"(Not set)" : rom_filename.c_str());
359 if (Button(absl::StrFormat(
"%s Labels File",
ICON_MD_LABEL).c_str(),
364 Text(
"%s", labels_filename.empty() ?
"(Not set)" : labels_filename.c_str());
366 if (Button(absl::StrFormat(
"%s Code Folder",
ICON_MD_CODE).c_str(),
371 Text(
"%s", code_folder.empty() ?
"(Not set)" : code_folder.c_str());
375 if (Button(absl::StrFormat(
"%s Choose Project File Location",
ICON_MD_SAVE)
378 auto project_file_path =
380 if (!project_file_path.empty()) {
381 if (project_file_path.find(
".yaze") == std::string::npos) {
382 project_file_path +=
".yaze";
384 project_filepath = project_file_path;
388 if (Button(absl::StrFormat(
"%s Create Project",
ICON_MD_ADD).c_str(),
390 if (!project_filepath.empty() && !project_name.empty()) {
395 project_filepath =
"";
397 labels_filename =
"";
408 project_filepath =
"";
410 labels_filename =
"";
417 if (CollapsingHeader(
419 ImGuiTreeNodeFlags_DefaultOpen)) {
420 BulletText(
"LW/DW/SW Tilemap Editing");
421 BulletText(
"LW/DW/SW Map Properties");
422 BulletText(
"Create/Delete/Update Entrances");
423 BulletText(
"Create/Delete/Update Exits");
424 BulletText(
"Create/Delete/Update Sprites");
425 BulletText(
"Create/Delete/Update Items");
426 BulletText(
"Multi-session map editing support");
429 if (CollapsingHeader(
431 BulletText(
"View Room Header Properties");
432 BulletText(
"View Entrance Properties");
433 BulletText(
"Enhanced room navigation");
436 if (CollapsingHeader(
438 BulletText(
"View Decompressed Graphics Sheets");
439 BulletText(
"View/Update Graphics Groups");
441 "5+ Built-in themes (Classic, Cyberpunk, Sunset, Forest, Midnight)");
442 BulletText(
"Custom theme creation and editing");
443 BulletText(
"Theme import/export functionality");
444 BulletText(
"Animated background grid effects");
447 if (CollapsingHeader(
449 BulletText(
"View Palette Groups");
450 BulletText(
"Enhanced palette editing tools");
451 BulletText(
"Color conversion utilities");
454 if (CollapsingHeader(
455 absl::StrFormat(
"%s Project Management",
ICON_MD_FOLDER).c_str())) {
456 BulletText(
"Multi-session workspace support");
457 BulletText(
"Enhanced project creation and management");
458 BulletText(
"ZScream project format compatibility");
459 BulletText(
"Workspace settings and feature flags");
462 if (CollapsingHeader(
463 absl::StrFormat(
"%s Development Tools",
ICON_MD_BUILD).c_str())) {
464 BulletText(
"Asar 65816 assembler integration");
465 BulletText(
"Enhanced CLI tools with TUI interface");
466 BulletText(
"Memory editor with advanced features");
467 BulletText(
"Hex editor with search and navigation");
468 BulletText(
"Assembly validation and symbol extraction");
471 if (CollapsingHeader(
472 absl::StrFormat(
"%s Save Capabilities",
ICON_MD_SAVE).c_str())) {
473 BulletText(
"All Overworld editing features");
474 BulletText(
"Hex Editor changes");
475 BulletText(
"Theme configurations");
476 BulletText(
"Project settings and workspace layouts");
477 BulletText(
"Custom assembly patches");
481 Hide(
"Supported Features");
486 Text(
"File -> Open");
487 Text(
"Select a ROM file to open");
488 Text(
"Supported ROMs (headered or unheadered):");
489 Text(
"The Legend of Zelda: A Link to the Past");
490 Text(
"US Version 1.0");
491 Text(
"JP Version 1.0");
499 Text(
"Project Menu");
500 Text(
"Create a new project or open an existing one.");
501 Text(
"Save the project to save the current state of the project.");
503 "To save a project, you need to first open a ROM and initialize your "
504 "code path and labels file. Label resource manager can be found in "
505 "the View menu. Code path is set in the Code editor after opening a "
509 Hide(
"Manage Project");
514 TextWrapped(
"Welcome to YAZE v0.3!");
516 "This software allows you to modify 'The Legend of Zelda: A Link to the "
517 "Past' (US or JP) ROMs.");
519 TextWrapped(
"General Tips:");
520 BulletText(
"Experiment flags determine whether certain features are enabled");
521 BulletText(
"Backup files are enabled by default for safety");
522 BulletText(
"Use File > Options to configure settings");
525 Hide(
"Getting Started");
530 TextWrapped(
"Asar 65816 Assembly Integration");
532 "YAZE v0.3 includes full Asar assembler support for ROM patching.");
534 TextWrapped(
"Features:");
535 BulletText(
"Cross-platform ROM patching with assembly code");
536 BulletText(
"Symbol extraction with addresses and opcodes");
537 BulletText(
"Assembly validation with error reporting");
538 BulletText(
"Memory-safe operations with automatic ROM size management");
541 Hide(
"Asar Integration");
546 TextWrapped(
"Build Instructions");
547 TextWrapped(
"YAZE uses modern CMake for cross-platform builds.");
549 TextWrapped(
"Quick Start:");
550 BulletText(
"cmake -B build");
551 BulletText(
"cmake --build build --target yaze");
553 TextWrapped(
"Development:");
554 BulletText(
"cmake --preset dev");
555 BulletText(
"cmake --build --preset dev");
558 Hide(
"Build Instructions");
563 TextWrapped(
"Command Line Interface (z3ed)");
564 TextWrapped(
"Enhanced CLI tool with Asar integration.");
566 TextWrapped(
"Commands:");
567 BulletText(
"z3ed asar patch.asm --rom=file.sfc");
568 BulletText(
"z3ed extract symbols.asm");
569 BulletText(
"z3ed validate assembly.asm");
570 BulletText(
"z3ed patch file.bps --rom=file.sfc");
578 TextWrapped(
"Troubleshooting");
579 TextWrapped(
"Common issues and solutions:");
581 BulletText(
"ROM won't load: Check file format (SFC/SMC supported)");
582 BulletText(
"Graphics issues: Try disabling experimental features");
583 BulletText(
"Performance: Enable hardware acceleration in display settings");
584 BulletText(
"Crashes: Check ROM file integrity and available memory");
587 Hide(
"Troubleshooting");
592 TextWrapped(
"Contributing to YAZE");
593 TextWrapped(
"YAZE is open source and welcomes contributions!");
595 TextWrapped(
"How to contribute:");
596 BulletText(
"Fork the repository on GitHub");
597 BulletText(
"Create feature branches for new work");
598 BulletText(
"Follow C++ coding standards");
599 BulletText(
"Include tests for new features");
600 BulletText(
"Submit pull requests for review");
603 Hide(
"Contributing");
608 TextWrapped(
"What's New in YAZE v0.3");
611 if (CollapsingHeader(
614 ImGuiTreeNodeFlags_DefaultOpen)) {
615 BulletText(
"Complete theme management system with 5+ built-in themes");
616 BulletText(
"Custom theme editor with save-to-file functionality");
617 BulletText(
"Animated background grid with breathing effects (optional)");
618 BulletText(
"Enhanced welcome screen with themed elements");
619 BulletText(
"Multi-session workspace support with docking");
620 BulletText(
"Improved editor organization and navigation");
623 if (CollapsingHeader(
624 absl::StrFormat(
"%s Development & Build System",
ICON_MD_BUILD)
626 ImGuiTreeNodeFlags_DefaultOpen)) {
627 BulletText(
"Asar 65816 assembler integration for ROM patching");
628 BulletText(
"Enhanced CLI tools with TUI (Terminal User Interface)");
629 BulletText(
"Modernized CMake build system with presets");
630 BulletText(
"Cross-platform CI/CD pipeline (Windows, macOS, Linux)");
631 BulletText(
"Comprehensive testing framework with 46+ core tests");
632 BulletText(
"Professional packaging for all platforms (DMG, MSI, DEB)");
635 if (CollapsingHeader(
637 BulletText(
"Enhanced project management with YazeProject structure");
638 BulletText(
"Improved ROM loading and validation");
639 BulletText(
"Better error handling and status reporting");
640 BulletText(
"Memory safety improvements with sanitizers");
641 BulletText(
"Enhanced file dialog integration");
642 BulletText(
"Improved logging and debugging capabilities");
645 if (CollapsingHeader(
646 absl::StrFormat(
"%s Editor Features",
ICON_MD_EDIT).c_str())) {
647 BulletText(
"Enhanced overworld editing capabilities");
648 BulletText(
"Improved graphics sheet viewing and editing");
649 BulletText(
"Better palette management and editing");
650 BulletText(
"Enhanced memory and hex editing tools");
651 BulletText(
"Improved sprite and item management");
652 BulletText(
"Better entrance and exit editing");
656 if (Button(absl::StrFormat(
"%s View Theme Editor",
ICON_MD_PALETTE).c_str(),
659 Hide(
"Whats New v03");
664 Hide(
"Whats New v03");
669 TextWrapped(
"Workspace Management");
671 "YAZE supports multiple ROM sessions and flexible workspace layouts.");
674 TextWrapped(
"Session Management:");
675 BulletText(
"Ctrl+Shift+N: Create new session");
676 BulletText(
"Ctrl+Shift+W: Close current session");
677 BulletText(
"Ctrl+Tab: Quick session switcher");
678 BulletText(
"Each session maintains its own ROM and editor state");
681 TextWrapped(
"Layout Management:");
682 BulletText(
"Drag window tabs to dock/undock");
683 BulletText(
"Ctrl+Shift+S: Save current layout");
684 BulletText(
"Ctrl+Shift+O: Load saved layout");
685 BulletText(
"F11: Maximize current window");
688 TextWrapped(
"Preset Layouts:");
689 BulletText(
"Developer: Code, memory, testing tools");
690 BulletText(
"Designer: Graphics, palettes, sprites");
691 BulletText(
"Modder: All gameplay editing tools");
694 Hide(
"Workspace Help");
699 TextColored(ImVec4(1.0f, 0.5f, 0.0f, 1.0f),
"%s Warning",
ICON_MD_WARNING);
700 TextWrapped(
"You have reached the recommended session limit.");
701 TextWrapped(
"Having too many sessions open may impact performance.");
703 TextWrapped(
"Consider closing unused sessions or saving your work.");
706 Hide(
"Session Limit Warning");
710 Hide(
"Session Limit Warning");
716 TextColored(ImVec4(1.0f, 0.5f, 0.0f, 1.0f),
"%s Confirm Reset",
718 TextWrapped(
"This will reset your current workspace layout to default.");
719 TextWrapped(
"Any custom window arrangements will be lost.");
721 TextWrapped(
"Do you want to continue?");
724 Hide(
"Layout Reset Confirm");
729 Hide(
"Layout Reset Confirm");
734 TextColored(ImVec4(0.4f, 0.8f, 1.0f, 1.0f),
"%s Layout Presets",
739 TextWrapped(
"Choose a workspace preset to quickly configure your layout:");
746 const char* description;
750 PresetInfo presets[] = {
752 "Essential cards only - maximum editing space",
755 "Debug and development focused - CPU/Memory/Breakpoints",
758 "Visual and artistic focused - Graphics/Palettes/Sprites",
761 "Full-featured - All tools available for comprehensive editing",
764 "Complete overworld editing toolkit with all map tools",
767 "Complete dungeon editing toolkit with room tools",
770 "Quality assurance and ROM testing layout",
773 "Music and sound editing layout",
777 constexpr int kPresetCount = 8;
780 float button_width = 200.0f;
781 float button_height = 50.0f;
783 for (
int i = 0; i < kPresetCount; i++) {
784 if (i % 2 != 0) SameLine();
786 PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f));
787 if (Button(absl::StrFormat(
"%s %s", presets[i].icon, presets[i].name).c_str(),
788 ImVec2(button_width, button_height))) {
790 auto preset = presets[i].getter();
795 for (
const auto& panel_id : preset.default_visible_panels) {
796 panel_manager.ShowPanel(panel_id);
802 if (IsItemHovered()) {
804 TextUnformatted(presets[i].description);
814 if (Button(absl::StrFormat(
"%s Reset Current Editor",
ICON_MD_REFRESH).c_str(),
818 if (current_editor) {
819 auto current_type = current_editor->type();
820 panel_manager.ResetToDefaults(0, current_type);
826 if (Button(
"Close", ImVec2(-1, 0))) {
832 TextColored(ImVec4(0.4f, 0.8f, 1.0f, 1.0f),
"%s Session Manager",
840 Text(
"Active Sessions: %zu", session_count);
844 if (BeginTable(
"SessionTable", 4,
845 ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
846 TableSetupColumn(
"#", ImGuiTableColumnFlags_WidthFixed, 30.0f);
847 TableSetupColumn(
"ROM", ImGuiTableColumnFlags_WidthStretch);
848 TableSetupColumn(
"Status", ImGuiTableColumnFlags_WidthFixed, 80.0f);
849 TableSetupColumn(
"Actions", ImGuiTableColumnFlags_WidthFixed, 120.0f);
852 for (
size_t i = 0; i < session_count; i++) {
856 TableSetColumnIndex(0);
860 TableSetColumnIndex(1);
861 if (i == active_session) {
863 if (rom && rom->is_loaded()) {
864 TextUnformatted(rom->filename().c_str());
866 TextDisabled(
"(No ROM loaded)");
869 TextDisabled(
"Session %zu", i + 1);
873 TableSetColumnIndex(2);
874 if (i == active_session) {
875 TextColored(ImVec4(0.2f, 0.8f, 0.2f, 1.0f),
"%s Active",
878 TextDisabled(
"Inactive");
882 TableSetColumnIndex(3);
883 PushID(
static_cast<int>(i));
885 if (i != active_session) {
886 if (SmallButton(
"Switch")) {
892 BeginDisabled(session_count <= 1);
893 if (SmallButton(
"Close")) {
909 if (Button(absl::StrFormat(
"%s New Session",
ICON_MD_ADD).c_str(),
915 if (Button(
"Close", ImVec2(-1, 0))) {
922 SetNextWindowSize(ImVec2(900, 700), ImGuiCond_FirstUseEver);
923 SetNextWindowSizeConstraints(ImVec2(600, 400), ImVec2(FLT_MAX, FLT_MAX));
926 TextWrapped(
"Customize your YAZE experience - accessible anytime!");
931 float available_height =
932 GetContentRegionAvail().y - 60;
933 if (BeginChild(
"DisplaySettingsContent", ImVec2(0, available_height),
true,
934 ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
943 ImGuiIO& io = GetIO();
945 Text(
"Global Font Scale");
946 static float font_global_scale = io.FontGlobalScale;
947 if (SliderFloat(
"##global_scale", &font_global_scale, 0.5f, 1.8f,
"%.2f")) {
951 io.FontGlobalScale = font_global_scale;
959 Hide(
"Display Settings");
964 using namespace ImGui;
967 Text(
"Feature Flags Configuration");
970 BeginChild(
"##FlagsContent", ImVec2(0, -30),
true);
975 if (BeginTabBar(
"FlagCategories")) {
976 if (BeginTabItem(
"Overworld")) {
980 if (BeginTabItem(
"Dungeon")) {
984 if (BeginTabItem(
"Resources")) {
988 if (BeginTabItem(
"System")) {
1004 using namespace ImGui;
1006 Text(
"Data Integrity Check Results");
1009 BeginChild(
"##IntegrityContent", ImVec2(0, -30),
true);
1013 Text(
"ROM Data Integrity:");
1015 TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f),
"✓ ROM header valid");
1016 TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f),
"✓ Checksum valid");
1017 TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f),
"✓ Graphics data intact");
1018 TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f),
"✓ Map data intact");
1021 Text(
"No issues detected.");
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)
size_t GetActiveSessionCount() const
absl::Status CreateNewProject(const std::string &template_name="Basic ROM Hack")
void SetFontGlobalScale(float scale)
auto GetCurrentEditor() const -> Editor *
PanelManager & card_registry()
PanelManager & panel_manager()
size_t GetCurrentSessionId() const
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)
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 ICON_MD_FOLDER_OPEN
#define ICON_MD_DOOR_SLIDING
#define ICON_MD_VIDEOGAME_ASSET
#define ICON_MD_BUG_REPORT
#define ICON_MD_MUSIC_NOTE
#define ICON_MD_DISPLAY_SETTINGS
#define ICON_MD_CHECK_CIRCLE
#define ICON_MD_DASHBOARD
#define ICON_MD_CONTENT_COPY
#define ICON_MD_COLOR_LENS
#define ICON_MD_CROP_FREE
void DrawDisplaySettingsForPopup(ImGuiStyle *ref)
constexpr ImVec2 kDefaultModalSize
void TextWithSeparators(const absl::string_view &text)
std::string HexLongLong(uint64_t qword, HexStringParams params)
Defines default panel visibility for an editor type.