6#include "absl/strings/str_cat.h"
7#include "absl/strings/str_format.h"
15#include "imgui/imgui.h"
29 return "Dungeon Room";
31 return "Dungeon Object";
33 return "Dungeon Sprite";
35 return "Dungeon Entrance";
37 return "Overworld Map";
39 return "Overworld Tile";
41 return "Overworld Sprite";
43 return "Overworld Entrance";
45 return "Overworld Exit";
47 return "Overworld Item";
49 return "Graphics Sheet";
128 std::string full_title = absl::StrFormat(
"%s %s", icon, title);
133 absl::StrAppend(&full_title,
" (Read Only)");
156 ImGui::TextDisabled(tr(
"Read Only"));
160 bool wrote_action =
false;
164 std::snprintf(buffer,
sizeof(buffer),
"%d",
selection_.
id);
165 ImGui::SetClipboardText(buffer);
174 std::snprintf(buffer,
sizeof(buffer),
"0x%X",
selection_.
id);
175 ImGui::SetClipboardText(buffer);
207 ImGui::BeginDisabled(no_selection);
217 SendAgentPrompt(
"Audit this selection for possible issues or conflicts.");
219 ImGui::EndDisabled();
221 ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
222 ImGui::SetTooltip(tr(
"Select an object first to use agent actions"));
227 std::string context = absl::StrFormat(
"Selection Type: %s",
233 context += absl::StrFormat(
"\nID: 0x%X",
selection_.
id);
239 context +=
"\nRead Only: true";
245 const char* intent)
const {
246 std::string prompt = intent ? intent :
"Review this selection.";
249 prompt +=
"\n\nProvide actionable steps inside Yaze where possible.";
266 bool changed =
false;
267 ImGui::PushID(label);
269 ImGui::Text(
"%s", label);
270 ImGui::PushItemWidth(80);
272 ImGui::Text(tr(
"X:"));
274 if (ImGui::InputInt(
"##X", x, 1, 8)) {
275 *x = std::clamp(*x, min_val, max_val);
280 ImGui::Text(tr(
"Y:"));
282 if (ImGui::InputInt(
"##Y", y, 1, 8)) {
283 *y = std::clamp(*y, min_val, max_val);
287 ImGui::PopItemWidth();
295 bool changed =
false;
296 ImGui::PushID(label);
298 ImGui::Text(
"%s", label);
299 ImGui::PushItemWidth(80);
301 ImGui::Text(tr(
"W:"));
303 if (ImGui::InputInt(
"##W", width, 1, 8)) {
304 *width = std::max(1, *width);
309 ImGui::Text(tr(
"H:"));
311 if (ImGui::InputInt(
"##H", height, 1, 8)) {
312 *height = std::max(1, *height);
316 ImGui::PopItemWidth();
324 const char* tooltip) {
325 bool changed =
false;
328 ImGui::PushItemWidth(80);
329 if (ImGui::InputInt(label, &val, 1, 16)) {
330 *value =
static_cast<uint8_t
>(std::clamp(val, 0, 255));
333 ImGui::PopItemWidth();
335 if (tooltip && ImGui::IsItemHovered()) {
336 ImGui::SetTooltip(
"%s", tooltip);
344 const char* tooltip) {
345 bool changed =
false;
348 ImGui::PushItemWidth(100);
349 if (ImGui::InputInt(label, &val, 1, 256)) {
350 *value =
static_cast<uint16_t
>(std::clamp(val, 0, 65535));
353 ImGui::PopItemWidth();
355 if (tooltip && ImGui::IsItemHovered()) {
356 ImGui::SetTooltip(
"%s", tooltip);
364 const char*
const items[],
366 return ImGui::Combo(label, current_item, items, items_count);
371 const char*
const flag_names[],
373 bool changed =
false;
375 if (ImGui::TreeNode(label)) {
376 for (
int i = 0; i < flag_count && i < 8; ++i) {
377 bool bit_set = (*flags >> i) & 1;
378 if (ImGui::Checkbox(flag_names[i], &bit_set)) {
395 ImGui::Text(
"%s:", label);
397 ImGui::TextDisabled(
"%s", value);
401 uint32_t value,
int digits) {
402 ImGui::Text(
"%s:", label);
405 snprintf(fmt,
sizeof(fmt),
"0x%%0%dX", digits);
406 ImGui::TextDisabled(fmt, value);
423 ImGui::TextDisabled(tr(
"No room data available."));
429 if (ImGui::CollapsingHeader(tr(
"Identity"), ImGuiTreeNodeFlags_DefaultOpen)) {
434 if (ImGui::CollapsingHeader(tr(
"Graphics & Layout"),
435 ImGuiTreeNodeFlags_DefaultOpen)) {
436 uint8_t blockset = room->blockset();
438 "Tile graphics and layout definition")) {
439 room->SetBlockset(blockset);
443 uint8_t palette = room->palette();
445 room->SetPalette(palette);
449 uint8_t spriteset = room->spriteset();
451 "Enemy graphics and behavior")) {
452 room->SetSpriteset(spriteset);
458 ImGui::CollapsingHeader(tr(
"Advanced Settings"),
459 ImGuiTreeNodeFlags_DefaultOpen)) {
462 auto draw_tag_combo = [&](
const char* label,
zelda3::TagKey current,
464 std::string current_label =
466 if (ImGui::BeginCombo(label, current_label.c_str())) {
468 for (
int i = 0; i < static_cast<int>(vanilla_tags.size()); ++i) {
470 if (ImGui::Selectable(item_label.c_str(),
471 static_cast<int>(current) == i)) {
480 draw_tag_combo(
"Tag 1", room->tag1(),
482 draw_tag_combo(
"Tag 2", room->tag2(),
486 int effect =
static_cast<int>(room->effect());
488 std::vector<const char*> effect_ptrs;
489 for (
const auto& s : effects)
490 effect_ptrs.push_back(s.c_str());
492 if (ImGui::Combo(tr(
"Effect"), &effect, effect_ptrs.data(),
493 static_cast<int>(effect_ptrs.size()))) {
503 if (ImGui::CollapsingHeader(tr(
"Transform"),
504 ImGuiTreeNodeFlags_DefaultOpen)) {
517 if (ImGui::CollapsingHeader(tr(
"Object Type"),
518 ImGuiTreeNodeFlags_DefaultOpen)) {
519 ImGui::TextDisabled(tr(
"Object ID: --"));
520 ImGui::TextDisabled(tr(
"Subtype: --"));
521 ImGui::TextDisabled(tr(
"Layer: --"));
525 ImGui::CollapsingHeader(tr(
"Raw Data"), ImGuiTreeNodeFlags_None)) {
526 ImGui::TextDisabled(tr(
"Byte 1: 0x00"));
527 ImGui::TextDisabled(tr(
"Byte 2: 0x00"));
528 ImGui::TextDisabled(tr(
"Byte 3: 0x00"));
535 if (ImGui::CollapsingHeader(tr(
"Position"), ImGuiTreeNodeFlags_DefaultOpen)) {
542 if (ImGui::CollapsingHeader(tr(
"Sprite Data"),
543 ImGuiTreeNodeFlags_DefaultOpen)) {
544 ImGui::TextDisabled(tr(
"Sprite ID: --"));
545 ImGui::TextDisabled(tr(
"Subtype: --"));
546 ImGui::TextDisabled(tr(
"Overlord: No"));
553 if (ImGui::CollapsingHeader(tr(
"Target"), ImGuiTreeNodeFlags_DefaultOpen)) {
554 ImGui::TextDisabled(tr(
"Target Room: --"));
555 ImGui::TextDisabled(tr(
"Entry Position: --"));
558 if (ImGui::CollapsingHeader(tr(
"Properties"),
559 ImGuiTreeNodeFlags_DefaultOpen)) {
560 ImGui::TextDisabled(tr(
"Door Type: --"));
561 ImGui::TextDisabled(tr(
"Direction: --"));
568 if (ImGui::CollapsingHeader(tr(
"Identity"), ImGuiTreeNodeFlags_DefaultOpen)) {
573 if (ImGui::CollapsingHeader(tr(
"Graphics"), ImGuiTreeNodeFlags_DefaultOpen)) {
574 ImGui::TextDisabled(tr(
"GFX Set: --"));
575 ImGui::TextDisabled(tr(
"Palette: --"));
576 ImGui::TextDisabled(tr(
"Sprite GFX: --"));
577 ImGui::TextDisabled(tr(
"Sprite Palette: --"));
580 if (ImGui::CollapsingHeader(tr(
"Properties"),
581 ImGuiTreeNodeFlags_DefaultOpen)) {
582 ImGui::TextDisabled(tr(
"Large Map: No"));
583 ImGui::TextDisabled(tr(
"Area Size: 1x1"));
584 ImGui::TextDisabled(tr(
"Parent ID: --"));
591 if (ImGui::CollapsingHeader(tr(
"Tile Info"),
592 ImGuiTreeNodeFlags_DefaultOpen)) {
594 ImGui::TextDisabled(tr(
"Position: --"));
598 ImGui::CollapsingHeader(tr(
"Tile16 Data"), ImGuiTreeNodeFlags_None)) {
599 ImGui::TextDisabled(tr(
"TL: 0x0000"));
600 ImGui::TextDisabled(tr(
"TR: 0x0000"));
601 ImGui::TextDisabled(tr(
"BL: 0x0000"));
602 ImGui::TextDisabled(tr(
"BR: 0x0000"));
609 if (ImGui::CollapsingHeader(tr(
"Position"), ImGuiTreeNodeFlags_DefaultOpen)) {
616 if (ImGui::CollapsingHeader(tr(
"Sprite"), ImGuiTreeNodeFlags_DefaultOpen)) {
617 ImGui::TextDisabled(tr(
"Sprite ID: --"));
618 ImGui::TextDisabled(tr(
"Map ID: --"));
625 if (ImGui::CollapsingHeader(tr(
"Position"), ImGuiTreeNodeFlags_DefaultOpen)) {
632 if (ImGui::CollapsingHeader(tr(
"Target"), ImGuiTreeNodeFlags_DefaultOpen)) {
633 ImGui::TextDisabled(tr(
"Entrance ID: --"));
634 ImGui::TextDisabled(tr(
"Target Room: --"));
641 if (ImGui::CollapsingHeader(tr(
"Exit Point"),
642 ImGuiTreeNodeFlags_DefaultOpen)) {
643 ImGui::TextDisabled(tr(
"Exit ID: --"));
650 if (ImGui::CollapsingHeader(tr(
"Target Map"),
651 ImGuiTreeNodeFlags_DefaultOpen)) {
652 ImGui::TextDisabled(tr(
"Room ID: --"));
653 ImGui::TextDisabled(tr(
"Target Map: --"));
660 if (ImGui::CollapsingHeader(tr(
"Position"), ImGuiTreeNodeFlags_DefaultOpen)) {
667 if (ImGui::CollapsingHeader(tr(
"Item Data"),
668 ImGuiTreeNodeFlags_DefaultOpen)) {
669 ImGui::TextDisabled(tr(
"Item ID: --"));
670 ImGui::TextDisabled(tr(
"Map ID: --"));
677 if (ImGui::CollapsingHeader(tr(
"Sheet Info"),
678 ImGuiTreeNodeFlags_DefaultOpen)) {
680 ImGui::TextDisabled(tr(
"Size: 128x32"));
681 ImGui::TextDisabled(tr(
"BPP: 4"));
685 ImGui::CollapsingHeader(tr(
"ROM Location"), ImGuiTreeNodeFlags_None)) {
686 ImGui::TextDisabled(tr(
"Address: --"));
687 ImGui::TextDisabled(tr(
"Compressed: Yes"));
688 ImGui::TextDisabled(tr(
"Original Size: --"));
695 if (ImGui::CollapsingHeader(tr(
"Palette Info"),
696 ImGuiTreeNodeFlags_DefaultOpen)) {
698 ImGui::TextDisabled(tr(
"Colors: 16"));
701 if (ImGui::CollapsingHeader(tr(
"Colors"), ImGuiTreeNodeFlags_DefaultOpen)) {
703 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.
#define ICON_MD_GRID_VIEW
#define ICON_MD_EXIT_TO_APP
#define ICON_MD_DOOR_FRONT
#define ICON_MD_PEST_CONTROL
#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.
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)
void ColoredTextF(const ImVec4 &color, const char *fmt,...)
bool DrawEmptyState(const EmptyStateOptions &options)
Draw a centered empty-state block.
EmptyStateOptions EmptyNoSelection(bool compact)
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()