refactor(editor): introduce UICoordinator for UI management

- Added UICoordinator class to centralize UI drawing operations and state management, improving separation of concerns within the editor.
- Refactored EditorManager to delegate UI-related tasks to UICoordinator, enhancing maintainability and clarity.
- Updated CMake configuration to include new source files for the UICoordinator component.

Benefits:
- Streamlines UI management, leading to a more organized and efficient user experience.
- Enhances the overall architecture by clearly defining roles for UI handling and editor operations.
This commit is contained in:
scawful
2025-10-14 22:56:01 -04:00
parent 0127913ff9
commit 9f41f8c2b8
12 changed files with 1500 additions and 672 deletions

View File

@@ -43,11 +43,12 @@ set(
app/editor/system/session_card_registry.cc
app/editor/system/settings_editor.cc
app/editor/system/shortcut_manager.cc
app/editor/system/session_coordinator.cc
app/editor/system/user_settings.cc
app/editor/system/window_delegate.cc
app/editor/ui/editor_selection_dialog.cc
app/editor/ui/menu_builder.cc
app/editor/ui/session_coordinator.cc
app/editor/ui/ui_coordinator.cc
app/editor/ui/welcome_screen.cc
app/editor/ui/workspace_manager.cc
)

View File

@@ -7,6 +7,7 @@
#include <memory>
#include <sstream>
#include <string>
#include "zelda3/screen/dungeon_map.h"
#define IMGUI_DEFINE_MATH_OPERATORS
@@ -138,6 +139,11 @@ EditorManager::EditorManager()
menu_orchestrator_ = std::make_unique<MenuOrchestrator>(
menu_builder_, rom_file_manager_, project_manager_, editor_registry_,
*session_coordinator_, toast_manager_);
// Initialize UICoordinator after all other components are created
ui_coordinator_ = std::make_unique<UICoordinator>(
this, rom_file_manager_, project_manager_, editor_registry_,
*session_coordinator_, window_delegate_, toast_manager_, *popup_manager_);
}
EditorManager::~EditorManager() = default;
@@ -1041,60 +1047,10 @@ absl::Status EditorManager::DrawRomSelector() {
}
void EditorManager::DrawContextSensitiveCardControl() {
if (!current_editor_set_ || !current_editor_) {
return;
// Delegate to UICoordinator for clean separation of concerns
if (ui_coordinator_) {
ui_coordinator_->DrawContextSensitiveCardControl();
}
// Determine which category to show based on active editor
std::string category;
switch (current_editor_->type()) {
case EditorType::kDungeon:
category = "Dungeon";
break;
case EditorType::kGraphics:
category = "Graphics";
break;
case EditorType::kScreen:
category = "Screen";
break;
case EditorType::kSprite:
category = "Sprite";
break;
case EditorType::kOverworld:
category = "Overworld";
break;
case EditorType::kMessage:
category = "Message";
break;
case EditorType::kPalette:
category = "Palette";
break;
case EditorType::kAssembly:
// Assembly editor uses dynamic file tabs
return;
case EditorType::kEmulator:
category = "Emulator";
break;
case EditorType::kMusic:
// Music editor doesn't use cards yet
return;
default:
return; // No cards for this editor type
}
// Draw compact card control for the active editor's cards with session awareness
auto& card_manager = gui::EditorCardManager::Get();
if (session_coordinator_ && session_coordinator_->HasMultipleSessions()) {
std::string session_prefix = absl::StrFormat("s%zu", context_.session_id);
card_manager.DrawCompactCardControlWithSession(category, session_prefix);
} else {
card_manager.DrawCompactCardControl(category);
}
// Show visible/total count
SameLine();
card_manager.DrawInlineCardToggles(category);
}
void EditorManager::BuildModernMenu() {
@@ -1105,63 +1061,10 @@ void EditorManager::BuildModernMenu() {
}
void EditorManager::DrawMenuBarExtras() {
auto* current_rom = GetCurrentRom();
std::string version_text = absl::StrFormat("v%s", version_.c_str());
float version_width = ImGui::CalcTextSize(version_text.c_str()).x;
float session_rom_area_width = 280.0f;
SameLine(ImGui::GetWindowWidth() - version_width - 10 -
session_rom_area_width);
if (session_coordinator_ && session_coordinator_->HasMultipleSessions()) {
if (ImGui::SmallButton(
absl::StrFormat("%s%zu", ICON_MD_TAB, session_coordinator_->GetActiveSessionCount())
.c_str())) {
session_coordinator_->ToggleSessionSwitcher();
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Sessions: %zu active\nClick to switch",
session_coordinator_->GetActiveSessionCount());
}
ImGui::SameLine();
// Delegate to UICoordinator for clean separation of concerns
if (ui_coordinator_) {
ui_coordinator_->DrawMenuBarExtras();
}
if (current_rom && current_rom->is_loaded()) {
if (ImGui::SmallButton(ICON_MD_APPS)) {
ShowEditorSelection();
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(ICON_MD_DASHBOARD " Editor Selection (Ctrl+E)");
}
ImGui::SameLine();
if (ImGui::SmallButton(ICON_MD_DISPLAY_SETTINGS)) {
ShowDisplaySettings();
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(ICON_MD_TUNE " Display Settings");
}
ImGui::SameLine();
ImGui::Separator();
ImGui::SameLine();
}
if (current_rom && current_rom->is_loaded()) {
std::string rom_display = current_rom->title();
if (rom_display.length() > 22) {
rom_display = rom_display.substr(0, 19) + "...";
}
if (ImGui::SmallButton(absl::StrFormat("%s%s", rom_display.c_str(),
current_rom->dirty() ? "*" : "")
.c_str())) {
ImGui::OpenPopup("ROM Details");
}
} else {
ImGui::TextColored(ImVec4(0.5f, 0.5f, 0.5f, 1.0f), "No ROM");
ImGui::SameLine();
}
SameLine(ImGui::GetWindowWidth() - version_width - 10);
ImGui::Text("%s", version_text.c_str());
}
void EditorManager::ShowSessionSwitcher() {
@@ -1170,13 +1073,25 @@ void EditorManager::ShowSessionSwitcher() {
}
}
void EditorManager::DrawSessionSwitcher() {
// Delegate to UICoordinator for clean separation of concerns
if (ui_coordinator_) {
ui_coordinator_->DrawSessionSwitcher();
}
}
void EditorManager::ShowEditorSelection() {
show_editor_selection_ = true;
// Delegate to UICoordinator for clean separation of concerns
if (ui_coordinator_) {
ui_coordinator_->ShowEditorSelection();
}
}
void EditorManager::ShowDisplaySettings() {
if (popup_manager_)
popup_manager_->Show("Display Settings");
// Delegate to UICoordinator for clean separation of concerns
if (ui_coordinator_) {
ui_coordinator_->ShowDisplaySettings();
}
}
void EditorManager::DrawMenuBar() {
@@ -2030,8 +1945,8 @@ absl::Status EditorManager::CreateNewProject(const std::string& template_name) {
auto status = project_manager_.CreateNewProject(template_name);
if (status.ok()) {
current_project_ = project_manager_.GetCurrentProject();
// Show project creation dialog
popup_manager_->Show("Create New Project");
// Show project creation dialog
popup_manager_->Show("Create New Project");
}
return status;
}
@@ -2255,10 +2170,10 @@ void EditorManager::CreateNewSession() {
// Wire editor contexts for new session
if (!sessions_.empty()) {
RomSession& session = sessions_.back();
session.editors.set_user_settings(&user_settings_);
for (auto* editor : session.editors.active_editors_) {
editor->set_context(&context_);
RomSession& session = sessions_.back();
session.editors.set_user_settings(&user_settings_);
for (auto* editor : session.editors.active_editors_) {
editor->set_context(&context_);
}
}
}
@@ -2289,9 +2204,9 @@ void EditorManager::DuplicateCurrentSession() {
// Wire editor contexts for duplicated session
if (!sessions_.empty()) {
RomSession& session = sessions_.back();
for (auto* editor : session.editors.active_editors_) {
editor->set_context(&context_);
}
for (auto* editor : session.editors.active_editors_) {
editor->set_context(&context_);
}
}
}
}
@@ -2334,15 +2249,15 @@ void EditorManager::SwitchToSession(size_t index) {
// Update current pointers after session switch
if (index < sessions_.size()) {
auto& session = sessions_[index];
current_rom_ = &session.rom;
current_editor_set_ = &session.editors;
// Update test manager with current ROM for ROM-dependent tests
util::logf("EditorManager: Setting ROM in TestManager - %p ('%s')",
(void*)current_rom_,
current_rom_ ? current_rom_->title().c_str() : "null");
test::TestManager::Get().SetCurrentRom(current_rom_);
auto& session = sessions_[index];
current_rom_ = &session.rom;
current_editor_set_ = &session.editors;
// Update test manager with current ROM for ROM-dependent tests
util::logf("EditorManager: Setting ROM in TestManager - %p ('%s')",
(void*)current_rom_,
current_rom_ ? current_rom_->title().c_str() : "null");
test::TestManager::Get().SetCurrentRom(current_rom_);
}
}
}
@@ -2407,45 +2322,17 @@ void EditorManager::LoadWorkspaceLayout() {
}
void EditorManager::ShowAllWindows() {
if (!current_editor_set_)
return;
// Delegate to WindowDelegate for registered windows
window_delegate_.ShowAllWindows();
// Also show editor windows
for (auto* editor : current_editor_set_->active_editors_) {
editor->set_active(true);
// Delegate to UICoordinator for clean separation of concerns
if (ui_coordinator_) {
ui_coordinator_->ShowAllWindows();
}
show_imgui_demo_ = true;
show_imgui_metrics_ = true;
show_performance_dashboard_ = true;
#ifdef YAZE_ENABLE_TESTING
show_test_dashboard_ = true;
#endif
toast_manager_.Show("All windows shown", editor::ToastType::kInfo);
}
void EditorManager::HideAllWindows() {
if (!current_editor_set_)
return;
// Delegate to WindowDelegate for registered windows
window_delegate_.HideAllWindows();
// Also hide editor windows
for (auto* editor : current_editor_set_->active_editors_) {
editor->set_active(false);
// Delegate to UICoordinator for clean separation of concerns
if (ui_coordinator_) {
ui_coordinator_->HideAllWindows();
}
show_imgui_demo_ = false;
show_imgui_metrics_ = false;
show_performance_dashboard_ = false;
#ifdef YAZE_ENABLE_TESTING
show_test_dashboard_ = false;
#endif
toast_manager_.Show("All windows hidden", editor::ToastType::kInfo);
}
void EditorManager::MaximizeCurrentWindow() {
@@ -2523,519 +2410,35 @@ void EditorManager::LoadModderLayout() {
toast_manager_.Show("Modder layout loaded", editor::ToastType::kSuccess);
}
void EditorManager::DrawSessionSwitcher() {
if (!show_session_switcher_)
return;
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(),
ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
ImGui::SetNextWindowSize(ImVec2(700, 450), ImGuiCond_Appearing);
if (ImGui::Begin(
absl::StrFormat("%s Session Switcher", ICON_MD_SWITCH_ACCOUNT)
.c_str(),
&show_session_switcher_, ImGuiWindowFlags_NoCollapse)) {
// Header with enhanced info
ImGui::Text("%s %zu Sessions Available", ICON_MD_TAB, sessions_.size());
ImGui::SameLine(ImGui::GetWindowWidth() - 120);
if (ImGui::Button(absl::StrFormat("%s New", ICON_MD_ADD).c_str(),
ImVec2(50, 0))) {
CreateNewSession();
}
ImGui::SameLine();
if (ImGui::Button(absl::StrFormat("%s Manager", ICON_MD_SETTINGS).c_str(),
ImVec2(60, 0))) {
show_session_manager_ = true;
}
ImGui::Separator();
// Enhanced session list using table for better layout
const float TABLE_HEIGHT = ImGui::GetContentRegionAvail().y -
50; // Reserve space for close button
if (ImGui::BeginTable("SessionSwitcherTable", 4,
ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg |
ImGuiTableFlags_SizingStretchProp |
ImGuiTableFlags_ScrollY |
ImGuiTableFlags_Resizable,
ImVec2(0, TABLE_HEIGHT))) {
// Setup columns with proper sizing weights
ImGui::TableSetupColumn("Session", ImGuiTableColumnFlags_WidthStretch,
0.3f);
ImGui::TableSetupColumn("ROM Info", ImGuiTableColumnFlags_WidthStretch,
0.4f);
ImGui::TableSetupColumn("Status", ImGuiTableColumnFlags_WidthFixed,
90.0f);
ImGui::TableSetupColumn("Actions", ImGuiTableColumnFlags_WidthFixed,
140.0f);
ImGui::TableHeadersRow();
for (size_t i = 0; i < sessions_.size(); ++i) {
auto& session = sessions_[i];
// Skip closed sessions
if (session.custom_name == "[CLOSED SESSION]") {
continue;
}
bool is_current = (&session.rom == current_rom_);
ImGui::PushID(static_cast<int>(i));
ImGui::TableNextRow(ImGuiTableRowFlags_None,
55.0f); // Consistent row height
// Session name column with better styling
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
if (is_current) {
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.2f, 0.8f, 0.2f, 1.0f));
ImGui::Text("%s %s", ICON_MD_STAR, session.GetDisplayName().c_str());
ImGui::PopStyleColor();
} else {
ImGui::Text("%s %s", ICON_MD_TAB, session.GetDisplayName().c_str());
}
// ROM info column with better information layout
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
if (session.rom.is_loaded()) {
ImGui::Text("%s %s", ICON_MD_VIDEOGAME_ASSET,
session.rom.title().c_str());
ImGui::Text("%.1f MB | %s", session.rom.size() / 1048576.0f,
session.rom.dirty() ? "Modified" : "Clean");
} else {
ImGui::TextColored(ImVec4(0.6f, 0.6f, 0.6f, 1.0f), "%s No ROM loaded",
ICON_MD_WARNING);
}
// Status column with better visual indicators
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
if (session.rom.is_loaded()) {
if (session.rom.dirty()) {
ImGui::TextColored(ImVec4(1.0f, 0.5f, 0.0f, 1.0f), "%s",
ICON_MD_EDIT);
} else {
ImGui::TextColored(ImVec4(0.2f, 0.8f, 0.2f, 1.0f), "%s",
ICON_MD_CHECK_CIRCLE);
}
} else {
ImGui::TextColored(ImVec4(0.6f, 0.6f, 0.6f, 1.0f), "%s",
ICON_MD_RADIO_BUTTON_UNCHECKED);
}
// Actions column with improved button layout
ImGui::TableNextColumn();
// Create button group for better alignment
ImGui::BeginGroup();
if (!is_current) {
if (ImGui::Button("Switch")) {
SwitchToSession(i);
show_session_switcher_ = false;
}
} else {
ImGui::BeginDisabled();
ImGui::Button("Current");
ImGui::EndDisabled();
}
ImGui::SameLine();
if (ImGui::Button("Rename")) {
session_to_rename_ = i;
// Safe string copy with bounds checking
const std::string& name = session.GetDisplayName();
size_t copy_len =
std::min(name.length(), sizeof(session_rename_buffer_) - 1);
std::memcpy(session_rename_buffer_, name.c_str(), copy_len);
session_rename_buffer_[copy_len] = '\0';
show_session_rename_dialog_ = true;
}
ImGui::SameLine();
// Close button logic
bool can_close = GetActiveSessionCount() > 1;
if (!can_close) {
ImGui::BeginDisabled();
}
if (ImGui::Button("Close")) {
if (is_current) {
CloseCurrentSession();
} else {
// Remove non-current session directly
RemoveSession(i);
show_session_switcher_ =
false; // Close switcher since indices changed
}
}
if (!can_close) {
ImGui::EndDisabled();
}
ImGui::EndGroup();
ImGui::PopID();
}
ImGui::EndTable();
}
ImGui::Separator();
if (ImGui::Button(
absl::StrFormat("%s Close Switcher", ICON_MD_CLOSE).c_str(),
ImVec2(-1, 0))) {
show_session_switcher_ = false;
}
void EditorManager::DrawWelcomeScreen() {
// Delegate to UICoordinator for clean separation of concerns
if (ui_coordinator_) {
ui_coordinator_->DrawWelcomeScreen();
}
ImGui::End();
}
void EditorManager::DrawSessionManager() {
if (!show_session_manager_)
return;
if (ImGui::Begin(absl::StrCat(ICON_MD_VIEW_LIST, " Session Manager").c_str(),
&show_session_manager_)) {
ImGui::Text("%s Session Management", ICON_MD_MANAGE_ACCOUNTS);
if (ImGui::Button(absl::StrCat(ICON_MD_ADD, " New Session").c_str())) {
CreateNewSession();
}
ImGui::SameLine();
if (ImGui::Button(
absl::StrCat(ICON_MD_CONTENT_COPY, " Duplicate Current").c_str()) &&
current_rom_) {
DuplicateCurrentSession();
}
ImGui::Separator();
ImGui::Text("%s Active Sessions (%zu)", ICON_MD_TAB,
GetActiveSessionCount());
// Enhanced session management table with proper sizing
const float AVAILABLE_HEIGHT = ImGui::GetContentRegionAvail().y;
if (ImGui::BeginTable("SessionTable", 6,
ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg |
ImGuiTableFlags_Resizable |
ImGuiTableFlags_ScrollY |
ImGuiTableFlags_SizingStretchProp |
ImGuiTableFlags_ContextMenuInBody,
ImVec2(0, AVAILABLE_HEIGHT))) {
// Setup columns with explicit sizing for better control
ImGui::TableSetupColumn("Session", ImGuiTableColumnFlags_WidthStretch,
0.15f);
ImGui::TableSetupColumn("ROM Title", ImGuiTableColumnFlags_WidthStretch,
0.3f);
ImGui::TableSetupColumn("Size", ImGuiTableColumnFlags_WidthFixed, 70.0f);
ImGui::TableSetupColumn("Status", ImGuiTableColumnFlags_WidthFixed,
80.0f);
ImGui::TableSetupColumn("Custom OW", ImGuiTableColumnFlags_WidthFixed,
80.0f);
ImGui::TableSetupColumn("Actions", ImGuiTableColumnFlags_WidthStretch,
0.25f);
ImGui::TableHeadersRow();
for (size_t i = 0; i < sessions_.size(); ++i) {
auto& session = sessions_[i];
// Skip closed sessions in session manager too
if (session.custom_name == "[CLOSED SESSION]") {
continue;
}
bool is_current = (&session.rom == current_rom_);
ImGui::TableNextRow(ImGuiTableRowFlags_None,
50.0f); // Consistent row height
ImGui::PushID(static_cast<int>(i));
// Session name column
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
if (is_current) {
ImGui::TextColored(ImVec4(0.2f, 0.8f, 0.2f, 1.0f), "%s Session %zu",
ICON_MD_STAR, i + 1);
} else {
ImGui::Text("%s Session %zu", ICON_MD_TAB, i + 1);
}
// ROM title column
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
std::string display_name = session.GetDisplayName();
if (!session.custom_name.empty()) {
ImGui::TextColored(ImVec4(0.7f, 0.9f, 1.0f, 1.0f), "%s %s",
ICON_MD_EDIT, display_name.c_str());
} else {
// Use TextWrapped for long ROM titles
ImGui::PushTextWrapPos(ImGui::GetCursorPos().x +
ImGui::GetColumnWidth());
ImGui::Text("%s", display_name.c_str());
ImGui::PopTextWrapPos();
}
// File size column
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
if (session.rom.is_loaded()) {
ImGui::Text("%.1f MB", session.rom.size() / 1048576.0f);
} else {
ImGui::TextDisabled("N/A");
}
// Status column
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
if (session.rom.is_loaded()) {
if (session.rom.dirty()) {
ImGui::TextColored(ImVec4(1.0f, 0.5f, 0.0f, 1.0f), "%s",
ICON_MD_EDIT);
} else {
ImGui::TextColored(ImVec4(0.2f, 0.8f, 0.2f, 1.0f), "%s",
ICON_MD_CHECK_CIRCLE);
}
} else {
ImGui::TextColored(ImVec4(0.6f, 0.6f, 0.6f, 1.0f), "%s",
ICON_MD_RADIO_BUTTON_UNCHECKED);
}
// Custom Overworld checkbox column
ImGui::TableNextColumn();
// Center the checkbox vertically
float checkbox_offset =
(ImGui::GetFrameHeight() - ImGui::GetTextLineHeight()) * 0.5f;
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + checkbox_offset);
ImGui::PushID(
static_cast<int>(i + 100)); // Different ID to avoid conflicts
bool custom_ow_enabled =
session.feature_flags.overworld.kLoadCustomOverworld;
if (ImGui::Checkbox("##CustomOW", &custom_ow_enabled)) {
session.feature_flags.overworld.kLoadCustomOverworld =
custom_ow_enabled;
if (is_current) {
core::FeatureFlags::get().overworld.kLoadCustomOverworld =
custom_ow_enabled;
}
toast_manager_.Show(
absl::StrFormat("Session %zu: Custom Overworld %s", i + 1,
custom_ow_enabled ? "Enabled" : "Disabled"),
editor::ToastType::kInfo);
}
ImGui::PopID();
// Actions column with better button layout
ImGui::TableNextColumn();
// Create button group for better alignment
ImGui::BeginGroup();
if (!is_current) {
if (ImGui::Button("Switch")) {
SwitchToSession(i);
}
} else {
ImGui::BeginDisabled();
ImGui::Button("Current");
ImGui::EndDisabled();
}
ImGui::SameLine();
if (ImGui::Button("Rename")) {
session_to_rename_ = i;
// Safe string copy with bounds checking
const std::string& name = session.GetDisplayName();
size_t copy_len =
std::min(name.length(), sizeof(session_rename_buffer_) - 1);
std::memcpy(session_rename_buffer_, name.c_str(), copy_len);
session_rename_buffer_[copy_len] = '\0';
show_session_rename_dialog_ = true;
}
ImGui::SameLine();
// Close button logic
bool can_close = GetActiveSessionCount() > 1;
if (!can_close || is_current) {
ImGui::BeginDisabled();
}
if (ImGui::Button("Close")) {
if (is_current) {
CloseCurrentSession();
break; // Exit loop since current session was closed
} else {
// Remove non-current session directly
RemoveSession(i);
break; // Exit loop since session indices changed
}
}
if (!can_close || is_current) {
ImGui::EndDisabled();
}
ImGui::EndGroup();
ImGui::PopID();
}
ImGui::EndTable();
}
}
ImGui::End();
}
void EditorManager::DrawLayoutPresets() {
if (!show_layout_presets_)
return;
if (ImGui::Begin(absl::StrCat(ICON_MD_BOOKMARK, " Layout Presets").c_str(),
&show_layout_presets_)) {
ImGui::Text("%s Predefined Layouts", ICON_MD_DASHBOARD);
// Predefined layouts
if (ImGui::Button(
absl::StrCat(ICON_MD_DEVELOPER_MODE, " Developer Layout").c_str(),
ImVec2(-1, 40))) {
LoadDeveloperLayout();
}
ImGui::SameLine();
ImGui::Text("Code editing, debugging, testing");
if (ImGui::Button(
absl::StrCat(ICON_MD_DESIGN_SERVICES, " Designer Layout").c_str(),
ImVec2(-1, 40))) {
LoadDesignerLayout();
}
ImGui::SameLine();
ImGui::Text("Graphics, palettes, sprites");
if (ImGui::Button(absl::StrCat(ICON_MD_GAMEPAD, " Modder Layout").c_str(),
ImVec2(-1, 40))) {
LoadModderLayout();
}
ImGui::SameLine();
ImGui::Text("All gameplay editors");
ImGui::Separator();
ImGui::Text("%s Custom Presets", ICON_MD_BOOKMARK);
// Lazy load workspace presets when UI is accessed
if (!workspace_manager_.workspace_presets_loaded()) {
RefreshWorkspacePresets();
}
for (const auto& preset : workspace_manager_.workspace_presets()) {
if (ImGui::Button(
absl::StrFormat("%s %s", ICON_MD_BOOKMARK, preset.c_str())
.c_str(),
ImVec2(-1, 0))) {
LoadWorkspacePreset(preset);
toast_manager_.Show(
absl::StrFormat("Loaded preset: %s", preset.c_str()),
editor::ToastType::kSuccess);
}
}
if (workspace_manager_.workspace_presets().empty()) {
ImGui::TextColored(ImVec4(0.6f, 0.6f, 0.6f, 1.0f),
"No custom presets saved");
}
ImGui::Separator();
if (ImGui::Button(
absl::StrCat(ICON_MD_ADD, " Save Current Layout").c_str())) {
show_save_workspace_preset_ = true;
}
}
ImGui::End();
}
bool EditorManager::HasDuplicateSession(const std::string& filepath) {
for (const auto& session : sessions_) {
if (session.filepath == filepath) {
return true;
}
}
return false;
}
void EditorManager::RenameSession(size_t index, const std::string& new_name) {
if (index < sessions_.size()) {
sessions_[index].custom_name = new_name;
toast_manager_.Show(
absl::StrFormat("Session renamed to: %s", new_name.c_str()),
editor::ToastType::kSuccess);
// Delegate to UICoordinator for clean separation of concerns
if (ui_coordinator_) {
ui_coordinator_->DrawSessionManager();
}
}
void EditorManager::DrawSessionRenameDialog() {
if (!show_session_rename_dialog_)
return;
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(),
ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
ImGui::SetNextWindowSize(ImVec2(400, 150), ImGuiCond_Appearing);
if (ImGui::Begin("Rename Session", &show_session_rename_dialog_,
ImGuiWindowFlags_NoResize)) {
if (session_to_rename_ < sessions_.size()) {
const auto& session = sessions_[session_to_rename_];
ImGui::Text("Rename Session:");
ImGui::Text("Current: %s", session.GetDisplayName().c_str());
ImGui::Separator();
ImGui::InputText("New Name", session_rename_buffer_,
sizeof(session_rename_buffer_));
ImGui::Separator();
if (ImGui::Button("Rename", ImVec2(120, 0))) {
std::string new_name(session_rename_buffer_);
if (!new_name.empty()) {
RenameSession(session_to_rename_, new_name);
}
show_session_rename_dialog_ = false;
}
ImGui::SameLine();
if (ImGui::Button("Cancel", ImVec2(120, 0))) {
show_session_rename_dialog_ = false;
}
}
}
ImGui::End();
}
void EditorManager::DrawWelcomeScreen() {
// Use the new WelcomeScreen class for a modern, feature-rich experience
welcome_screen_.RefreshRecentProjects();
bool was_open = show_welcome_screen_;
bool action_taken = welcome_screen_.Show(&show_welcome_screen_);
// Check if the welcome screen was manually closed via the close button
if (was_open && !show_welcome_screen_) {
welcome_screen_manually_closed_ = true;
welcome_screen_.MarkManuallyClosed();
// Delegate to UICoordinator for clean separation of concerns
if (ui_coordinator_) {
ui_coordinator_->DrawSessionRenameDialog();
}
}
void EditorManager::DrawLayoutPresets() {
// Delegate to UICoordinator for clean separation of concerns
if (ui_coordinator_) {
ui_coordinator_->DrawLayoutPresets();
}
}
// ============================================================================
// Jump-to Functionality for Cross-Editor Navigation
// ============================================================================
@@ -3148,5 +2551,14 @@ EditorManager::SessionScope::~SessionScope() {
manager_->context_.session_id = prev_session_id_;
}
bool EditorManager::HasDuplicateSession(const std::string& filepath) {
for (const auto& session : sessions_) {
if (session.filepath == filepath) {
return true;
}
}
return false;
}
} // namespace editor
} // namespace yaze

View File

@@ -41,9 +41,10 @@
#include "app/editor/system/project_manager.h"
#include "app/editor/system/rom_file_manager.h"
#include "app/editor/system/session_card_registry.h"
#include "app/editor/system/session_coordinator.h"
#include "app/editor/system/window_delegate.h"
#include "app/editor/ui/session_coordinator.h"
#include "app/editor/ui/editor_selection_dialog.h"
#include "app/editor/ui/ui_coordinator.h"
#include "app/editor/ui/welcome_screen.h"
#include "app/emu/emulator.h"
#include "app/gfx/debug/performance/performance_dashboard.h"
@@ -359,6 +360,7 @@ class EditorManager {
ProjectManager project_manager_;
RomFileManager rom_file_manager_;
SessionCardRegistry card_registry_;
std::unique_ptr<UICoordinator> ui_coordinator_;
WindowDelegate window_delegate_;
std::unique_ptr<SessionCoordinator> session_coordinator_;

View File

@@ -7,7 +7,7 @@
#include "app/editor/system/rom_file_manager.h"
#include "app/editor/system/toast_manager.h"
#include "app/editor/ui/menu_builder.h"
#include "app/editor/ui/session_coordinator.h"
#include "app/editor/system/session_coordinator.h"
#include "app/gui/core/icons.h"
namespace yaze {

View File

@@ -6,6 +6,7 @@
#include "absl/status/status.h"
#include "app/editor/editor.h"
#include "app/editor/system/session_coordinator.h"
#include "app/editor/ui/menu_builder.h"
namespace yaze {

View File

@@ -1,5 +1,5 @@
#ifndef YAZE_APP_EDITOR_UI_SESSION_COORDINATOR_H_
#define YAZE_APP_EDITOR_UI_SESSION_COORDINATOR_H_
#ifndef YAZE_APP_EDITOR_SYSTEM_SESSION_COORDINATOR_H_
#define YAZE_APP_EDITOR_SYSTEM_SESSION_COORDINATOR_H_
#include <deque>
#include <string>
@@ -161,4 +161,4 @@ class SessionCoordinator {
} // namespace editor
} // namespace yaze
#endif // YAZE_APP_EDITOR_UI_SESSION_COORDINATOR_H_
#endif // YAZE_APP_EDITOR_SYSTEM_SESSION_COORDINATOR_H_

View File

@@ -0,0 +1,492 @@
#include "ui_coordinator.h"
#include <functional>
#include <memory>
#include <string>
#include "absl/strings/str_format.h"
#include "app/editor/editor.h"
#include "app/editor/editor_manager.h"
#include "app/editor/system/editor_registry.h"
#include "app/editor/system/popup_manager.h"
#include "app/editor/system/project_manager.h"
#include "app/editor/system/rom_file_manager.h"
#include "app/editor/system/session_coordinator.h"
#include "app/editor/system/toast_manager.h"
#include "app/editor/system/window_delegate.h"
#include "app/editor/ui/welcome_screen.h"
#include "app/gui/core/icons.h"
#include "app/gui/core/style.h"
#include "app/gui/core/theme_manager.h"
#include "imgui/imgui.h"
namespace yaze {
namespace editor {
UICoordinator::UICoordinator(
EditorManager* editor_manager,
RomFileManager& rom_manager,
ProjectManager& project_manager,
EditorRegistry& editor_registry,
SessionCoordinator& session_coordinator,
WindowDelegate& window_delegate,
ToastManager& toast_manager,
PopupManager& popup_manager)
: editor_manager_(editor_manager),
rom_manager_(rom_manager),
project_manager_(project_manager),
editor_registry_(editor_registry),
session_coordinator_(session_coordinator),
window_delegate_(window_delegate),
toast_manager_(toast_manager),
popup_manager_(popup_manager) {
// Initialize welcome screen
welcome_screen_ = std::make_unique<WelcomeScreen>();
}
void UICoordinator::DrawAllUI() {
// Apply Material Design styling
ApplyMaterialDesignStyling();
// Draw all UI components in order
DrawMenuBarExtras();
DrawContextSensitiveCardControl();
DrawSessionSwitcher();
DrawSessionManager();
DrawSessionRenameDialog();
DrawLayoutPresets();
DrawWelcomeScreen();
DrawProjectHelp();
DrawWindowManagementUI();
// Draw all popups
DrawAllPopups();
}
void UICoordinator::DrawMenuBarExtras() {
auto* current_rom = rom_manager_.GetCurrentRom();
std::string version_text = absl::StrFormat("v%s", editor_manager_->version().c_str());
float version_width = ImGui::CalcTextSize(version_text.c_str()).x;
float session_rom_area_width = 280.0f;
ImGui::SameLine(ImGui::GetWindowWidth() - version_width - 10 - session_rom_area_width);
// Session indicator with Material Design styling
if (session_coordinator_.HasMultipleSessions()) {
std::string session_button_text = absl::StrFormat("%s%zu", ICON_MD_TAB,
session_coordinator_.GetActiveSessionCount());
// Material Design button styling
ImGui::PushStyleColor(ImGuiCol_Button, gui::GetPrimaryVec4());
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, gui::GetPrimaryHoverVec4());
ImGui::PushStyleColor(ImGuiCol_ButtonActive, gui::GetPrimaryActiveVec4());
if (ImGui::SmallButton(session_button_text.c_str())) {
session_coordinator_.ToggleSessionSwitcher();
}
ImGui::PopStyleColor(3);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Sessions: %zu active\nClick to switch",
session_coordinator_.GetActiveSessionCount());
}
ImGui::SameLine();
}
// ROM information display with Material Design card styling
if (current_rom && current_rom->is_loaded()) {
ImGui::PushStyleColor(ImGuiCol_Text, gui::GetTextSecondaryVec4());
ImGui::Text("%s %s", ICON_MD_INSERT_DRIVE_FILE, current_rom->title().c_str());
ImGui::PopStyleColor();
ImGui::SameLine();
}
// Version info with subtle styling
ImGui::PushStyleColor(ImGuiCol_Text, gui::GetTextDisabledVec4());
ImGui::Text("%s", version_text.c_str());
ImGui::PopStyleColor();
}
void UICoordinator::DrawContextSensitiveCardControl() {
// Get current editor and determine category
auto* current_editor = editor_manager_->GetCurrentEditorSet();
if (!current_editor) return;
// Find active card-based editor
Editor* active_editor = nullptr;
for (auto* editor : current_editor->active_editors_) {
if (*editor->active() && editor_registry_.IsCardBasedEditor(editor->type())) {
active_editor = editor;
break;
}
}
if (!active_editor) return;
std::string category = editor_registry_.GetEditorCategory(active_editor->type());
// Draw compact card control with session awareness
auto& card_manager = gui::EditorCardManager::Get();
if (session_coordinator_.HasMultipleSessions()) {
std::string session_prefix = absl::StrFormat("s%zu", session_coordinator_.GetActiveSessionIndex());
card_manager.DrawCompactCardControlWithSession(category, session_prefix);
} else {
card_manager.DrawCompactCardControl(category);
}
}
void UICoordinator::DrawSessionSwitcher() {
if (!show_session_switcher_) return;
// Material Design dialog styling
ImGui::SetNextWindowSize(ImVec2(400, 300), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(16, 16));
ImGui::PushStyleColor(ImGuiCol_WindowBg, gui::GetSurfaceVec4());
ImGui::PushStyleColor(ImGuiCol_Border, gui::GetOutlineVec4());
if (ImGui::Begin("Session Switcher", &show_session_switcher_,
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse)) {
// Header with Material Design typography
ImGui::PushStyleColor(ImGuiCol_Text, gui::GetOnSurfaceVec4());
ImGui::Text("%s Session Switcher", ICON_MD_TAB);
ImGui::PopStyleColor();
ImGui::Separator();
// Session list with Material Design list styling
for (size_t i = 0; i < session_coordinator_.GetActiveSessionCount(); ++i) {
std::string session_name = session_coordinator_.GetSessionDisplayName(i);
bool is_active = (i == session_coordinator_.GetActiveSessionIndex());
// Active session highlighting
if (is_active) {
ImGui::PushStyleColor(ImGuiCol_Button, gui::GetPrimaryVec4());
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, gui::GetPrimaryHoverVec4());
ImGui::PushStyleColor(ImGuiCol_Text, gui::GetOnPrimaryVec4());
}
std::string button_text = absl::StrFormat("%s %s",
is_active ? ICON_MD_RADIO_BUTTON_CHECKED : ICON_MD_RADIO_BUTTON_UNCHECKED,
session_name.c_str());
if (ImGui::Button(button_text.c_str(), ImVec2(-1, 0))) {
session_coordinator_.SwitchToSession(i);
show_session_switcher_ = false;
}
if (is_active) {
ImGui::PopStyleColor(3);
}
}
ImGui::Separator();
// Action buttons with Material Design styling
if (ImGui::Button(absl::StrFormat("%s New Session", ICON_MD_ADD).c_str(), ImVec2(-1, 0))) {
session_coordinator_.CreateNewSession();
show_session_switcher_ = false;
}
if (ImGui::Button(absl::StrFormat("%s Close", ICON_MD_CLOSE).c_str(), ImVec2(-1, 0))) {
show_session_switcher_ = false;
}
}
ImGui::End();
ImGui::PopStyleColor(2);
ImGui::PopStyleVar();
}
void UICoordinator::DrawSessionManager() {
// TODO: Implement session manager dialog
// This would be a more comprehensive session management interface
}
void UICoordinator::DrawSessionRenameDialog() {
// TODO: Implement session rename dialog
// This would allow users to rename sessions for better organization
}
void UICoordinator::DrawLayoutPresets() {
// TODO: Implement layout presets UI
// This would show available layout presets (Developer, Designer, Modder)
}
void UICoordinator::DrawWelcomeScreen() {
if (!show_welcome_screen_) return;
if (welcome_screen_) {
welcome_screen_->Show(&show_welcome_screen_);
}
}
void UICoordinator::DrawProjectHelp() {
// TODO: Implement project help UI
// This would show project-specific help and documentation
}
void UICoordinator::DrawWindowManagementUI() {
// TODO: Implement window management UI
// This would provide controls for window visibility, docking, etc.
}
void UICoordinator::DrawAllPopups() {
// Draw all registered popups
popup_manager_.DrawPopups();
}
void UICoordinator::ShowPopup(const std::string& popup_name) {
popup_manager_.Show(popup_name.c_str());
}
void UICoordinator::HidePopup(const std::string& popup_name) {
popup_manager_.Hide(popup_name.c_str());
}
void UICoordinator::ShowEditorSelection() {
show_editor_selection_ = true;
}
void UICoordinator::ShowDisplaySettings() {
show_display_settings_ = true;
ShowPopup("Display Settings");
}
void UICoordinator::ShowSessionSwitcher() {
show_session_switcher_ = true;
}
void UICoordinator::HideCurrentEditorCards() {
// TODO: Implement card hiding logic
// This would hide cards for the current editor
}
void UICoordinator::ShowAllWindows() {
window_delegate_.ShowAllWindows();
}
void UICoordinator::HideAllWindows() {
window_delegate_.HideAllWindows();
}
void UICoordinator::ApplyMaterialDesignStyling() {
// Apply Material Design 3 color scheme
ImGuiStyle& style = ImGui::GetStyle();
// Set Material Design colors
style.Colors[ImGuiCol_WindowBg] = gui::GetSurfaceVec4();
style.Colors[ImGuiCol_ChildBg] = gui::GetSurfaceVariantVec4();
style.Colors[ImGuiCol_PopupBg] = gui::GetSurfaceContainerVec4();
style.Colors[ImGuiCol_Border] = gui::GetOutlineVec4();
style.Colors[ImGuiCol_BorderShadow] = gui::GetShadowVec4();
// Text colors
style.Colors[ImGuiCol_Text] = gui::GetOnSurfaceVec4();
style.Colors[ImGuiCol_TextDisabled] = gui::GetOnSurfaceVariantVec4();
// Button colors
style.Colors[ImGuiCol_Button] = gui::GetSurfaceContainerHighestVec4();
style.Colors[ImGuiCol_ButtonHovered] = gui::GetSurfaceContainerHighVec4();
style.Colors[ImGuiCol_ButtonActive] = gui::GetPrimaryVec4();
// Header colors
style.Colors[ImGuiCol_Header] = gui::GetSurfaceContainerHighVec4();
style.Colors[ImGuiCol_HeaderHovered] = gui::GetSurfaceContainerHighestVec4();
style.Colors[ImGuiCol_HeaderActive] = gui::GetPrimaryVec4();
// Frame colors
style.Colors[ImGuiCol_FrameBg] = gui::GetSurfaceContainerHighestVec4();
style.Colors[ImGuiCol_FrameBgHovered] = gui::GetSurfaceContainerHighVec4();
style.Colors[ImGuiCol_FrameBgActive] = gui::GetPrimaryVec4();
// Scrollbar colors
style.Colors[ImGuiCol_ScrollbarBg] = gui::GetSurfaceContainerVec4();
style.Colors[ImGuiCol_ScrollbarGrab] = gui::GetOutlineVec4();
style.Colors[ImGuiCol_ScrollbarGrabHovered] = gui::GetOnSurfaceVariantVec4();
style.Colors[ImGuiCol_ScrollbarGrabActive] = gui::GetOnSurfaceVec4();
// Slider colors
style.Colors[ImGuiCol_SliderGrab] = gui::GetPrimaryVec4();
style.Colors[ImGuiCol_SliderGrabActive] = gui::GetPrimaryActiveVec4();
// Tab colors
style.Colors[ImGuiCol_Tab] = gui::GetSurfaceContainerHighVec4();
style.Colors[ImGuiCol_TabHovered] = gui::GetSurfaceContainerHighestVec4();
style.Colors[ImGuiCol_TabActive] = gui::GetPrimaryVec4();
style.Colors[ImGuiCol_TabUnfocused] = gui::GetSurfaceContainerVec4();
style.Colors[ImGuiCol_TabUnfocusedActive] = gui::GetPrimaryActiveVec4();
// Title bar colors
style.Colors[ImGuiCol_TitleBg] = gui::GetSurfaceContainerVec4();
style.Colors[ImGuiCol_TitleBgActive] = gui::GetSurfaceContainerHighVec4();
style.Colors[ImGuiCol_TitleBgCollapsed] = gui::GetSurfaceContainerVec4();
// Menu bar colors
style.Colors[ImGuiCol_MenuBarBg] = gui::GetSurfaceContainerVec4();
// Modal dimming
style.Colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.0f, 0.0f, 0.0f, 0.6f);
}
void UICoordinator::UpdateThemeElements() {
// Update theme-specific elements
ApplyMaterialDesignStyling();
}
void UICoordinator::DrawThemePreview() {
// TODO: Implement theme preview
// This would show a preview of the current theme
}
// Helper methods for drawing operations
void UICoordinator::DrawSessionIndicator() {
// TODO: Implement session indicator
}
void UICoordinator::DrawVersionInfo() {
// TODO: Implement version info display
}
void UICoordinator::DrawSessionTabs() {
// TODO: Implement session tabs
}
void UICoordinator::DrawSessionBadges() {
// TODO: Implement session badges
}
// Material Design component helpers
void UICoordinator::DrawMaterialButton(const std::string& text, const std::string& icon,
std::function<void()> callback, bool enabled) {
if (!enabled) {
ImGui::PushStyleColor(ImGuiCol_Button, gui::GetSurfaceContainerHighestVec4());
ImGui::PushStyleColor(ImGuiCol_Text, gui::GetOnSurfaceVariantVec4());
}
std::string button_text = absl::StrFormat("%s %s", icon.c_str(), text.c_str());
if (ImGui::Button(button_text.c_str())) {
if (enabled && callback) {
callback();
}
}
if (!enabled) {
ImGui::PopStyleColor(2);
}
}
void UICoordinator::DrawMaterialCard(const std::string& title, const std::string& content) {
// TODO: Implement Material Design card component
}
void UICoordinator::DrawMaterialDialog(const std::string& title, std::function<void()> content) {
// TODO: Implement Material Design dialog component
}
// Layout and positioning helpers
void UICoordinator::CenterWindow(const std::string& window_name) {
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
}
void UICoordinator::PositionWindow(const std::string& window_name, float x, float y) {
ImGui::SetNextWindowPos(ImVec2(x, y), ImGuiCond_Appearing);
}
void UICoordinator::SetWindowSize(const std::string& window_name, float width, float height) {
ImGui::SetNextWindowSize(ImVec2(width, height), ImGuiCond_FirstUseEver);
}
// Icon and theming helpers
std::string UICoordinator::GetIconForEditor(EditorType type) const {
switch (type) {
case EditorType::kDungeon: return ICON_MD_CASTLE;
case EditorType::kOverworld: return ICON_MD_MAP;
case EditorType::kGraphics: return ICON_MD_IMAGE;
case EditorType::kPalette: return ICON_MD_PALETTE;
case EditorType::kSprite: return ICON_MD_TOYS;
case EditorType::kScreen: return ICON_MD_TV;
case EditorType::kMessage: return ICON_MD_CHAT_BUBBLE;
case EditorType::kMusic: return ICON_MD_MUSIC_NOTE;
case EditorType::kAssembly: return ICON_MD_CODE;
case EditorType::kHex: return ICON_MD_DATA_ARRAY;
case EditorType::kEmulator: return ICON_MD_PLAY_ARROW;
case EditorType::kSettings: return ICON_MD_SETTINGS;
default: return ICON_MD_HELP;
}
}
std::string UICoordinator::GetColorForEditor(EditorType type) const {
// TODO: Implement editor-specific colors
return "primary"; // Placeholder for now
}
void UICoordinator::ApplyEditorTheme(EditorType type) {
// TODO: Implement editor-specific theming
}
// Session UI helpers
void UICoordinator::DrawSessionList() {
// TODO: Implement session list
}
void UICoordinator::DrawSessionControls() {
// TODO: Implement session controls
}
void UICoordinator::DrawSessionInfo() {
// TODO: Implement session info
}
void UICoordinator::DrawSessionStatus() {
// TODO: Implement session status
}
// Popup helpers
void UICoordinator::DrawHelpMenuPopups() {
// TODO: Implement help menu popups
}
void UICoordinator::DrawSettingsPopups() {
// TODO: Implement settings popups
}
void UICoordinator::DrawProjectPopups() {
// TODO: Implement project popups
}
void UICoordinator::DrawSessionPopups() {
// TODO: Implement session popups
}
// Window management helpers
void UICoordinator::DrawWindowControls() {
// TODO: Implement window controls
}
void UICoordinator::DrawLayoutControls() {
// TODO: Implement layout controls
}
void UICoordinator::DrawDockingControls() {
// TODO: Implement docking controls
}
// Performance and debug UI
void UICoordinator::DrawPerformanceUI() {
// TODO: Implement performance UI
}
void UICoordinator::DrawDebugUI() {
// TODO: Implement debug UI
}
void UICoordinator::DrawTestingUI() {
// TODO: Implement testing UI
}
} // namespace editor
} // namespace yaze

View File

@@ -0,0 +1,181 @@
#ifndef YAZE_APP_EDITOR_SYSTEM_UI_COORDINATOR_H_
#define YAZE_APP_EDITOR_SYSTEM_UI_COORDINATOR_H_
#include <string>
#include <memory>
#include "absl/status/status.h"
#include "app/editor/editor.h"
#include "app/editor/system/popup_manager.h"
#include "app/editor/system/session_coordinator.h"
#include "app/editor/ui/welcome_screen.h"
#include "app/gui/core/icons.h"
namespace yaze {
namespace editor {
// Forward declarations to avoid circular dependencies
class EditorManager;
class RomFileManager;
class ProjectManager;
class EditorRegistry;
class SessionCoordinator;
class ToastManager;
class WindowDelegate;
/**
* @class UICoordinator
* @brief Handles all UI drawing operations and state management
*
* Extracted from EditorManager to provide focused UI coordination:
* - Drawing operations (menus, dialogs, screens)
* - UI state management (visibility, focus, layout)
* - Popup and dialog coordination
* - Welcome screen and session UI
* - Material Design theming and icons
*
* This class follows the Single Responsibility Principle by focusing solely
* on UI presentation and user interaction, delegating business logic to
* specialized managers.
*/
class UICoordinator {
public:
// Constructor takes references to the managers it coordinates with
UICoordinator(EditorManager* editor_manager,
RomFileManager& rom_manager,
ProjectManager& project_manager,
EditorRegistry& editor_registry,
SessionCoordinator& session_coordinator,
WindowDelegate& window_delegate,
ToastManager& toast_manager,
PopupManager& popup_manager);
~UICoordinator() = default;
// Non-copyable due to reference members
UICoordinator(const UICoordinator&) = delete;
UICoordinator& operator=(const UICoordinator&) = delete;
// Main UI drawing interface
void DrawAllUI();
void DrawMenuBarExtras();
void DrawContextSensitiveCardControl();
// Session UI components
void DrawSessionSwitcher();
void DrawSessionManager();
void DrawSessionRenameDialog();
void DrawLayoutPresets();
// Welcome screen and project UI
void DrawWelcomeScreen();
void DrawProjectHelp();
// Window management UI
void DrawWindowManagementUI();
// Popup and dialog management
void DrawAllPopups();
void ShowPopup(const std::string& popup_name);
void HidePopup(const std::string& popup_name);
// UI state management
void ShowEditorSelection();
void ShowDisplaySettings();
void ShowSessionSwitcher();
void HideCurrentEditorCards();
// Window visibility management
void ShowAllWindows();
void HideAllWindows();
// UI state queries
bool IsEditorSelectionVisible() const { return show_editor_selection_; }
bool IsDisplaySettingsVisible() const { return show_display_settings_; }
bool IsSessionSwitcherVisible() const { return show_session_switcher_; }
bool IsWelcomeScreenVisible() const { return show_welcome_screen_; }
// UI state setters
void SetEditorSelectionVisible(bool visible) { show_editor_selection_ = visible; }
void SetDisplaySettingsVisible(bool visible) { show_display_settings_ = visible; }
void SetSessionSwitcherVisible(bool visible) { show_session_switcher_ = visible; }
void SetWelcomeScreenVisible(bool visible) { show_welcome_screen_ = visible; }
// Theme and styling helpers
void ApplyMaterialDesignStyling();
void UpdateThemeElements();
void DrawThemePreview();
private:
// References to coordinated managers
EditorManager* editor_manager_;
RomFileManager& rom_manager_;
ProjectManager& project_manager_;
EditorRegistry& editor_registry_;
SessionCoordinator& session_coordinator_;
WindowDelegate& window_delegate_;
ToastManager& toast_manager_;
PopupManager& popup_manager_;
// UI state flags
bool show_editor_selection_ = false;
bool show_display_settings_ = false;
bool show_session_switcher_ = false;
bool show_welcome_screen_ = true;
bool show_global_search_ = false;
bool show_performance_dashboard_ = false;
bool show_imgui_demo_ = false;
bool show_imgui_metrics_ = false;
bool show_test_dashboard_ = false;
// Welcome screen component
std::unique_ptr<WelcomeScreen> welcome_screen_;
// Helper methods for drawing operations
void DrawSessionIndicator();
void DrawVersionInfo();
void DrawSessionTabs();
void DrawSessionBadges();
// Material Design component helpers
void DrawMaterialButton(const std::string& text, const std::string& icon,
std::function<void()> callback, bool enabled = true);
void DrawMaterialCard(const std::string& title, const std::string& content);
void DrawMaterialDialog(const std::string& title, std::function<void()> content);
// Layout and positioning helpers
void CenterWindow(const std::string& window_name);
void PositionWindow(const std::string& window_name, float x, float y);
void SetWindowSize(const std::string& window_name, float width, float height);
// Icon and theming helpers
std::string GetIconForEditor(EditorType type) const;
std::string GetColorForEditor(EditorType type) const;
void ApplyEditorTheme(EditorType type);
// Session UI helpers
void DrawSessionList();
void DrawSessionControls();
void DrawSessionInfo();
void DrawSessionStatus();
// Popup helpers
void DrawHelpMenuPopups();
void DrawSettingsPopups();
void DrawProjectPopups();
void DrawSessionPopups();
// Window management helpers
void DrawWindowControls();
void DrawLayoutControls();
void DrawDockingControls();
// Performance and debug UI
void DrawPerformanceUI();
void DrawDebugUI();
void DrawTestingUI();
};
} // namespace editor
} // namespace yaze
#endif // YAZE_APP_EDITOR_SYSTEM_UI_COORDINATOR_H_

View File

@@ -0,0 +1,492 @@
#include "app/editor/ui/ui_coordinator.h"
#include <functional>
#include <memory>
#include <string>
#include "absl/strings/str_format.h"
#include "app/editor/editor.h"
#include "app/editor/editor_manager.h"
#include "app/editor/system/editor_registry.h"
#include "app/editor/system/popup_manager.h"
#include "app/editor/system/project_manager.h"
#include "app/editor/system/rom_file_manager.h"
#include "app/editor/system/session_coordinator.h"
#include "app/editor/system/toast_manager.h"
#include "app/editor/system/window_delegate.h"
#include "app/editor/ui/welcome_screen.h"
#include "app/gui/core/icons.h"
#include "app/gui/core/style.h"
#include "app/gui/core/theme_manager.h"
#include "imgui/imgui.h"
namespace yaze {
namespace editor {
UICoordinator::UICoordinator(
EditorManager* editor_manager,
RomFileManager& rom_manager,
ProjectManager& project_manager,
EditorRegistry& editor_registry,
SessionCoordinator& session_coordinator,
WindowDelegate& window_delegate,
ToastManager& toast_manager,
PopupManager& popup_manager)
: editor_manager_(editor_manager),
rom_manager_(rom_manager),
project_manager_(project_manager),
editor_registry_(editor_registry),
session_coordinator_(session_coordinator),
window_delegate_(window_delegate),
toast_manager_(toast_manager),
popup_manager_(popup_manager) {
// Initialize welcome screen
welcome_screen_ = std::make_unique<WelcomeScreen>();
}
void UICoordinator::DrawAllUI() {
// Apply Material Design styling
ApplyMaterialDesignStyling();
// Draw all UI components in order
DrawMenuBarExtras();
DrawContextSensitiveCardControl();
DrawSessionSwitcher();
DrawSessionManager();
DrawSessionRenameDialog();
DrawLayoutPresets();
DrawWelcomeScreen();
DrawProjectHelp();
DrawWindowManagementUI();
// Draw all popups
DrawAllPopups();
}
void UICoordinator::DrawMenuBarExtras() {
auto* current_rom = rom_manager_.GetCurrentRom();
std::string version_text = absl::StrFormat("v%s", editor_manager_->version().c_str());
float version_width = ImGui::CalcTextSize(version_text.c_str()).x;
float session_rom_area_width = 280.0f;
ImGui::SameLine(ImGui::GetWindowWidth() - version_width - 10 - session_rom_area_width);
// Session indicator with Material Design styling
if (session_coordinator_.HasMultipleSessions()) {
std::string session_button_text = absl::StrFormat("%s%zu", ICON_MD_TAB,
session_coordinator_.GetActiveSessionCount());
// Material Design button styling
ImGui::PushStyleColor(ImGuiCol_Button, gui::GetPrimaryVec4());
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, gui::GetPrimaryHoverVec4());
ImGui::PushStyleColor(ImGuiCol_ButtonActive, gui::GetPrimaryActiveVec4());
if (ImGui::SmallButton(session_button_text.c_str())) {
session_coordinator_.ToggleSessionSwitcher();
}
ImGui::PopStyleColor(3);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Sessions: %zu active\nClick to switch",
session_coordinator_.GetActiveSessionCount());
}
ImGui::SameLine();
}
// ROM information display with Material Design card styling
if (current_rom && current_rom->is_loaded()) {
ImGui::PushStyleColor(ImGuiCol_Text, gui::GetTextSecondaryVec4());
ImGui::Text("%s %s", ICON_MD_INSERT_DRIVE_FILE, current_rom->title().c_str());
ImGui::PopStyleColor();
ImGui::SameLine();
}
// Version info with subtle styling
ImGui::PushStyleColor(ImGuiCol_Text, gui::GetTextDisabledVec4());
ImGui::Text("%s", version_text.c_str());
ImGui::PopStyleColor();
}
void UICoordinator::DrawContextSensitiveCardControl() {
// Get current editor and determine category
auto* current_editor = editor_manager_->GetCurrentEditorSet();
if (!current_editor) return;
// Find active card-based editor
Editor* active_editor = nullptr;
for (auto* editor : current_editor->active_editors_) {
if (*editor->active() && editor_registry_.IsCardBasedEditor(editor->type())) {
active_editor = editor;
break;
}
}
if (!active_editor) return;
std::string category = editor_registry_.GetEditorCategory(active_editor->type());
// Draw compact card control with session awareness
auto& card_manager = gui::EditorCardManager::Get();
if (session_coordinator_.HasMultipleSessions()) {
std::string session_prefix = absl::StrFormat("s%zu", session_coordinator_.GetActiveSessionIndex());
card_manager.DrawCompactCardControlWithSession(category, session_prefix);
} else {
card_manager.DrawCompactCardControl(category);
}
}
void UICoordinator::DrawSessionSwitcher() {
if (!show_session_switcher_) return;
// Material Design dialog styling
ImGui::SetNextWindowSize(ImVec2(400, 300), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(16, 16));
ImGui::PushStyleColor(ImGuiCol_WindowBg, gui::GetSurfaceVec4());
ImGui::PushStyleColor(ImGuiCol_Border, gui::GetOutlineVec4());
if (ImGui::Begin("Session Switcher", &show_session_switcher_,
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse)) {
// Header with Material Design typography
ImGui::PushStyleColor(ImGuiCol_Text, gui::GetOnSurfaceVec4());
ImGui::Text("%s Session Switcher", ICON_MD_TAB);
ImGui::PopStyleColor();
ImGui::Separator();
// Session list with Material Design list styling
for (size_t i = 0; i < session_coordinator_.GetActiveSessionCount(); ++i) {
std::string session_name = session_coordinator_.GetSessionDisplayName(i);
bool is_active = (i == session_coordinator_.GetActiveSessionIndex());
// Active session highlighting
if (is_active) {
ImGui::PushStyleColor(ImGuiCol_Button, gui::GetPrimaryVec4());
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, gui::GetPrimaryHoverVec4());
ImGui::PushStyleColor(ImGuiCol_Text, gui::GetOnPrimaryVec4());
}
std::string button_text = absl::StrFormat("%s %s",
is_active ? ICON_MD_RADIO_BUTTON_CHECKED : ICON_MD_RADIO_BUTTON_UNCHECKED,
session_name.c_str());
if (ImGui::Button(button_text.c_str(), ImVec2(-1, 0))) {
session_coordinator_.SwitchToSession(i);
show_session_switcher_ = false;
}
if (is_active) {
ImGui::PopStyleColor(3);
}
}
ImGui::Separator();
// Action buttons with Material Design styling
if (ImGui::Button(absl::StrFormat("%s New Session", ICON_MD_ADD).c_str(), ImVec2(-1, 0))) {
session_coordinator_.CreateNewSession();
show_session_switcher_ = false;
}
if (ImGui::Button(absl::StrFormat("%s Close", ICON_MD_CLOSE).c_str(), ImVec2(-1, 0))) {
show_session_switcher_ = false;
}
}
ImGui::End();
ImGui::PopStyleColor(2);
ImGui::PopStyleVar();
}
void UICoordinator::DrawSessionManager() {
// TODO: Implement session manager dialog
// This would be a more comprehensive session management interface
}
void UICoordinator::DrawSessionRenameDialog() {
// TODO: Implement session rename dialog
// This would allow users to rename sessions for better organization
}
void UICoordinator::DrawLayoutPresets() {
// TODO: Implement layout presets UI
// This would show available layout presets (Developer, Designer, Modder)
}
void UICoordinator::DrawWelcomeScreen() {
if (!show_welcome_screen_) return;
if (welcome_screen_) {
welcome_screen_->Show(&show_welcome_screen_);
}
}
void UICoordinator::DrawProjectHelp() {
// TODO: Implement project help UI
// This would show project-specific help and documentation
}
void UICoordinator::DrawWindowManagementUI() {
// TODO: Implement window management UI
// This would provide controls for window visibility, docking, etc.
}
void UICoordinator::DrawAllPopups() {
// Draw all registered popups
popup_manager_.DrawPopups();
}
void UICoordinator::ShowPopup(const std::string& popup_name) {
popup_manager_.Show(popup_name.c_str());
}
void UICoordinator::HidePopup(const std::string& popup_name) {
popup_manager_.Hide(popup_name.c_str());
}
void UICoordinator::ShowEditorSelection() {
show_editor_selection_ = true;
}
void UICoordinator::ShowDisplaySettings() {
show_display_settings_ = true;
ShowPopup("Display Settings");
}
void UICoordinator::ShowSessionSwitcher() {
show_session_switcher_ = true;
}
void UICoordinator::HideCurrentEditorCards() {
// TODO: Implement card hiding logic
// This would hide cards for the current editor
}
void UICoordinator::ShowAllWindows() {
window_delegate_.ShowAllWindows();
}
void UICoordinator::HideAllWindows() {
window_delegate_.HideAllWindows();
}
void UICoordinator::ApplyMaterialDesignStyling() {
// Apply Material Design 3 color scheme
ImGuiStyle& style = ImGui::GetStyle();
// Set Material Design colors
style.Colors[ImGuiCol_WindowBg] = gui::GetSurfaceVec4();
style.Colors[ImGuiCol_ChildBg] = gui::GetSurfaceVariantVec4();
style.Colors[ImGuiCol_PopupBg] = gui::GetSurfaceContainerVec4();
style.Colors[ImGuiCol_Border] = gui::GetOutlineVec4();
style.Colors[ImGuiCol_BorderShadow] = gui::GetShadowVec4();
// Text colors
style.Colors[ImGuiCol_Text] = gui::GetOnSurfaceVec4();
style.Colors[ImGuiCol_TextDisabled] = gui::GetOnSurfaceVariantVec4();
// Button colors
style.Colors[ImGuiCol_Button] = gui::GetSurfaceContainerHighestVec4();
style.Colors[ImGuiCol_ButtonHovered] = gui::GetSurfaceContainerHighVec4();
style.Colors[ImGuiCol_ButtonActive] = gui::GetPrimaryVec4();
// Header colors
style.Colors[ImGuiCol_Header] = gui::GetSurfaceContainerHighVec4();
style.Colors[ImGuiCol_HeaderHovered] = gui::GetSurfaceContainerHighestVec4();
style.Colors[ImGuiCol_HeaderActive] = gui::GetPrimaryVec4();
// Frame colors
style.Colors[ImGuiCol_FrameBg] = gui::GetSurfaceContainerHighestVec4();
style.Colors[ImGuiCol_FrameBgHovered] = gui::GetSurfaceContainerHighVec4();
style.Colors[ImGuiCol_FrameBgActive] = gui::GetPrimaryVec4();
// Scrollbar colors
style.Colors[ImGuiCol_ScrollbarBg] = gui::GetSurfaceContainerVec4();
style.Colors[ImGuiCol_ScrollbarGrab] = gui::GetOutlineVec4();
style.Colors[ImGuiCol_ScrollbarGrabHovered] = gui::GetOnSurfaceVariantVec4();
style.Colors[ImGuiCol_ScrollbarGrabActive] = gui::GetOnSurfaceVec4();
// Slider colors
style.Colors[ImGuiCol_SliderGrab] = gui::GetPrimaryVec4();
style.Colors[ImGuiCol_SliderGrabActive] = gui::GetPrimaryActiveVec4();
// Tab colors
style.Colors[ImGuiCol_Tab] = gui::GetSurfaceContainerHighVec4();
style.Colors[ImGuiCol_TabHovered] = gui::GetSurfaceContainerHighestVec4();
style.Colors[ImGuiCol_TabActive] = gui::GetPrimaryVec4();
style.Colors[ImGuiCol_TabUnfocused] = gui::GetSurfaceContainerVec4();
style.Colors[ImGuiCol_TabUnfocusedActive] = gui::GetPrimaryActiveVec4();
// Title bar colors
style.Colors[ImGuiCol_TitleBg] = gui::GetSurfaceContainerVec4();
style.Colors[ImGuiCol_TitleBgActive] = gui::GetSurfaceContainerHighVec4();
style.Colors[ImGuiCol_TitleBgCollapsed] = gui::GetSurfaceContainerVec4();
// Menu bar colors
style.Colors[ImGuiCol_MenuBarBg] = gui::GetSurfaceContainerVec4();
// Modal dimming
style.Colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.0f, 0.0f, 0.0f, 0.6f);
}
void UICoordinator::UpdateThemeElements() {
// Update theme-specific elements
ApplyMaterialDesignStyling();
}
void UICoordinator::DrawThemePreview() {
// TODO: Implement theme preview
// This would show a preview of the current theme
}
// Helper methods for drawing operations
void UICoordinator::DrawSessionIndicator() {
// TODO: Implement session indicator
}
void UICoordinator::DrawVersionInfo() {
// TODO: Implement version info display
}
void UICoordinator::DrawSessionTabs() {
// TODO: Implement session tabs
}
void UICoordinator::DrawSessionBadges() {
// TODO: Implement session badges
}
// Material Design component helpers
void UICoordinator::DrawMaterialButton(const std::string& text, const std::string& icon,
std::function<void()> callback, bool enabled) {
if (!enabled) {
ImGui::PushStyleColor(ImGuiCol_Button, gui::GetSurfaceContainerHighestVec4());
ImGui::PushStyleColor(ImGuiCol_Text, gui::GetOnSurfaceVariantVec4());
}
std::string button_text = absl::StrFormat("%s %s", icon.c_str(), text.c_str());
if (ImGui::Button(button_text.c_str())) {
if (enabled && callback) {
callback();
}
}
if (!enabled) {
ImGui::PopStyleColor(2);
}
}
void UICoordinator::DrawMaterialCard(const std::string& title, const std::string& content) {
// TODO: Implement Material Design card component
}
void UICoordinator::DrawMaterialDialog(const std::string& title, std::function<void()> content) {
// TODO: Implement Material Design dialog component
}
// Layout and positioning helpers
void UICoordinator::CenterWindow(const std::string& window_name) {
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
}
void UICoordinator::PositionWindow(const std::string& window_name, float x, float y) {
ImGui::SetNextWindowPos(ImVec2(x, y), ImGuiCond_Appearing);
}
void UICoordinator::SetWindowSize(const std::string& window_name, float width, float height) {
ImGui::SetNextWindowSize(ImVec2(width, height), ImGuiCond_FirstUseEver);
}
// Icon and theming helpers
std::string UICoordinator::GetIconForEditor(EditorType type) const {
switch (type) {
case EditorType::kDungeon: return ICON_MD_CASTLE;
case EditorType::kOverworld: return ICON_MD_MAP;
case EditorType::kGraphics: return ICON_MD_IMAGE;
case EditorType::kPalette: return ICON_MD_PALETTE;
case EditorType::kSprite: return ICON_MD_TOYS;
case EditorType::kScreen: return ICON_MD_TV;
case EditorType::kMessage: return ICON_MD_CHAT_BUBBLE;
case EditorType::kMusic: return ICON_MD_MUSIC_NOTE;
case EditorType::kAssembly: return ICON_MD_CODE;
case EditorType::kHex: return ICON_MD_DATA_ARRAY;
case EditorType::kEmulator: return ICON_MD_PLAY_ARROW;
case EditorType::kSettings: return ICON_MD_SETTINGS;
default: return ICON_MD_HELP;
}
}
std::string UICoordinator::GetColorForEditor(EditorType type) const {
// TODO: Implement editor-specific colors
return "primary"; // Placeholder for now
}
void UICoordinator::ApplyEditorTheme(EditorType type) {
// TODO: Implement editor-specific theming
}
// Session UI helpers
void UICoordinator::DrawSessionList() {
// TODO: Implement session list
}
void UICoordinator::DrawSessionControls() {
// TODO: Implement session controls
}
void UICoordinator::DrawSessionInfo() {
// TODO: Implement session info
}
void UICoordinator::DrawSessionStatus() {
// TODO: Implement session status
}
// Popup helpers
void UICoordinator::DrawHelpMenuPopups() {
// TODO: Implement help menu popups
}
void UICoordinator::DrawSettingsPopups() {
// TODO: Implement settings popups
}
void UICoordinator::DrawProjectPopups() {
// TODO: Implement project popups
}
void UICoordinator::DrawSessionPopups() {
// TODO: Implement session popups
}
// Window management helpers
void UICoordinator::DrawWindowControls() {
// TODO: Implement window controls
}
void UICoordinator::DrawLayoutControls() {
// TODO: Implement layout controls
}
void UICoordinator::DrawDockingControls() {
// TODO: Implement docking controls
}
// Performance and debug UI
void UICoordinator::DrawPerformanceUI() {
// TODO: Implement performance UI
}
void UICoordinator::DrawDebugUI() {
// TODO: Implement debug UI
}
void UICoordinator::DrawTestingUI() {
// TODO: Implement testing UI
}
} // namespace editor
} // namespace yaze

