From 61e35f2819fe8b1c10ba8b0d581659d82d50277e Mon Sep 17 00:00:00 2001 From: scawful Date: Tue, 11 Mar 2025 21:05:04 -0400 Subject: [PATCH] Implement docking support in the main editor window; enhance editor activation management --- src/app/core/controller.cc | 65 ++++++++++++++++++++++++-------- src/app/editor/editor.h | 4 ++ src/app/editor/editor_manager.cc | 53 +++++++++++++++++++++++--- src/app/editor/editor_manager.h | 5 +-- 4 files changed, 104 insertions(+), 23 deletions(-) diff --git a/src/app/core/controller.cc b/src/app/core/controller.cc index 475f769f..ee1d8fd5 100644 --- a/src/app/core/controller.cc +++ b/src/app/core/controller.cc @@ -18,6 +18,29 @@ namespace yaze { namespace core { +namespace { +// Helper function to draw the main window without docking enabled +// Should be followed by ImGui::End() to close the window +void DrawBasicWindow() { + constexpr ImGuiWindowFlags kMainEditorFlags = + ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | + ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_MenuBar | + ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoTitleBar; + + const ImGuiIO &io = ImGui::GetIO(); + ImGui_ImplSDLRenderer2_NewFrame(); + ImGui_ImplSDL2_NewFrame(); + ImGui::NewFrame(); + ImGui::SetNextWindowPos(gui::kZeroPos); + ImVec2 dimensions(io.DisplaySize.x, io.DisplaySize.y); + ImGui::SetNextWindowSize(dimensions, ImGuiCond_Always); + + if (!ImGui::Begin("##YazeMain", nullptr, kMainEditorFlags)) { + ImGui::End(); + } +} +} // namespace + absl::Status Controller::OnEntry(std::string filename) { RETURN_IF_ERROR(CreateWindow()) RETURN_IF_ERROR(CreateRenderer()) @@ -88,28 +111,39 @@ absl::Status Controller::OnLoad() { if (editor_manager_.quit()) { active_ = false; } -#if TARGET_OS_IPHONE != 1 - constexpr ImGuiWindowFlags kMainEditorFlags = - ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | - ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_MenuBar | - ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoTitleBar; - const ImGuiIO &io = ImGui::GetIO(); +#if TARGET_OS_IPHONE != 1 ImGui_ImplSDLRenderer2_NewFrame(); ImGui_ImplSDL2_NewFrame(); ImGui::NewFrame(); - ImGui::SetNextWindowPos(gui::kZeroPos); - ImVec2 dimensions(io.DisplaySize.x, io.DisplaySize.y); - ImGui::SetNextWindowSize(dimensions, ImGuiCond_Always); - if (!ImGui::Begin("##YazeMain", nullptr, kMainEditorFlags)) { - ImGui::End(); - } -#endif - RETURN_IF_ERROR(editor_manager_.Update()); -#if TARGET_OS_IPHONE != 1 + const ImGuiViewport *viewport = ImGui::GetMainViewport(); + ImGui::SetNextWindowPos(viewport->WorkPos); + ImGui::SetNextWindowSize(viewport->WorkSize); + ImGui::SetNextWindowViewport(viewport->ID); + + ImGuiWindowFlags window_flags = + ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking; + window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | + ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove; + window_flags |= + ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus; + + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); + ImGui::Begin("DockSpaceWindow", nullptr, window_flags); + ImGui::PopStyleVar(2); + + // Create DockSpace + ImGuiID dockspace_id = ImGui::GetID("MyDockSpace"); + ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), + ImGuiDockNodeFlags_PassthruCentralNode); + + editor_manager_.DrawMenuBar(); // Draw the fixed menu bar at the top + ImGui::End(); #endif + RETURN_IF_ERROR(editor_manager_.Update()); return absl::OkStatus(); } @@ -168,6 +202,7 @@ absl::Status Controller::CreateGuiContext() { ImGuiIO &io = ImGui::GetIO(); io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Initialize ImGui based on the backend ImGui_ImplSDL2_InitForSDLRenderer(window_.get(), diff --git a/src/app/editor/editor.h b/src/app/editor/editor.h index 41878128..6814309c 100644 --- a/src/app/editor/editor.h +++ b/src/app/editor/editor.h @@ -77,7 +77,11 @@ class Editor { void set_context(EditorContext* context) { context_ = context; } + bool* active() { return &active_; } + void set_active(bool active) { active_ = active; } + protected: + bool active_ = false; EditorType type_; EditorContext* context_ = nullptr; }; diff --git a/src/app/editor/editor_manager.cc b/src/app/editor/editor_manager.cc index 975bec97..27036614 100644 --- a/src/app/editor/editor_manager.cc +++ b/src/app/editor/editor_manager.cc @@ -47,6 +47,10 @@ bool IsEditorActive(Editor *editor, std::vector &active_editors) { active_editors.end(); } +std::string GetEditorName(EditorType type) { + return kEditorNames[static_cast(type)]; +} + } // namespace void EditorManager::Initialize(const std::string &filename) { @@ -144,8 +148,8 @@ void EditorManager::Initialize(const std::string &filename) { {absl::StrCat(ICON_MD_CLOSE, " Close"), "", [&]() { rom()->Close(); }}, {gui::kSeparator, "", nullptr, []() { return true; }}, - {absl::StrCat(ICON_MD_SETTINGS, " Options"), "", [&]() {}, - []() { return true; }, options_subitems}, + {absl::StrCat(ICON_MD_MISCELLANEOUS_SERVICES, " Options"), "", + [&]() {}, []() { return true; }, options_subitems}, {absl::StrCat(ICON_MD_EXIT_TO_APP, " Quit"), "Ctrl+Q", [&]() { quit_ = true; }}, }}, @@ -182,12 +186,38 @@ void EditorManager::Initialize(const std::string &filename) { { {absl::StrCat(ICON_MD_CODE, " Assembly Editor"), "", [&]() { show_asm_editor_ = true; }}, + {absl::StrCat(ICON_MD_CASTLE, " Dungeon Editor"), "", + [&]() { dungeon_editor_.set_active(true); }, + [&]() { return *dungeon_editor_.active(); }}, + {absl::StrCat(ICON_MD_PHOTO, " Graphics Editor"), "", + [&]() { graphics_editor_.set_active(true); }, + [&]() { return *graphics_editor_.active(); }}, + {absl::StrCat(ICON_MD_MUSIC_NOTE, " Music Editor"), "", + [&]() { music_editor_.set_active(true); }, + [&]() { return *music_editor_.active(); }}, + {absl::StrCat(ICON_MD_LAYERS, " Overworld Editor"), "", + [&]() { overworld_editor_.set_active(true); }, + [&]() { return *overworld_editor_.active(); }}, + {absl::StrCat(ICON_MD_PALETTE, " Palette Editor"), "", + [&]() { palette_editor_.set_active(true); }, + [&]() { return *palette_editor_.active(); }}, + {absl::StrCat(ICON_MD_SCREENSHOT, " Screen Editor"), "", + [&]() { screen_editor_.set_active(true); }, + [&]() { return *screen_editor_.active(); }}, + {absl::StrCat(ICON_MD_SMART_TOY, " Sprite Editor"), "", + [&]() { sprite_editor_.set_active(true); }, + [&]() { return *sprite_editor_.active(); }}, + {absl::StrCat(ICON_MD_MESSAGE, " Message Editor"), "", + [&]() { message_editor_.set_active(true); }, + [&]() { return *message_editor_.active(); }}, + {absl::StrCat(ICON_MD_SETTINGS, " Settings Editor"), "", + [&]() { settings_editor_.set_active(true); }, + [&]() { return *settings_editor_.active(); }}, + {gui::kSeparator, "", nullptr, []() { return true; }}, {absl::StrCat(ICON_MD_GAMEPAD, " Emulator"), "", [&]() { show_emulator_ = true; }}, {absl::StrCat(ICON_MD_MEMORY, " Memory Editor"), "", [&]() { show_memory_editor_ = true; }}, - {absl::StrCat(ICON_MD_PALETTE, " Palette Editor"), "", - [&]() { show_palette_editor_ = true; }}, {absl::StrCat(ICON_MD_SIM_CARD, " ROM Metadata"), "", [&]() { rom_info_ = true; }}, {gui::kSeparator, "", nullptr, []() { return true; }}, @@ -228,7 +258,20 @@ absl::Status EditorManager::Update() { ExecuteShortcuts(context_.shortcut_manager); context_.command_manager.ShowWhichKey(); - if (ImGui::Begin("Home", nullptr, ImGuiWindowFlags_None)) { + for (auto editor : active_editors_) { + if (*editor->active()) { + if (ImGui::Begin(GetEditorName(editor->type()).c_str(), + editor->active())) { + current_editor_ = editor; + status_ = editor->Update(); + ImGui::End(); + } + } + } + + static bool show_home = true; + + if (ImGui::Begin("Home", &show_home)) { if (!current_rom_) { DrawHomepage(); } else { diff --git a/src/app/editor/editor_manager.h b/src/app/editor/editor_manager.h index 6cf57e37..2e22bdfe 100644 --- a/src/app/editor/editor_manager.h +++ b/src/app/editor/editor_manager.h @@ -41,7 +41,8 @@ class EditorManager : public SharedRom { current_editor_ = &overworld_editor_; active_editors_ = {&overworld_editor_, &dungeon_editor_, &graphics_editor_, &palette_editor_, &sprite_editor_, &message_editor_, - &screen_editor_, &settings_editor_}; + &music_editor_, &screen_editor_, &settings_editor_, + &assembly_editor_}; for (auto *editor : active_editors_) { editor->set_context(&context_); } @@ -53,7 +54,6 @@ class EditorManager : public SharedRom { void Initialize(const std::string &filename = ""); absl::Status Update(); - void DrawMenuBar(); auto emulator() -> emu::Emulator & { return emulator_; } @@ -62,7 +62,6 @@ class EditorManager : public SharedRom { private: void ManageActiveEditors(); void DrawHomepage(); - void DrawPopups(); void LoadRom();