77 title = absl::StrFormat(
82 title = absl::StrFormat(
87 ImGui::SetNextWindowSize(ImVec2(550, 500), ImGuiCond_FirstUseEver);
88 if (!ImGui::Begin(title.c_str(), &
is_open_)) {
100 if (ImGui::BeginTable(
101 "##TileEditorLayout", 2,
102 ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersInnerV)) {
103 ImGui::TableSetupColumn(
"Tile Grid", ImGuiTableColumnFlags_WidthFixed,
105 ImGui::TableSetupColumn(
"Source Sheet", ImGuiTableColumnFlags_WidthStretch);
107 ImGui::TableNextRow();
108 ImGui::TableNextColumn();
111 ImGui::TableNextColumn();
126 ImGui::OpenPopup(
"Shared Tile Data");
129 if (ImGui::BeginPopupModal(
"Shared Tile Data",
nullptr,
130 ImGuiWindowFlags_AlwaysAutoResize)) {
131 ImGui::Text(
"This tile data is shared by %d objects.",
133 ImGui::Text(
"Changes will affect all of them.");
135 if (ImGui::Button(
"Apply Anyway", ImVec2(120, 0))) {
137 ImGui::CloseCurrentPopup();
140 if (ImGui::Button(
"Cancel", ImVec2(120, 0))) {
141 ImGui::CloseCurrentPopup();
185 constexpr float kScale = 4.0f;
189 ImVec2 canvas_pos = ImGui::GetCursorScreenPos();
190 ImVec2 canvas_size(grid_width, grid_height);
197 ImGui::Dummy(canvas_size);
200 ImDrawList* draw_list = ImGui::GetWindowDrawList();
204 float line_x = canvas_pos.x + gx * 8 *
kScale;
205 draw_list->AddLine(ImVec2(line_x, canvas_pos.y),
206 ImVec2(line_x, canvas_pos.y + grid_height),
207 IM_COL32(128, 128, 128, 80));
210 float line_y = canvas_pos.y + gy * 8 *
kScale;
211 draw_list->AddLine(ImVec2(canvas_pos.x, line_y),
212 ImVec2(canvas_pos.x + grid_width, line_y),
213 IM_COL32(128, 128, 128, 80));
220 ImVec2 cell_min(canvas_pos.x + cell.rel_x * 8 *
kScale,
221 canvas_pos.y + cell.rel_y * 8 *
kScale);
222 ImVec2 cell_max(cell_min.x + 8 *
kScale, cell_min.y + 8 *
kScale);
223 draw_list->AddRect(cell_min, cell_max, IM_COL32(255, 255, 0, 255), 0, 0,
228 if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(0)) {
229 ImVec2 mouse = ImGui::GetMousePos();
231 static_cast<int>((mouse.x - canvas_pos.x) / (8 *
kScale));
233 static_cast<int>((mouse.y - canvas_pos.y) / (8 *
kScale));
247 int modified_count = 0;
265 ImGui::SetNextItemWidth(80);
270 constexpr float kAtlasScale = 2.0f;
274 ImVec2 atlas_pos = ImGui::GetCursorScreenPos();
275 ImVec2 atlas_size(display_width, display_height);
278 ImGui::BeginChild(
"##AtlasScroll", ImVec2(display_width + 16, 300),
true,
279 ImGuiWindowFlags_HorizontalScrollbar);
281 atlas_pos = ImGui::GetCursorScreenPos();
286 ImGui::Dummy(atlas_size);
289 ImDrawList* draw_list = ImGui::GetWindowDrawList();
293 float line_x = atlas_pos.x + gx * 8 * kAtlasScale;
294 draw_list->AddLine(ImVec2(line_x, atlas_pos.y),
295 ImVec2(line_x, atlas_pos.y + display_height),
296 IM_COL32(64, 64, 64, 60));
299 float line_y = atlas_pos.y + gy * 8 * kAtlasScale;
300 draw_list->AddLine(ImVec2(atlas_pos.x, line_y),
301 ImVec2(atlas_pos.x + display_width, line_y),
302 IM_COL32(64, 64, 64, 60));
311 ImVec2 sel_min(atlas_pos.x + src_col * 8 * kAtlasScale,
312 atlas_pos.y + src_row * 8 * kAtlasScale);
313 ImVec2 sel_max(sel_min.x + 8 * kAtlasScale, sel_min.y + 8 * kAtlasScale);
314 draw_list->AddRect(sel_min, sel_max, IM_COL32(0, 255, 255, 255), 0, 0,
319 if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(0)) {
320 ImVec2 mouse = ImGui::GetMousePos();
322 static_cast<int>((mouse.x - atlas_pos.x) / (8 * kAtlasScale));
324 static_cast<int>((mouse.y - atlas_pos.y) / (8 * kAtlasScale));
326 if (click_col >= 0 &&
339 cell.tile_info.id_ =
static_cast<uint16_t
>(tile_id);
341 cell.modified =
true;
357 ImGui::TextDisabled(
"Select a tile cell to edit properties");
362 ImGui::Text(
"Cell (%d, %d)", cell.rel_x, cell.rel_y);
366 int tile_id = cell.tile_info.id_;
367 ImGui::SetNextItemWidth(80);
368 if (ImGui::InputInt(
"ID", &tile_id, 1, 16)) {
369 cell.tile_info.id_ =
static_cast<uint16_t
>(tile_id & 0x3FF);
370 cell.modified =
true;
376 int pal = cell.tile_info.palette_;
377 ImGui::SetNextItemWidth(60);
378 if (ImGui::SliderInt(
"Pal", &pal, 0, 7)) {
379 cell.tile_info.palette_ =
static_cast<uint8_t
>(pal);
380 cell.modified =
true;
386 if (ImGui::Checkbox(
"H", &cell.tile_info.horizontal_mirror_)) {
387 cell.modified =
true;
391 if (ImGui::Checkbox(
"V", &cell.tile_info.vertical_mirror_)) {
392 cell.modified =
true;
396 if (ImGui::Checkbox(
"Pri", &cell.tile_info.over_)) {
397 cell.modified =
true;
496 if (!ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows))
504 auto find_neighbor = [&](
int dx,
int dy) ->
int {
508 int target_x = cur.rel_x + dx;
509 int target_y = cur.rel_y + dy;
510 for (
int i = 0; i < cell_count; ++i) {
519 if (ImGui::IsKeyPressed(ImGuiKey_LeftArrow,
false)) {
522 if (ImGui::IsKeyPressed(ImGuiKey_RightArrow,
false)) {
525 if (ImGui::IsKeyPressed(ImGuiKey_UpArrow,
false)) {
528 if (ImGui::IsKeyPressed(ImGuiKey_DownArrow,
false)) {
535 for (
int key = 0; key <= 7; ++key) {
536 if (ImGui::IsKeyPressed(
static_cast<ImGuiKey
>(ImGuiKey_0 + key),
false)) {
537 cell.tile_info.palette_ =
static_cast<uint8_t
>(key);
538 cell.modified =
true;
544 if (ImGui::IsKeyPressed(ImGuiKey_H,
false)) {
545 cell.tile_info.horizontal_mirror_ = !cell.tile_info.horizontal_mirror_;
546 cell.modified =
true;
551 if (ImGui::IsKeyPressed(ImGuiKey_V,
false)) {
552 cell.tile_info.vertical_mirror_ = !cell.tile_info.vertical_mirror_;
553 cell.modified =
true;
558 if (ImGui::IsKeyPressed(ImGuiKey_P,
false)) {
559 cell.tile_info.over_ = !cell.tile_info.over_;
560 cell.modified =
true;
566 if (ImGui::IsKeyPressed(ImGuiKey_Escape,
false)) {
575 if (ImGui::IsKeyPressed(ImGuiKey_Tab,
false)) {
576 if (cell_count > 0) {