feat: Refactor dungeon object selection and editing interfaces for improved usability
This commit is contained in:
@@ -42,7 +42,20 @@ void DungeonEditor::Initialize() {
|
||||
if (rom_ && !dungeon_editor_system_) {
|
||||
dungeon_editor_system_ =
|
||||
std::make_unique<zelda3::DungeonEditorSystem>(rom_);
|
||||
object_editor_ = std::make_shared<zelda3::DungeonObjectEditor>(rom_);
|
||||
}
|
||||
|
||||
// Phase 5: Initialize integrated object editor
|
||||
if (rom_ && !object_editor_) {
|
||||
object_editor_ = std::make_unique<zelda3::DungeonObjectEditor>(rom_);
|
||||
|
||||
// Configure editor for dungeon editing
|
||||
auto config = object_editor_->GetConfig();
|
||||
config.show_selection_highlight = enable_selection_highlight_;
|
||||
config.show_layer_colors = enable_layer_visualization_;
|
||||
config.show_property_panel = show_object_property_panel_;
|
||||
config.snap_to_grid = true;
|
||||
config.grid_size = 16; // 16x16 tiles
|
||||
object_editor_->SetConfig(config);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,6 +237,10 @@ absl::Status DungeonEditor::UpdateDungeonRoomView() {
|
||||
// Column 3: Object selector, room graphics, and object editor
|
||||
TableNextColumn();
|
||||
object_selector_.Draw();
|
||||
|
||||
// Phase 5: Draw integrated object editor panels below object selector
|
||||
ImGui::Separator();
|
||||
DrawObjectEditorPanels();
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
@@ -667,6 +684,9 @@ void DungeonEditor::DrawDungeonCanvas(int room_id) {
|
||||
}
|
||||
}
|
||||
|
||||
// Phase 5: Render with integrated object editor
|
||||
RenderRoomWithObjects(room_id);
|
||||
|
||||
// Draw selection box and drag preview using component
|
||||
object_interaction_.DrawSelectBox();
|
||||
object_interaction_.DrawDragPreview();
|
||||
@@ -675,6 +695,97 @@ void DungeonEditor::DrawDungeonCanvas(int room_id) {
|
||||
canvas_.DrawOverlay();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Phase 5: Integrated Object Editor Methods
|
||||
// ============================================================================
|
||||
|
||||
void DungeonEditor::UpdateObjectEditor() {
|
||||
if (!object_editor_ || !rom_ || !rom_->is_loaded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get current room ID
|
||||
int room_id = current_room_id_;
|
||||
if (!active_rooms_.empty() && current_active_room_tab_ < active_rooms_.Size) {
|
||||
room_id = active_rooms_[current_active_room_tab_];
|
||||
}
|
||||
|
||||
if (room_id < 0 || room_id >= rooms_.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure room graphics and objects are loaded
|
||||
auto& room = rooms_[room_id];
|
||||
|
||||
// Load room graphics if not already loaded (this populates arena buffers)
|
||||
if (room.blocks().empty()) {
|
||||
auto status = LoadAndRenderRoomGraphics(room_id);
|
||||
if (!status.ok()) {
|
||||
// Log error but continue
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Load room objects if not already loaded
|
||||
if (room.GetTileObjects().empty()) {
|
||||
room.LoadObjects();
|
||||
}
|
||||
|
||||
// Sync object editor with current room's objects
|
||||
// The object editor should work with the room's tile_objects_ directly
|
||||
// rather than maintaining its own copy
|
||||
}
|
||||
|
||||
void DungeonEditor::RenderRoomWithObjects(int room_id) {
|
||||
if (!object_editor_ || room_id < 0 || room_id >= rooms_.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure room graphics are loaded and rendered to arena buffers first
|
||||
if (rooms_[room_id].blocks().empty()) {
|
||||
// Room graphics not loaded yet, will be loaded by LoadAndRenderRoomGraphics
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the arena buffers for rendering - these should already be populated
|
||||
// by Room::RenderRoomGraphics() which was called in LoadAndRenderRoomGraphics
|
||||
auto& bg1_bitmap = gfx::Arena::Get().bg1().bitmap();
|
||||
auto& bg2_bitmap = gfx::Arena::Get().bg2().bitmap();
|
||||
|
||||
if (!bg1_bitmap.is_active() || !bg2_bitmap.is_active()) {
|
||||
// Arena bitmaps not initialized, this means RenderRoomGraphics wasn't called
|
||||
return;
|
||||
}
|
||||
|
||||
// Render layer visualization if enabled (draws on top of existing bitmap)
|
||||
if (enable_layer_visualization_) {
|
||||
object_editor_->RenderLayerVisualization(bg1_bitmap);
|
||||
}
|
||||
|
||||
// Render selection highlights if enabled (draws on top of existing bitmap)
|
||||
if (enable_selection_highlight_) {
|
||||
object_editor_->RenderSelectionHighlight(bg1_bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
void DungeonEditor::DrawObjectEditorPanels() {
|
||||
if (!object_editor_) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update editor state
|
||||
UpdateObjectEditor();
|
||||
|
||||
// Render ImGui panels
|
||||
if (show_object_property_panel_) {
|
||||
object_editor_->RenderObjectPropertyPanel();
|
||||
}
|
||||
|
||||
if (show_layer_controls_) {
|
||||
object_editor_->RenderLayerControls();
|
||||
}
|
||||
}
|
||||
|
||||
// Legacy method implementations that delegate to components
|
||||
absl::Status DungeonEditor::LoadAndRenderRoomGraphics(int room_id) {
|
||||
if (room_id < 0 || room_id >= rooms_.size()) {
|
||||
|
||||
@@ -57,7 +57,7 @@ class DungeonEditor : public Editor {
|
||||
// Initialize the new dungeon editor system
|
||||
if (rom) {
|
||||
dungeon_editor_system_ = std::make_unique<zelda3::DungeonEditorSystem>(rom);
|
||||
object_editor_ = std::make_shared<zelda3::DungeonObjectEditor>(rom);
|
||||
object_editor_ = std::make_unique<zelda3::DungeonObjectEditor>(rom);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,6 +105,11 @@ class DungeonEditor : public Editor {
|
||||
void DrawCanvasAndPropertiesPanel();
|
||||
void DrawRoomPropertiesDebugPopup();
|
||||
|
||||
// Phase 5: Integrated editor panels
|
||||
void DrawObjectEditorPanels();
|
||||
void RenderRoomWithObjects(int room_id);
|
||||
void UpdateObjectEditor();
|
||||
|
||||
// Room selection management
|
||||
void OnRoomSelected(int room_id);
|
||||
|
||||
@@ -126,10 +131,15 @@ class DungeonEditor : public Editor {
|
||||
bool palette_showing_ = false;
|
||||
bool refresh_graphics_ = false;
|
||||
|
||||
// New editor system integration
|
||||
// Phase 5: Integrated object editor system
|
||||
std::unique_ptr<zelda3::DungeonObjectEditor> object_editor_;
|
||||
bool show_object_property_panel_ = true;
|
||||
bool show_layer_controls_ = true;
|
||||
bool enable_selection_highlight_ = true;
|
||||
bool enable_layer_visualization_ = true;
|
||||
|
||||
// Legacy editor system (deprecated)
|
||||
std::unique_ptr<zelda3::DungeonEditorSystem> dungeon_editor_system_;
|
||||
std::shared_ptr<zelda3::DungeonObjectEditor> object_editor_;
|
||||
bool show_object_editor_ = false;
|
||||
bool show_sprite_editor_ = false;
|
||||
bool show_item_editor_ = false;
|
||||
bool show_entrance_editor_ = false;
|
||||
|
||||
@@ -374,7 +374,7 @@ void DungeonObjectSelector::DrawRoomGraphics() {
|
||||
}
|
||||
|
||||
void DungeonObjectSelector::DrawIntegratedEditingPanels() {
|
||||
if (!dungeon_editor_system_ || !object_editor_ || !*dungeon_editor_system_ || !*object_editor_) {
|
||||
if (!dungeon_editor_system_ || !*dungeon_editor_system_ || !object_editor_) {
|
||||
ImGui::Text("Editor systems not initialized");
|
||||
return;
|
||||
}
|
||||
@@ -428,12 +428,12 @@ void DungeonObjectSelector::DrawIntegratedEditingPanels() {
|
||||
}
|
||||
|
||||
void DungeonObjectSelector::DrawCompactObjectEditor() {
|
||||
if (!object_editor_ || !*object_editor_) {
|
||||
if (!object_editor_) {
|
||||
ImGui::Text("Object editor not initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
auto& editor = **object_editor_;
|
||||
auto& editor = *object_editor_;
|
||||
|
||||
ImGui::Text("Object Editor");
|
||||
Separator();
|
||||
|
||||
@@ -38,8 +38,8 @@ class DungeonObjectSelector {
|
||||
void set_dungeon_editor_system(std::unique_ptr<zelda3::DungeonEditorSystem>* system) {
|
||||
dungeon_editor_system_ = system;
|
||||
}
|
||||
void set_object_editor(std::shared_ptr<zelda3::DungeonObjectEditor>* editor) {
|
||||
object_editor_ = editor;
|
||||
void set_object_editor(std::unique_ptr<zelda3::DungeonObjectEditor>* editor) {
|
||||
object_editor_ = editor ? editor->get() : nullptr;
|
||||
}
|
||||
|
||||
// Room data access
|
||||
@@ -93,7 +93,7 @@ class DungeonObjectSelector {
|
||||
|
||||
// Editor systems
|
||||
std::unique_ptr<zelda3::DungeonEditorSystem>* dungeon_editor_system_ = nullptr;
|
||||
std::shared_ptr<zelda3::DungeonObjectEditor>* object_editor_ = nullptr;
|
||||
zelda3::DungeonObjectEditor* object_editor_ = nullptr;
|
||||
|
||||
// Room data
|
||||
std::array<zelda3::Room, 0x128>* rooms_ = nullptr;
|
||||
|
||||
Reference in New Issue
Block a user