5#include "absl/strings/str_cat.h"
6#include "absl/strings/str_format.h"
13#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);
189 std::snprintf(buffer,
sizeof(buffer),
"0x%X",
selection_.
id);
190 ImGui::SetClipboardText(buffer);
222 ImGui::BeginDisabled(no_selection);
232 SendAgentPrompt(
"Audit this selection for possible issues or conflicts.");
234 ImGui::EndDisabled();
236 ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
237 ImGui::SetTooltip(
"Select an object first to use agent actions");
242 std::string context = absl::StrFormat(
"Selection Type: %s",
248 context += absl::StrFormat(
"\nID: 0x%X",
selection_.
id);
254 context +=
"\nRead Only: true";
260 const char* intent)
const {
261 std::string prompt = intent ? intent :
"Review this selection.";
264 prompt +=
"\n\nProvide actionable steps inside Yaze where possible.";
281 bool changed =
false;
282 ImGui::PushID(label);
284 ImGui::Text(
"%s", label);
285 ImGui::PushItemWidth(80);
289 if (ImGui::InputInt(
"##X", x, 1, 8)) {
290 *x = std::clamp(*x, min_val, max_val);
297 if (ImGui::InputInt(
"##Y", y, 1, 8)) {
298 *y = std::clamp(*y, min_val, max_val);
302 ImGui::PopItemWidth();
310 bool changed =
false;
311 ImGui::PushID(label);
313 ImGui::Text(
"%s", label);
314 ImGui::PushItemWidth(80);
318 if (ImGui::InputInt(
"##W", width, 1, 8)) {
319 *width = std::max(1, *width);
326 if (ImGui::InputInt(
"##H", height, 1, 8)) {
327 *height = std::max(1, *height);
331 ImGui::PopItemWidth();
339 const char* tooltip) {
340 bool changed =
false;
343 ImGui::PushItemWidth(80);
344 if (ImGui::InputInt(label, &val, 1, 16)) {
345 *value =
static_cast<uint8_t
>(std::clamp(val, 0, 255));
348 ImGui::PopItemWidth();
350 if (tooltip && ImGui::IsItemHovered()) {
351 ImGui::SetTooltip(
"%s", tooltip);
359 const char* tooltip) {
360 bool changed =
false;
363 ImGui::PushItemWidth(100);
364 if (ImGui::InputInt(label, &val, 1, 256)) {
365 *value =
static_cast<uint16_t
>(std::clamp(val, 0, 65535));
368 ImGui::PopItemWidth();
370 if (tooltip && ImGui::IsItemHovered()) {
371 ImGui::SetTooltip(
"%s", tooltip);
379 const char*
const items[],
381 return ImGui::Combo(label, current_item, items, items_count);
386 const char*
const flag_names[],
388 bool changed =
false;
390 if (ImGui::TreeNode(label)) {
391 for (
int i = 0; i < flag_count && i < 8; ++i) {
392 bool bit_set = (*flags >> i) & 1;
393 if (ImGui::Checkbox(flag_names[i], &bit_set)) {
410 ImGui::Text(
"%s:", label);
412 ImGui::TextDisabled(
"%s", value);
416 uint32_t value,
int digits) {
417 ImGui::Text(
"%s:", label);
420 snprintf(fmt,
sizeof(fmt),
"0x%%0%dX", digits);
421 ImGui::TextDisabled(fmt, value);
438 ImGui::TextDisabled(
"No room data available.");
444 if (ImGui::CollapsingHeader(
"Identity", ImGuiTreeNodeFlags_DefaultOpen)) {
449 if (ImGui::CollapsingHeader(
"Graphics & Layout",
450 ImGuiTreeNodeFlags_DefaultOpen)) {
451 uint8_t blockset = room->blockset();
453 "Tile graphics and layout definition")) {
454 room->SetBlockset(blockset);
458 uint8_t palette = room->palette();
460 room->SetPalette(palette);
464 uint8_t spriteset = room->spriteset();
466 "Enemy graphics and behavior")) {
467 room->SetSpriteset(spriteset);
473 ImGui::CollapsingHeader(
"Advanced Settings",
474 ImGuiTreeNodeFlags_DefaultOpen)) {
477 auto draw_tag_combo = [&](
const char* label,
zelda3::TagKey current,
479 std::string current_label =
481 if (ImGui::BeginCombo(label, current_label.c_str())) {
483 for (
int i = 0; i < static_cast<int>(vanilla_tags.size()); ++i) {
485 if (ImGui::Selectable(item_label.c_str(),
486 static_cast<int>(current) == i)) {
495 draw_tag_combo(
"Tag 1", room->tag1(),
497 draw_tag_combo(
"Tag 2", room->tag2(),
501 int effect =
static_cast<int>(room->effect());
503 std::vector<const char*> effect_ptrs;
504 for (
const auto& s : effects)
505 effect_ptrs.push_back(s.c_str());
507 if (ImGui::Combo(
"Effect", &effect, effect_ptrs.data(),
508 static_cast<int>(effect_ptrs.size()))) {
518 if (ImGui::CollapsingHeader(
"Transform", ImGuiTreeNodeFlags_DefaultOpen)) {
531 if (ImGui::CollapsingHeader(
"Object Type", ImGuiTreeNodeFlags_DefaultOpen)) {
532 ImGui::TextDisabled(
"Object ID: --");
533 ImGui::TextDisabled(
"Subtype: --");
534 ImGui::TextDisabled(
"Layer: --");
538 ImGui::CollapsingHeader(
"Raw Data", ImGuiTreeNodeFlags_None)) {
539 ImGui::TextDisabled(
"Byte 1: 0x00");
540 ImGui::TextDisabled(
"Byte 2: 0x00");
541 ImGui::TextDisabled(
"Byte 3: 0x00");
548 if (ImGui::CollapsingHeader(
"Position", ImGuiTreeNodeFlags_DefaultOpen)) {
555 if (ImGui::CollapsingHeader(
"Sprite Data", ImGuiTreeNodeFlags_DefaultOpen)) {
556 ImGui::TextDisabled(
"Sprite ID: --");
557 ImGui::TextDisabled(
"Subtype: --");
558 ImGui::TextDisabled(
"Overlord: No");
565 if (ImGui::CollapsingHeader(
"Target", ImGuiTreeNodeFlags_DefaultOpen)) {
566 ImGui::TextDisabled(
"Target Room: --");
567 ImGui::TextDisabled(
"Entry Position: --");
570 if (ImGui::CollapsingHeader(
"Properties", ImGuiTreeNodeFlags_DefaultOpen)) {
571 ImGui::TextDisabled(
"Door Type: --");
572 ImGui::TextDisabled(
"Direction: --");
579 if (ImGui::CollapsingHeader(
"Identity", ImGuiTreeNodeFlags_DefaultOpen)) {
584 if (ImGui::CollapsingHeader(
"Graphics", ImGuiTreeNodeFlags_DefaultOpen)) {
585 ImGui::TextDisabled(
"GFX Set: --");
586 ImGui::TextDisabled(
"Palette: --");
587 ImGui::TextDisabled(
"Sprite GFX: --");
588 ImGui::TextDisabled(
"Sprite Palette: --");
591 if (ImGui::CollapsingHeader(
"Properties", ImGuiTreeNodeFlags_DefaultOpen)) {
592 ImGui::TextDisabled(
"Large Map: No");
593 ImGui::TextDisabled(
"Area Size: 1x1");
594 ImGui::TextDisabled(
"Parent ID: --");
601 if (ImGui::CollapsingHeader(
"Tile Info", ImGuiTreeNodeFlags_DefaultOpen)) {
603 ImGui::TextDisabled(
"Position: --");
607 ImGui::CollapsingHeader(
"Tile16 Data", ImGuiTreeNodeFlags_None)) {
608 ImGui::TextDisabled(
"TL: 0x0000");
609 ImGui::TextDisabled(
"TR: 0x0000");
610 ImGui::TextDisabled(
"BL: 0x0000");
611 ImGui::TextDisabled(
"BR: 0x0000");
618 if (ImGui::CollapsingHeader(
"Position", ImGuiTreeNodeFlags_DefaultOpen)) {
625 if (ImGui::CollapsingHeader(
"Sprite", ImGuiTreeNodeFlags_DefaultOpen)) {
626 ImGui::TextDisabled(
"Sprite ID: --");
627 ImGui::TextDisabled(
"Map ID: --");
634 if (ImGui::CollapsingHeader(
"Position", ImGuiTreeNodeFlags_DefaultOpen)) {
641 if (ImGui::CollapsingHeader(
"Target", ImGuiTreeNodeFlags_DefaultOpen)) {
642 ImGui::TextDisabled(
"Entrance ID: --");
643 ImGui::TextDisabled(
"Target Room: --");
650 if (ImGui::CollapsingHeader(
"Exit Point", ImGuiTreeNodeFlags_DefaultOpen)) {
651 ImGui::TextDisabled(
"Exit ID: --");
658 if (ImGui::CollapsingHeader(
"Target Map", ImGuiTreeNodeFlags_DefaultOpen)) {
659 ImGui::TextDisabled(
"Room ID: --");
660 ImGui::TextDisabled(
"Target Map: --");
667 if (ImGui::CollapsingHeader(
"Position", ImGuiTreeNodeFlags_DefaultOpen)) {
674 if (ImGui::CollapsingHeader(
"Item Data", ImGuiTreeNodeFlags_DefaultOpen)) {
675 ImGui::TextDisabled(
"Item ID: --");
676 ImGui::TextDisabled(
"Map ID: --");
683 if (ImGui::CollapsingHeader(
"Sheet Info", ImGuiTreeNodeFlags_DefaultOpen)) {
685 ImGui::TextDisabled(
"Size: 128x32");
686 ImGui::TextDisabled(
"BPP: 4");
690 ImGui::CollapsingHeader(
"ROM Location", ImGuiTreeNodeFlags_None)) {
691 ImGui::TextDisabled(
"Address: --");
692 ImGui::TextDisabled(
"Compressed: Yes");
693 ImGui::TextDisabled(
"Original Size: --");
700 if (ImGui::CollapsingHeader(
"Palette Info", ImGuiTreeNodeFlags_DefaultOpen)) {
702 ImGui::TextDisabled(
"Colors: 16");
705 if (ImGui::CollapsingHeader(
"Colors", ImGuiTreeNodeFlags_DefaultOpen)) {
707 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()