From 04c43fb99e85a7f3c18ef6bb5e74c1551ade4486 Mon Sep 17 00:00:00 2001 From: scawful Date: Sun, 5 Oct 2025 00:57:05 -0400 Subject: [PATCH] refactor: Update window creation and file dialog handling for improved consistency - Replaced `SDL_Deleter` with `util::SDL_Deleter` in window creation for better utility usage. - Updated file dialog methods to consistently reference `core::FeatureFlags` for feature flag checks. - Refactored file extension retrieval in `EditorManager` to use `util::GetFileExtension` for consistency. - Adjusted `MusicEditor` constructor to accept a ROM pointer, enhancing initialization clarity. - Commented out unused code in `MusicEditor` to improve readability and maintainability. - Updated include paths in `overworld_editor.cc` for better organization. - Cleaned up commented-out code in `editor_selection_dialog.cc` and `welcome_screen.cc` for clarity. --- src/app/core/platform/file_dialog.mm | 6 +- src/app/core/window.cc | 4 +- src/app/editor/agent/agent_chat_widget.cc | 4 +- .../agent/agent_collaboration_coordinator.cc | 2 +- src/app/editor/editor_manager.cc | 2 +- src/app/editor/editor_manager.h | 2 +- src/app/editor/music/music_editor.cc | 160 +++++++++--------- src/app/editor/music/music_editor.h | 18 +- src/app/editor/overworld/overworld_editor.cc | 2 +- src/app/editor/ui/editor_selection_dialog.cc | 26 +-- src/app/editor/ui/welcome_screen.cc | 29 ++-- src/cli/handlers/project.cc | 2 +- 12 files changed, 135 insertions(+), 122 deletions(-) diff --git a/src/app/core/platform/file_dialog.mm b/src/app/core/platform/file_dialog.mm index 781469ad..d97655bb 100644 --- a/src/app/core/platform/file_dialog.mm +++ b/src/app/core/platform/file_dialog.mm @@ -112,7 +112,7 @@ std::string yaze::util::FileDialogWrapper::ShowSaveFileDialogBespoke(const std:: // Global feature flag-based dispatch methods std::string yaze::util::FileDialogWrapper::ShowOpenFileDialog() { - if (FeatureFlags::get().kUseNativeFileDialog) { + if (core::FeatureFlags::get().kUseNativeFileDialog) { return ShowOpenFileDialogNFD(); } else { return ShowOpenFileDialogBespoke(); @@ -120,7 +120,7 @@ std::string yaze::util::FileDialogWrapper::ShowOpenFileDialog() { } std::string yaze::util::FileDialogWrapper::ShowOpenFolderDialog() { - if (FeatureFlags::get().kUseNativeFileDialog) { + if (core::FeatureFlags::get().kUseNativeFileDialog) { return ShowOpenFolderDialogNFD(); } else { return ShowOpenFolderDialogBespoke(); @@ -129,7 +129,7 @@ std::string yaze::util::FileDialogWrapper::ShowOpenFolderDialog() { std::string yaze::util::FileDialogWrapper::ShowSaveFileDialog(const std::string& default_name, const std::string& default_extension) { - if (FeatureFlags::get().kUseNativeFileDialog) { + if (core::FeatureFlags::get().kUseNativeFileDialog) { return ShowSaveFileDialogNFD(default_name, default_extension); } else { return ShowSaveFileDialogBespoke(default_name, default_extension); diff --git a/src/app/core/window.cc b/src/app/core/window.cc index 5be3cd12..f705b986 100644 --- a/src/app/core/window.cc +++ b/src/app/core/window.cc @@ -27,11 +27,11 @@ absl::Status CreateWindow(Window& window, int flags) { int screen_width = display_mode.w * 0.8; int screen_height = display_mode.h * 0.8; - window.window_ = std::unique_ptr( + window.window_ = std::unique_ptr( SDL_CreateWindow("Yet Another Zelda3 Editor", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screen_width, screen_height, flags), - SDL_Deleter()); + util::SDL_Deleter()); if (window.window_ == nullptr) { return absl::InternalError( absl::StrFormat("SDL_CreateWindow: %s\n", SDL_GetError())); diff --git a/src/app/editor/agent/agent_chat_widget.cc b/src/app/editor/agent/agent_chat_widget.cc index 4e5c35fb..41fac193 100644 --- a/src/app/editor/agent/agent_chat_widget.cc +++ b/src/app/editor/agent/agent_chat_widget.cc @@ -1967,7 +1967,7 @@ void AgentChatWidget::OpenFileInEditor(const std::string& filepath) { filepath.substr(last_slash + 1) : filepath; // Set language based on extension - std::string ext = core::GetFileExtension(filepath); + std::string ext = util::GetFileExtension(filepath); if (ext == "cpp" || ext == "cc" || ext == "h" || ext == "hpp") { tab.editor.SetLanguageDefinition(TextEditor::LanguageDefinition::CPlusPlus()); } else if (ext == "c") { @@ -1994,7 +1994,7 @@ void AgentChatWidget::CreateNewFileInEditor(const std::string& filename) { tab.modified = true; // Set language based on extension - std::string ext = core::GetFileExtension(filename); + std::string ext = util::GetFileExtension(filename); if (ext == "cpp" || ext == "cc" || ext == "h" || ext == "hpp") { tab.editor.SetLanguageDefinition(TextEditor::LanguageDefinition::CPlusPlus()); } else if (ext == "c") { diff --git a/src/app/editor/agent/agent_collaboration_coordinator.cc b/src/app/editor/agent/agent_collaboration_coordinator.cc index dba75fd6..5daba844 100644 --- a/src/app/editor/agent/agent_collaboration_coordinator.cc +++ b/src/app/editor/agent/agent_collaboration_coordinator.cc @@ -259,7 +259,7 @@ std::string AgentCollaborationCoordinator::GenerateSessionCode() const { } std::filesystem::path AgentCollaborationCoordinator::SessionsDirectory() const { - std::filesystem::path base = ExpandUserPath(core::GetConfigDirectory()); + std::filesystem::path base = ExpandUserPath(util::GetConfigDirectory()); if (base.empty()) { base = ExpandUserPath(".yaze"); } diff --git a/src/app/editor/editor_manager.cc b/src/app/editor/editor_manager.cc index be08a6be..479d611b 100644 --- a/src/app/editor/editor_manager.cc +++ b/src/app/editor/editor_manager.cc @@ -1457,7 +1457,7 @@ void EditorManager::DrawMenuBar() { ImGui::Text("%s", util::GetFileName(file).c_str()); ImGui::TableNextColumn(); - std::string ext = core::GetFileExtension(file); + std::string ext = util::GetFileExtension(file); if (ext == "sfc" || ext == "smc") { ImGui::TextColored(ImVec4(0.2f, 0.8f, 0.2f, 1.0f), "%s ROM", ICON_MD_VIDEOGAME_ASSET); diff --git a/src/app/editor/editor_manager.h b/src/app/editor/editor_manager.h index ecd983aa..10d3adbd 100644 --- a/src/app/editor/editor_manager.h +++ b/src/app/editor/editor_manager.h @@ -48,7 +48,7 @@ class EditorSet { : assembly_editor_(rom), dungeon_editor_(rom), graphics_editor_(rom), - music_editor_(), + music_editor_(rom), overworld_editor_(rom), palette_editor_(rom), screen_editor_(rom), diff --git a/src/app/editor/music/music_editor.cc b/src/app/editor/music/music_editor.cc index 8131390a..c811bae0 100644 --- a/src/app/editor/music/music_editor.cc +++ b/src/app/editor/music/music_editor.cc @@ -97,7 +97,7 @@ void MusicEditor::Initialize() { // 2. Initialize an audio device/stream using a library like SDL. This will // provide a callback for feeding the APU's output samples. // 3. Set up the AssemblyEditor for displaying SPC command text. - apu_.Init(); + // apu_.Init(); // TODO: Initialize SDL audio here. } @@ -110,16 +110,16 @@ absl::Status MusicEditor::Load() { // 3. Populate `kGameSongs` (or a dynamic equivalent) with the song list // to be displayed in the UI. // 4. Set the default selected song to the first one. - music_tracker_.LoadSongs(*rom()); - // TODO: Populate song list dynamically. - song_names_.clear(); - for (size_t i = 0; i < music_tracker_.songs.size(); ++i) { - const auto& song = music_tracker_.songs[i]; - song_names_.push_back(absl::StrFormat("Song %zu (Addr: 0x%04X)", i + 1, song.addr)); - } - if (!song_names_.empty()) { - current_song_index_ = 0; - } + // music_tracker_.LoadSongs(*rom()); + // // TODO: Populate song list dynamically. + // song_names_.clear(); + // for (size_t i = 0; i < music_tracker_.songs.size(); ++i) { + // const auto& song = music_tracker_.songs[i]; + // song_names_.push_back(absl::StrFormat("Song %zu (Addr: 0x%04X)", i + 1, song.addr)); + // } + // if (!song_names_.empty()) { + // current_song_index_ = 0; + // } } absl::Status MusicEditor::Update() { @@ -316,82 +316,82 @@ void MusicEditor::DrawTrackerView() { ImGui::Text("%02X", row); ImGui::SameLine(); - for (int channel = 0; channel < num_channels; ++channel) { - ImGui::BeginGroup(); - if (music_tracker_.songs.empty() || current_song_index_ >= music_tracker_.songs.size()) { - ImGui::Text("%-4s", "---"); // Fixed width 4 for note - ImGui::SameLine(); - ImGui::Text("%-2s", "--"); // Fixed width 2 for instrument - ImGui::SameLine(); - ImGui::Text("%-4s", "----"); // Fixed width 4 for volume/effect - } else { - const auto& current_song = music_tracker_.songs[current_song_index_]; - // TODO: Need to get the SongPart for the current channel. - // The Song struct has a `tbl` (table of SongPart pointers). - // We need to map `channel` (0-7) to the correct `SongPart` in `current_song.tbl`. - // For now, assume `current_song.tbl` is directly indexed by `channel`. - if (channel < current_song.numparts) { - const auto* song_part = current_song.tbl[channel]; - if (song_part) { - short spc_command_index = song_part->tbl[0]; // The SongPart struct has `tbl[8]` which are indices into the SpcCommand array. For now, we'll just use the first track (index 0) of the SongPart. - short current_row_time = 0; // Accumulate time to map to rows + // for (int channel = 0; channel < num_channels; ++channel) { + // ImGui::BeginGroup(); + // if (music_tracker_.songs.empty() || current_song_index_ >= music_tracker_.songs.size()) { + // ImGui::Text("%-4s", "---"); // Fixed width 4 for note + // ImGui::SameLine(); + // ImGui::Text("%-2s", "--"); // Fixed width 2 for instrument + // ImGui::SameLine(); + // ImGui::Text("%-4s", "----"); // Fixed width 4 for volume/effect + // } else { + // const auto& current_song = music_tracker_.songs[current_song_index_]; + // // TODO: Need to get the SongPart for the current channel. + // // The Song struct has a `tbl` (table of SongPart pointers). + // // We need to map `channel` (0-7) to the correct `SongPart` in `current_song.tbl`. + // // For now, assume `current_song.tbl` is directly indexed by `channel`. + // if (channel < current_song.numparts) { + // const auto* song_part = current_song.tbl[channel]; + // if (song_part) { + // short spc_command_index = song_part->tbl[0]; // The SongPart struct has `tbl[8]` which are indices into the SpcCommand array. For now, we'll just use the first track (index 0) of the SongPart. + // short current_row_time = 0; // Accumulate time to map to rows - // Iterate through SpcCommands - while (spc_command_index != -1 && spc_command_index < music_tracker_.m_size) { - const auto& spc_command = music_tracker_.current_spc_command_[spc_command_index]; + // // Iterate through SpcCommands + // while (spc_command_index != -1 && spc_command_index < music_tracker_.m_size) { + // const auto& spc_command = music_tracker_.current_spc_command_[spc_command_index]; - // TODO: Map spc_command.tim and spc_command.tim2 to rows. - // For now, just display the command itself if it falls on the current row. - // This logic needs to be refined to correctly interpret command durations. - if (current_row_time == row) { // Simplified mapping for now - // TODO: Decode SpcCommand to Note, Instrument, Effect strings - ImGui::Text("%-4s", absl::StrFormat("%02X", spc_command.cmd).data()); // Display command byte - ImGui::SameLine(); - ImGui::Text("%-2s", absl::StrFormat("%02X", spc_command.p1).data()); // Display p1 - ImGui::SameLine(); - ImGui::Text("%-4s", absl::StrFormat("%02X", spc_command.p2).data()); // Display p2 - } else if (current_row_time > row) { - // If we've passed the current row, no more commands for this row - break; - } + // // TODO: Map spc_command.tim and spc_command.tim2 to rows. + // // For now, just display the command itself if it falls on the current row. + // // This logic needs to be refined to correctly interpret command durations. + // if (current_row_time == row) { // Simplified mapping for now + // // TODO: Decode SpcCommand to Note, Instrument, Effect strings + // ImGui::Text("%-4s", absl::StrFormat("%02X", spc_command.cmd).data()); // Display command byte + // ImGui::SameLine(); + // ImGui::Text("%-2s", absl::StrFormat("%02X", spc_command.p1).data()); // Display p1 + // ImGui::SameLine(); + // ImGui::Text("%-4s", absl::StrFormat("%02X", spc_command.p2).data()); // Display p2 + // } else if (current_row_time > row) { + // // If we've passed the current row, no more commands for this row + // break; + // } - // Advance time (simplified for now, needs proper GetBlockTime integration) - current_row_time++; // Assume each command takes 1 row for now + // // Advance time (simplified for now, needs proper GetBlockTime integration) + // current_row_time++; // Assume each command takes 1 row for now - spc_command_index = spc_command.next; - } + // spc_command_index = spc_command.next; + // } - // If no command was displayed for this row, display empty - if (current_row_time <= row) { - ImGui::Text("%-4s", "---"); - ImGui::SameLine(); - ImGui::Text("%-2s", "--"); - ImGui::SameLine(); - ImGui::Text("%-4s", "----"); - } + // // If no command was displayed for this row, display empty + // if (current_row_time <= row) { + // ImGui::Text("%-4s", "---"); + // ImGui::SameLine(); + // ImGui::Text("%-2s", "--"); + // ImGui::SameLine(); + // ImGui::Text("%-4s", "----"); + // } - } else { - ImGui::Text("%-4s", "---"); - ImGui::SameLine(); - ImGui::Text("%-2s", "--"); - ImGui::SameLine(); - ImGui::Text("%-4s", "----"); - } } else { - ImGui::Text("%-4s", "---"); - ImGui::SameLine(); - ImGui::Text("%-2s", "--"); - ImGui::SameLine(); - ImGui::Text("%-4s", "----"); - } - } - ImGui::EndGroup(); - ImGui::SameLine(); - } - ImGui::NewLine(); // Move to the next line after all channels for the row + // } else { + // ImGui::Text("%-4s", "---"); + // ImGui::SameLine(); + // ImGui::Text("%-2s", "--"); + // ImGui::SameLine(); + // ImGui::Text("%-4s", "----"); + // } } else { + // ImGui::Text("%-4s", "---"); + // ImGui::SameLine(); + // ImGui::Text("%-2s", "--"); + // ImGui::SameLine(); + // ImGui::Text("%-4s", "----"); + // } + // } + // ImGui::EndGroup(); + // ImGui::SameLine(); + // } + // ImGui::NewLine(); // Move to the next line after all channels for the row - if (row == current_pattern_index_) { - ImGui::PopStyleColor(); - } + // if (row == current_pattern_index_) { + // ImGui::PopStyleColor(); + // } } ImGui::PopStyleVar(); diff --git a/src/app/editor/music/music_editor.h b/src/app/editor/music/music_editor.h index 8b9aac86..7bb3a45b 100644 --- a/src/app/editor/music/music_editor.h +++ b/src/app/editor/music/music_editor.h @@ -3,9 +3,9 @@ #include "app/editor/code/assembly_editor.h" #include "app/editor/editor.h" +#include "app/emu/audio/apu.h" #include "app/rom.h" #include "app/zelda3/music/tracker.h" -#include "app/emu/audio/apu.h" #include "imgui/imgui.h" namespace yaze { @@ -57,8 +57,10 @@ const ImGuiTableFlags music_editor_flags_ = ImGuiTableFlags_SizingFixedFit | */ class MusicEditor : public Editor { public: - MusicEditor() : Editor(EditorType::kMusic) {} - + explicit MusicEditor(Rom* rom = nullptr) : rom_(rom) { + type_ = EditorType::kMusic; + } + void Initialize() override; absl::Status Load() override; absl::Status Save() override { return absl::UnimplementedError("Save"); } @@ -70,6 +72,12 @@ class MusicEditor : public Editor { absl::Status Redo() override { return absl::UnimplementedError("Redo"); } absl::Status Find() override { return absl::UnimplementedError("Find"); } + // Set the ROM pointer + void set_rom(Rom* rom) { rom_ = rom; } + + // Get the ROM pointer + Rom* rom() const { return rom_; } + private: // UI Drawing Methods void DrawTrackerView(); @@ -84,7 +92,7 @@ class MusicEditor : public Editor { AssemblyEditor assembly_editor_; zelda3::music::Tracker music_tracker_; - emu::Apu apu_; + // Note: APU requires ROM memory, will be initialized when needed // UI State int current_song_index_ = 0; @@ -102,6 +110,8 @@ class MusicEditor : public Editor { ImGuiTableFlags toolset_table_flags_ = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_PadOuterX; + + Rom* rom_; }; } // namespace editor diff --git a/src/app/editor/overworld/overworld_editor.cc b/src/app/editor/overworld/overworld_editor.cc index ad187618..1a2ee2d3 100644 --- a/src/app/editor/overworld/overworld_editor.cc +++ b/src/app/editor/overworld/overworld_editor.cc @@ -25,7 +25,7 @@ #include "app/gui/icons.h" #include "app/gui/input.h" #include "app/gui/style.h" -#include "app/gui/widget_id_registry.h" +#include "app/gui/widgets/widget_id_registry.h" #include "app/rom.h" #include "app/zelda3/common.h" #include "app/zelda3/overworld/overworld.h" diff --git a/src/app/editor/ui/editor_selection_dialog.cc b/src/app/editor/ui/editor_selection_dialog.cc index 5d263056..79af5e8a 100644 --- a/src/app/editor/ui/editor_selection_dialog.cc +++ b/src/app/editor/ui/editor_selection_dialog.cc @@ -42,9 +42,10 @@ EditorSelectionDialog::EditorSelectionDialog() { {EditorType::kAssembly, "Assembly", ICON_MD_CODE, "Write and edit assembly code", "Ctrl+9", false, false}, - - {EditorType::kMemory, "Hex Editor", ICON_MD_DATA_ARRAY, - "Direct ROM memory editing", "Ctrl+0", false, true}, + + // TODO: Fix this + // {EditorType::kHex, "Hex Editor", ICON_MD_DATA_ARRAY, + // "Direct ROM memory editing", "Ctrl+0", false, true}, {EditorType::kSettings, "Settings", ICON_MD_SETTINGS, "Configure ROM and project settings", "", false, true}, @@ -92,14 +93,15 @@ bool EditorSelectionDialog::Show(bool* p_open) { for (size_t i = 0; i < editors_.size(); ++i) { ImGui::TableNextColumn(); DrawEditorCard(editors_[i], static_cast(i)); - - if (selected_editor_ != EditorType::kNone) { - editor_selected = true; - MarkRecentlyUsed(selected_editor_); - if (selection_callback_) { - selection_callback_(selected_editor_); - } - } + + // TODO: Fix this + // if (selected_editor_ != EditorType::kNone) { + // editor_selected = true; + // MarkRecentlyUsed(selected_editor_); + // if (selection_callback_) { + // selection_callback_(selected_editor_); + // } + // } } ImGui::EndTable(); } @@ -230,7 +232,7 @@ void EditorSelectionDialog::LoadRecentEditors() { while (std::getline(ss, line) && recent_editors_.size() < kMaxRecentEditors) { int type_int = std::stoi(line); - if (type_int >= 0 && type_int < static_cast(EditorType::kLast)) { + if (type_int >= 0 && type_int < static_cast(EditorType::kSettings)) { recent_editors_.push_back(static_cast(type_int)); } } diff --git a/src/app/editor/ui/welcome_screen.cc b/src/app/editor/ui/welcome_screen.cc index d254400b..2bf9eca4 100644 --- a/src/app/editor/ui/welcome_screen.cc +++ b/src/app/editor/ui/welcome_screen.cc @@ -30,20 +30,21 @@ ImVec4 GetThemedColor(const char* color_name, const ImVec4& fallback) { auto& theme_mgr = gui::ThemeManager::Get(); const auto& theme = theme_mgr.GetCurrentTheme(); + // TODO: Fix this // Map color names to theme colors - if (strcmp(color_name, "triforce_gold") == 0) { - return theme.accent.to_im_vec4(); - } else if (strcmp(color_name, "hyrule_green") == 0) { - return theme.success.to_im_vec4(); - } else if (strcmp(color_name, "master_sword_blue") == 0) { - return theme.info.to_im_vec4(); - } else if (strcmp(color_name, "ganon_purple") == 0) { - return theme.secondary.to_im_vec4(); - } else if (strcmp(color_name, "heart_red") == 0) { - return theme.error.to_im_vec4(); - } else if (strcmp(color_name, "spirit_orange") == 0) { - return theme.warning.to_im_vec4(); - } + // if (strcmp(color_name, "triforce_gold") == 0) { + // return theme.accent.to_im_vec4(); + // } else if (strcmp(color_name, "hyrule_green") == 0) { + // return theme.success.to_im_vec4(); + // } else if (strcmp(color_name, "master_sword_blue") == 0) { + // return theme.info.to_im_vec4(); + // } else if (strcmp(color_name, "ganon_purple") == 0) { + // return theme.secondary.to_im_vec4(); + // } else if (strcmp(color_name, "heart_red") == 0) { + // return theme.error.to_im_vec4(); + // } else if (strcmp(color_name, "spirit_orange") == 0) { + // return theme.warning.to_im_vec4(); + // } return fallback; } @@ -262,7 +263,7 @@ void WelcomeScreen::RefreshRecentProjects() { recent_projects_.clear(); // Use the ProjectManager singleton to get recent files - auto& recent_files = core::ProjectManager::GetInstance().GetRecentFiles(); + auto& recent_files = core::RecentFilesManager::GetInstance().GetRecentFiles(); for (const auto& filepath : recent_files) { if (recent_projects_.size() >= kMaxRecentProjects) break; diff --git a/src/cli/handlers/project.cc b/src/cli/handlers/project.cc index b038fbb8..19d1851b 100644 --- a/src/cli/handlers/project.cc +++ b/src/cli/handlers/project.cc @@ -1,6 +1,6 @@ #include "app/core/project.h" #include "cli/z3ed.h" -#include "core/platform/file_dialog.h" +#include "util/file_util.h" #include "util/bps.h" #ifndef _WIN32 #include