backend-infra-engineer: Release v0.3.1 snapshot
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
#include "dungeon_object_selector.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <cstring>
|
||||
|
||||
#include "app/core/window.h"
|
||||
#include "app/gfx/arena.h"
|
||||
@@ -1045,7 +1047,10 @@ void DungeonObjectSelector::DrawCompactPropertiesEditor() {
|
||||
static int music_id = 0;
|
||||
|
||||
// Copy current values
|
||||
strncpy(room_name, properties.name.c_str(), sizeof(room_name) - 1);
|
||||
// Safe string copy with bounds checking
|
||||
size_t name_len = std::min(properties.name.length(), sizeof(room_name) - 1);
|
||||
std::memcpy(room_name, properties.name.c_str(), name_len);
|
||||
room_name[name_len] = '\0';
|
||||
dungeon_id = properties.dungeon_id;
|
||||
floor_level = properties.floor_level;
|
||||
is_boss_room = properties.is_boss_room;
|
||||
|
||||
@@ -11,6 +11,7 @@ set(
|
||||
app/editor/dungeon/dungeon_room_loader.cc
|
||||
app/editor/dungeon/dungeon_usage_tracker.cc
|
||||
app/editor/overworld/overworld_editor.cc
|
||||
app/editor/overworld/overworld_editor_manager.cc
|
||||
app/editor/sprite/sprite_editor.cc
|
||||
app/editor/music/music_editor.cc
|
||||
app/editor/message/message_editor.cc
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,6 +7,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
#include "app/core/features.h"
|
||||
#include "app/core/project.h"
|
||||
#include "app/editor/code/assembly_editor.h"
|
||||
#include "app/editor/code/memory_editor.h"
|
||||
@@ -19,10 +20,9 @@
|
||||
#include "app/editor/overworld/overworld_editor.h"
|
||||
#include "app/editor/sprite/sprite_editor.h"
|
||||
#include "app/editor/system/popup_manager.h"
|
||||
#include "app/editor/system/toast_manager.h"
|
||||
#include "app/editor/system/settings_editor.h"
|
||||
#include "app/editor/system/toast_manager.h"
|
||||
#include "app/emu/emulator.h"
|
||||
#include "app/core/features.h"
|
||||
#include "app/rom.h"
|
||||
#include "yaze_config.h"
|
||||
|
||||
@@ -100,34 +100,41 @@ class EditorManager {
|
||||
absl::Status SetCurrentRom(Rom* rom);
|
||||
auto GetCurrentRom() -> Rom* { return current_rom_; }
|
||||
auto GetCurrentEditorSet() -> EditorSet* { return current_editor_set_; }
|
||||
|
||||
|
||||
// Get current session's feature flags (falls back to global if no session)
|
||||
core::FeatureFlags::Flags* GetCurrentFeatureFlags() {
|
||||
size_t current_index = GetCurrentSessionIndex();
|
||||
if (current_index < sessions_.size()) {
|
||||
return &sessions_[current_index].feature_flags;
|
||||
}
|
||||
return &core::FeatureFlags::get(); // Fallback to global
|
||||
return &core::FeatureFlags::get(); // Fallback to global
|
||||
}
|
||||
|
||||
void SetFontGlobalScale(float scale) {
|
||||
font_global_scale_ = scale;
|
||||
ImGui::GetIO().FontGlobalScale = scale;
|
||||
SaveUserSettings();
|
||||
}
|
||||
|
||||
private:
|
||||
void DrawHomepage();
|
||||
void DrawWelcomeScreen();
|
||||
absl::Status DrawRomSelector();
|
||||
absl::Status LoadRom();
|
||||
absl::Status LoadAssets();
|
||||
absl::Status SaveRom();
|
||||
absl::Status SaveRomAs(const std::string& filename);
|
||||
absl::Status OpenRomOrProject(const std::string& filename);
|
||||
|
||||
|
||||
// Enhanced project management
|
||||
absl::Status CreateNewProject(const std::string& template_name = "Basic ROM Hack");
|
||||
absl::Status CreateNewProject(
|
||||
const std::string& template_name = "Basic ROM Hack");
|
||||
absl::Status OpenProject();
|
||||
absl::Status SaveProject();
|
||||
absl::Status SaveProjectAs();
|
||||
absl::Status ImportProject(const std::string& project_path);
|
||||
absl::Status RepairCurrentProject();
|
||||
void ShowProjectHelp();
|
||||
|
||||
|
||||
// Testing system
|
||||
void InitializeTestSuites();
|
||||
|
||||
@@ -157,9 +164,10 @@ class EditorManager {
|
||||
bool show_global_search_ = false;
|
||||
bool show_session_rename_dialog_ = false;
|
||||
bool show_welcome_screen_ = false;
|
||||
bool welcome_screen_manually_closed_ = false;
|
||||
size_t session_to_rename_ = 0;
|
||||
char session_rename_buffer_[256] = {};
|
||||
|
||||
|
||||
// Testing interface
|
||||
bool show_test_dashboard_ = false;
|
||||
|
||||
@@ -177,18 +185,17 @@ class EditorManager {
|
||||
struct RomSession {
|
||||
Rom rom;
|
||||
EditorSet editors;
|
||||
std::string custom_name; // User-defined session name
|
||||
std::string filepath; // ROM filepath for duplicate detection
|
||||
core::FeatureFlags::Flags feature_flags; // Per-session feature flags
|
||||
std::string custom_name; // User-defined session name
|
||||
std::string filepath; // ROM filepath for duplicate detection
|
||||
core::FeatureFlags::Flags feature_flags; // Per-session feature flags
|
||||
|
||||
RomSession() = default;
|
||||
explicit RomSession(Rom&& r)
|
||||
: rom(std::move(r)), editors(&rom) {
|
||||
explicit RomSession(Rom&& r) : rom(std::move(r)), editors(&rom) {
|
||||
filepath = rom.filename();
|
||||
// Initialize with default feature flags
|
||||
feature_flags = core::FeatureFlags::Flags{};
|
||||
}
|
||||
|
||||
|
||||
// Get display name (custom name or ROM title)
|
||||
std::string GetDisplayName() const {
|
||||
if (!custom_name.empty()) {
|
||||
@@ -212,20 +219,24 @@ class EditorManager {
|
||||
// Settings helpers
|
||||
void LoadUserSettings();
|
||||
void SaveUserSettings();
|
||||
|
||||
void RefreshWorkspacePresets();
|
||||
void SaveWorkspacePreset(const std::string& name);
|
||||
void LoadWorkspacePreset(const std::string& name);
|
||||
|
||||
|
||||
// Workspace management
|
||||
void CreateNewSession();
|
||||
void DuplicateCurrentSession();
|
||||
void CloseCurrentSession();
|
||||
void RemoveSession(size_t index);
|
||||
void SwitchToSession(size_t index);
|
||||
size_t GetCurrentSessionIndex() const;
|
||||
size_t GetActiveSessionCount() const;
|
||||
void ResetWorkspaceLayout();
|
||||
|
||||
|
||||
// Multi-session editor management
|
||||
std::string GenerateUniqueEditorTitle(EditorType type, size_t session_index) const;
|
||||
std::string GenerateUniqueEditorTitle(EditorType type,
|
||||
size_t session_index) const;
|
||||
void SaveWorkspaceLayout();
|
||||
void LoadWorkspaceLayout();
|
||||
void ShowAllWindows();
|
||||
@@ -236,12 +247,12 @@ class EditorManager {
|
||||
void LoadDeveloperLayout();
|
||||
void LoadDesignerLayout();
|
||||
void LoadModderLayout();
|
||||
|
||||
|
||||
// Session management helpers
|
||||
bool HasDuplicateSession(const std::string& filepath);
|
||||
void RenameSession(size_t index, const std::string& new_name);
|
||||
std::string GenerateUniqueEditorTitle(EditorType type, size_t session_index);
|
||||
|
||||
|
||||
// UI drawing helpers
|
||||
void DrawSessionSwitcher();
|
||||
void DrawSessionManager();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -64,6 +64,7 @@ class MapPropertiesSystem {
|
||||
void DrawSpritePropertiesTab(int current_map);
|
||||
void DrawCustomFeaturesTab(int current_map);
|
||||
void DrawTileGraphicsTab(int current_map);
|
||||
void DrawMusicTab(int current_map);
|
||||
|
||||
// Utility methods
|
||||
void RefreshMapProperties();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,9 +12,9 @@
|
||||
#include "app/gfx/tilemap.h"
|
||||
#include "app/gui/canvas.h"
|
||||
#include "app/gui/input.h"
|
||||
#include "app/gui/zeml.h"
|
||||
#include "app/rom.h"
|
||||
#include "app/zelda3/overworld/overworld.h"
|
||||
#include "app/editor/overworld/overworld_editor_manager.h"
|
||||
#include "imgui/imgui.h"
|
||||
|
||||
namespace yaze {
|
||||
@@ -188,6 +188,16 @@ class OverworldEditor : public Editor, public gfx::GfxContext {
|
||||
void DrawMapPropertiesPanel();
|
||||
void HandleMapInteraction();
|
||||
void SetupOverworldCanvasContextMenu();
|
||||
|
||||
// Scratch space canvas methods
|
||||
absl::Status DrawScratchSpace();
|
||||
absl::Status SaveCurrentSelectionToScratch(int slot);
|
||||
absl::Status LoadScratchToSelection(int slot);
|
||||
absl::Status ClearScratchSpace(int slot);
|
||||
void DrawScratchSpaceEdits();
|
||||
void DrawScratchSpacePattern();
|
||||
void DrawScratchSpaceSelection();
|
||||
void UpdateScratchBitmapTile(int tile_x, int tile_y, int tile_id, int slot = -1);
|
||||
|
||||
absl::Status UpdateUsageStats();
|
||||
void DrawUsageGrid();
|
||||
@@ -253,6 +263,24 @@ class OverworldEditor : public Editor, public gfx::GfxContext {
|
||||
|
||||
// Map properties system for UI organization
|
||||
std::unique_ptr<MapPropertiesSystem> map_properties_system_;
|
||||
std::unique_ptr<OverworldEditorManager> overworld_manager_;
|
||||
|
||||
// Scratch space for large layouts
|
||||
// Scratch space canvas for tile16 drawing (like a mini overworld)
|
||||
struct ScratchSpaceSlot {
|
||||
gfx::Bitmap scratch_bitmap;
|
||||
std::array<std::array<int, 32>, 32> tile_data; // 32x32 grid of tile16 IDs
|
||||
bool in_use = false;
|
||||
std::string name = "Empty";
|
||||
int width = 16; // Default 16x16 tiles
|
||||
int height = 16;
|
||||
// Independent selection system for scratch space
|
||||
std::vector<ImVec2> selected_tiles;
|
||||
std::vector<ImVec2> selected_points;
|
||||
bool select_rect_active = false;
|
||||
};
|
||||
std::array<ScratchSpaceSlot, 4> scratch_spaces_;
|
||||
int current_scratch_slot_ = 0;
|
||||
|
||||
gfx::Tilemap tile16_blockset_;
|
||||
|
||||
@@ -295,12 +323,12 @@ class OverworldEditor : public Editor, public gfx::GfxContext {
|
||||
gui::Canvas graphics_bin_canvas_{"GraphicsBin", kGraphicsBinCanvasSize,
|
||||
gui::CanvasGridSize::k16x16};
|
||||
gui::Canvas properties_canvas_;
|
||||
gui::Canvas scratch_canvas_{"ScratchSpace", ImVec2(320, 480), gui::CanvasGridSize::k32x32};
|
||||
|
||||
gui::Table toolset_table_{"##ToolsetTable0", 12, kToolsetTableFlags};
|
||||
gui::Table map_settings_table_{kOWMapTable.data(), 8, kOWMapFlags,
|
||||
ImVec2(0, 0)};
|
||||
|
||||
gui::zeml::Node layout_node_;
|
||||
absl::Status status_;
|
||||
};
|
||||
} // namespace editor
|
||||
|
||||
423
src/app/editor/overworld/overworld_editor_manager.cc
Normal file
423
src/app/editor/overworld/overworld_editor_manager.cc
Normal file
@@ -0,0 +1,423 @@
|
||||
#include "overworld_editor_manager.h"
|
||||
|
||||
#include "app/gfx/snes_color.h"
|
||||
#include "app/gui/icons.h"
|
||||
#include "app/gui/input.h"
|
||||
#include "app/gui/style.h"
|
||||
#include "app/zelda3/overworld/overworld_map.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace editor {
|
||||
|
||||
using namespace ImGui;
|
||||
|
||||
absl::Status OverworldEditorManager::DrawV3SettingsPanel() {
|
||||
if (BeginTabItem("v3 Settings")) {
|
||||
Text("ZSCustomOverworld v3 Settings");
|
||||
Separator();
|
||||
|
||||
// Check if custom ASM is applied
|
||||
uint8_t asm_version = GetCustomASMVersion();
|
||||
if (asm_version >= 3 && asm_version != 0xFF) {
|
||||
TextColored(ImVec4(0, 1, 0, 1), "Custom Overworld ASM v%d Applied", asm_version);
|
||||
} else if (asm_version == 0x00) {
|
||||
TextColored(ImVec4(1, 1, 0, 1), "Vanilla ROM - Custom features available via flag");
|
||||
} else {
|
||||
TextColored(ImVec4(1, 0, 0, 1), "Custom ASM v%d - Consider upgrading to v3", asm_version);
|
||||
}
|
||||
|
||||
Separator();
|
||||
|
||||
RETURN_IF_ERROR(DrawCustomOverworldSettings());
|
||||
RETURN_IF_ERROR(DrawAreaSpecificSettings());
|
||||
RETURN_IF_ERROR(DrawTransitionSettings());
|
||||
RETURN_IF_ERROR(DrawOverlaySettings());
|
||||
|
||||
EndTabItem();
|
||||
}
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status OverworldEditorManager::DrawCustomOverworldSettings() {
|
||||
if (TreeNode("Custom Overworld Features")) {
|
||||
RETURN_IF_ERROR(DrawBooleanSetting("Enable Area-Specific Background Colors",
|
||||
&enable_area_specific_bg_,
|
||||
"Allows each overworld area to have its own background color"));
|
||||
|
||||
RETURN_IF_ERROR(DrawBooleanSetting("Enable Main Palette Override",
|
||||
&enable_main_palette_,
|
||||
"Allows each area to override the main palette"));
|
||||
|
||||
RETURN_IF_ERROR(DrawBooleanSetting("Enable Mosaic Transitions",
|
||||
&enable_mosaic_,
|
||||
"Enables mosaic screen transitions between areas"));
|
||||
|
||||
RETURN_IF_ERROR(DrawBooleanSetting("Enable Custom GFX Groups",
|
||||
&enable_gfx_groups_,
|
||||
"Allows each area to have custom tile GFX groups"));
|
||||
|
||||
RETURN_IF_ERROR(DrawBooleanSetting("Enable Subscreen Overlays",
|
||||
&enable_subscreen_overlay_,
|
||||
"Enables custom subscreen overlays (fog, sky, etc.)"));
|
||||
|
||||
RETURN_IF_ERROR(DrawBooleanSetting("Enable Animated GFX Override",
|
||||
&enable_animated_gfx_,
|
||||
"Allows each area to have custom animated tiles"));
|
||||
|
||||
Separator();
|
||||
|
||||
if (Button("Apply Custom Overworld ASM")) {
|
||||
RETURN_IF_ERROR(ApplyCustomOverworldASM());
|
||||
}
|
||||
SameLine();
|
||||
HOVER_HINT("Writes the custom overworld settings to ROM");
|
||||
|
||||
TreePop();
|
||||
}
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status OverworldEditorManager::DrawAreaSpecificSettings() {
|
||||
if (TreeNode("Area-Specific Settings")) {
|
||||
// Map selection
|
||||
int map_count = zelda3::kNumOverworldMaps;
|
||||
SliderInt("Map Index", ¤t_map_index_, 0, map_count - 1);
|
||||
|
||||
auto* current_map = overworld_->mutable_overworld_map(current_map_index_);
|
||||
|
||||
// Area size controls
|
||||
RETURN_IF_ERROR(DrawAreaSizeControls());
|
||||
|
||||
// Background color
|
||||
if (enable_area_specific_bg_) {
|
||||
uint16_t bg_color = current_map->area_specific_bg_color();
|
||||
RETURN_IF_ERROR(DrawColorPicker("Background Color", &bg_color));
|
||||
current_map->set_area_specific_bg_color(bg_color);
|
||||
}
|
||||
|
||||
// Main palette
|
||||
if (enable_main_palette_) {
|
||||
uint8_t main_palette = current_map->main_palette();
|
||||
SliderInt("Main Palette", (int*)&main_palette, 0, 5);
|
||||
current_map->set_main_palette(main_palette);
|
||||
}
|
||||
|
||||
// Mosaic settings
|
||||
if (enable_mosaic_) {
|
||||
RETURN_IF_ERROR(DrawMosaicControls());
|
||||
}
|
||||
|
||||
// GFX groups
|
||||
if (enable_gfx_groups_) {
|
||||
RETURN_IF_ERROR(DrawGfxGroupControls());
|
||||
}
|
||||
|
||||
// Subscreen overlay
|
||||
if (enable_subscreen_overlay_) {
|
||||
uint16_t overlay = current_map->subscreen_overlay();
|
||||
RETURN_IF_ERROR(DrawOverlaySetting("Subscreen Overlay", &overlay));
|
||||
current_map->set_subscreen_overlay(overlay);
|
||||
}
|
||||
|
||||
// Animated GFX
|
||||
if (enable_animated_gfx_) {
|
||||
uint8_t animated_gfx = current_map->animated_gfx();
|
||||
RETURN_IF_ERROR(DrawGfxGroupSetting("Animated GFX", &animated_gfx));
|
||||
current_map->set_animated_gfx(animated_gfx);
|
||||
}
|
||||
|
||||
TreePop();
|
||||
}
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status OverworldEditorManager::DrawAreaSizeControls() {
|
||||
auto* current_map = overworld_->mutable_overworld_map(current_map_index_);
|
||||
|
||||
const char* area_size_names[] = {"Small", "Large", "Wide", "Tall"};
|
||||
int current_size = static_cast<int>(current_map->area_size());
|
||||
|
||||
if (Combo("Area Size", ¤t_size, area_size_names, 4)) {
|
||||
current_map->SetAreaSize(static_cast<zelda3::AreaSizeEnum>(current_size));
|
||||
}
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status OverworldEditorManager::DrawMosaicControls() {
|
||||
auto* current_map = overworld_->mutable_overworld_map(current_map_index_);
|
||||
const auto& mosaic = current_map->mosaic_expanded();
|
||||
|
||||
bool mosaic_up = mosaic[0];
|
||||
bool mosaic_down = mosaic[1];
|
||||
bool mosaic_left = mosaic[2];
|
||||
bool mosaic_right = mosaic[3];
|
||||
|
||||
if (Checkbox("Mosaic Up", &mosaic_up)) {
|
||||
current_map->set_mosaic_expanded(0, mosaic_up);
|
||||
}
|
||||
SameLine();
|
||||
if (Checkbox("Mosaic Down", &mosaic_down)) {
|
||||
current_map->set_mosaic_expanded(1, mosaic_down);
|
||||
}
|
||||
if (Checkbox("Mosaic Left", &mosaic_left)) {
|
||||
current_map->set_mosaic_expanded(2, mosaic_left);
|
||||
}
|
||||
SameLine();
|
||||
if (Checkbox("Mosaic Right", &mosaic_right)) {
|
||||
current_map->set_mosaic_expanded(3, mosaic_right);
|
||||
}
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status OverworldEditorManager::DrawGfxGroupControls() {
|
||||
auto* current_map = overworld_->mutable_overworld_map(current_map_index_);
|
||||
|
||||
Text("Custom Tile GFX Groups:");
|
||||
for (int i = 0; i < 8; i++) {
|
||||
uint8_t gfx_id = current_map->custom_tileset(i);
|
||||
std::string label = "GFX " + std::to_string(i);
|
||||
RETURN_IF_ERROR(DrawGfxGroupSetting(label.c_str(), &gfx_id));
|
||||
current_map->set_custom_tileset(i, gfx_id);
|
||||
if (i < 7) SameLine();
|
||||
}
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status OverworldEditorManager::DrawTransitionSettings() {
|
||||
if (TreeNode("Transition Settings")) {
|
||||
Text("Complex area transition calculations are automatically handled");
|
||||
Text("based on neighboring area sizes (Large, Wide, Tall, Small).");
|
||||
|
||||
if (GetCustomASMVersion() >= 3) {
|
||||
TextColored(ImVec4(0, 1, 0, 1), "Using v3+ enhanced transitions");
|
||||
} else {
|
||||
TextColored(ImVec4(1, 1, 0, 1), "Using vanilla/v2 transitions");
|
||||
}
|
||||
|
||||
TreePop();
|
||||
}
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status OverworldEditorManager::DrawOverlaySettings() {
|
||||
if (TreeNode("Interactive Overlay Settings")) {
|
||||
Text("Interactive overlays reveal holes and change map elements.");
|
||||
|
||||
auto* current_map = overworld_->mutable_overworld_map(current_map_index_);
|
||||
|
||||
Text("Map %d has %s", current_map_index_,
|
||||
current_map->has_overlay() ? "interactive overlay" : "no overlay");
|
||||
|
||||
if (current_map->has_overlay()) {
|
||||
Text("Overlay ID: 0x%04X", current_map->overlay_id());
|
||||
Text("Overlay data size: %zu bytes", current_map->overlay_data().size());
|
||||
}
|
||||
|
||||
TreePop();
|
||||
}
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status OverworldEditorManager::ApplyCustomOverworldASM() {
|
||||
return overworld_->SaveCustomOverworldASM(
|
||||
enable_area_specific_bg_, enable_main_palette_, enable_mosaic_,
|
||||
enable_gfx_groups_, enable_subscreen_overlay_, enable_animated_gfx_);
|
||||
}
|
||||
|
||||
bool OverworldEditorManager::ValidateV3Compatibility() {
|
||||
uint8_t asm_version = GetCustomASMVersion();
|
||||
return (asm_version >= 3 && asm_version != 0xFF);
|
||||
}
|
||||
|
||||
bool OverworldEditorManager::CheckCustomASMApplied() {
|
||||
uint8_t asm_version = GetCustomASMVersion();
|
||||
return (asm_version != 0xFF && asm_version != 0x00);
|
||||
}
|
||||
|
||||
uint8_t OverworldEditorManager::GetCustomASMVersion() {
|
||||
return (*rom_)[zelda3::OverworldCustomASMHasBeenApplied];
|
||||
}
|
||||
|
||||
absl::Status OverworldEditorManager::DrawBooleanSetting(const char* label, bool* setting,
|
||||
const char* help_text) {
|
||||
Checkbox(label, setting);
|
||||
if (help_text && IsItemHovered()) {
|
||||
SetTooltip("%s", help_text);
|
||||
}
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status OverworldEditorManager::DrawColorPicker(const char* label, uint16_t* color) {
|
||||
gfx::SnesColor snes_color(*color);
|
||||
ImVec4 imgui_color = snes_color.rgb();
|
||||
|
||||
if (ColorEdit3(label, &imgui_color.x)) {
|
||||
gfx::SnesColor new_color;
|
||||
new_color.set_rgb(imgui_color);
|
||||
*color = new_color.snes();
|
||||
}
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status OverworldEditorManager::DrawOverlaySetting(const char* label, uint16_t* overlay) {
|
||||
int overlay_int = *overlay;
|
||||
if (InputInt(label, &overlay_int, 1, 16, ImGuiInputTextFlags_CharsHexadecimal)) {
|
||||
*overlay = static_cast<uint16_t>(overlay_int & 0xFFFF);
|
||||
}
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status OverworldEditorManager::DrawGfxGroupSetting(const char* label, uint8_t* gfx_id,
|
||||
int max_value) {
|
||||
int gfx_int = *gfx_id;
|
||||
if (SliderInt(label, &gfx_int, 0, max_value)) {
|
||||
*gfx_id = static_cast<uint8_t>(gfx_int);
|
||||
}
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status OverworldEditorManager::DrawUnifiedSettingsTable() {
|
||||
// Create a comprehensive settings table that combines toolset and properties
|
||||
if (BeginTable("##UnifiedOverworldSettings", 6,
|
||||
ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersOuter |
|
||||
ImGuiTableFlags_BordersV | ImGuiTableFlags_SizingFixedFit)) {
|
||||
|
||||
// Setup columns with proper widths
|
||||
TableSetupColumn(ICON_MD_BUILD " Tools", ImGuiTableColumnFlags_WidthFixed, 120);
|
||||
TableSetupColumn(ICON_MD_MAP " World", ImGuiTableColumnFlags_WidthFixed, 100);
|
||||
TableSetupColumn(ICON_MD_IMAGE " Graphics", ImGuiTableColumnFlags_WidthFixed, 100);
|
||||
TableSetupColumn(ICON_MD_PALETTE " Palette", ImGuiTableColumnFlags_WidthFixed, 100);
|
||||
TableSetupColumn(ICON_MD_SETTINGS " Properties", ImGuiTableColumnFlags_WidthStretch);
|
||||
TableSetupColumn(ICON_MD_EXTENSION " v3 Features", ImGuiTableColumnFlags_WidthFixed, 120);
|
||||
TableHeadersRow();
|
||||
|
||||
TableNextRow();
|
||||
|
||||
// Tools column
|
||||
TableNextColumn();
|
||||
RETURN_IF_ERROR(DrawToolsetInSettings());
|
||||
|
||||
// World column
|
||||
TableNextColumn();
|
||||
Text(ICON_MD_PUBLIC " Current World");
|
||||
SetNextItemWidth(80.f);
|
||||
// if (Combo("##world", ¤t_world_, kWorldList.data(), 3)) {
|
||||
// // World change logic would go here
|
||||
// }
|
||||
|
||||
// Graphics column
|
||||
TableNextColumn();
|
||||
Text(ICON_MD_IMAGE " Area Graphics");
|
||||
// Graphics controls would go here
|
||||
|
||||
// Palette column
|
||||
TableNextColumn();
|
||||
Text(ICON_MD_PALETTE " Area Palette");
|
||||
// Palette controls would go here
|
||||
|
||||
// Properties column
|
||||
TableNextColumn();
|
||||
Text(ICON_MD_SETTINGS " Map Properties");
|
||||
// Map properties would go here
|
||||
|
||||
// v3 Features column
|
||||
TableNextColumn();
|
||||
uint8_t asm_version = GetCustomASMVersion();
|
||||
if (asm_version >= 3 && asm_version != 0xFF) {
|
||||
TextColored(ImVec4(0, 1, 0, 1), ICON_MD_NEW_RELEASES " v3 Active");
|
||||
if (Button(ICON_MD_TUNE " Settings")) {
|
||||
// Open v3 settings
|
||||
}
|
||||
} else {
|
||||
TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1), ICON_MD_UPGRADE " v3 Available");
|
||||
if (Button(ICON_MD_UPGRADE " Upgrade")) {
|
||||
// Trigger upgrade
|
||||
}
|
||||
}
|
||||
|
||||
EndTable();
|
||||
}
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status OverworldEditorManager::DrawToolsetInSettings() {
|
||||
// Compact toolset layout within the settings table
|
||||
BeginGroup();
|
||||
|
||||
// Core editing tools in a compact grid
|
||||
if (Button(ICON_MD_PAN_TOOL_ALT, ImVec2(25, 25))) {
|
||||
// Set PAN mode
|
||||
}
|
||||
HOVER_HINT("Pan (1)");
|
||||
|
||||
SameLine();
|
||||
if (Button(ICON_MD_DRAW, ImVec2(25, 25))) {
|
||||
// Set DRAW_TILE mode
|
||||
}
|
||||
HOVER_HINT("Draw Tile (2)");
|
||||
|
||||
SameLine();
|
||||
if (Button(ICON_MD_DOOR_FRONT, ImVec2(25, 25))) {
|
||||
// Set ENTRANCES mode
|
||||
}
|
||||
HOVER_HINT("Entrances (3)");
|
||||
|
||||
SameLine();
|
||||
if (Button(ICON_MD_DOOR_BACK, ImVec2(25, 25))) {
|
||||
// Set EXITS mode
|
||||
}
|
||||
HOVER_HINT("Exits (4)");
|
||||
|
||||
// Second row
|
||||
if (Button(ICON_MD_GRASS, ImVec2(25, 25))) {
|
||||
// Set ITEMS mode
|
||||
}
|
||||
HOVER_HINT("Items (5)");
|
||||
|
||||
SameLine();
|
||||
if (Button(ICON_MD_PEST_CONTROL_RODENT, ImVec2(25, 25))) {
|
||||
// Set SPRITES mode
|
||||
}
|
||||
HOVER_HINT("Sprites (6)");
|
||||
|
||||
SameLine();
|
||||
if (Button(ICON_MD_ADD_LOCATION, ImVec2(25, 25))) {
|
||||
// Set TRANSPORTS mode
|
||||
}
|
||||
HOVER_HINT("Transports (7)");
|
||||
|
||||
SameLine();
|
||||
if (Button(ICON_MD_MUSIC_NOTE, ImVec2(25, 25))) {
|
||||
// Set MUSIC mode
|
||||
}
|
||||
HOVER_HINT("Music (8)");
|
||||
|
||||
EndGroup();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status OverworldEditorManager::HandleCanvasSelectionTransfer() {
|
||||
// This could be called to manage bidirectional selection transfer
|
||||
// For now, it's a placeholder for future canvas interaction management
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status OverworldEditorManager::TransferOverworldSelectionToScratch() {
|
||||
// Transfer logic would go here to copy selections from overworld to scratch
|
||||
// This could be integrated with the editor's context system
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status OverworldEditorManager::TransferScratchSelectionToOverworld() {
|
||||
// Transfer logic would go here to copy selections from scratch to overworld
|
||||
// This could be integrated with the editor's context system
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
} // namespace editor
|
||||
} // namespace yaze
|
||||
108
src/app/editor/overworld/overworld_editor_manager.h
Normal file
108
src/app/editor/overworld/overworld_editor_manager.h
Normal file
@@ -0,0 +1,108 @@
|
||||
#ifndef YAZE_APP_EDITOR_OVERWORLD_OVERWORLD_EDITOR_MANAGER_H
|
||||
#define YAZE_APP_EDITOR_OVERWORLD_OVERWORLD_EDITOR_MANAGER_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
#include "app/rom.h"
|
||||
#include "app/zelda3/overworld/overworld.h"
|
||||
#include "app/gui/canvas.h"
|
||||
#include "app/gui/input.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace editor {
|
||||
|
||||
// Forward declarations
|
||||
enum class EditingMode;
|
||||
class OverworldEditor;
|
||||
|
||||
/**
|
||||
* @class OverworldEditorManager
|
||||
* @brief Manages the complex overworld editor functionality and v3 features
|
||||
*
|
||||
* This class separates the complex overworld editing functionality from the main
|
||||
* OverworldEditor class to improve maintainability and organization, especially
|
||||
* for ZSCustomOverworld v3 features.
|
||||
*/
|
||||
class OverworldEditorManager {
|
||||
public:
|
||||
OverworldEditorManager(zelda3::Overworld* overworld, Rom* rom,
|
||||
OverworldEditor* editor = nullptr)
|
||||
: overworld_(overworld), rom_(rom), editor_(editor) {}
|
||||
|
||||
// Set editor context for mode changes
|
||||
void SetEditorContext(OverworldEditor* editor) { editor_ = editor; }
|
||||
|
||||
// v3 Feature Management
|
||||
absl::Status DrawV3SettingsPanel();
|
||||
absl::Status DrawCustomOverworldSettings();
|
||||
absl::Status DrawAreaSpecificSettings();
|
||||
absl::Status DrawTransitionSettings();
|
||||
absl::Status DrawOverlaySettings();
|
||||
|
||||
// Map Properties Management
|
||||
absl::Status DrawMapPropertiesTable();
|
||||
absl::Status DrawUnifiedSettingsTable();
|
||||
absl::Status DrawToolsetInSettings();
|
||||
absl::Status DrawAreaSizeControls();
|
||||
absl::Status DrawMosaicControls();
|
||||
absl::Status DrawPaletteControls();
|
||||
absl::Status DrawGfxGroupControls();
|
||||
|
||||
// Save/Load Operations for v3
|
||||
absl::Status SaveCustomOverworldData();
|
||||
absl::Status LoadCustomOverworldData();
|
||||
absl::Status ApplyCustomOverworldASM();
|
||||
|
||||
// Canvas Interaction Management
|
||||
absl::Status HandleCanvasSelectionTransfer();
|
||||
absl::Status TransferOverworldSelectionToScratch();
|
||||
absl::Status TransferScratchSelectionToOverworld();
|
||||
|
||||
// Validation and Checks
|
||||
bool ValidateV3Compatibility();
|
||||
bool CheckCustomASMApplied();
|
||||
uint8_t GetCustomASMVersion();
|
||||
|
||||
// Getters/Setters for v3 settings
|
||||
auto enable_area_specific_bg() const { return enable_area_specific_bg_; }
|
||||
auto enable_main_palette() const { return enable_main_palette_; }
|
||||
auto enable_mosaic() const { return enable_mosaic_; }
|
||||
auto enable_gfx_groups() const { return enable_gfx_groups_; }
|
||||
auto enable_subscreen_overlay() const { return enable_subscreen_overlay_; }
|
||||
auto enable_animated_gfx() const { return enable_animated_gfx_; }
|
||||
|
||||
void set_enable_area_specific_bg(bool value) { enable_area_specific_bg_ = value; }
|
||||
void set_enable_main_palette(bool value) { enable_main_palette_ = value; }
|
||||
void set_enable_mosaic(bool value) { enable_mosaic_ = value; }
|
||||
void set_enable_gfx_groups(bool value) { enable_gfx_groups_ = value; }
|
||||
void set_enable_subscreen_overlay(bool value) { enable_subscreen_overlay_ = value; }
|
||||
void set_enable_animated_gfx(bool value) { enable_animated_gfx_ = value; }
|
||||
|
||||
private:
|
||||
zelda3::Overworld* overworld_;
|
||||
Rom* rom_;
|
||||
OverworldEditor* editor_;
|
||||
|
||||
// v3 Feature flags
|
||||
bool enable_area_specific_bg_ = false;
|
||||
bool enable_main_palette_ = false;
|
||||
bool enable_mosaic_ = false;
|
||||
bool enable_gfx_groups_ = false;
|
||||
bool enable_subscreen_overlay_ = false;
|
||||
bool enable_animated_gfx_ = false;
|
||||
|
||||
// Current editing state
|
||||
int current_map_index_ = 0;
|
||||
|
||||
// Helper methods
|
||||
absl::Status DrawBooleanSetting(const char* label, bool* setting, const char* help_text = nullptr);
|
||||
absl::Status DrawColorPicker(const char* label, uint16_t* color);
|
||||
absl::Status DrawOverlaySetting(const char* label, uint16_t* overlay);
|
||||
absl::Status DrawGfxGroupSetting(const char* label, uint8_t* gfx_id, int max_value = 255);
|
||||
};
|
||||
|
||||
} // namespace editor
|
||||
} // namespace yaze
|
||||
|
||||
#endif // YAZE_APP_EDITOR_OVERWORLD_OVERWORLD_EDITOR_MANAGER_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,8 @@
|
||||
#define YAZE_APP_EDITOR_TILE16EDITOR_H
|
||||
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
@@ -19,29 +21,43 @@
|
||||
namespace yaze {
|
||||
namespace editor {
|
||||
|
||||
// Constants for tile editing
|
||||
constexpr int kTile16Size = 16;
|
||||
constexpr int kTile8Size = 8;
|
||||
constexpr int kTilesheetEditorWidth = 0x100;
|
||||
constexpr int kTilesheetEditorHeight = 0x4000;
|
||||
constexpr int kTile16CanvasSize = 0x20;
|
||||
constexpr int kTile8CanvasHeight = 0x175;
|
||||
constexpr int kNumScratchSlots = 4;
|
||||
constexpr int kNumPalettes = 8;
|
||||
constexpr int kTile8PixelCount = 64;
|
||||
constexpr int kTile16PixelCount = 256;
|
||||
|
||||
/**
|
||||
* @brief Popup window to edit Tile16 data
|
||||
*/
|
||||
class Tile16Editor : public gfx::GfxContext {
|
||||
public:
|
||||
Tile16Editor(Rom *rom, gfx::Tilemap *tile16_blockset)
|
||||
Tile16Editor(Rom* rom, gfx::Tilemap* tile16_blockset)
|
||||
: rom_(rom), tile16_blockset_(tile16_blockset) {}
|
||||
absl::Status Initialize(const gfx::Bitmap &tile16_blockset_bmp,
|
||||
const gfx::Bitmap ¤t_gfx_bmp,
|
||||
std::array<uint8_t, 0x200> &all_tiles_types);
|
||||
absl::Status Initialize(const gfx::Bitmap& tile16_blockset_bmp,
|
||||
const gfx::Bitmap& current_gfx_bmp,
|
||||
std::array<uint8_t, 0x200>& all_tiles_types);
|
||||
|
||||
absl::Status Update();
|
||||
|
||||
void DrawTile16Editor();
|
||||
absl::Status UpdateTile16Transfer();
|
||||
absl::Status UpdateBlockset();
|
||||
|
||||
absl::Status DrawToCurrentTile16(ImVec2 pos);
|
||||
// Scratch space for tile16 layouts
|
||||
void DrawScratchSpace();
|
||||
absl::Status SaveLayoutToScratch(int slot);
|
||||
absl::Status LoadLayoutFromScratch(int slot);
|
||||
|
||||
absl::Status DrawToCurrentTile16(ImVec2 pos, const gfx::Bitmap* source_tile = nullptr);
|
||||
|
||||
absl::Status UpdateTile16Edit();
|
||||
|
||||
absl::Status UpdateTransferTileCanvas();
|
||||
|
||||
absl::Status LoadTile8();
|
||||
|
||||
absl::Status SetCurrentTile(int id);
|
||||
@@ -53,14 +69,69 @@ class Tile16Editor : public gfx::GfxContext {
|
||||
absl::Status LoadTile16FromScratchSpace(int slot);
|
||||
absl::Status ClearScratchSpace(int slot);
|
||||
|
||||
void set_rom(Rom *rom) { rom_ = rom; }
|
||||
Rom *rom() const { return rom_; }
|
||||
// Advanced editing features
|
||||
absl::Status FlipTile16Horizontal();
|
||||
absl::Status FlipTile16Vertical();
|
||||
absl::Status RotateTile16();
|
||||
absl::Status FillTile16WithTile8(int tile8_id);
|
||||
absl::Status AutoTileTile16();
|
||||
absl::Status ClearTile16();
|
||||
|
||||
// Palette management
|
||||
absl::Status CyclePalette(bool forward = true);
|
||||
absl::Status ApplyPaletteToAll(uint8_t palette_id);
|
||||
absl::Status PreviewPaletteChange(uint8_t palette_id);
|
||||
|
||||
// Batch operations
|
||||
absl::Status ApplyToSelection(const std::function<void(int)>& operation);
|
||||
absl::Status BatchEdit(const std::vector<int>& tile_ids,
|
||||
const std::function<void(int)>& operation);
|
||||
|
||||
// History and undo system
|
||||
absl::Status Undo();
|
||||
absl::Status Redo();
|
||||
void SaveUndoState();
|
||||
|
||||
// Live preview system
|
||||
void EnableLivePreview(bool enable) { live_preview_enabled_ = enable; }
|
||||
absl::Status UpdateLivePreview();
|
||||
|
||||
// Validation and integrity checks
|
||||
absl::Status ValidateTile16Data();
|
||||
bool IsTile16Valid(int tile_id) const;
|
||||
|
||||
// Integration with overworld system
|
||||
absl::Status SaveTile16ToROM();
|
||||
absl::Status UpdateOverworldTilemap();
|
||||
absl::Status CommitChangesToBlockset();
|
||||
absl::Status CommitChangesToOverworld();
|
||||
absl::Status DiscardChanges();
|
||||
|
||||
// Helper methods for palette management
|
||||
absl::Status UpdateTile8Palette(int tile8_id);
|
||||
absl::Status RefreshAllPalettes();
|
||||
void DrawPaletteSettings();
|
||||
|
||||
// ROM data access and modification
|
||||
absl::Status UpdateROMTile16Data();
|
||||
absl::Status RefreshTile16Blockset();
|
||||
gfx::Tile16* GetCurrentTile16Data();
|
||||
absl::Status RegenerateTile16BitmapFromROM();
|
||||
|
||||
// Manual tile8 input controls
|
||||
void DrawManualTile8Inputs();
|
||||
|
||||
void set_rom(Rom* rom) { rom_ = rom; }
|
||||
Rom* rom() const { return rom_; }
|
||||
|
||||
// Callback for when changes are committed to notify parent editor
|
||||
void set_on_changes_committed(std::function<absl::Status()> callback) {
|
||||
on_changes_committed_ = callback;
|
||||
}
|
||||
|
||||
private:
|
||||
Rom *rom_ = nullptr;
|
||||
Rom* rom_ = nullptr;
|
||||
bool map_blockset_loaded_ = false;
|
||||
bool transfer_started_ = false;
|
||||
bool transfer_blockset_loaded_ = false;
|
||||
bool x_flip = false;
|
||||
bool y_flip = false;
|
||||
bool priority_tile = false;
|
||||
@@ -78,19 +149,67 @@ class Tile16Editor : public gfx::GfxContext {
|
||||
std::array<gfx::Bitmap, 4> scratch_space_;
|
||||
std::array<bool, 4> scratch_space_used_ = {false, false, false, false};
|
||||
|
||||
// Layout scratch space for tile16 arrangements (4 slots of 8x8 grids)
|
||||
struct LayoutScratch {
|
||||
std::array<std::array<int, 8>, 8> tile_layout; // 8x8 grid of tile16 IDs
|
||||
bool in_use = false;
|
||||
std::string name = "Empty";
|
||||
};
|
||||
std::array<LayoutScratch, 4> layout_scratch_;
|
||||
|
||||
// Undo/Redo system
|
||||
struct UndoState {
|
||||
int tile_id;
|
||||
gfx::Bitmap tile_bitmap;
|
||||
gfx::Tile16 tile_data;
|
||||
uint8_t palette;
|
||||
bool x_flip, y_flip, priority;
|
||||
};
|
||||
std::vector<UndoState> undo_stack_;
|
||||
std::vector<UndoState> redo_stack_;
|
||||
static constexpr size_t kMaxUndoStates_ = 50;
|
||||
|
||||
// Live preview system
|
||||
bool live_preview_enabled_ = true;
|
||||
gfx::Bitmap preview_tile16_;
|
||||
bool preview_dirty_ = false;
|
||||
|
||||
// Selection system
|
||||
std::vector<int> selected_tiles_;
|
||||
int selection_start_tile_ = -1;
|
||||
bool multi_select_mode_ = false;
|
||||
|
||||
// Advanced editing state
|
||||
bool auto_tile_mode_ = false;
|
||||
bool grid_snap_enabled_ = true;
|
||||
bool show_tile_info_ = true;
|
||||
bool show_palette_preview_ = true;
|
||||
|
||||
// Palette management settings
|
||||
bool show_palette_settings_ = false;
|
||||
int current_palette_group_ = 0; // 0=overworld_main, 1=aux1, 2=aux2, etc.
|
||||
uint8_t palette_normalization_mask_ = 0x0F; // Default 4-bit mask
|
||||
bool auto_normalize_pixels_ = true;
|
||||
|
||||
// Performance tracking
|
||||
std::chrono::steady_clock::time_point last_edit_time_;
|
||||
bool batch_mode_ = false;
|
||||
|
||||
util::NotifyValue<uint32_t> notify_tile16;
|
||||
util::NotifyValue<uint8_t> notify_palette;
|
||||
|
||||
std::array<uint8_t, 0x200> all_tiles_types_;
|
||||
|
||||
// Tile16 blockset for selecting the tile to edit
|
||||
gui::Canvas blockset_canvas_{"blocksetCanvas", ImVec2(0x100, 0x4000),
|
||||
gui::CanvasGridSize::k32x32,};
|
||||
gui::Canvas blockset_canvas_{
|
||||
"blocksetCanvas", ImVec2(kTilesheetEditorWidth, kTilesheetEditorHeight),
|
||||
gui::CanvasGridSize::k32x32};
|
||||
gfx::Bitmap tile16_blockset_bmp_;
|
||||
|
||||
// Canvas for editing the selected tile
|
||||
gui::Canvas tile16_edit_canvas_{"Tile16EditCanvas", ImVec2(0x40, 0x40),
|
||||
gui::CanvasGridSize::k64x64};
|
||||
// Canvas for editing the selected tile - optimized for 2x2 grid of 8x8 tiles (16x16 total)
|
||||
gui::Canvas tile16_edit_canvas_{"Tile16EditCanvas",
|
||||
ImVec2(64, 64), // Fixed 64x64 display size (16x16 pixels at 4x scale)
|
||||
gui::CanvasGridSize::k8x8, 4.0F}; // 8x8 grid with 4x scale for clarity
|
||||
gfx::Bitmap current_tile16_bmp_;
|
||||
|
||||
// Tile8 canvas to get the tile to drawing in the tile16_edit_canvas_
|
||||
@@ -100,23 +219,18 @@ class Tile16Editor : public gfx::GfxContext {
|
||||
gui::CanvasGridSize::k32x32};
|
||||
gfx::Bitmap current_gfx_bmp_;
|
||||
|
||||
gui::Canvas transfer_canvas_;
|
||||
gfx::Bitmap transfer_blockset_bmp_;
|
||||
|
||||
gui::Table tile_edit_table_{"##TileEditTable", 3, ImGuiTableFlags_Borders};
|
||||
|
||||
gfx::Tilemap *tile16_blockset_ = nullptr;
|
||||
gfx::Tilemap* tile16_blockset_ = nullptr;
|
||||
std::vector<gfx::Bitmap> current_gfx_individual_;
|
||||
|
||||
PaletteEditor palette_editor_;
|
||||
gfx::SnesPalette palette_;
|
||||
|
||||
absl::Status status_;
|
||||
|
||||
Rom *transfer_rom_ = nullptr;
|
||||
zelda3::Overworld transfer_overworld_{transfer_rom_};
|
||||
std::array<gfx::Bitmap, kNumGfxSheets> transfer_gfx_;
|
||||
absl::Status transfer_status_;
|
||||
|
||||
// Callback to notify parent editor when changes are committed
|
||||
std::function<absl::Status()> on_changes_committed_;
|
||||
};
|
||||
|
||||
} // namespace editor
|
||||
|
||||
@@ -38,6 +38,9 @@ void PopupManager::Initialize() {
|
||||
popups_["Workspace Help"] = {"Workspace Help", false, [this]() { DrawWorkspaceHelpPopup(); }};
|
||||
popups_["Session Limit Warning"] = {"Session Limit Warning", false, [this]() { DrawSessionLimitWarningPopup(); }};
|
||||
popups_["Layout Reset Confirm"] = {"Reset Layout Confirmation", false, [this]() { DrawLayoutResetConfirmPopup(); }};
|
||||
|
||||
// Settings popups (accessible without ROM)
|
||||
popups_["Display Settings"] = {"Display Settings", false, [this]() { DrawDisplaySettingsPopup(); }};
|
||||
}
|
||||
|
||||
void PopupManager::DrawPopups() {
|
||||
@@ -48,7 +51,14 @@ void PopupManager::DrawPopups() {
|
||||
for (auto& [name, params] : popups_) {
|
||||
if (params.is_visible) {
|
||||
OpenPopup(name.c_str());
|
||||
if (BeginPopupModal(name.c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
|
||||
// Special handling for Display Settings popup to make it resizable
|
||||
ImGuiWindowFlags popup_flags = ImGuiWindowFlags_AlwaysAutoResize;
|
||||
if (name == "Display Settings") {
|
||||
popup_flags = ImGuiWindowFlags_None; // Allow resizing for display settings
|
||||
}
|
||||
|
||||
if (BeginPopupModal(name.c_str(), nullptr, popup_flags)) {
|
||||
params.draw_function();
|
||||
EndPopup();
|
||||
}
|
||||
@@ -491,5 +501,46 @@ void PopupManager::DrawLayoutResetConfirmPopup() {
|
||||
}
|
||||
}
|
||||
|
||||
void PopupManager::DrawDisplaySettingsPopup() {
|
||||
// Set a comfortable default size with natural constraints
|
||||
SetNextWindowSize(ImVec2(900, 700), ImGuiCond_FirstUseEver);
|
||||
SetNextWindowSizeConstraints(ImVec2(600, 400), ImVec2(FLT_MAX, FLT_MAX));
|
||||
|
||||
Text("%s Display & Theme Settings", ICON_MD_DISPLAY_SETTINGS);
|
||||
TextWrapped("Customize your YAZE experience - accessible anytime!");
|
||||
Separator();
|
||||
|
||||
// Create a child window for scrollable content to avoid table conflicts
|
||||
// Use remaining space minus the close button area
|
||||
float available_height = GetContentRegionAvail().y - 60; // Reserve space for close button
|
||||
if (BeginChild("DisplaySettingsContent", ImVec2(0, available_height), true, ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
|
||||
// Use the popup-safe version to avoid table conflicts
|
||||
gui::DrawDisplaySettingsForPopup();
|
||||
|
||||
Separator();
|
||||
gui::TextWithSeparators("Font Manager");
|
||||
gui::DrawFontManager();
|
||||
|
||||
// Global font scale (moved from the old display settings window)
|
||||
ImGuiIO &io = GetIO();
|
||||
Separator();
|
||||
Text("Global Font Scale");
|
||||
static float font_global_scale = io.FontGlobalScale;
|
||||
if (SliderFloat("##global_scale", &font_global_scale, 0.5f, 1.8f, "%.2f")) {
|
||||
if (editor_manager_) {
|
||||
editor_manager_->SetFontGlobalScale(font_global_scale);
|
||||
} else {
|
||||
io.FontGlobalScale = font_global_scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
EndChild();
|
||||
|
||||
Separator();
|
||||
if (Button("Close", gui::kDefaultModalSize)) {
|
||||
Hide("Display Settings");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace editor
|
||||
} // namespace yaze
|
||||
|
||||
@@ -86,6 +86,9 @@ class PopupManager {
|
||||
void DrawWorkspaceHelpPopup();
|
||||
void DrawSessionLimitWarningPopup();
|
||||
void DrawLayoutResetConfirmPopup();
|
||||
|
||||
// Settings popups (accessible without ROM)
|
||||
void DrawDisplaySettingsPopup();
|
||||
|
||||
EditorManager* editor_manager_;
|
||||
std::unordered_map<std::string, PopupParams> popups_;
|
||||
|
||||
Reference in New Issue
Block a user