230 ImGui::TextWrapped(
"Select a door style, then click a wall to place it.");
242 constexpr float kDoorCardHeight = 48.0f;
243 constexpr float kDoorCardSpacing = 6.0f;
244 constexpr float kMinDoorCardWidth = 92.0f;
246 const float grid_height =
247 show_room_doors ? 150.0f
248 : std::max(1.0f, ImGui::GetContentRegionAvail().y);
249 ImGui::BeginChild(
"##DoorTypeGrid", ImVec2(0, grid_height),
true,
250 ImGuiWindowFlags_AlwaysVerticalScrollbar);
251 ImGui::BeginDisabled(!can_edit);
252 const float panel_width = ImGui::GetContentRegionAvail().x;
253 const int items_per_row =
254 std::max(1,
static_cast<int>((panel_width + kDoorCardSpacing) /
255 (kMinDoorCardWidth + kDoorCardSpacing)));
256 const float card_width = std::max(
258 (panel_width - (items_per_row - 1) * kDoorCardSpacing) / items_per_row);
261 for (
size_t i = 0; i < kDoorTypes.size(); ++i) {
262 const auto door_type = kDoorTypes[i];
264 const int type_val =
static_cast<int>(door_type);
265 ImGui::PushID(
static_cast<int>(i));
267 ImVec4 button_color = DoorTypeAccent(theme, door_type);
269 button_color.x = std::min(1.0f, button_color.x + 0.2f);
270 button_color.y = std::min(1.0f, button_color.y + 0.2f);
271 button_color.z = std::min(1.0f, button_color.z + 0.2f);
275 {ImGuiCol_Button, button_color},
276 {ImGuiCol_ButtonHovered,
277 ImVec4(button_color.x + 0.1f, button_color.y + 0.1f,
278 button_color.z + 0.1f, 1.0f)},
279 {ImGuiCol_ButtonActive,
280 ImVec4(button_color.x + 0.2f, button_color.y + 0.2f,
281 button_color.z + 0.2f, 1.0f)},
284 const std::string label =
285 absl::StrFormat(
"%s %02X\n%s", DoorTypeIcon(door_type), type_val,
286 ShortDoorTypeLabel(door_type).c_str());
288 ImGui::Button(label.c_str(), ImVec2(card_width, kDoorCardHeight));
290 absl::StrFormat(
"place_door_%02X", type_val));
291 if (picked && can_edit) {
300 if (ImGui::IsItemHovered()) {
301 ImGui::SetTooltip(tr(
"%s (0x%02X)\nClick to select for placement"),
307 ImVec2 min = ImGui::GetItemRectMin();
308 ImVec2 max = ImGui::GetItemRectMax();
309 ImGui::GetWindowDrawList()->AddRect(min, max, IM_COL32(255, 255, 0, 255),
315 if (col < items_per_row && i < kDoorTypes.size() - 1) {
316 ImGui::SameLine(0, kDoorCardSpacing);
322 ImGui::EndDisabled();
331 const auto& doors = room.GetDoors();
336 ImGui::TextColored(theme.text_secondary_gray,
341 int selected_door_index = -1;
344 const auto selected_entity =
346 if (selected_entity.type == EntityType::Door) {
347 selected_door_index =
static_cast<int>(selected_entity.index);
351 if (selected_door_index >= 0 &&
352 selected_door_index <
static_cast<int>(doors.size())) {
353 ImGui::BeginDisabled(!can_edit);
354 uint8_t raw_type =
static_cast<uint8_t
>(doors[selected_door_index].type);
355 ImGui::AlignTextToFramePadding();
356 ImGui::TextUnformatted(tr(
"Selected raw type"));
358 ImGui::SetNextItemWidth(72.0f);
360 "##SelectedDoorRawType", ImGuiDataType_U8, &raw_type,
"%02X",
361 ImGuiInputTextFlags_CharsHexadecimal,
362 {
reinterpret_cast<uintptr_t
>(
rooms_),
364 static_cast<uint64_t
>(selected_door_index)});
366 "Selected door raw type byte");
367 ImGui::EndDisabled();
368 if (type_changed && can_edit) {
377 ImGui::BeginChild(
"##DoorList", ImVec2(0, 0),
true);
378 for (
size_t i = 0; i < doors.size(); ++i) {
379 const auto& door = doors[i];
380 const auto [tile_x, tile_y] = door.GetTileCoords();
384 ImGui::PushID(
static_cast<int>(i));
385 const std::string row_label = absl::StrFormat(
"[%zu] %s", i, type_name);
386 const bool row_selected = ImGui::Selectable(
387 row_label.c_str(), selected_door_index ==
static_cast<int>(i));
389 "Select a door in the current dungeon room");
396 ImGui::TextColored(theme.text_secondary_gray,
"(%s @ %d,%d)",
397 dir_name.c_str(), tile_x, tile_y);
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_
ImVec4 DoorTypeAccent(const AgentUITheme &theme, zelda3::DoorType type)