Refactoring, FFmpeg updates
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
#include "spritesheet_editor.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <utility>
|
||||
|
||||
#include "math_.h"
|
||||
#include "tool.h"
|
||||
#include "types.h"
|
||||
@@ -20,17 +23,20 @@ namespace anm2ed::imgui
|
||||
|
||||
void SpritesheetEditor::update(Manager& manager, Settings& settings, Resources& resources)
|
||||
{
|
||||
|
||||
auto& document = *manager.get();
|
||||
auto& anm2 = document.anm2;
|
||||
auto& reference = document.reference;
|
||||
auto& referenceSpritesheet = document.referenceSpritesheet;
|
||||
auto& referenceSpritesheet = document.spritesheet.reference;
|
||||
auto& pan = document.editorPan;
|
||||
auto& zoom = document.editorZoom;
|
||||
auto& backgroundColor = settings.editorBackgroundColor;
|
||||
auto& gridColor = settings.editorGridColor;
|
||||
auto& gridSize = settings.editorGridSize;
|
||||
auto& gridOffset = settings.editorGridOffset;
|
||||
auto& toolColor = settings.toolColor;
|
||||
auto& isGrid = settings.editorIsGrid;
|
||||
auto& isGridSnap = settings.editorIsGridSnap;
|
||||
auto& zoomStep = settings.viewZoomStep;
|
||||
auto& isBorder = settings.editorIsBorder;
|
||||
auto spritesheet = document.spritesheet_get();
|
||||
@@ -39,6 +45,8 @@ namespace anm2ed::imgui
|
||||
auto& shaderTexture = resources.shaders[shader::TEXTURE];
|
||||
auto& dashedShader = resources.shaders[shader::DASHED];
|
||||
|
||||
auto center_view = [&]() { pan = -size * 0.5f; };
|
||||
|
||||
if (ImGui::Begin("Spritesheet Editor", &settings.windowIsSpritesheetEditor))
|
||||
{
|
||||
auto childSize = ImVec2(imgui::row_widget_width_get(3),
|
||||
@@ -47,10 +55,19 @@ namespace anm2ed::imgui
|
||||
if (ImGui::BeginChild("##Grid Child", childSize, true, ImGuiWindowFlags_HorizontalScrollbar))
|
||||
{
|
||||
ImGui::Checkbox("Grid", &isGrid);
|
||||
ImGui::SetItemTooltip("Toggle the visibility of the grid.");
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Snap", &isGridSnap);
|
||||
ImGui::SetItemTooltip("Cropping will snap points to the grid.");
|
||||
ImGui::SameLine();
|
||||
ImGui::ColorEdit4("Color", value_ptr(gridColor), ImGuiColorEditFlags_NoInputs);
|
||||
ImGui::InputInt2("Size", value_ptr(gridSize));
|
||||
ImGui::InputInt2("Offset", value_ptr(gridOffset));
|
||||
ImGui::SetItemTooltip("Change the grid's color.");
|
||||
|
||||
input_int2_range("Size", gridSize, ivec2(GRID_SIZE_MIN), ivec2(GRID_SIZE_MAX));
|
||||
ImGui::SetItemTooltip("Change the size of all cells in the grid.");
|
||||
|
||||
input_int2_range("Offset", gridOffset, ivec2(GRID_OFFSET_MIN), ivec2(GRID_OFFSET_MAX));
|
||||
ImGui::SetItemTooltip("Change the offset of the grid.");
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
@@ -59,11 +76,12 @@ namespace anm2ed::imgui
|
||||
if (ImGui::BeginChild("##View Child", childSize, true, ImGuiWindowFlags_HorizontalScrollbar))
|
||||
{
|
||||
ImGui::InputFloat("Zoom", &zoom, zoomStep, zoomStep, "%.0f%%");
|
||||
ImGui::SetItemTooltip("Change the zoom of the editor.");
|
||||
|
||||
auto widgetSize = ImVec2(imgui::row_widget_width_get(2), 0);
|
||||
|
||||
imgui::shortcut(settings.shortcutCenterView);
|
||||
if (ImGui::Button("Center View", widgetSize)) pan = -size * 0.5f;
|
||||
if (ImGui::Button("Center View", widgetSize)) center_view();
|
||||
imgui::set_item_tooltip_shortcut("Centers the view.", settings.shortcutCenterView);
|
||||
|
||||
ImGui::SameLine();
|
||||
@@ -82,8 +100,10 @@ namespace anm2ed::imgui
|
||||
if (ImGui::BeginChild("##Background Child", childSize, true, ImGuiWindowFlags_HorizontalScrollbar))
|
||||
{
|
||||
ImGui::ColorEdit4("Background", value_ptr(backgroundColor), ImGuiColorEditFlags_NoInputs);
|
||||
ImGui::SetItemTooltip("Change the background color.");
|
||||
|
||||
ImGui::Checkbox("Border", &isBorder);
|
||||
ImGui::SetItemTooltip("Toggle a border appearing around the spritesheet.");
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
@@ -127,45 +147,85 @@ namespace anm2ed::imgui
|
||||
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::SetKeyboardFocusHere(-1);
|
||||
|
||||
previousMousePos = mousePos;
|
||||
mousePos = position_translate(zoom, pan, to_vec2(ImGui::GetMousePos()) - to_vec2(cursorScreenPos));
|
||||
|
||||
auto isMouseClicked = ImGui::IsMouseClicked(ImGuiMouseButton_Left);
|
||||
auto isMouseDown = ImGui::IsMouseDown(ImGuiMouseButton_Left);
|
||||
auto isMouseLeftClicked = ImGui::IsMouseClicked(ImGuiMouseButton_Left);
|
||||
auto isMouseLeftReleased = ImGui::IsMouseReleased(ImGuiMouseButton_Left);
|
||||
auto isMouseLeftDown = ImGui::IsMouseDown(ImGuiMouseButton_Left);
|
||||
auto isMouseMiddleDown = ImGui::IsMouseDown(ImGuiMouseButton_Middle);
|
||||
auto isMouseRightClicked = ImGui::IsMouseClicked(ImGuiMouseButton_Right);
|
||||
auto isMouseRightDown = ImGui::IsMouseDown(ImGuiMouseButton_Right);
|
||||
auto isMouseRightReleased = ImGui::IsMouseReleased(ImGuiMouseButton_Right);
|
||||
auto mouseDelta = to_ivec2(ImGui::GetIO().MouseDelta);
|
||||
auto mouseWheel = ImGui::GetIO().MouseWheel;
|
||||
auto& toolColor = settings.toolColor;
|
||||
auto isZoomIn = imgui::chord_repeating(imgui::string_to_chord(settings.shortcutZoomIn));
|
||||
auto isZoomOut = imgui::chord_repeating(imgui::string_to_chord(settings.shortcutZoomOut));
|
||||
auto isLeft = imgui::chord_repeating(ImGuiKey_LeftArrow);
|
||||
auto isRight = imgui::chord_repeating(ImGuiKey_RightArrow);
|
||||
auto isUp = imgui::chord_repeating(ImGuiKey_UpArrow);
|
||||
auto isDown = imgui::chord_repeating(ImGuiKey_DownArrow);
|
||||
auto isMod = ImGui::IsKeyDown(ImGuiMod_Shift);
|
||||
auto step = isMod ? canvas::STEP_FAST : canvas::STEP;
|
||||
auto useTool = tool;
|
||||
auto isMouseClick = ImGui::IsMouseClicked(ImGuiMouseButton_Left);
|
||||
auto isMouseReleased = ImGui::IsMouseReleased(ImGuiMouseButton_Left);
|
||||
auto isLeftPressed = ImGui::IsKeyPressed(ImGuiKey_LeftArrow, false);
|
||||
auto isRightPressed = ImGui::IsKeyPressed(ImGuiKey_RightArrow, false);
|
||||
auto isUpPressed = ImGui::IsKeyPressed(ImGuiKey_UpArrow, false);
|
||||
auto isDownPressed = ImGui::IsKeyPressed(ImGuiKey_DownArrow, false);
|
||||
auto isMouseClicked = isMouseLeftClicked || isMouseRightClicked;
|
||||
auto isMouseDown = isMouseLeftDown || isMouseRightDown;
|
||||
auto isMouseReleased = isMouseLeftReleased || isMouseRightReleased;
|
||||
|
||||
auto isLeftJustPressed = ImGui::IsKeyPressed(ImGuiKey_LeftArrow, false);
|
||||
auto isRightJustPressed = ImGui::IsKeyPressed(ImGuiKey_RightArrow, false);
|
||||
auto isUpJustPressed = ImGui::IsKeyPressed(ImGuiKey_UpArrow, false);
|
||||
auto isDownJustPressed = ImGui::IsKeyPressed(ImGuiKey_DownArrow, false);
|
||||
auto isLeftPressed = ImGui::IsKeyPressed(ImGuiKey_LeftArrow);
|
||||
auto isRightPressed = ImGui::IsKeyPressed(ImGuiKey_RightArrow);
|
||||
auto isUpPressed = ImGui::IsKeyPressed(ImGuiKey_UpArrow);
|
||||
auto isDownPressed = ImGui::IsKeyPressed(ImGuiKey_DownArrow);
|
||||
auto isLeftDown = ImGui::IsKeyDown(ImGuiKey_LeftArrow);
|
||||
auto isRightDown = ImGui::IsKeyDown(ImGuiKey_RightArrow);
|
||||
auto isUpDown = ImGui::IsKeyDown(ImGuiKey_UpArrow);
|
||||
auto isDownDown = ImGui::IsKeyDown(ImGuiKey_DownArrow);
|
||||
auto isLeftReleased = ImGui::IsKeyReleased(ImGuiKey_LeftArrow);
|
||||
auto isRightReleased = ImGui::IsKeyReleased(ImGuiKey_RightArrow);
|
||||
auto isUpReleased = ImGui::IsKeyReleased(ImGuiKey_UpArrow);
|
||||
auto isDownReleased = ImGui::IsKeyReleased(ImGuiKey_DownArrow);
|
||||
auto frame = document.frame_get();
|
||||
auto isKeyPressed = isLeftPressed || isRightPressed || isUpPressed || isDownPressed;
|
||||
auto isKeyJustPressed = isLeftJustPressed || isRightJustPressed || isUpJustPressed || isDownJustPressed;
|
||||
auto isKeyDown = isLeftDown || isRightDown || isUpDown || isDownDown;
|
||||
auto isKeyReleased = isLeftReleased || isRightReleased || isUpReleased || isDownReleased;
|
||||
auto isBegin = isMouseClick || isKeyPressed;
|
||||
|
||||
auto isZoomIn = chord_repeating(string_to_chord(settings.shortcutZoomIn));
|
||||
auto isZoomOut = chord_repeating(string_to_chord(settings.shortcutZoomOut));
|
||||
|
||||
auto isBegin = isMouseClicked || isKeyJustPressed;
|
||||
auto isDuring = isMouseDown || isKeyDown;
|
||||
auto isEnd = isMouseReleased || isKeyReleased;
|
||||
|
||||
if (isMouseMiddleDown) useTool = tool::PAN;
|
||||
auto isMod = ImGui::IsKeyDown(ImGuiMod_Shift);
|
||||
|
||||
ImGui::SetMouseCursor(tool::INFO[useTool].cursor);
|
||||
auto frame = document.frame_get();
|
||||
auto useTool = tool;
|
||||
auto step = isMod ? canvas::STEP_FAST : canvas::STEP;
|
||||
auto stepX = isGridSnap ? step * gridSize.x : step;
|
||||
auto stepY = isGridSnap ? step * gridSize.y : step;
|
||||
previousMousePos = mousePos;
|
||||
mousePos = position_translate(zoom, pan, to_vec2(ImGui::GetMousePos()) - to_vec2(cursorScreenPos));
|
||||
|
||||
auto snap_rect = [&](glm::vec2 minPoint, glm::vec2 maxPoint)
|
||||
{
|
||||
if (isGridSnap)
|
||||
{
|
||||
if (gridSize.x != 0)
|
||||
{
|
||||
minPoint.x = std::floor(minPoint.x / gridSize.x) * gridSize.x;
|
||||
maxPoint.x = std::ceil(maxPoint.x / gridSize.x) * gridSize.x;
|
||||
}
|
||||
if (gridSize.y != 0)
|
||||
{
|
||||
minPoint.y = std::floor(minPoint.y / gridSize.y) * gridSize.y;
|
||||
maxPoint.y = std::ceil(maxPoint.y / gridSize.y) * gridSize.y;
|
||||
}
|
||||
}
|
||||
return std::pair{minPoint, maxPoint};
|
||||
};
|
||||
|
||||
if (isMouseMiddleDown) useTool = tool::PAN;
|
||||
if (tool == tool::MOVE && isMouseRightDown) useTool = tool::CROP;
|
||||
if (tool == tool::CROP && isMouseRightDown) useTool = tool::MOVE;
|
||||
if (tool == tool::DRAW && isMouseRightDown) useTool = tool::ERASE;
|
||||
if (tool == tool::ERASE && isMouseRightDown) useTool = tool::DRAW;
|
||||
|
||||
auto& areaType = tool::INFO[useTool].areaType;
|
||||
auto cursor = areaType == tool::SPRITESHEET_EDITOR || areaType == tool::ALL ? tool::INFO[useTool].cursor
|
||||
: ImGuiMouseCursor_NotAllowed;
|
||||
ImGui::SetMouseCursor(cursor);
|
||||
ImGui::SetKeyboardFocusHere(-1);
|
||||
|
||||
switch (useTool)
|
||||
{
|
||||
@@ -176,36 +236,84 @@ namespace anm2ed::imgui
|
||||
if (!frame) break;
|
||||
if (isBegin) document.snapshot("Frame Pivot");
|
||||
if (isMouseDown) frame->pivot = ivec2(mousePos - frame->crop);
|
||||
if (isLeft) frame->pivot.x -= step;
|
||||
if (isRight) frame->pivot.x += step;
|
||||
if (isUp) frame->pivot.y -= step;
|
||||
if (isDown) frame->pivot.y += step;
|
||||
if (isLeftPressed) frame->pivot.x -= step;
|
||||
if (isRightPressed) frame->pivot.x += step;
|
||||
if (isUpPressed) frame->pivot.y -= step;
|
||||
if (isDownPressed) frame->pivot.y += step;
|
||||
if (isDuring)
|
||||
{
|
||||
if (ImGui::BeginTooltip())
|
||||
{
|
||||
auto pivotFormat = math::vec2_format_get(frame->pivot);
|
||||
auto pivotString = std::format("Pivot: ({}, {})", pivotFormat, pivotFormat);
|
||||
ImGui::Text(pivotString.c_str(), frame->pivot.x, frame->pivot.y);
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
if (isEnd) document.change(Document::FRAMES);
|
||||
break;
|
||||
case tool::CROP:
|
||||
if (!frame) break;
|
||||
if (isBegin) document.snapshot(isMod ? "Frame Size" : "Frame Crop");
|
||||
if (isMouseClicked) frame->crop = ivec2(mousePos);
|
||||
if (isMouseDown) frame->size = ivec2(mousePos - frame->crop);
|
||||
if (isLeft) isMod ? frame->size.x -= step : frame->crop.x -= step;
|
||||
if (isRight) isMod ? frame->size.x += step : frame->crop.x += step;
|
||||
if (isUp) isMod ? frame->size.y -= step : frame->crop.y -= step;
|
||||
if (isDown) isMod ? frame->size.y += step : frame->crop.y += step;
|
||||
if (isBegin) document.snapshot("Frame Crop");
|
||||
|
||||
if (isMouseClicked)
|
||||
{
|
||||
cropAnchor = mousePos;
|
||||
frame->crop = cropAnchor;
|
||||
frame->size = vec2();
|
||||
}
|
||||
if (isMouseDown)
|
||||
{
|
||||
auto [minPoint, maxPoint] = snap_rect(glm::min(cropAnchor, mousePos), glm::max(cropAnchor, mousePos));
|
||||
frame->crop = minPoint;
|
||||
frame->size = maxPoint - minPoint;
|
||||
}
|
||||
if (isLeftPressed) frame->crop.x -= stepX;
|
||||
if (isRightPressed) frame->crop.x += stepX;
|
||||
if (isUpPressed) frame->crop.y -= stepY;
|
||||
if (isDownPressed) frame->crop.y += stepY;
|
||||
if (isDuring)
|
||||
{
|
||||
if (!isMouseDown)
|
||||
{
|
||||
auto minPoint = glm::min(frame->crop, frame->crop + frame->size);
|
||||
auto maxPoint = glm::max(frame->crop, frame->crop + frame->size);
|
||||
frame->crop = minPoint;
|
||||
frame->size = maxPoint - minPoint;
|
||||
if (isGridSnap)
|
||||
{
|
||||
auto [snapMin, snapMax] = snap_rect(frame->crop, frame->crop + frame->size);
|
||||
frame->crop = snapMin;
|
||||
frame->size = snapMax - snapMin;
|
||||
}
|
||||
}
|
||||
if (ImGui::BeginTooltip())
|
||||
{
|
||||
auto cropFormat = math::vec2_format_get(frame->crop);
|
||||
auto sizeFormat = math::vec2_format_get(frame->size);
|
||||
auto cropString = std::format("Crop: ({}, {})", cropFormat, cropFormat);
|
||||
auto sizeString = std::format("Size: ({}, {})", sizeFormat, sizeFormat);
|
||||
ImGui::Text(cropString.c_str(), frame->crop.x, frame->crop.y);
|
||||
ImGui::Text(sizeString.c_str(), frame->size.x, frame->size.y);
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
if (isEnd) document.change(Document::FRAMES);
|
||||
break;
|
||||
case tool::DRAW:
|
||||
case tool::ERASE:
|
||||
{
|
||||
if (!spritesheet) break;
|
||||
auto color = tool == tool::DRAW ? toolColor : vec4();
|
||||
if (isMouseClicked) document.snapshot(tool == tool::DRAW ? "Draw" : "Erase");
|
||||
auto color = useTool == tool::DRAW ? toolColor : vec4();
|
||||
if (isMouseClicked) document.snapshot(useTool == tool::DRAW ? "Draw" : "Erase");
|
||||
if (isMouseDown) spritesheet->texture.pixel_line(ivec2(previousMousePos), ivec2(mousePos), color);
|
||||
if (isMouseReleased) document.change(Document::FRAMES);
|
||||
if (isMouseReleased) document.change(Document::SPRITESHEETS);
|
||||
break;
|
||||
}
|
||||
case tool::COLOR_PICKER:
|
||||
{
|
||||
if (isMouseDown)
|
||||
if (isDuring)
|
||||
{
|
||||
auto position = to_vec2(ImGui::GetMousePos());
|
||||
toolColor = pixel_read(position, {settings.windowSize.x, settings.windowSize.y});
|
||||
@@ -222,9 +330,26 @@ namespace anm2ed::imgui
|
||||
}
|
||||
|
||||
if (mouseWheel != 0 || isZoomIn || isZoomOut)
|
||||
zoom_set(zoom, pan, mousePos, (mouseWheel > 0 || isZoomIn) ? zoomStep : -zoomStep);
|
||||
{
|
||||
auto focus = mouseWheel != 0 ? vec2(mousePos) : vec2();
|
||||
if (auto spritesheet = document.spritesheet_get(); spritesheet && mouseWheel == 0)
|
||||
focus = spritesheet->texture.size / 2;
|
||||
|
||||
zoom_set(zoom, pan, focus, (mouseWheel > 0 || isZoomIn) ? zoomStep : -zoomStep);
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
if (!document.isSpritesheetEditorSet)
|
||||
{
|
||||
size = settings.editorSize;
|
||||
zoom = settings.editorStartZoom;
|
||||
center_view();
|
||||
document.isSpritesheetEditorSet = true;
|
||||
}
|
||||
|
||||
settings.editorSize = size;
|
||||
settings.editorStartZoom = zoom;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user