yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
dungeon_room_nav_widget.cc
Go to the documentation of this file.
2
3#include <charconv>
4#include <cstring>
5#include <string>
6
7#include "imgui/imgui.h"
10
11namespace yaze::editor {
12
13namespace {
14
15constexpr int kRoomMatrixCols = 16;
16constexpr int kRoomMatrixRows = 19;
17std::optional<int> RoomIfValid(int candidate) {
18 if (candidate < 0 || candidate >= zelda3::kNumberOfRooms) {
19 return std::nullopt;
20 }
21 return candidate;
22}
23
24std::string MakeTooltip(const std::optional<int>& target,
25 const char* direction) {
26 if (!target.has_value()) {
27 return "";
28 }
29 const auto label = zelda3::GetRoomLabel(*target);
30 char buf[192];
31 snprintf(buf, sizeof(buf),
32 "Room grid %s: [%03X] %s\nGrid position does not confirm a door "
33 "connection.",
34 direction, *target, label.c_str());
35 return buf;
36}
37
38bool ArrowButtonWithTooltip(const char* id, ImGuiDir dir,
39 const std::optional<int>& target,
40 const std::string& tooltip,
41 const std::function<void(int)>& on_navigate) {
42 const bool enabled = target.has_value();
43 if (!enabled) {
44 ImGui::BeginDisabled();
45 }
46 const bool pressed = ImGui::ArrowButton(id, dir);
47 if (!enabled) {
48 ImGui::EndDisabled();
49 }
50 if (enabled && ImGui::IsItemHovered() && !tooltip.empty()) {
51 ImGui::SetTooltip("%s", tooltip.c_str());
52 }
53 if (pressed && enabled && on_navigate) {
54 on_navigate(*target);
55 return true;
56 }
57 return false;
58}
59
60} // namespace
61
63 int room_id) {
64 if (room_id < 0 || room_id >= zelda3::kNumberOfRooms) {
65 return {};
66 }
67
68 const int col = room_id % kRoomMatrixCols;
69 const int row = room_id / kRoomMatrixCols;
70
71 // Note: the matrix has empty slots in the final row; RoomIfValid handles it.
72 Neighbors out;
73 out.west = RoomIfValid(col > 0 ? room_id - 1 : -1);
74 out.east = RoomIfValid(col < (kRoomMatrixCols - 1) ? room_id + 1 : -1);
75 out.north = RoomIfValid(row > 0 ? room_id - kRoomMatrixCols : -1);
76 out.south =
77 RoomIfValid(row < (kRoomMatrixRows - 1) ? room_id + kRoomMatrixCols : -1);
78 return out;
79}
80
81bool DungeonRoomNavWidget::Draw(const char* id, int room_id,
82 const std::function<void(int)>& on_navigate) {
83 ImGui::PushID(id);
84
85 char room_text[9];
86 snprintf(room_text, sizeof(room_text), "%03X", room_id);
87 ImGui::SetNextItemWidth(ImGui::CalcTextSize("00000").x +
88 ImGui::GetStyle().FramePadding.x * 2.0f);
89 const bool submitted =
90 ImGui::InputText("##RoomId", room_text, sizeof(room_text),
91 ImGuiInputTextFlags_CharsHexadecimal |
92 ImGuiInputTextFlags_EnterReturnsTrue);
93 if (ImGui::IsItemHovered()) {
94 ImGui::SetTooltip("Room ID (hexadecimal, 000-127). Press Enter to open.");
95 }
96 bool navigated = false;
97 if (submitted && on_navigate) {
98 int requested_room = -1;
99 const auto parsed = std::from_chars(
100 room_text, room_text + std::strlen(room_text), requested_room, 16);
101 if (parsed.ec == std::errc{} &&
102 parsed.ptr == room_text + std::strlen(room_text) &&
103 requested_room != room_id && RoomIfValid(requested_room)) {
104 on_navigate(requested_room);
105 navigated = true;
106 }
107 }
108 ImGui::SameLine();
109
110 const Neighbors n = GetNeighbors(room_id);
111 const std::string tip_w = MakeTooltip(n.west, "West");
112 const std::string tip_n = MakeTooltip(n.north, "North");
113 const std::string tip_s = MakeTooltip(n.south, "South");
114 const std::string tip_e = MakeTooltip(n.east, "East");
115
116 navigated |=
117 ArrowButtonWithTooltip("West", ImGuiDir_Left, n.west, tip_w, on_navigate);
118 ImGui::SameLine();
119 navigated |=
120 ArrowButtonWithTooltip("North", ImGuiDir_Up, n.north, tip_n, on_navigate);
121 ImGui::SameLine();
122 navigated |= ArrowButtonWithTooltip("South", ImGuiDir_Down, n.south, tip_s,
123 on_navigate);
124 ImGui::SameLine();
125 navigated |= ArrowButtonWithTooltip("East", ImGuiDir_Right, n.east, tip_e,
126 on_navigate);
127
128 ImGui::PopID();
129 return navigated;
130}
131
132} // namespace yaze::editor
static bool Draw(const char *id, int room_id, const std::function< void(int)> &on_navigate)
static Neighbors GetNeighbors(int room_id)
std::string MakeTooltip(const std::optional< int > &target, const char *direction)
bool ArrowButtonWithTooltip(const char *id, ImGuiDir dir, const std::optional< int > &target, const std::string &tooltip, const std::function< void(int)> &on_navigate)
Editors are the view controllers for the application.
std::string GetRoomLabel(int id)
Convenience function to get a room label.
constexpr int kNumberOfRooms