yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
selection_properties_panel.cc
Go to the documentation of this file.
2
6#include "rom/rom.h"
7#include "imgui/imgui.h"
8
9namespace yaze {
10namespace editor {
11
13 switch (type) {
15 return "None";
17 return "Dungeon Room";
19 return "Dungeon Object";
21 return "Dungeon Sprite";
23 return "Dungeon Entrance";
25 return "Overworld Map";
27 return "Overworld Tile";
29 return "Overworld Sprite";
31 return "Overworld Entrance";
33 return "Overworld Exit";
35 return "Overworld Item";
37 return "Graphics Sheet";
39 return "Palette";
40 default:
41 return "Unknown";
42 }
43}
44
48
52
54 switch (selection_.type) {
57 break;
60 break;
63 break;
66 break;
69 break;
72 break;
75 break;
78 break;
81 break;
84 break;
87 break;
90 break;
93 break;
94 }
95
96 // Advanced options toggle
97 ImGui::Spacing();
98 ImGui::Separator();
99 ImGui::Spacing();
100 ImGui::Checkbox("Show Advanced", &show_advanced_);
101 ImGui::SameLine();
102 ImGui::Checkbox("Raw Data", &show_raw_data_);
103}
104
106 const auto& theme = gui::ThemeManager::Get().GetCurrentTheme();
107
108 ImGui::PushStyleColor(ImGuiCol_Text, gui::GetTextDisabledVec4());
109 ImGui::Text(ICON_MD_TOUCH_APP " Select an Item");
110 ImGui::PopStyleColor();
111
112 ImGui::Spacing();
113 ImGui::TextWrapped(
114 "Click on an object in the editor to view and edit its properties.");
115
116 ImGui::Spacing();
117 ImGui::Separator();
118 ImGui::Spacing();
119
120 // Show quick reference for what can be selected
121 ImGui::TextDisabled("Selectable Items:");
122 ImGui::BulletText("Dungeon: Rooms, Objects, Sprites");
123 ImGui::BulletText("Overworld: Maps, Tiles, Entities");
124 ImGui::BulletText("Graphics: Sheets, Palettes");
125}
126
128 const char* title) {
129 ImGui::PushStyleColor(ImGuiCol_Text, gui::GetPrimaryVec4());
130 ImGui::Text("%s", icon);
131 ImGui::PopStyleColor();
132 ImGui::SameLine();
133 ImGui::Text("%s", title);
134
135 if (!selection_.display_name.empty()) {
136 ImGui::SameLine();
137 ImGui::TextDisabled("- %s", selection_.display_name.c_str());
138 }
139
140 if (selection_.read_only) {
141 ImGui::SameLine();
142 ImGui::TextDisabled("(Read Only)");
143 }
144
145 ImGui::Separator();
146 ImGui::Spacing();
147}
148
149bool SelectionPropertiesPanel::DrawPositionEditor(const char* label, int* x,
150 int* y, int min_val,
151 int max_val) {
152 bool changed = false;
153 ImGui::PushID(label);
154
155 ImGui::Text("%s", label);
156 ImGui::PushItemWidth(80);
157
158 ImGui::Text("X:");
159 ImGui::SameLine();
160 if (ImGui::InputInt("##X", x, 1, 8)) {
161 *x = std::clamp(*x, min_val, max_val);
162 changed = true;
163 }
164
165 ImGui::SameLine();
166 ImGui::Text("Y:");
167 ImGui::SameLine();
168 if (ImGui::InputInt("##Y", y, 1, 8)) {
169 *y = std::clamp(*y, min_val, max_val);
170 changed = true;
171 }
172
173 ImGui::PopItemWidth();
174 ImGui::PopID();
175
176 return changed;
177}
178
179bool SelectionPropertiesPanel::DrawSizeEditor(const char* label, int* width,
180 int* height) {
181 bool changed = false;
182 ImGui::PushID(label);
183
184 ImGui::Text("%s", label);
185 ImGui::PushItemWidth(80);
186
187 ImGui::Text("W:");
188 ImGui::SameLine();
189 if (ImGui::InputInt("##W", width, 1, 8)) {
190 *width = std::max(1, *width);
191 changed = true;
192 }
193
194 ImGui::SameLine();
195 ImGui::Text("H:");
196 ImGui::SameLine();
197 if (ImGui::InputInt("##H", height, 1, 8)) {
198 *height = std::max(1, *height);
199 changed = true;
200 }
201
202 ImGui::PopItemWidth();
203 ImGui::PopID();
204
205 return changed;
206}
207
209 uint8_t* value,
210 const char* tooltip) {
211 bool changed = false;
212 int val = *value;
213
214 ImGui::PushItemWidth(80);
215 if (ImGui::InputInt(label, &val, 1, 16)) {
216 *value = static_cast<uint8_t>(std::clamp(val, 0, 255));
217 changed = true;
218 }
219 ImGui::PopItemWidth();
220
221 if (tooltip && ImGui::IsItemHovered()) {
222 ImGui::SetTooltip("%s", tooltip);
223 }
224
225 return changed;
226}
227
229 uint16_t* value,
230 const char* tooltip) {
231 bool changed = false;
232 int val = *value;
233
234 ImGui::PushItemWidth(100);
235 if (ImGui::InputInt(label, &val, 1, 256)) {
236 *value = static_cast<uint16_t>(std::clamp(val, 0, 65535));
237 changed = true;
238 }
239 ImGui::PopItemWidth();
240
241 if (tooltip && ImGui::IsItemHovered()) {
242 ImGui::SetTooltip("%s", tooltip);
243 }
244
245 return changed;
246}
247
249 int* current_item,
250 const char* const items[],
251 int items_count) {
252 return ImGui::Combo(label, current_item, items, items_count);
253}
254
256 uint8_t* flags,
257 const char* const flag_names[],
258 int flag_count) {
259 bool changed = false;
260
261 if (ImGui::TreeNode(label)) {
262 for (int i = 0; i < flag_count && i < 8; ++i) {
263 bool bit_set = (*flags >> i) & 1;
264 if (ImGui::Checkbox(flag_names[i], &bit_set)) {
265 if (bit_set) {
266 *flags |= (1 << i);
267 } else {
268 *flags &= ~(1 << i);
269 }
270 changed = true;
271 }
272 }
273 ImGui::TreePop();
274 }
275
276 return changed;
277}
278
280 const char* value) {
281 ImGui::Text("%s:", label);
282 ImGui::SameLine();
283 ImGui::TextDisabled("%s", value);
284}
285
287 uint32_t value, int digits) {
288 ImGui::Text("%s:", label);
289 ImGui::SameLine();
290 char fmt[16];
291 snprintf(fmt, sizeof(fmt), "0x%%0%dX", digits);
292 ImGui::TextDisabled(fmt, value);
293}
294
300
301// ============================================================================
302// Type-specific property editors
303// ============================================================================
304
306 DrawPropertyHeader(ICON_MD_GRID_VIEW, "Dungeon Room");
307
308 if (ImGui::CollapsingHeader("Identity", ImGuiTreeNodeFlags_DefaultOpen)) {
309 DrawReadOnlyHex("Room ID", selection_.id, 4);
311 }
312
313 if (ImGui::CollapsingHeader("Layout", ImGuiTreeNodeFlags_DefaultOpen)) {
314 // Placeholder - actual implementation would use real room data
315 ImGui::TextDisabled("Layout properties would appear here");
316 ImGui::BulletText("Floor 1 tileset");
317 ImGui::BulletText("Floor 2 tileset");
318 ImGui::BulletText("Sprite graphics");
319 ImGui::BulletText("Room palette");
320 }
321
322 if (show_advanced_ &&
323 ImGui::CollapsingHeader("Advanced", ImGuiTreeNodeFlags_None)) {
324 ImGui::TextDisabled("Advanced room settings");
325 ImGui::BulletText("Room effects");
326 ImGui::BulletText("Message ID");
327 ImGui::BulletText("Tag 1 / Tag 2");
328 }
329}
330
332 DrawPropertyHeader(ICON_MD_CATEGORY, "Dungeon Object");
333
334 if (ImGui::CollapsingHeader("Transform", ImGuiTreeNodeFlags_DefaultOpen)) {
335 // Placeholder for actual object data
336 int x = 0, y = 0;
337 if (DrawPositionEditor("Position", &x, &y, 0, 63)) {
338 NotifyChange();
339 }
340
341 int w = 1, h = 1;
342 if (DrawSizeEditor("Size", &w, &h)) {
343 NotifyChange();
344 }
345 }
346
347 if (ImGui::CollapsingHeader("Object Type", ImGuiTreeNodeFlags_DefaultOpen)) {
348 ImGui::TextDisabled("Object ID: --");
349 ImGui::TextDisabled("Subtype: --");
350 ImGui::TextDisabled("Layer: --");
351 }
352
353 if (show_raw_data_ &&
354 ImGui::CollapsingHeader("Raw Data", ImGuiTreeNodeFlags_None)) {
355 ImGui::TextDisabled("Byte 1: 0x00");
356 ImGui::TextDisabled("Byte 2: 0x00");
357 ImGui::TextDisabled("Byte 3: 0x00");
358 }
359}
360
362 DrawPropertyHeader(ICON_MD_PEST_CONTROL, "Dungeon Sprite");
363
364 if (ImGui::CollapsingHeader("Position", ImGuiTreeNodeFlags_DefaultOpen)) {
365 int x = 0, y = 0;
366 if (DrawPositionEditor("Position", &x, &y, 0, 255)) {
367 NotifyChange();
368 }
369 }
370
371 if (ImGui::CollapsingHeader("Sprite Data", ImGuiTreeNodeFlags_DefaultOpen)) {
372 ImGui::TextDisabled("Sprite ID: --");
373 ImGui::TextDisabled("Subtype: --");
374 ImGui::TextDisabled("Overlord: No");
375 }
376}
377
379 DrawPropertyHeader(ICON_MD_DOOR_FRONT, "Dungeon Entrance");
380
381 if (ImGui::CollapsingHeader("Target", ImGuiTreeNodeFlags_DefaultOpen)) {
382 ImGui::TextDisabled("Target Room: --");
383 ImGui::TextDisabled("Entry Position: --");
384 }
385
386 if (ImGui::CollapsingHeader("Properties", ImGuiTreeNodeFlags_DefaultOpen)) {
387 ImGui::TextDisabled("Door Type: --");
388 ImGui::TextDisabled("Direction: --");
389 }
390}
391
393 DrawPropertyHeader(ICON_MD_MAP, "Overworld Map");
394
395 if (ImGui::CollapsingHeader("Identity", ImGuiTreeNodeFlags_DefaultOpen)) {
396 DrawReadOnlyHex("Map ID", selection_.id, 2);
398 }
399
400 if (ImGui::CollapsingHeader("Graphics", ImGuiTreeNodeFlags_DefaultOpen)) {
401 ImGui::TextDisabled("GFX Set: --");
402 ImGui::TextDisabled("Palette: --");
403 ImGui::TextDisabled("Sprite GFX: --");
404 ImGui::TextDisabled("Sprite Palette: --");
405 }
406
407 if (ImGui::CollapsingHeader("Properties", ImGuiTreeNodeFlags_DefaultOpen)) {
408 ImGui::TextDisabled("Large Map: No");
409 ImGui::TextDisabled("Area Size: 1x1");
410 ImGui::TextDisabled("Parent ID: --");
411 }
412}
413
415 DrawPropertyHeader(ICON_MD_GRID_ON, "Overworld Tile");
416
417 if (ImGui::CollapsingHeader("Tile Info", ImGuiTreeNodeFlags_DefaultOpen)) {
418 DrawReadOnlyHex("Tile16 ID", selection_.id, 4);
419 ImGui::TextDisabled("Position: --");
420 }
421
422 if (show_advanced_ &&
423 ImGui::CollapsingHeader("Tile16 Data", ImGuiTreeNodeFlags_None)) {
424 ImGui::TextDisabled("TL: 0x0000");
425 ImGui::TextDisabled("TR: 0x0000");
426 ImGui::TextDisabled("BL: 0x0000");
427 ImGui::TextDisabled("BR: 0x0000");
428 }
429}
430
432 DrawPropertyHeader(ICON_MD_PEST_CONTROL, "Overworld Sprite");
433
434 if (ImGui::CollapsingHeader("Position", ImGuiTreeNodeFlags_DefaultOpen)) {
435 int x = 0, y = 0;
436 if (DrawPositionEditor("Position", &x, &y, 0, 8191)) {
437 NotifyChange();
438 }
439 }
440
441 if (ImGui::CollapsingHeader("Sprite", ImGuiTreeNodeFlags_DefaultOpen)) {
442 ImGui::TextDisabled("Sprite ID: --");
443 ImGui::TextDisabled("Map ID: --");
444 }
445}
446
448 DrawPropertyHeader(ICON_MD_DOOR_FRONT, "Overworld Entrance");
449
450 if (ImGui::CollapsingHeader("Position", ImGuiTreeNodeFlags_DefaultOpen)) {
451 int x = 0, y = 0;
452 if (DrawPositionEditor("Position", &x, &y)) {
453 NotifyChange();
454 }
455 }
456
457 if (ImGui::CollapsingHeader("Target", ImGuiTreeNodeFlags_DefaultOpen)) {
458 ImGui::TextDisabled("Entrance ID: --");
459 ImGui::TextDisabled("Target Room: --");
460 }
461}
462
464 DrawPropertyHeader(ICON_MD_EXIT_TO_APP, "Overworld Exit");
465
466 if (ImGui::CollapsingHeader("Exit Point", ImGuiTreeNodeFlags_DefaultOpen)) {
467 ImGui::TextDisabled("Exit ID: --");
468 int x = 0, y = 0;
469 if (DrawPositionEditor("Position", &x, &y)) {
470 NotifyChange();
471 }
472 }
473
474 if (ImGui::CollapsingHeader("Target Map", ImGuiTreeNodeFlags_DefaultOpen)) {
475 ImGui::TextDisabled("Room ID: --");
476 ImGui::TextDisabled("Target Map: --");
477 }
478}
479
481 DrawPropertyHeader(ICON_MD_STAR, "Overworld Item");
482
483 if (ImGui::CollapsingHeader("Position", ImGuiTreeNodeFlags_DefaultOpen)) {
484 int x = 0, y = 0;
485 if (DrawPositionEditor("Position", &x, &y)) {
486 NotifyChange();
487 }
488 }
489
490 if (ImGui::CollapsingHeader("Item Data", ImGuiTreeNodeFlags_DefaultOpen)) {
491 ImGui::TextDisabled("Item ID: --");
492 ImGui::TextDisabled("Map ID: --");
493 }
494}
495
497 DrawPropertyHeader(ICON_MD_IMAGE, "Graphics Sheet");
498
499 if (ImGui::CollapsingHeader("Sheet Info", ImGuiTreeNodeFlags_DefaultOpen)) {
500 DrawReadOnlyHex("Sheet ID", selection_.id, 2);
501 ImGui::TextDisabled("Size: 128x32");
502 ImGui::TextDisabled("BPP: 4");
503 }
504
505 if (show_advanced_ &&
506 ImGui::CollapsingHeader("ROM Location", ImGuiTreeNodeFlags_None)) {
507 ImGui::TextDisabled("Address: --");
508 ImGui::TextDisabled("Compressed: Yes");
509 ImGui::TextDisabled("Original Size: --");
510 }
511}
512
515
516 if (ImGui::CollapsingHeader("Palette Info", ImGuiTreeNodeFlags_DefaultOpen)) {
517 DrawReadOnlyHex("Palette ID", selection_.id, 2);
518 ImGui::TextDisabled("Colors: 16");
519 }
520
521 if (ImGui::CollapsingHeader("Colors", ImGuiTreeNodeFlags_DefaultOpen)) {
522 // Would show color swatches in actual implementation
523 ImGui::TextDisabled("Color editing not yet implemented");
524 }
525}
526
527} // namespace editor
528} // namespace yaze
bool DrawByteProperty(const char *label, uint8_t *value, const char *tooltip=nullptr)
bool DrawFlagsProperty(const char *label, uint8_t *flags, const char *const flag_names[], int flag_count)
bool DrawPositionEditor(const char *label, int *x, int *y, int min_val=0, int max_val=512)
void DrawReadOnlyText(const char *label, const char *value)
bool DrawSizeEditor(const char *label, int *width, int *height)
bool DrawWordProperty(const char *label, uint16_t *value, const char *tooltip=nullptr)
bool DrawComboProperty(const char *label, int *current_item, const char *const items[], int items_count)
void ClearSelection()
Clear the current selection.
void Draw()
Draw the properties panel content.
void DrawReadOnlyHex(const char *label, uint32_t value, int digits=4)
void DrawPropertyHeader(const char *icon, const char *title)
void SetSelection(const SelectionContext &context)
Set the current selection to display/edit.
const Theme & GetCurrentTheme() const
static ThemeManager & Get()
#define ICON_MD_GRID_VIEW
Definition icons.h:897
#define ICON_MD_EXIT_TO_APP
Definition icons.h:699
#define ICON_MD_STAR
Definition icons.h:1848
#define ICON_MD_MAP
Definition icons.h:1173
#define ICON_MD_GRID_ON
Definition icons.h:896
#define ICON_MD_DOOR_FRONT
Definition icons.h:613
#define ICON_MD_IMAGE
Definition icons.h:982
#define ICON_MD_PEST_CONTROL
Definition icons.h:1429
#define ICON_MD_TOUCH_APP
Definition icons.h:2000
#define ICON_MD_PALETTE
Definition icons.h:1370
#define ICON_MD_CATEGORY
Definition icons.h:382
const char * GetSelectionTypeName(SelectionType type)
Get a human-readable name for a selection type.
SelectionType
Types of entities that can be selected and edited.
ImVec4 GetPrimaryVec4()
ImVec4 GetTextDisabledVec4()
Holds information about the current selection.