144 static constexpr std::array<zelda3::DoorType, 20> kDoorTypes = {{
180 ImGui::TextColored(theme.text_secondary_gray,
181 tr(
"Select a door style, then click a wall in the room "
182 "canvas to place it."));
194 constexpr float kDoorCardHeight = 48.0f;
195 constexpr float kDoorCardSpacing = 6.0f;
196 constexpr float kMinDoorCardWidth = 92.0f;
197 const float panel_width = ImGui::GetContentRegionAvail().x;
198 const int items_per_row =
199 std::max(2,
static_cast<int>((panel_width + kDoorCardSpacing) /
200 (kMinDoorCardWidth + kDoorCardSpacing)));
201 const float card_width = std::max(
203 (panel_width - (items_per_row - 1) * kDoorCardSpacing) / items_per_row);
205 ImGui::BeginChild(
"##DoorTypeGrid", ImVec2(0, 150),
true,
206 ImGuiWindowFlags_AlwaysVerticalScrollbar);
209 for (
size_t i = 0; i < kDoorTypes.size(); ++i) {
210 const auto door_type = kDoorTypes[i];
212 const int type_val =
static_cast<int>(door_type);
213 ImGui::PushID(
static_cast<int>(i));
215 ImVec4 button_color = DoorTypeAccent(theme, door_type);
217 button_color.x = std::min(1.0f, button_color.x + 0.2f);
218 button_color.y = std::min(1.0f, button_color.y + 0.2f);
219 button_color.z = std::min(1.0f, button_color.z + 0.2f);
223 {ImGuiCol_Button, button_color},
224 {ImGuiCol_ButtonHovered,
225 ImVec4(button_color.x + 0.1f, button_color.y + 0.1f,
226 button_color.z + 0.1f, 1.0f)},
227 {ImGuiCol_ButtonActive,
228 ImVec4(button_color.x + 0.2f, button_color.y + 0.2f,
229 button_color.z + 0.2f, 1.0f)},
232 const std::string label =
233 absl::StrFormat(
"%s %02X\n%s", DoorTypeIcon(door_type), type_val,
234 ShortDoorTypeLabel(door_type).c_str());
235 if (ImGui::Button(label.c_str(), ImVec2(card_width, kDoorCardHeight))) {
244 if (ImGui::IsItemHovered()) {
245 ImGui::SetTooltip(tr(
"%s (0x%02X)\nClick to select for placement"),
251 ImVec2 min = ImGui::GetItemRectMin();
252 ImVec2 max = ImGui::GetItemRectMax();
253 ImGui::GetWindowDrawList()->AddRect(min, max, IM_COL32(255, 255, 0, 255),
259 if (col < items_per_row && i < kDoorTypes.size() - 1) {
268 if (!
rooms_ || current_room_id_ < 0 || current_room_id_ >= 296) {
273 const auto& doors = room.GetDoors();
278 ImGui::TextColored(theme.text_secondary_gray,
283 int selected_door_index = -1;
286 const auto selected_entity =
289 selected_door_index =
static_cast<int>(selected_entity.index);
293 if (selected_door_index >= 0 &&
294 selected_door_index <
static_cast<int>(doors.size())) {
295 uint8_t raw_type =
static_cast<uint8_t
>(doors[selected_door_index].type);
296 ImGui::AlignTextToFramePadding();
297 ImGui::TextUnformatted(tr(
"Selected raw type"));
299 ImGui::SetNextItemWidth(72.0f);
301 "##SelectedDoorRawType", ImGuiDataType_U8, &raw_type,
"%02X",
302 ImGuiInputTextFlags_CharsHexadecimal,
303 {
reinterpret_cast<uintptr_t
>(
rooms_),
305 static_cast<uint64_t
>(selected_door_index)});
307 "Selected door raw type byte");
317 ImGui::BeginChild(
"##DoorList", ImVec2(0, 0),
true);
318 for (
size_t i = 0; i < doors.size(); ++i) {
319 const auto& door = doors[i];
320 const auto [tile_x, tile_y] = door.GetTileCoords();
324 ImGui::PushID(
static_cast<int>(i));
325 const std::string row_label = absl::StrFormat(
"[%zu] %s", i, type_name);
326 const bool row_selected = ImGui::Selectable(
327 row_label.c_str(), selected_door_index ==
static_cast<int>(i));
329 "Select a door in the current dungeon room");
336 ImGui::TextColored(theme.text_secondary_gray,
"(%s @ %d,%d)",
337 dir_name.c_str(), tile_x, tile_y);
DungeonCanvasViewer * canvas_viewer_
zelda3::DoorType selected_door_type_
DungeonRoomStore * rooms_
DungeonCanvasViewer * ResolveCanvasViewer()
std::function< DungeonCanvasViewer *()> canvas_viewer_provider_
void OnClose() override
Called when panel is hidden.
void Draw(bool *p_open) override
Draw the panel content.
std::function< void()> open_selection_inspector_callback_
std::string ShortDoorTypeLabel(zelda3::DoorType type)
ImVec4 DoorTypeAccent(const AgentUITheme &theme, zelda3::DoorType type)
const char * DoorTypeIcon(zelda3::DoorType type)