yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
object_editor_card.cc
Go to the documentation of this file.
2
3#include "absl/strings/str_format.h"
5#include "app/gui/icons.h"
7#include "imgui/imgui.h"
8
9namespace yaze::editor {
10
12 : renderer_(renderer), rom_(rom), canvas_viewer_(canvas_viewer), object_selector_(rom) {
13 emulator_preview_.Initialize(renderer, rom);
14}
15
16void ObjectEditorCard::Draw(bool* p_open) {
17 gui::EditorCard card("Object Editor", ICON_MD_CONSTRUCTION, p_open);
18 card.SetDefaultSize(450, 750);
20
21 if (card.Begin(p_open)) {
22 // Interaction mode controls at top (moved from tab)
23 ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "Mode:");
24 ImGui::SameLine();
25
26 if (ImGui::RadioButton("None", interaction_mode_ == InteractionMode::None)) {
30 }
31 ImGui::SameLine();
32
33 if (ImGui::RadioButton("Place", interaction_mode_ == InteractionMode::Place)) {
38 }
39 }
40 ImGui::SameLine();
41
42 if (ImGui::RadioButton("Select", interaction_mode_ == InteractionMode::Select)) {
46 }
47 ImGui::SameLine();
48
49 if (ImGui::RadioButton("Delete", interaction_mode_ == InteractionMode::Delete)) {
53 }
54
55 // Current object info
57
58 ImGui::Separator();
59
60 // Tabbed interface for Browser and Preview
61 if (ImGui::BeginTabBar("##ObjectEditorTabs", ImGuiTabBarFlags_None)) {
62
63 // Tab 1: Object Browser
64 if (ImGui::BeginTabItem(ICON_MD_LIST " Browser")) {
66 ImGui::EndTabItem();
67 }
68
69 // Tab 2: Emulator Preview (enhanced)
70 if (ImGui::BeginTabItem(ICON_MD_MONITOR " Preview")) {
72 ImGui::EndTabItem();
73 }
74
75 ImGui::EndTabBar();
76 }
77 }
78 card.End();
79}
80
82 ImGui::Text(ICON_MD_INFO " Select an object to place on the canvas");
83 ImGui::Separator();
84
85 // Text filter for objects
86 static char object_filter[256] = "";
87 ImGui::SetNextItemWidth(-1);
88 if (ImGui::InputTextWithHint("##ObjectFilter",
89 ICON_MD_SEARCH " Filter objects...",
90 object_filter, sizeof(object_filter))) {
91 // Filter updated
92 }
93
94 ImGui::Separator();
95
96 // Object list with categories
97 if (ImGui::BeginChild("##ObjectList", ImVec2(0, 0), true)) {
98 // Floor objects
99 if (ImGui::CollapsingHeader(ICON_MD_GRID_ON " Floor Objects",
100 ImGuiTreeNodeFlags_DefaultOpen)) {
101 for (int i = 0; i < 0x100; i++) {
102 std::string filter_str = object_filter;
103 if (!filter_str.empty()) {
104 // Simple name-based filtering
105 std::string object_name = absl::StrFormat("Object %02X", i);
106 std::transform(filter_str.begin(), filter_str.end(),
107 filter_str.begin(), ::tolower);
108 std::transform(object_name.begin(), object_name.end(),
109 object_name.begin(), ::tolower);
110 if (object_name.find(filter_str) == std::string::npos) {
111 continue;
112 }
113 }
114
115 // Create preview icon with small canvas
116 ImGui::BeginGroup();
117
118 // Small preview canvas (32x32 pixels)
119 DrawObjectPreviewIcon(i, ImVec2(32, 32));
120
121 ImGui::SameLine();
122
123 // Object label and selection
124 std::string object_label = absl::StrFormat("%02X - Floor Object", i);
125
126 if (ImGui::Selectable(object_label.c_str(),
128 0, ImVec2(0, 32))) { // Match preview height
130 static_cast<int16_t>(i), 0, 0, 0, 0};
131 has_preview_object_ = true;
135 }
136
137 ImGui::EndGroup();
138
139 if (ImGui::IsItemHovered()) {
140 ImGui::BeginTooltip();
141 ImGui::Text("Object ID: 0x%02X", i);
142 ImGui::Text("Type: Floor Object");
143 ImGui::Text("Click to select for placement");
144 ImGui::EndTooltip();
145 }
146 }
147 }
148
149 // Wall objects
150 if (ImGui::CollapsingHeader(ICON_MD_BORDER_ALL " Wall Objects")) {
151 for (int i = 0; i < 0x50; i++) {
152 std::string object_label = absl::StrFormat(
153 "%s %02X - Wall Object", ICON_MD_BORDER_VERTICAL, i);
154
155 if (ImGui::Selectable(object_label.c_str())) {
156 // Wall objects have special handling
158 static_cast<int16_t>(i), 0, 0, 0, 1}; // layer=1 for walls
159 has_preview_object_ = true;
163 }
164 }
165 }
166
167 // Special objects
168 if (ImGui::CollapsingHeader(ICON_MD_STAR " Special Objects")) {
169 const char* special_objects[] = {
170 "Stairs Down", "Stairs Up", "Chest", "Door", "Pot", "Block",
171 "Switch", "Torch"
172 };
173
174 for (int i = 0; i < IM_ARRAYSIZE(special_objects); i++) {
175 std::string object_label = absl::StrFormat(
176 "%s %s", ICON_MD_STAR, special_objects[i]);
177
178 if (ImGui::Selectable(object_label.c_str())) {
179 // Special object IDs start at 0xF8
181 static_cast<int16_t>(0xF8 + i), 0, 0, 0, 2};
182 has_preview_object_ = true;
186 }
187 }
188 }
189
190 ImGui::EndChild();
191 }
192
193 // Quick actions at bottom
194 if (ImGui::Button(ICON_MD_CLEAR " Clear Selection", ImVec2(-1, 0))) {
195 has_preview_object_ = false;
199 }
200}
201
203 ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f),
204 ICON_MD_INFO " Real-time object rendering preview");
205 ImGui::Separator();
206
207 // Toggle emulator preview visibility
208 ImGui::Checkbox("Enable Preview", &show_emulator_preview_);
209 ImGui::SameLine();
210 gui::HelpMarker("Uses SNES emulation to render objects accurately.\n"
211 "May impact performance.");
212
214 ImGui::Separator();
215
216 // Embed the emulator preview with improved layout
217 ImGui::BeginChild("##EmulatorPreviewRegion", ImVec2(0, 0), true);
218
220
221 ImGui::EndChild();
222 } else {
223 ImGui::Separator();
224 ImGui::TextDisabled(ICON_MD_PREVIEW " Preview disabled for performance");
225 ImGui::TextWrapped("Enable to see accurate object rendering using "
226 "SNES emulation.");
227 }
228}
229
230// DrawInteractionControls removed - controls moved to top of card
231
232void ObjectEditorCard::DrawObjectPreviewIcon(int object_id, const ImVec2& size) {
233 // Create a small preview box for the object
234 ImDrawList* draw_list = ImGui::GetWindowDrawList();
235 ImVec2 cursor_pos = ImGui::GetCursorScreenPos();
236 ImVec2 box_min = cursor_pos;
237 ImVec2 box_max = ImVec2(cursor_pos.x + size.x, cursor_pos.y + size.y);
238
239 // Draw background
240 draw_list->AddRectFilled(box_min, box_max, IM_COL32(40, 40, 45, 255));
241 draw_list->AddRect(box_min, box_max, IM_COL32(100, 100, 100, 255));
242
243 // Draw a simple representation based on object ID
244 // For now, use colored squares and icons as placeholders
245 // Later this can be replaced with actual object bitmaps
246
247 // Color based on object ID for visual variety
248 float hue = (object_id % 16) / 16.0f;
249 ImU32 obj_color = ImGui::ColorConvertFloat4ToU32(
250 ImVec4(0.5f + hue * 0.3f, 0.4f, 0.6f - hue * 0.2f, 1.0f));
251
252 // Draw inner colored square (16x16 in the center)
253 ImVec2 inner_min = ImVec2(cursor_pos.x + 8, cursor_pos.y + 8);
254 ImVec2 inner_max = ImVec2(cursor_pos.x + 24, cursor_pos.y + 24);
255 draw_list->AddRectFilled(inner_min, inner_max, obj_color);
256 draw_list->AddRect(inner_min, inner_max, IM_COL32(200, 200, 200, 255));
257
258 // Draw object ID text (very small)
259 std::string id_text = absl::StrFormat("%02X", object_id);
260 ImVec2 text_size = ImGui::CalcTextSize(id_text.c_str());
261 ImVec2 text_pos = ImVec2(
262 cursor_pos.x + (size.x - text_size.x) * 0.5f,
263 cursor_pos.y + size.y - text_size.y - 2);
264 draw_list->AddText(text_pos, IM_COL32(180, 180, 180, 255), id_text.c_str());
265
266 // Advance cursor
267 ImGui::Dummy(size);
268}
269
271 ImGui::BeginGroup();
272
273 // Show current object for placement
274 ImGui::TextColored(ImVec4(0.4f, 0.8f, 1.0f, 1.0f),
275 ICON_MD_INFO " Current:");
276
278 ImGui::SameLine();
279 ImGui::Text("ID: 0x%02X", preview_object_.id_);
280 ImGui::SameLine();
281 ImGui::Text("Layer: %s",
284 } else {
285 ImGui::SameLine();
286 ImGui::TextDisabled("None");
287 }
288
289 // Show selection count
290 auto& interaction = canvas_viewer_->object_interaction();
291 const auto& selected = interaction.GetSelectedObjectIndices();
292
293 ImGui::SameLine();
294 ImGui::Text("|");
295 ImGui::SameLine();
296 ImGui::TextColored(ImVec4(1.0f, 0.8f, 0.4f, 1.0f),
297 ICON_MD_CHECKLIST " Selected: %zu", selected.size());
298
299 ImGui::SameLine();
300 ImGui::Text("|");
301 ImGui::SameLine();
302 ImGui::Text("Mode: %s",
306
307 // Show quick actions for selections
308 if (!selected.empty()) {
309 ImGui::SameLine();
310 if (ImGui::SmallButton(ICON_MD_CLEAR " Clear")) {
311 interaction.ClearSelection();
312 }
313 }
314
315 ImGui::EndGroup();
316}
317
318} // namespace yaze::editor
The Rom class is used to load, save, and modify Rom data.
Definition rom.h:71
Handles the main dungeon canvas rendering and interaction.
DungeonObjectInteraction & object_interaction()
void SetPreviewObject(const zelda3::RoomObject &object)
const std::vector< size_t > & GetSelectedObjectIndices() const
gui::DungeonObjectEmulatorPreview emulator_preview_
DungeonCanvasViewer * canvas_viewer_
ObjectEditorCard(gfx::IRenderer *renderer, Rom *rom, DungeonCanvasViewer *canvas_viewer)
void DrawObjectPreviewIcon(int object_id, const ImVec2 &size)
Defines an abstract interface for all rendering operations.
Definition irenderer.h:35
void Initialize(gfx::IRenderer *renderer, Rom *rom)
Draggable, dockable card for editor sub-windows.
bool Begin(bool *p_open=nullptr)
void SetDefaultSize(float width, float height)
void SetPosition(Position pos)
#define ICON_MD_CHECK_BOX
Definition icons.h:396
#define ICON_MD_MONITOR
Definition icons.h:1231
#define ICON_MD_INFO
Definition icons.h:991
#define ICON_MD_SEARCH
Definition icons.h:1671
#define ICON_MD_CHECKLIST
Definition icons.h:400
#define ICON_MD_STAR
Definition icons.h:1846
#define ICON_MD_CONSTRUCTION
Definition icons.h:456
#define ICON_MD_BORDER_VERTICAL
Definition icons.h:301
#define ICON_MD_GRID_ON
Definition icons.h:894
#define ICON_MD_LIST
Definition icons.h:1092
#define ICON_MD_BORDER_ALL
Definition icons.h:290
#define ICON_MD_ADD_BOX
Definition icons.h:88
#define ICON_MD_CLEAR
Definition icons.h:414
#define ICON_MD_PREVIEW
Definition icons.h:1510
#define ICON_MD_DELETE
Definition icons.h:528
Editors are the view controllers for the application.
void HelpMarker(const char *desc)