5#include "absl/strings/str_cat.h"
6#include "absl/strings/str_format.h"
14#include "imgui/imgui.h"
27 return "Dungeon Room";
29 return "Dungeon Object";
31 return "Dungeon Sprite";
33 return "Dungeon Entrance";
35 return "Overworld Map";
37 return "Overworld Tile";
39 return "Overworld Sprite";
41 return "Overworld Entrance";
43 return "Overworld Exit";
45 return "Overworld Item";
47 return "Graphics Sheet";
128 "Click on an object in the editor to view and edit its properties.");
135 ImGui::TextDisabled(
"Selectable Items:");
136 ImGui::BulletText(
"Dungeon: Rooms, Objects, Sprites");
137 ImGui::BulletText(
"Overworld: Maps, Tiles, Entities");
138 ImGui::BulletText(
"Graphics: Sheets, Palettes");
143 std::string full_title = absl::StrFormat(
"%s %s", icon, title);
148 absl::StrAppend(&full_title,
" (Read Only)");
171 ImGui::TextDisabled(
"Read Only");
175 bool wrote_action =
false;
179 std::snprintf(buffer,
sizeof(buffer),
"%d",
selection_.
id);
180 ImGui::SetClipboardText(buffer);
185 if (wrote_action) ImGui::SameLine();
188 std::snprintf(buffer,
sizeof(buffer),
"0x%X",
selection_.
id);
189 ImGui::SetClipboardText(buffer);
194 if (wrote_action) ImGui::SameLine();
220 ImGui::BeginDisabled(no_selection);
230 SendAgentPrompt(
"Audit this selection for possible issues or conflicts.");
232 ImGui::EndDisabled();
234 ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
235 ImGui::SetTooltip(
"Select an object first to use agent actions");
240 std::string context = absl::StrFormat(
"Selection Type: %s",
246 context += absl::StrFormat(
"\nID: 0x%X",
selection_.
id);
249 context += absl::StrFormat(
"\nSecondary ID: 0x%X",
253 context +=
"\nRead Only: true";
259 std::string prompt = intent ? intent :
"Review this selection.";
262 prompt +=
"\n\nProvide actionable steps inside Yaze where possible.";
279 bool changed =
false;
280 ImGui::PushID(label);
282 ImGui::Text(
"%s", label);
283 ImGui::PushItemWidth(80);
287 if (ImGui::InputInt(
"##X", x, 1, 8)) {
288 *x = std::clamp(*x, min_val, max_val);
295 if (ImGui::InputInt(
"##Y", y, 1, 8)) {
296 *y = std::clamp(*y, min_val, max_val);
300 ImGui::PopItemWidth();
308 bool changed =
false;
309 ImGui::PushID(label);
311 ImGui::Text(
"%s", label);
312 ImGui::PushItemWidth(80);
316 if (ImGui::InputInt(
"##W", width, 1, 8)) {
317 *width = std::max(1, *width);
324 if (ImGui::InputInt(
"##H", height, 1, 8)) {
325 *height = std::max(1, *height);
329 ImGui::PopItemWidth();
337 const char* tooltip) {
338 bool changed =
false;
341 ImGui::PushItemWidth(80);
342 if (ImGui::InputInt(label, &val, 1, 16)) {
343 *value =
static_cast<uint8_t
>(std::clamp(val, 0, 255));
346 ImGui::PopItemWidth();
348 if (tooltip && ImGui::IsItemHovered()) {
349 ImGui::SetTooltip(
"%s", tooltip);
357 const char* tooltip) {
358 bool changed =
false;
361 ImGui::PushItemWidth(100);
362 if (ImGui::InputInt(label, &val, 1, 256)) {
363 *value =
static_cast<uint16_t
>(std::clamp(val, 0, 65535));
366 ImGui::PopItemWidth();
368 if (tooltip && ImGui::IsItemHovered()) {
369 ImGui::SetTooltip(
"%s", tooltip);
377 const char*
const items[],
379 return ImGui::Combo(label, current_item, items, items_count);
384 const char*
const flag_names[],
386 bool changed =
false;
388 if (ImGui::TreeNode(label)) {
389 for (
int i = 0; i < flag_count && i < 8; ++i) {
390 bool bit_set = (*flags >> i) & 1;
391 if (ImGui::Checkbox(flag_names[i], &bit_set)) {
408 ImGui::Text(
"%s:", label);
410 ImGui::TextDisabled(
"%s", value);
414 uint32_t value,
int digits) {
415 ImGui::Text(
"%s:", label);
418 snprintf(fmt,
sizeof(fmt),
"0x%%0%dX", digits);
419 ImGui::TextDisabled(fmt, value);
436 ImGui::TextDisabled(
"No room data available.");
442 if (ImGui::CollapsingHeader(
"Identity", ImGuiTreeNodeFlags_DefaultOpen)) {
447 if (ImGui::CollapsingHeader(
"Graphics & Layout", ImGuiTreeNodeFlags_DefaultOpen)) {
448 uint8_t blockset = room->blockset();
449 if (
DrawByteProperty(
"Blockset", &blockset,
"Tile graphics and layout definition")) {
450 room->SetBlockset(blockset);
454 uint8_t palette = room->palette();
456 room->SetPalette(palette);
460 uint8_t spriteset = room->spriteset();
461 if (
DrawByteProperty(
"Spriteset", &spriteset,
"Enemy graphics and behavior")) {
462 room->SetSpriteset(spriteset);
468 ImGui::CollapsingHeader(
"Advanced Settings", ImGuiTreeNodeFlags_DefaultOpen)) {
473 if (ImGui::BeginCombo(label, current_label.c_str())) {
475 for (
int i = 0; i < static_cast<int>(vanilla_tags.size()); ++i) {
477 if (ImGui::Selectable(item_label.c_str(),
static_cast<int>(current) == i)) {
486 draw_tag_combo(
"Tag 1", room->tag1(), [&](
zelda3::TagKey val) { room->SetTag1(val); });
487 draw_tag_combo(
"Tag 2", room->tag2(), [&](
zelda3::TagKey val) { room->SetTag2(val); });
490 int effect =
static_cast<int>(room->effect());
492 std::vector<const char*> effect_ptrs;
493 for (
const auto& s : effects) effect_ptrs.push_back(s.c_str());
495 if (ImGui::Combo(
"Effect", &effect, effect_ptrs.data(),
static_cast<int>(effect_ptrs.size()))) {
505 if (ImGui::CollapsingHeader(
"Transform", ImGuiTreeNodeFlags_DefaultOpen)) {
518 if (ImGui::CollapsingHeader(
"Object Type", ImGuiTreeNodeFlags_DefaultOpen)) {
519 ImGui::TextDisabled(
"Object ID: --");
520 ImGui::TextDisabled(
"Subtype: --");
521 ImGui::TextDisabled(
"Layer: --");
525 ImGui::CollapsingHeader(
"Raw Data", ImGuiTreeNodeFlags_None)) {
526 ImGui::TextDisabled(
"Byte 1: 0x00");
527 ImGui::TextDisabled(
"Byte 2: 0x00");
528 ImGui::TextDisabled(
"Byte 3: 0x00");
535 if (ImGui::CollapsingHeader(
"Position", ImGuiTreeNodeFlags_DefaultOpen)) {
542 if (ImGui::CollapsingHeader(
"Sprite Data", ImGuiTreeNodeFlags_DefaultOpen)) {
543 ImGui::TextDisabled(
"Sprite ID: --");
544 ImGui::TextDisabled(
"Subtype: --");
545 ImGui::TextDisabled(
"Overlord: No");
552 if (ImGui::CollapsingHeader(
"Target", ImGuiTreeNodeFlags_DefaultOpen)) {
553 ImGui::TextDisabled(
"Target Room: --");
554 ImGui::TextDisabled(
"Entry Position: --");
557 if (ImGui::CollapsingHeader(
"Properties", ImGuiTreeNodeFlags_DefaultOpen)) {
558 ImGui::TextDisabled(
"Door Type: --");
559 ImGui::TextDisabled(
"Direction: --");
566 if (ImGui::CollapsingHeader(
"Identity", ImGuiTreeNodeFlags_DefaultOpen)) {
571 if (ImGui::CollapsingHeader(
"Graphics", ImGuiTreeNodeFlags_DefaultOpen)) {
572 ImGui::TextDisabled(
"GFX Set: --");
573 ImGui::TextDisabled(
"Palette: --");
574 ImGui::TextDisabled(
"Sprite GFX: --");
575 ImGui::TextDisabled(
"Sprite Palette: --");
578 if (ImGui::CollapsingHeader(
"Properties", ImGuiTreeNodeFlags_DefaultOpen)) {
579 ImGui::TextDisabled(
"Large Map: No");
580 ImGui::TextDisabled(
"Area Size: 1x1");
581 ImGui::TextDisabled(
"Parent ID: --");
588 if (ImGui::CollapsingHeader(
"Tile Info", ImGuiTreeNodeFlags_DefaultOpen)) {
590 ImGui::TextDisabled(
"Position: --");
594 ImGui::CollapsingHeader(
"Tile16 Data", ImGuiTreeNodeFlags_None)) {
595 ImGui::TextDisabled(
"TL: 0x0000");
596 ImGui::TextDisabled(
"TR: 0x0000");
597 ImGui::TextDisabled(
"BL: 0x0000");
598 ImGui::TextDisabled(
"BR: 0x0000");
605 if (ImGui::CollapsingHeader(
"Position", ImGuiTreeNodeFlags_DefaultOpen)) {
612 if (ImGui::CollapsingHeader(
"Sprite", ImGuiTreeNodeFlags_DefaultOpen)) {
613 ImGui::TextDisabled(
"Sprite ID: --");
614 ImGui::TextDisabled(
"Map ID: --");
621 if (ImGui::CollapsingHeader(
"Position", ImGuiTreeNodeFlags_DefaultOpen)) {
628 if (ImGui::CollapsingHeader(
"Target", ImGuiTreeNodeFlags_DefaultOpen)) {
629 ImGui::TextDisabled(
"Entrance ID: --");
630 ImGui::TextDisabled(
"Target Room: --");
637 if (ImGui::CollapsingHeader(
"Exit Point", ImGuiTreeNodeFlags_DefaultOpen)) {
638 ImGui::TextDisabled(
"Exit ID: --");
645 if (ImGui::CollapsingHeader(
"Target Map", ImGuiTreeNodeFlags_DefaultOpen)) {
646 ImGui::TextDisabled(
"Room ID: --");
647 ImGui::TextDisabled(
"Target Map: --");
654 if (ImGui::CollapsingHeader(
"Position", ImGuiTreeNodeFlags_DefaultOpen)) {
661 if (ImGui::CollapsingHeader(
"Item Data", ImGuiTreeNodeFlags_DefaultOpen)) {
662 ImGui::TextDisabled(
"Item ID: --");
663 ImGui::TextDisabled(
"Map ID: --");
670 if (ImGui::CollapsingHeader(
"Sheet Info", ImGuiTreeNodeFlags_DefaultOpen)) {
672 ImGui::TextDisabled(
"Size: 128x32");
673 ImGui::TextDisabled(
"BPP: 4");
677 ImGui::CollapsingHeader(
"ROM Location", ImGuiTreeNodeFlags_None)) {
678 ImGui::TextDisabled(
"Address: --");
679 ImGui::TextDisabled(
"Compressed: Yes");
680 ImGui::TextDisabled(
"Original Size: --");
687 if (ImGui::CollapsingHeader(
"Palette Info", ImGuiTreeNodeFlags_DefaultOpen)) {
689 ImGui::TextDisabled(
"Colors: 16");
692 if (ImGui::CollapsingHeader(
"Colors", ImGuiTreeNodeFlags_DefaultOpen)) {
694 ImGui::TextDisabled(
"Color editing not yet implemented");
void DrawGraphicsSheetProperties()
void DrawDungeonEntranceProperties()
bool DrawByteProperty(const char *label, uint8_t *value, const char *tooltip=nullptr)
ChangeCallback on_change_
void DrawDungeonRoomProperties()
bool DrawFlagsProperty(const char *label, uint8_t *flags, const char *const flag_names[], int flag_count)
void DrawOverworldExitProperties()
std::function< void()> focus_agent_panel_
void DrawSelectionSummary()
std::string BuildAgentPrompt(const char *intent) const
void SendAgentPrompt(const char *intent)
void DrawOverworldItemProperties()
void DrawOverworldMapProperties()
bool DrawPositionEditor(const char *label, int *x, int *y, int min_val=0, int max_val=512)
void DrawOverworldTileProperties()
std::function< void(const std::string &) send_to_agent_)
SelectionContext selection_
std::string BuildSelectionContext() const
void DrawReadOnlyText(const char *label, const char *value)
void DrawOverworldSpriteProperties()
bool DrawSizeEditor(const char *label, int *width, int *height)
bool DrawWordProperty(const char *label, uint16_t *value, const char *tooltip=nullptr)
void DrawDungeonObjectProperties()
void DrawDungeonSpriteProperties()
void DrawPaletteProperties()
bool DrawComboProperty(const char *label, int *current_item, const char *const items[], int items_count)
void DrawOverworldEntranceProperties()
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
#define ICON_MD_EXIT_TO_APP
#define ICON_MD_DOOR_FRONT
#define ICON_MD_PEST_CONTROL
#define ICON_MD_TOUCH_APP
#define ICON_MD_SMART_TOY
const char * GetSelectionTypeName(SelectionType type)
Get a human-readable name for a selection type.
SelectionType
Types of entities that can be selected and edited.
void ColoredText(const char *text, const ImVec4 &color)
bool ThemedButton(const char *label, const ImVec2 &size, const char *panel_id, const char *anim_id)
Draw a standard text button with theme colors.
void SectionHeader(const char *icon, const char *label, const ImVec4 &color)
ImVec4 GetTextDisabledVec4()
void ColoredTextF(const ImVec4 &color, const char *fmt,...)
std::string GetRoomTagLabel(int id)
Convenience function to get a room tag label.
Holds information about the current selection.
static const std::vector< std::string > & GetRoomEffectNames()
static const std::vector< std::string > & GetRoomTagNames()