8#include "absl/strings/str_format.h"
9#include "imgui/imgui.h"
32 if (sprite_index.has_value()) {
36 ImVec2(
static_cast<float>(canvas_x),
static_cast<float>(canvas_y));
64 auto [tile_x, tile_y] =
72 auto& sprites = room->GetSprites();
90 if (!canvas->IsMouseHovering())
93 const ImGuiIO& io = ImGui::GetIO();
94 ImVec2 canvas_pos = canvas->zero_point();
98 int canvas_x =
static_cast<int>((io.MousePos.x - canvas_pos.x) / scale);
99 int canvas_y =
static_cast<int>((io.MousePos.y - canvas_pos.y) / scale);
108 ImVec2 rect_min(canvas_pos.x + snapped_x * scale,
109 canvas_pos.y + snapped_y * scale);
114 ImU32 fill_color = IM_COL32(50, 200, 50, 100);
115 ImU32 outline_color = IM_COL32(50, 255, 50, 200);
117 canvas->draw_list()->AddRectFilled(rect_min, rect_max, fill_color);
118 canvas->draw_list()->AddRect(rect_min, rect_max, outline_color, 0.0f, 0,
123 canvas->draw_list()->AddText(rect_min, IM_COL32(255, 255, 255, 255),
135 const auto& sprites = room->GetSprites();
147 auto [tile_x, tile_y] =
156 ImDrawList* draw_list = ImGui::GetWindowDrawList();
160 ImVec2 pos(canvas_pos.x + pixel_x * scale, canvas_pos.y + pixel_y * scale);
165 static float pulse = 0.0f;
166 pulse += ImGui::GetIO().DeltaTime * 3.0f;
167 float alpha = 0.5f + 0.3f * sinf(pulse);
169 ImU32 color = IM_COL32(0, 255, 0, 180);
171 (color & 0x00FFFFFF) | (
static_cast<ImU32
>(alpha * 100) << 24);
173 draw_list->AddRectFilled(pos, ImVec2(pos.x + size.x, pos.y + size.y),
175 draw_list->AddRect(pos, ImVec2(pos.x + size.x, pos.y + size.y), color, 0.0f,
179 ImVec2 text_pos(pos.x, pos.y - 14 * scale);
180 draw_list->AddText(text_pos, IM_COL32(255, 255, 255, 220),
"Sprite");
184 int canvas_x,
int canvas_y)
const {
194 int room_x =
static_cast<int>(canvas_x / scale);
195 int room_y =
static_cast<int>(canvas_y / scale);
198 const auto& sprites = room->GetSprites();
199 for (
size_t i = 0; i < sprites.size(); ++i) {
200 const auto& sprite = sprites[i];
207 if (room_x >= sprite_x &&
209 room_y >= sprite_y &&
236 auto& sprites = room->GetSprites();
241 sprites.erase(sprites.begin() +
266 static_cast<uint8_t
>(sprite_y), 0, 0);
269 room->GetSprites().push_back(new_sprite);
275 int canvas_x,
int canvas_y)
const {
278 int pixel_x =
static_cast<int>(canvas_x / scale);
279 int pixel_y =
static_cast<int>(canvas_y / scale);
InteractionContext * ctx_
float GetCanvasScale() const
Get canvas global scale.
zelda3::Room * GetCurrentRoom() const
Get current room (convenience method)
bool HasValidContext() const
Check if context is valid.
ImVec2 GetCanvasZeroPoint() const
Get canvas zero point (for screen coordinate conversion)
void PlaceSpriteAtPosition(int canvas_x, int canvas_y)
Place sprite at position.
void ClearSelection()
Clear sprite selection.
void HandleRelease() override
Handle mouse release.
void SelectSprite(size_t index)
Select sprite at index.
std::optional< size_t > selected_sprite_index_
std::optional< size_t > GetEntityAtPosition(int canvas_x, int canvas_y) const override
Get entity at canvas position.
void DrawGhostPreview() override
Draw ghost preview during placement.
uint8_t preview_sprite_id_
bool sprite_placement_mode_
void DrawSelectionHighlight() override
Draw selection highlight for selected entities.
void HandleDrag(ImVec2 current_pos, ImVec2 delta) override
Handle mouse drag.
bool HandleClick(int canvas_x, int canvas_y) override
Handle mouse click at canvas position.
std::pair< int, int > CanvasToSpriteCoords(int canvas_x, int canvas_y) const
Convert canvas to sprite coordinates (16-pixel grid)
void BeginPlacement() override
Begin placement mode.
void DeleteSelected()
Delete selected sprite.
A class for managing sprites in the overworld and underworld.
constexpr int kSpriteGridMax
constexpr int kSpriteTileSize
Editors are the view controllers for the application.
const zelda3::Room * GetCurrentRoomConst() const
Get const pointer to current room.
void NotifyEntityChanged() const
Notify that entity has changed.
void NotifyInvalidateCache() const
Notify that cache invalidation is needed.
void NotifyMutation() const
Notify that a mutation is about to happen.