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_) {
|
if (rom_ && !dungeon_editor_system_) {
|
||||||
dungeon_editor_system_ =
|
dungeon_editor_system_ =
|
||||||
std::make_unique<zelda3::DungeonEditorSystem>(rom_);
|
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
|
// Column 3: Object selector, room graphics, and object editor
|
||||||
TableNextColumn();
|
TableNextColumn();
|
||||||
object_selector_.Draw();
|
object_selector_.Draw();
|
||||||
|
|
||||||
|
// Phase 5: Draw integrated object editor panels below object selector
|
||||||
|
ImGui::Separator();
|
||||||
|
DrawObjectEditorPanels();
|
||||||
|
|
||||||
ImGui::EndTable();
|
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
|
// Draw selection box and drag preview using component
|
||||||
object_interaction_.DrawSelectBox();
|
object_interaction_.DrawSelectBox();
|
||||||
object_interaction_.DrawDragPreview();
|
object_interaction_.DrawDragPreview();
|
||||||
@@ -675,6 +695,97 @@ void DungeonEditor::DrawDungeonCanvas(int room_id) {
|
|||||||
canvas_.DrawOverlay();
|
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
|
// Legacy method implementations that delegate to components
|
||||||
absl::Status DungeonEditor::LoadAndRenderRoomGraphics(int room_id) {
|
absl::Status DungeonEditor::LoadAndRenderRoomGraphics(int room_id) {
|
||||||
if (room_id < 0 || room_id >= rooms_.size()) {
|
if (room_id < 0 || room_id >= rooms_.size()) {
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class DungeonEditor : public Editor {
|
|||||||
// Initialize the new dungeon editor system
|
// Initialize the new dungeon editor system
|
||||||
if (rom) {
|
if (rom) {
|
||||||
dungeon_editor_system_ = std::make_unique<zelda3::DungeonEditorSystem>(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 DrawCanvasAndPropertiesPanel();
|
||||||
void DrawRoomPropertiesDebugPopup();
|
void DrawRoomPropertiesDebugPopup();
|
||||||
|
|
||||||
|
// Phase 5: Integrated editor panels
|
||||||
|
void DrawObjectEditorPanels();
|
||||||
|
void RenderRoomWithObjects(int room_id);
|
||||||
|
void UpdateObjectEditor();
|
||||||
|
|
||||||
// Room selection management
|
// Room selection management
|
||||||
void OnRoomSelected(int room_id);
|
void OnRoomSelected(int room_id);
|
||||||
|
|
||||||
@@ -126,10 +131,15 @@ class DungeonEditor : public Editor {
|
|||||||
bool palette_showing_ = false;
|
bool palette_showing_ = false;
|
||||||
bool refresh_graphics_ = 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::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_sprite_editor_ = false;
|
||||||
bool show_item_editor_ = false;
|
bool show_item_editor_ = false;
|
||||||
bool show_entrance_editor_ = false;
|
bool show_entrance_editor_ = false;
|
||||||
|
|||||||
@@ -374,7 +374,7 @@ void DungeonObjectSelector::DrawRoomGraphics() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DungeonObjectSelector::DrawIntegratedEditingPanels() {
|
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");
|
ImGui::Text("Editor systems not initialized");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -428,12 +428,12 @@ void DungeonObjectSelector::DrawIntegratedEditingPanels() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DungeonObjectSelector::DrawCompactObjectEditor() {
|
void DungeonObjectSelector::DrawCompactObjectEditor() {
|
||||||
if (!object_editor_ || !*object_editor_) {
|
if (!object_editor_) {
|
||||||
ImGui::Text("Object editor not initialized");
|
ImGui::Text("Object editor not initialized");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& editor = **object_editor_;
|
auto& editor = *object_editor_;
|
||||||
|
|
||||||
ImGui::Text("Object Editor");
|
ImGui::Text("Object Editor");
|
||||||
Separator();
|
Separator();
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ class DungeonObjectSelector {
|
|||||||
void set_dungeon_editor_system(std::unique_ptr<zelda3::DungeonEditorSystem>* system) {
|
void set_dungeon_editor_system(std::unique_ptr<zelda3::DungeonEditorSystem>* system) {
|
||||||
dungeon_editor_system_ = system;
|
dungeon_editor_system_ = system;
|
||||||
}
|
}
|
||||||
void set_object_editor(std::shared_ptr<zelda3::DungeonObjectEditor>* editor) {
|
void set_object_editor(std::unique_ptr<zelda3::DungeonObjectEditor>* editor) {
|
||||||
object_editor_ = editor;
|
object_editor_ = editor ? editor->get() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Room data access
|
// Room data access
|
||||||
@@ -93,7 +93,7 @@ class DungeonObjectSelector {
|
|||||||
|
|
||||||
// Editor systems
|
// Editor systems
|
||||||
std::unique_ptr<zelda3::DungeonEditorSystem>* dungeon_editor_system_ = nullptr;
|
std::unique_ptr<zelda3::DungeonEditorSystem>* dungeon_editor_system_ = nullptr;
|
||||||
std::shared_ptr<zelda3::DungeonObjectEditor>* object_editor_ = nullptr;
|
zelda3::DungeonObjectEditor* object_editor_ = nullptr;
|
||||||
|
|
||||||
// Room data
|
// Room data
|
||||||
std::array<zelda3::Room, 0x128>* rooms_ = nullptr;
|
std::array<zelda3::Room, 0x128>* rooms_ = nullptr;
|
||||||
|
|||||||
Reference in New Issue
Block a user