dragging frames with ctrl

This commit is contained in:
2025-08-15 16:18:00 -04:00
parent 5ee3ec4351
commit f75369f670
2 changed files with 58 additions and 28 deletions

View File

@@ -970,6 +970,12 @@ static void _imgui_timeline(Imgui* self)
std::function<void(s32, Anm2Frame&)> timeline_item_frame = [&](s32 i, Anm2Frame& frame) std::function<void(s32, Anm2Frame&)> timeline_item_frame = [&](s32 i, Anm2Frame& frame)
{ {
static s32 frameDelayStart{};
static f32 frameDelayTimeStart{};
const bool isModCtrl = ImGui::IsKeyDown(IMGUI_INPUT_CTRL);
static Anm2Frame* draggingFrame = nullptr;
static Anm2Type draggingFrameType = ANM2_NONE;
ImGui::PushID(i); ImGui::PushID(i);
reference.frameIndex = i; reference.frameIndex = i;
ImVec2 framePos = ImGui::GetCursorPos(); ImVec2 framePos = ImGui::GetCursorPos();
@@ -986,8 +992,7 @@ static void _imgui_timeline(Imgui* self)
ImGui::SetCursorPos(framePos); ImGui::SetCursorPos(framePos);
if (_imgui_atlas_button(frameButton, self)) if (_imgui_atlas_button(frameButton, self)) *self->reference = reference;
*self->reference = reference;
if (ImGui::IsItemHovered()) if (ImGui::IsItemHovered())
{ {
@@ -995,23 +1000,47 @@ static void _imgui_timeline(Imgui* self)
_imgui_clipboard_hovered_item_set(self, frameWithReference); _imgui_clipboard_hovered_item_set(self, frameWithReference);
} }
if (type == ANM2_TRIGGERS) if (ImGui::IsItemActivated())
{ {
if (ImGui::IsItemActivated()) imgui_undo_push(self, IMGUI_ACTION_TRIGGER_MOVE); if (type == ANM2_TRIGGERS || isModCtrl)
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceNoPreviewTooltip))
{ {
frame.atFrame = std::max(frameTime, 0); draggingFrame = &frame;
draggingFrameType = type;
*self->reference = reference;
}
if (type == ANM2_TRIGGERS)
imgui_undo_push(self, IMGUI_ACTION_TRIGGER_MOVE);
else if (isModCtrl)
{
imgui_undo_push(self, IMGUI_ACTION_FRAME_DELAY);
frameDelayStart = draggingFrame->delay;
frameDelayTimeStart = frameTime;
}
}
if (draggingFrame)
{
if (draggingFrameType == ANM2_TRIGGERS)
{
draggingFrame->atFrame = std::max(frameTime, 0);
for (auto& frameCheck : animation->triggers.frames) for (auto& frameCheck : animation->triggers.frames)
{ {
if (&frame == &frameCheck) continue; if (draggingFrame == &frameCheck) continue;
if (frame.atFrame == frameCheck.atFrame) if (draggingFrame->atFrame == frameCheck.atFrame)
{ {
frame.atFrame++; draggingFrame->atFrame++;
break; break;
} }
} }
ImGui::EndDragDropSource(); }
else if (isModCtrl)
draggingFrame->delay = std::max(frameDelayStart + (s32)(frameTime - frameDelayTimeStart), ANM2_FRAME_NUM_MIN);
if (ImGui::IsMouseReleased(0))
{
draggingFrame = nullptr;
draggingFrameType = ANM2_NONE;
} }
} }
else else
@@ -1022,32 +1051,32 @@ static void _imgui_timeline(Imgui* self)
timeline_item_frame(i, frame); timeline_item_frame(i, frame);
ImGui::EndDragDropSource(); ImGui::EndDragDropSource();
} }
}
if (ImGui::BeginDragDropTarget()) if (ImGui::BeginDragDropTarget())
{
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(frameButton.drag_drop_get()))
{ {
Anm2Reference swapReference = *(Anm2Reference*)payload->Data; if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(frameButton.drag_drop_get()))
if (swapReference != reference)
{ {
imgui_undo_push(self, IMGUI_ACTION_FRAME_SWAP); Anm2Reference swapReference = *(Anm2Reference*)payload->Data;
if (swapReference != reference)
Anm2Frame* swapFrame = anm2_frame_from_reference(self->anm2, &reference);
Anm2Frame* dragFrame = anm2_frame_from_reference(self->anm2, &swapReference);
if (swapFrame && dragFrame)
{ {
Anm2Frame oldFrame = *swapFrame; imgui_undo_push(self, IMGUI_ACTION_FRAME_SWAP);
*swapFrame = *dragFrame; Anm2Frame* swapFrame = anm2_frame_from_reference(self->anm2, &reference);
*dragFrame = oldFrame; Anm2Frame* dragFrame = anm2_frame_from_reference(self->anm2, &swapReference);
if (swapFrame && dragFrame)
{
Anm2Frame oldFrame = *swapFrame;
*self->reference = swapReference; *swapFrame = *dragFrame;
*dragFrame = oldFrame;
*self->reference = swapReference;
}
} }
} }
ImGui::EndDragDropTarget();
} }
ImGui::EndDragDropTarget();
} }
if (i < (s32)item->frames.size() - 1) ImGui::SameLine(); if (i < (s32)item->frames.size() - 1) ImGui::SameLine();

View File

@@ -66,6 +66,7 @@
#define IMGUI_ACTION_FRAME_TRANSFORM "Frame Transform" #define IMGUI_ACTION_FRAME_TRANSFORM "Frame Transform"
#define IMGUI_ACTION_ANIMATION_SWAP "Animation Swap" #define IMGUI_ACTION_ANIMATION_SWAP "Animation Swap"
#define IMGUI_ACTION_TRIGGER_MOVE "Trigger AtFrame" #define IMGUI_ACTION_TRIGGER_MOVE "Trigger AtFrame"
#define IMGUI_ACTION_FRAME_DELAY "Frame Delay"
#define IMGUI_ACTION_MOVE_PLAYHEAD "Move Playhead" #define IMGUI_ACTION_MOVE_PLAYHEAD "Move Playhead"
#define IMGUI_POPUP_FLAGS ImGuiWindowFlags_NoMove #define IMGUI_POPUP_FLAGS ImGuiWindowFlags_NoMove