7#include "absl/strings/str_format.h"
14#include "imgui/imgui.h"
20ImVec4 WithAlpha(ImVec4 color,
float alpha) {
31 const float scale = std::max(canvas_rt.
scale, 0.01f);
34 const ImVec2 room_max(room_min.x + (512.0f * scale),
35 room_min.y + (512.0f * scale));
42 ImGui::GetColorU32(WithAlpha(theme.editor_background, 0.92f)));
43 canvas_rt.
draw_list->AddRect(room_min, room_max,
44 ImGui::GetColorU32(theme.panel_border_color),
46 canvas_rt.
draw_list->AddText(ImVec2(room_min.x + 12.0f, room_min.y + 12.0f),
47 ImGui::GetColorU32(theme.text_secondary_gray),
48 "Room image pending");
74 constexpr int kRoomPixelWidth = 512;
75 constexpr int kRoomPixelHeight = 512;
76 constexpr int kDungeonTileSize = 8;
84 const float pixel_x =
static_cast<float>(target_x * kDungeonTileSize) * scale;
85 const float pixel_y =
static_cast<float>(target_y * kDungeonTileSize) * scale;
86 const ImVec2 view_size = canvas_rt.
canvas_sz;
87 const ImVec2 content_size(
static_cast<float>(kRoomPixelWidth) * scale,
88 static_cast<float>(kRoomPixelHeight) * scale);
90 const ImVec2 desired_scroll((view_size.x * 0.5f) - pixel_x,
91 (view_size.y * 0.5f) - pixel_y);
109 snprintf(text1,
sizeof(text1),
"[%03X] %s", room_id, label.c_str());
111 const auto metadata =
112 absl::StrFormat(
"B:%02X P:%02X L:%02X S:%02X%s", room->blockset(),
113 room->palette(), room->layout_id(), room->spriteset(),
115 const float pad = 10.0f;
118 const float content_width = std::max(ImGui::CalcTextSize(text1).x,
119 ImGui::CalcTextSize(metadata.c_str()).x);
120 const float width = std::min(
122 if (width <= 16.0f) {
125 const ImVec2 hud_size(width, 0);
127 const auto hud_id = absl::StrFormat(
"##MetadataHUD_%p",
this);
130 ImGui::TextWrapped(
"%s", text1);
131 ImGui::PushTextWrapPos(0);
132 ImGui::TextDisabled(
"%s", metadata.c_str());
133 ImGui::PopTextWrapPos();
172 if (tile_x >= 0 && tile_x < 64 && tile_y >= 0 && tile_y < 64) {
173 const uint8_t object_size = obj_drop.
size;
175 static_cast<uint8_t
>(tile_x),
176 static_cast<uint8_t
>(tile_y), object_size, 0);
179 room_id, new_obj, tile_x, tile_y);
190 const auto [room_x, room_y] =
196 static_cast<uint8_t
>(sprite_x),
197 static_cast<uint8_t
>(sprite_y), 0, 0);
221 if ((panel->canvas_editing() || panel->collision_stamping()) &&
226 panel->set_collision_stamping(
false);
228 const bool owns_input =
229 (panel->canvas_editing() || panel->collision_stamping()) &&
240 panel->SetActiveRoom(room_id);
244 panel->set_collision_stamping(
false);
250 panel->collision_stamp_size(), panel->collision_stamp_callback());
254 .
tracks = panel->GetTracks(),
255 .selected = panel->selected_track(),
256 .picking = panel->GetPickingTrackIndex(),
257 .revision = panel->canvas_revision(),
258 .enabled = panel->canvas_editing(),
259 .select = [panel](
int id) { panel->SelectTrack(
id); },
262 return panel->MoveCartStart(before, after);
264 .cancel_pick = [panel]() { panel->CancelPick(); }};
287 if (!drew_background) {
288 DrawRoomRenderFallback(canvas_rt);
298 const bool tool_owns_input =
308 if (selected.size() == 1) {
310 const size_t idx = selected.front();
311 if (idx < objects.size()) {
312 const auto& obj = objects[idx];
314 obj.x_, obj.y_, obj.size_);
320 if (sel.type == EntityType::Sprite) {
322 if (sel.index < sprites.size()) {
323 const auto& sprite = sprites[sel.index];
InteractionContext * context() const
Get the interaction context.
bool DrawCanvas(const gui::CanvasRuntime &rt, bool interactive, bool shortcut_focus)
void HandleRoomCanvasDropTargets(zelda3::Room &room, int room_id)
bool DrawRoomBackgroundLayers(int room_id)
std::optional< std::pair< int, int > > pending_scroll_target_
bool has_canvas_capture_region_
void SyncCanvasCaptureRegion(const gui::CanvasRuntime &canvas_rt)
CrumbleFloorView crumble_floor_view_
MinecartCanvasTool minecart_canvas_tool_
bool object_interaction_enabled_
bool DrawCrumbleCanvas(const gui::CanvasRuntime &rt)
bool show_custom_collision_overlay_
bool DrawMinecartCanvas(const gui::CanvasRuntime &rt, zelda3::Room &room, int room_id)
DungeonObjectInteraction object_interaction_
void PrepareRoomStateForCanvas(zelda3::Room &room, int room_id)
void DrawRoomCanvasContent(const gui::CanvasRuntime &canvas_rt, zelda3::Room &room, int room_id)
bool room_canvas_shortcut_focus_
const project::YazeProject * project_
MinecartCollisionTool minecart_collision_tool_
uint8_t current_entrance_blockset_
int canvas_capture_height_
void DrawMaskHighlights(const gui::CanvasRuntime &rt, const zelda3::Room &room)
DungeonRoomStore * rooms_
gfx::IRenderer * renderer_
bool minecart_owned_input_
void ConsumePendingCanvasScroll(const gui::CanvasRuntime &canvas_rt)
void RenderEntityOverlay(const gui::CanvasRuntime &rt, const zelda3::Room &room)
void HandleTouchLongPressContextMenu(const gui::CanvasRuntime &rt, const zelda3::Room &room)
MinecartTrackEditorPanel * minecart_track_panel_
int canvas_capture_width_
void DrawHeaderHiddenMetadataHud(int room_id)
bool show_header_hidden_metadata_hud_
void SetSelectedObjects(const std::vector< size_t > &indices)
void HandleCanvasMouseInput()
bool IsMaskModeActive() const
SelectedEntity GetSelectedEntity() const
void HandleMouseRelease()
void DrawEntitySelectionHighlights()
void DrawSelectionHighlights()
void SetCurrentRoom(DungeonRoomStore *rooms, int room_id)
std::vector< size_t > GetSelectedObjectIndices() const
InteractionModeManager & mode_manager()
InteractionCoordinator & entity_coordinator()
Get the interaction coordinator for entity handling.
bool HasEntitySelection() const
void CheckForObjectSelection()
zelda3::Room * GetIfLoaded(int room_id)
SpriteInteractionHandler & sprite_handler()
TileObjectHandler & tile_handler()
void ClearAllEntitySelections()
Clear all entity selections.
void CancelCurrentMode()
Cancel current mode and return to Select.
bool IsSelectMode() const
Check if in normal selection mode.
void set_canvas_editing(bool enabled)
bool collision_stamping() const
bool canvas_editing() const
bool PlaceObjectAt(int room_id, const zelda3::RoomObject &object, int x, int y)
Place a new object. Returns false if blocked by ROM limits.
void ProcessTextureQueue(IRenderer *renderer)
void set_scrolling(ImVec2 scroll)
auto global_scale() const
const CustomCollisionMap & custom_collision() const
bool ArePotItemsLoaded() const
const std::vector< zelda3::Sprite > & GetSprites() const
void PrepareForRender(std::optional< uint8_t > entrance_blockset=std::nullopt)
const std::vector< RoomObject > & GetTileObjects() const
bool AreObjectsLoaded() const
bool AreSpritesLoaded() const
A class for managing sprites in the overworld and underworld.
const AgentUITheme & GetTheme()
void DrawRoomRenderFallback(const gui::CanvasRuntime &canvas_rt)
bool IsWithinBounds(int canvas_x, int canvas_y, int margin=0)
Check if coordinates are within room bounds.
constexpr int kSpriteTileSize
std::string GetRoomLabel(const project::YazeProject *project, int room_id)
Editors are the view controllers for the application.
bool BeginSpriteDragSource(int sprite_id, int room_id)
ImVec2 ClampScroll(ImVec2 scroll, ImVec2 content_px, ImVec2 canvas_px)
void DrawCanvasHUD(const char *label, const ImVec2 &pos, const ImVec2 &size, std::function< void()> draw_content)
Draw a stylized Heads-Up Display (HUD) for canvas status.
bool AcceptRoomObjectDrop(RoomObjectDragPayload *out)
bool AcceptSpriteDrop(SpriteDragPayload *out)
bool BeginRoomObjectDragSource(uint16_t object_id, int room_id, int pos_x, int pos_y, uint8_t size=0)
std::span< const MinecartTrack > tracks