View File

@@ -0,0 +1,180 @@
#ifndef YAZE_APP_EDITOR_UI_UI_COORDINATOR_H_
#define YAZE_APP_EDITOR_UI_UI_COORDINATOR_H_
#include <string>
#include <memory>
#include "absl/status/status.h"
#include "app/editor/editor.h"
#include "app/editor/system/popup_manager.h"
#include "app/editor/ui/welcome_screen.h"
#include "app/gui/core/icons.h"
namespace yaze {
namespace editor {
// Forward declarations to avoid circular dependencies
class EditorManager;
class RomFileManager;
class ProjectManager;
class EditorRegistry;
class SessionCoordinator;
class ToastManager;
class WindowDelegate;
/**
* @class UICoordinator
* @brief Handles all UI drawing operations and state management
*
* Extracted from EditorManager to provide focused UI coordination:
* - Drawing operations (menus, dialogs, screens)
* - UI state management (visibility, focus, layout)
* - Popup and dialog coordination
* - Welcome screen and session UI
* - Material Design theming and icons
*
* This class follows the Single Responsibility Principle by focusing solely
* on UI presentation and user interaction, delegating business logic to
* specialized managers.
*/
class UICoordinator {
public:
// Constructor takes references to the managers it coordinates with
UICoordinator(EditorManager* editor_manager,
RomFileManager& rom_manager,
ProjectManager& project_manager,
EditorRegistry& editor_registry,
SessionCoordinator& session_coordinator,
WindowDelegate& window_delegate,
ToastManager& toast_manager,
PopupManager& popup_manager);
~UICoordinator() = default;
// Non-copyable due to reference members
UICoordinator(const UICoordinator&) = delete;
UICoordinator& operator=(const UICoordinator&) = delete;
// Main UI drawing interface
void DrawAllUI();
void DrawMenuBarExtras();
void DrawContextSensitiveCardControl();
// Session UI components
void DrawSessionSwitcher();
void DrawSessionManager();
void DrawSessionRenameDialog();
void DrawLayoutPresets();
// Welcome screen and project UI
void DrawWelcomeScreen();
void DrawProjectHelp();
// Window management UI
void DrawWindowManagementUI();
// Popup and dialog management
void DrawAllPopups();
void ShowPopup(const std::string& popup_name);
void HidePopup(const std::string& popup_name);
// UI state management
void ShowEditorSelection();
void ShowDisplaySettings();
void ShowSessionSwitcher();
void HideCurrentEditorCards();
// Window visibility management
void ShowAllWindows();
void HideAllWindows();
// UI state queries
bool IsEditorSelectionVisible() const { return show_editor_selection_; }
bool IsDisplaySettingsVisible() const { return show_display_settings_; }
bool IsSessionSwitcherVisible() const { return show_session_switcher_; }
bool IsWelcomeScreenVisible() const { return show_welcome_screen_; }
// UI state setters
void SetEditorSelectionVisible(bool visible) { show_editor_selection_ = visible; }
void SetDisplaySettingsVisible(bool visible) { show_display_settings_ = visible; }
void SetSessionSwitcherVisible(bool visible) { show_session_switcher_ = visible; }
void SetWelcomeScreenVisible(bool visible) { show_welcome_screen_ = visible; }
// Theme and styling helpers
void ApplyMaterialDesignStyling();
void UpdateThemeElements();
void DrawThemePreview();
private:
// References to coordinated managers
EditorManager* editor_manager_;
RomFileManager& rom_manager_;
ProjectManager& project_manager_;
EditorRegistry& editor_registry_;
SessionCoordinator& session_coordinator_;
WindowDelegate& window_delegate_;
ToastManager& toast_manager_;
PopupManager& popup_manager_;
// UI state flags
bool show_editor_selection_ = false;
bool show_display_settings_ = false;
bool show_session_switcher_ = false;
bool show_welcome_screen_ = true;
bool show_global_search_ = false;
bool show_performance_dashboard_ = false;
bool show_imgui_demo_ = false;
bool show_imgui_metrics_ = false;
bool show_test_dashboard_ = false;
// Welcome screen component
std::unique_ptr<WelcomeScreen> welcome_screen_;
// Helper methods for drawing operations
void DrawSessionIndicator();
void DrawVersionInfo();
void DrawSessionTabs();
void DrawSessionBadges();
// Material Design component helpers
void DrawMaterialButton(const std::string& text, const std::string& icon,
std::function<void()> callback, bool enabled = true);
void DrawMaterialCard(const std::string& title, const std::string& content);
void DrawMaterialDialog(const std::string& title, std::function<void()> content);
// Layout and positioning helpers
void CenterWindow(const std::string& window_name);
void PositionWindow(const std::string& window_name, float x, float y);
void SetWindowSize(const std::string& window_name, float width, float height);
// Icon and theming helpers
std::string GetIconForEditor(EditorType type) const;
std::string GetColorForEditor(EditorType type) const;
void ApplyEditorTheme(EditorType type);
// Session UI helpers
void DrawSessionList();
void DrawSessionControls();
void DrawSessionInfo();
void DrawSessionStatus();
// Popup helpers
void DrawHelpMenuPopups();
void DrawSettingsPopups();
void DrawProjectPopups();
void DrawSessionPopups();
// Window management helpers
void DrawWindowControls();
void DrawLayoutControls();
void DrawDockingControls();
// Performance and debug UI
void DrawPerformanceUI();
void DrawDebugUI();
void DrawTestingUI();
};
} // namespace editor
} // namespace yaze
#endif // YAZE_APP_EDITOR_UI_UI_COORDINATOR_H_