169 void Draw(
bool* p_open)
override {
181 constexpr float kRoomWidth = 64.0f;
182 constexpr float kRoomHeight = 64.0f;
183 constexpr float kRoomSpacing = 8.0f;
186 float max_x = 0, max_y = 0;
188 max_x = std::max(max_x, pos.x);
189 max_y = std::max(max_y, pos.y);
192 (max_x + 1) * (kRoomWidth + kRoomSpacing) + kRoomSpacing;
193 float canvas_height =
194 (max_y + 1) * (kRoomHeight + kRoomSpacing) + kRoomSpacing;
197 canvas_width = std::max(canvas_width, 200.0f);
198 canvas_height = std::max(canvas_height, 200.0f);
200 const ImVec2 available = ImGui::GetContentRegionAvail();
201 const float footer = ImGui::GetTextLineHeightWithSpacing();
202 if (!ImGui::BeginChild(
"##DungeonMapCanvas",
203 ImVec2(0, std::max(1.0f, available.y - footer)),
204 false, ImGuiWindowFlags_HorizontalScrollbar)) {
208 const ImVec2 canvas_size(canvas_width, canvas_height);
211 ImVec2 canvas_pos = ImGui::GetCursorScreenPos();
212 ImDrawList* draw_list = ImGui::GetWindowDrawList();
215 ImU32 bg_color = ImGui::ColorConvertFloat4ToU32(theme.panel_bg_darker);
216 draw_list->AddRectFilled(
218 ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y),
222 auto RoomCenter = [&](
int room_id) -> ImVec2 {
226 ImVec2 pos = it->second;
227 return ImVec2(canvas_pos.x + kRoomSpacing +
228 pos.x * (kRoomWidth + kRoomSpacing) + kRoomWidth * 0.5f,
229 canvas_pos.y + kRoomSpacing +
230 pos.y * (kRoomHeight + kRoomSpacing) +
236 ImVec4 connection_color = theme.dungeon_room_border_dark;
237 connection_color.w = 0.45f;
239 const ImVec2 from = RoomCenter(link.from_room_id);
240 const ImVec2 to = RoomCenter(link.to_room_id);
244 from, to, ImGui::ColorConvertFloat4ToU32(connection_color), 1.5f);
251 const ImU32 red = IM_COL32(220, 60, 60, 200);
252 draw_list->AddLine(from, to, red, 2.0f);
265 ImVec2 grid_pos = pos_it->second;
266 ImVec2 room_min(canvas_pos.x + kRoomSpacing +
267 grid_pos.x * (kRoomWidth + kRoomSpacing),
268 canvas_pos.y + kRoomSpacing +
269 grid_pos.y * (kRoomHeight + kRoomSpacing));
270 ImVec2 room_max(room_min.x + kRoomWidth, room_min.y + kRoomHeight);
273 if (room_id < 0 || room_id >= 0x128)
277 bool is_open =
false;
288 if (loaded_room !=
nullptr) {
293 output = std::make_unique<RoomCompositeOutput>();
295 auto& preview_bitmap =
299 if (preview_bitmap.is_active() && preview_bitmap.texture() != 0) {
301 draw_list->AddImage((ImTextureID)(intptr_t)preview_bitmap.texture(),
302 room_min, room_max, ImVec2(0, 0), ImVec2(1, 1),
303 ImGui::GetColorU32(ImVec4(1, 1, 1, 1)));
306 draw_list->AddRectFilled(
308 ImGui::ColorConvertFloat4ToU32(theme.panel_bg_color));
312 draw_list->AddRectFilled(
314 ImGui::ColorConvertFloat4ToU32(theme.panel_bg_darker));
318 snprintf(label,
sizeof(label),
"%02X", room_id);
319 ImVec2 text_size = ImGui::CalcTextSize(label);
320 ImVec2 text_pos(room_min.x + (kRoomWidth - text_size.x) * 0.5f,
321 room_min.y + (kRoomHeight - text_size.y) * 0.5f);
324 ImGui::ColorConvertFloat4ToU32(theme.text_secondary_gray), label);
328 draw_list->AddRectFilled(
330 ImGui::ColorConvertFloat4ToU32(theme.panel_bg_darker));
334 snprintf(label,
sizeof(label),
"%02X", room_id);
335 ImVec2 text_size = ImGui::CalcTextSize(label);
336 ImVec2 text_pos(room_min.x + (kRoomWidth - text_size.x) * 0.5f,
337 room_min.y + (kRoomHeight - text_size.y) * 0.5f);
339 text_pos, ImGui::ColorConvertFloat4ToU32(theme.text_secondary_gray),
346 ImVec4 glow = theme.dungeon_selection_primary;
348 ImVec2 glow_min(room_min.x - 2, room_min.y - 2);
349 ImVec2 glow_max(room_max.x + 2, room_max.y + 2);
350 draw_list->AddRect(glow_min, glow_max,
351 ImGui::ColorConvertFloat4ToU32(glow), 0.0f, 4.0f);
355 ImGui::ColorConvertFloat4ToU32(theme.dungeon_selection_primary),
357 }
else if (is_open) {
360 ImGui::ColorConvertFloat4ToU32(theme.dungeon_grid_cell_selected),
365 ImGui::ColorConvertFloat4ToU32(theme.dungeon_grid_cell_border),
372 ImU32 badge_color = 0;
373 if (type_it->second ==
"entrance") {
374 badge_color = IM_COL32(76, 175, 80, 220);
375 }
else if (type_it->second ==
"boss") {
376 badge_color = IM_COL32(244, 67, 54, 220);
377 }
else if (type_it->second ==
"mini_boss") {
378 badge_color = IM_COL32(255, 152, 0, 220);
380 if (badge_color != 0) {
381 ImVec2 badge_center(room_min.x + 6.0f, room_min.y + 6.0f);
382 draw_list->AddCircleFilled(badge_center, 4.0f, badge_color);
387 ImGui::SetCursorScreenPos(room_min);
389 snprintf(btn_id,
sizeof(btn_id),
"##map_room%d", room_id);
390 ImGui::InvisibleButton(btn_id, ImVec2(kRoomWidth, kRoomHeight));
392 if (ImGui::IsItemClicked()) {
393 if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
405 if (ImGui::IsItemHovered()) {
406 ImGui::BeginTooltip();
407 ImGui::Text(
"[%03X] %s", room_id,
411 ImGui::TextDisabled(tr(
"Palette: %d"), loaded_room->palette());
414 ImGui::TextDisabled(tr(
"Click to select"));
421 ImGui::SetCursorScreenPos(canvas_pos);
422 ImGui::Dummy(canvas_size);