6#include "absl/strings/str_cat.h"
7#include "absl/strings/str_format.h"
14#include "imgui/imgui.h"
28 return "Dungeon Room";
30 return "Dungeon Object";
32 return "Dungeon Sprite";
34 return "Dungeon Entrance";
36 return "Overworld Map";
38 return "Overworld Tile";
40 return "Overworld Sprite";
42 return "Overworld Entrance";
44 return "Overworld Exit";
46 return "Overworld Item";
48 return "Graphics Sheet";
129 tr(
"Click on an object in the editor to view and edit its properties."));
136 ImGui::TextDisabled(tr(
"Selectable Items:"));
137 ImGui::BulletText(tr(
"Dungeon: Rooms, Objects, Sprites"));
138 ImGui::BulletText(tr(
"Overworld: Maps, Tiles, Entities"));
139 ImGui::BulletText(tr(
"Graphics: Sheets, Palettes"));
144 std::string full_title = absl::StrFormat(
"%s %s", icon, title);
149 absl::StrAppend(&full_title,
" (Read Only)");
172 ImGui::TextDisabled(tr(
"Read Only"));
176 bool wrote_action =
false;
180 std::snprintf(buffer,
sizeof(buffer),
"%d",
selection_.
id);
181 ImGui::SetClipboardText(buffer);
190 std::snprintf(buffer,
sizeof(buffer),
"0x%X",
selection_.
id);
191 ImGui::SetClipboardText(buffer);
223 ImGui::BeginDisabled(no_selection);
233 SendAgentPrompt(
"Audit this selection for possible issues or conflicts.");
235 ImGui::EndDisabled();
237 ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
238 ImGui::SetTooltip(tr(
"Select an object first to use agent actions"));
243 std::string context = absl::StrFormat(
"Selection Type: %s",
249 context += absl::StrFormat(
"\nID: 0x%X",
selection_.
id);
255 context +=
"\nRead Only: true";
261 const char* intent)
const {
262 std::string prompt = intent ? intent :
"Review this selection.";
265 prompt +=
"\n\nProvide actionable steps inside Yaze where possible.";
282 bool changed =
false;
283 ImGui::PushID(label);
285 ImGui::Text(
"%s", label);
286 ImGui::PushItemWidth(80);
288 ImGui::Text(tr(
"X:"));
290 if (ImGui::InputInt(
"##X", x, 1, 8)) {
291 *x = std::clamp(*x, min_val, max_val);
296 ImGui::Text(tr(
"Y:"));
298 if (ImGui::InputInt(
"##Y", y, 1, 8)) {
299 *y = std::clamp(*y, min_val, max_val);
303 ImGui::PopItemWidth();
311 bool changed =
false;
312 ImGui::PushID(label);
314 ImGui::Text(
"%s", label);
315 ImGui::PushItemWidth(80);
317 ImGui::Text(tr(
"W:"));
319 if (ImGui::InputInt(
"##W", width, 1, 8)) {
320 *width = std::max(1, *width);
325 ImGui::Text(tr(
"H:"));
327 if (ImGui::InputInt(
"##H", height, 1, 8)) {
328 *height = std::max(1, *height);
332 ImGui::PopItemWidth();
340 const char* tooltip) {
341 bool changed =
false;
344 ImGui::PushItemWidth(80);
345 if (ImGui::InputInt(label, &val, 1, 16)) {
346 *value =
static_cast<uint8_t
>(std::clamp(val, 0, 255));
349 ImGui::PopItemWidth();
351 if (tooltip && ImGui::IsItemHovered()) {
352 ImGui::SetTooltip(
"%s", tooltip);
360 const char* tooltip) {
361 bool changed =
false;
364 ImGui::PushItemWidth(100);
365 if (ImGui::InputInt(label, &val, 1, 256)) {
366 *value =
static_cast<uint16_t
>(std::clamp(val, 0, 65535));
369 ImGui::PopItemWidth();
371 if (tooltip && ImGui::IsItemHovered()) {
372 ImGui::SetTooltip(
"%s", tooltip);
380 const char*
const items[],
382 return ImGui::Combo(label, current_item, items, items_count);
387 const char*
const flag_names[],
389 bool changed =
false;
391 if (ImGui::TreeNode(label)) {
392 for (
int i = 0; i < flag_count && i < 8; ++i) {
393 bool bit_set = (*flags >> i) & 1;
394 if (ImGui::Checkbox(flag_names[i], &bit_set)) {
411 ImGui::Text(
"%s:", label);
413 ImGui::TextDisabled(
"%s", value);
417 uint32_t value,
int digits) {
418 ImGui::Text(
"%s:", label);
421 snprintf(fmt,
sizeof(fmt),
"0x%%0%dX", digits);
422 ImGui::TextDisabled(fmt, value);
439 ImGui::TextDisabled(tr(
"No room data available."));
445 if (ImGui::CollapsingHeader(tr(
"Identity"), ImGuiTreeNodeFlags_DefaultOpen)) {
450 if (ImGui::CollapsingHeader(tr(
"Graphics & Layout"),
451 ImGuiTreeNodeFlags_DefaultOpen)) {
452 uint8_t blockset = room->blockset();
454 "Tile graphics and layout definition")) {
455 room->SetBlockset(blockset);
459 uint8_t palette = room->palette();
461 room->SetPalette(palette);
465 uint8_t spriteset = room->spriteset();
467 "Enemy graphics and behavior")) {
468 room->SetSpriteset(spriteset);
474 ImGui::CollapsingHeader(tr(
"Advanced Settings"),
475 ImGuiTreeNodeFlags_DefaultOpen)) {
478 auto draw_tag_combo = [&](
const char* label,
zelda3::TagKey current,
480 std::string current_label =
482 if (ImGui::BeginCombo(label, current_label.c_str())) {
484 for (
int i = 0; i < static_cast<int>(vanilla_tags.size()); ++i) {
486 if (ImGui::Selectable(item_label.c_str(),
487 static_cast<int>(current) == i)) {
496 draw_tag_combo(
"Tag 1", room->tag1(),
498 draw_tag_combo(
"Tag 2", room->tag2(),
502 int effect =
static_cast<int>(room->effect());
504 std::vector<const char*> effect_ptrs;
505 for (
const auto& s : effects)
506 effect_ptrs.push_back(s.c_str());
508 if (ImGui::Combo(tr(
"Effect"), &effect, effect_ptrs.data(),
509 static_cast<int>(effect_ptrs.size()))) {
519 if (ImGui::CollapsingHeader(tr(
"Transform"),
520 ImGuiTreeNodeFlags_DefaultOpen)) {
533 if (ImGui::CollapsingHeader(tr(
"Object Type"),
534 ImGuiTreeNodeFlags_DefaultOpen)) {
535 ImGui::TextDisabled(tr(
"Object ID: --"));
536 ImGui::TextDisabled(tr(
"Subtype: --"));
537 ImGui::TextDisabled(tr(
"Layer: --"));
541 ImGui::CollapsingHeader(tr(
"Raw Data"), ImGuiTreeNodeFlags_None)) {
542 ImGui::TextDisabled(tr(
"Byte 1: 0x00"));
543 ImGui::TextDisabled(tr(
"Byte 2: 0x00"));
544 ImGui::TextDisabled(tr(
"Byte 3: 0x00"));
551 if (ImGui::CollapsingHeader(tr(
"Position"), ImGuiTreeNodeFlags_DefaultOpen)) {
558 if (ImGui::CollapsingHeader(tr(
"Sprite Data"),
559 ImGuiTreeNodeFlags_DefaultOpen)) {
560 ImGui::TextDisabled(tr(
"Sprite ID: --"));
561 ImGui::TextDisabled(tr(
"Subtype: --"));
562 ImGui::TextDisabled(tr(
"Overlord: No"));
569 if (ImGui::CollapsingHeader(tr(
"Target"), ImGuiTreeNodeFlags_DefaultOpen)) {
570 ImGui::TextDisabled(tr(
"Target Room: --"));
571 ImGui::TextDisabled(tr(
"Entry Position: --"));
574 if (ImGui::CollapsingHeader(tr(
"Properties"),
575 ImGuiTreeNodeFlags_DefaultOpen)) {
576 ImGui::TextDisabled(tr(
"Door Type: --"));
577 ImGui::TextDisabled(tr(
"Direction: --"));
584 if (ImGui::CollapsingHeader(tr(
"Identity"), ImGuiTreeNodeFlags_DefaultOpen)) {
589 if (ImGui::CollapsingHeader(tr(
"Graphics"), ImGuiTreeNodeFlags_DefaultOpen)) {
590 ImGui::TextDisabled(tr(
"GFX Set: --"));
591 ImGui::TextDisabled(tr(
"Palette: --"));
592 ImGui::TextDisabled(tr(
"Sprite GFX: --"));
593 ImGui::TextDisabled(tr(
"Sprite Palette: --"));
596 if (ImGui::CollapsingHeader(tr(
"Properties"),
597 ImGuiTreeNodeFlags_DefaultOpen)) {
598 ImGui::TextDisabled(tr(
"Large Map: No"));
599 ImGui::TextDisabled(tr(
"Area Size: 1x1"));
600 ImGui::TextDisabled(tr(
"Parent ID: --"));
607 if (ImGui::CollapsingHeader(tr(
"Tile Info"),
608 ImGuiTreeNodeFlags_DefaultOpen)) {
610 ImGui::TextDisabled(tr(
"Position: --"));
614 ImGui::CollapsingHeader(tr(
"Tile16 Data"), ImGuiTreeNodeFlags_None)) {
615 ImGui::TextDisabled(tr(
"TL: 0x0000"));
616 ImGui::TextDisabled(tr(
"TR: 0x0000"));
617 ImGui::TextDisabled(tr(
"BL: 0x0000"));
618 ImGui::TextDisabled(tr(
"BR: 0x0000"));
625 if (ImGui::CollapsingHeader(tr(
"Position"), ImGuiTreeNodeFlags_DefaultOpen)) {
632 if (ImGui::CollapsingHeader(tr(
"Sprite"), ImGuiTreeNodeFlags_DefaultOpen)) {
633 ImGui::TextDisabled(tr(
"Sprite ID: --"));
634 ImGui::TextDisabled(tr(
"Map ID: --"));
641 if (ImGui::CollapsingHeader(tr(
"Position"), ImGuiTreeNodeFlags_DefaultOpen)) {
648 if (ImGui::CollapsingHeader(tr(
"Target"), ImGuiTreeNodeFlags_DefaultOpen)) {
649 ImGui::TextDisabled(tr(
"Entrance ID: --"));
650 ImGui::TextDisabled(tr(
"Target Room: --"));
657 if (ImGui::CollapsingHeader(tr(
"Exit Point"),
658 ImGuiTreeNodeFlags_DefaultOpen)) {
659 ImGui::TextDisabled(tr(
"Exit ID: --"));
666 if (ImGui::CollapsingHeader(tr(
"Target Map"),
667 ImGuiTreeNodeFlags_DefaultOpen)) {
668 ImGui::TextDisabled(tr(
"Room ID: --"));
669 ImGui::TextDisabled(tr(
"Target Map: --"));
676 if (ImGui::CollapsingHeader(tr(
"Position"), ImGuiTreeNodeFlags_DefaultOpen)) {
683 if (ImGui::CollapsingHeader(tr(
"Item Data"),
684 ImGuiTreeNodeFlags_DefaultOpen)) {
685 ImGui::TextDisabled(tr(
"Item ID: --"));
686 ImGui::TextDisabled(tr(
"Map ID: --"));
693 if (ImGui::CollapsingHeader(tr(
"Sheet Info"),
694 ImGuiTreeNodeFlags_DefaultOpen)) {
696 ImGui::TextDisabled(tr(
"Size: 128x32"));
697 ImGui::TextDisabled(tr(
"BPP: 4"));
701 ImGui::CollapsingHeader(tr(
"ROM Location"), ImGuiTreeNodeFlags_None)) {
702 ImGui::TextDisabled(tr(
"Address: --"));
703 ImGui::TextDisabled(tr(
"Compressed: Yes"));
704 ImGui::TextDisabled(tr(
"Original Size: --"));
711 if (ImGui::CollapsingHeader(tr(
"Palette Info"),
712 ImGuiTreeNodeFlags_DefaultOpen)) {
714 ImGui::TextDisabled(tr(
"Colors: 16"));
717 if (ImGui::CollapsingHeader(tr(
"Colors"), ImGuiTreeNodeFlags_DefaultOpen)) {
719 ImGui::TextDisabled(tr(
"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()