136 if (tile_handler.was_placement_blocked()) {
138 tile_handler.clear_placement_blocked();
142 "Object limit reached (%d max) - placement blocked",
155 auto& sprite_handler = coordinator.sprite_handler();
156 if (sprite_handler.was_placement_blocked()) {
157 const auto reason = sprite_handler.placement_block_reason();
158 sprite_handler.clear_placement_blocked();
162 "Sprite limit reached (%d max) - placement blocked",
175 auto& door_handler = coordinator.door_handler();
176 if (door_handler.was_placement_blocked()) {
177 const auto reason = door_handler.placement_block_reason();
178 door_handler.clear_placement_blocked();
182 "Door limit reached (%d max) - placement blocked", max_doors));
235 const auto snapshot = viewer !=
nullptr
237 viewer->object_interaction(), viewer->rooms(),
238 viewer->current_room_id())
241 bool drew_primary_status =
false;
247 drew_primary_status =
true;
260 if (drew_primary_status) {
263 ImGui::TextColored(theme.status_warning,
268 const float cancel_width = ImGui::CalcTextSize(cancel_label).x +
269 ImGui::GetStyle().FramePadding.x * 2.0f;
270 const float next_x = ImGui::GetItemRectMax().x +
271 ImGui::GetStyle().ItemSpacing.x + cancel_width;
272 const float line_right =
273 ImGui::GetWindowPos().x + ImGui::GetWindowContentRegionMax().x;
274 if (next_x <= line_right) {
277 if (ImGui::SmallButton(cancel_label)) {
280 drew_primary_status =
true;
286 const ImVec2 available = ImGui::GetContentRegionAvail();
287 const bool show_secondary_status =
288 available.x >= 420.0f && available.y >= 260.0f;
289 if (!is_placing && show_secondary_status &&
291 ImGui::TextColored(theme.status_success,
294 }
else if (!is_placing && show_secondary_status &&
296 ImGui::TextColored(theme.status_success,
300 }
else if (!is_placing && show_secondary_status &&
304 ImGui::TextColored(theme.status_success,
308 }
else if (!is_placing && show_secondary_status &&
316 if (!show_secondary_status) {
324 size_t object_count = room.GetTileObjects().
size();
325 size_t sprite_count = room.GetSprites().size();
326 size_t door_count = room.GetDoors().size();
328 for (
const auto& obj : room.GetTileObjects()) {
340 auto usage_color = [&](
size_t count,
int max_val,
341 bool exact_capacity_warning) -> ImVec4 {
342 if (exact_capacity_warning) {
344 theme.text_secondary_gray);
346 float ratio =
static_cast<float>(count) /
static_cast<float>(max_val);
348 return theme.status_error;
350 if (ratio >= 0.75f) {
351 return theme.status_warning;
353 return theme.text_secondary_gray;
361 {{
ICON_MD_WIDGETS, absl::StrFormat(
"%zu/%d", object_count, kMaxObjects),
362 usage_color(object_count, kMaxObjects,
true)},
364 absl::StrFormat(
"%zu/%d", sprite_count, kMaxSprites),
365 usage_color(sprite_count, kMaxSprites,
true)},
367 usage_color(door_count, kMaxDoors,
true)},
369 absl::StrFormat(
"%d/%d", chest_count, kMaxChests),
370 usage_color(chest_count, kMaxChests,
false)}});
372 if (!result.errors.empty() || !result.warnings.empty()) {
374 result.errors.empty() ? theme.status_warning : theme.status_error,
375 tr(
"%s %zu issue%s"),
377 result.errors.size() + result.warnings.size(),
378 (result.errors.size() + result.warnings.size()) == 1 ?
"" :
"s");
379 if (ImGui::IsItemHovered()) {
380 ImGui::BeginTooltip();
381 for (
const auto& err : result.errors) {
385 for (
const auto& warn : result.warnings) {
void SetPlacementError(const std::string &message)
static constexpr double kPlacementErrorDuration
std::function< DungeonCanvasViewer *()> canvas_viewer_provider_
DungeonCanvasViewer * ResolveCanvasViewer()
std::shared_ptr< zelda3::DungeonObjectEditor > object_editor_
std::function< void()> open_object_editor_callback_
ObjectSelectorContent(Rom *rom, DungeonCanvasViewer *canvas_viewer, std::shared_ptr< zelda3::DungeonObjectEditor > object_editor=nullptr, ToastManager *toast_manager=nullptr)
DungeonCanvasViewer * canvas_viewer_
DungeonObjectSelector object_selector_
void Draw(bool *p_open) override
Draw the panel content.
void SetAgentOptimizedLayout(bool enabled)
void DrawInlineInspectButton(const std::function< void()> &callback)
void DrawUsageChips(std::initializer_list< UsageChip > chips)