fuck git and fuck vs code

This commit is contained in:
2025-11-11 11:25:46 -05:00
parent d07b4dc2eb
commit 07096c487b
62 changed files with 1635 additions and 1301 deletions

View File

@@ -24,14 +24,13 @@ namespace anm2ed::imgui
constexpr auto NULL_RECT_SIZE = vec2(100);
constexpr auto TRIGGER_TEXT_COLOR = ImVec4(1.0f, 1.0f, 1.0f, 0.5f);
AnimationPreview::AnimationPreview() : Canvas(vec2())
{
}
AnimationPreview::AnimationPreview() : Canvas(vec2()) {}
void AnimationPreview::tick(Manager& manager, Document& document, Settings& settings)
{
auto& anm2 = document.anm2;
auto& playback = document.playback;
auto& frameTime = document.frameTime;
auto& zoom = document.previewZoom;
auto& pan = document.previewPan;
auto& isRootTransform = settings.previewIsRootTransform;
@@ -53,7 +52,7 @@ namespace anm2ed::imgui
}
}
document.reference.frameTime = playback.time;
frameTime = playback.time;
}
if (manager.isRecording)
@@ -124,6 +123,7 @@ namespace anm2ed::imgui
settings.previewIsGrid = false;
settings.previewIsAxes = false;
settings.timelineIsOnlyShowLayers = true;
settings.onionskinIsEnabled = false;
savedZoom = zoom;
savedPan = pan;
@@ -211,13 +211,13 @@ namespace anm2ed::imgui
auto widgetSize = widget_size_with_row_get(2);
shortcut(settings.shortcutCenterView);
shortcut(manager.chords[SHORTCUT_CENTER_VIEW]);
if (ImGui::Button("Center View", widgetSize)) pan = vec2();
set_item_tooltip_shortcut("Centers the view.", settings.shortcutCenterView);
ImGui::SameLine();
shortcut(settings.shortcutFit);
shortcut(manager.chords[SHORTCUT_FIT]);
if (ImGui::Button("Fit", widgetSize))
if (animation) set_to_rect(zoom, pan, animation->rect(isRootTransform));
set_item_tooltip_shortcut("Set the view to match the extent of the animation.", settings.shortcutFit);
@@ -397,7 +397,7 @@ namespace anm2ed::imgui
onionskin_render(time, settings.onionskinAfterCount, 1, settings.onionskinAfterColor);
};
auto frameTime = reference.frameTime > -1 && !playback.isPlaying ? reference.frameTime : playback.time;
auto frameTime = document.frameTime > -1 && !playback.isPlaying ? document.frameTime : playback.time;
if (animation)
{
@@ -408,7 +408,7 @@ namespace anm2ed::imgui
render(animation, frameTime);
if (auto overlayAnimation = anm2.animation_get({overlayIndex}))
if (auto overlayAnimation = anm2.animation_get(overlayIndex))
render(overlayAnimation, frameTime, {}, 1.0f - math::uint8_to_float(overlayTransparency));
if (drawOrder == draw_order::ABOVE && isEnabled) onionskins_render(frameTime);
@@ -469,8 +469,8 @@ namespace anm2ed::imgui
auto isKeyDown = isLeftDown || isRightDown || isUpDown || isDownDown;
auto isKeyReleased = isLeftReleased || isRightReleased || isUpReleased || isDownReleased;
auto isZoomIn = chord_repeating(string_to_chord(settings.shortcutZoomIn));
auto isZoomOut = chord_repeating(string_to_chord(settings.shortcutZoomOut));
auto isZoomIn = chord_repeating(manager.chords[SHORTCUT_ZOOM_IN]);
auto isZoomOut = chord_repeating(manager.chords[SHORTCUT_ZOOM_OUT]);
auto isBegin = isMouseClicked || isKeyJustPressed;
auto isDuring = isMouseDown || isKeyDown;

View File

@@ -48,7 +48,10 @@ namespace anm2ed::imgui
ImGui::SetNextItemSelectionUserData((int)i);
if (selectable_input_text(animation.name, std::format("###Document #{} Animation #{}", manager.selected, i),
animation.name, selection.contains((int)i)))
{
reference = {(int)i};
document.frames.clear();
}
if (ImGui::IsItemHovered()) hovered = (int)i;
ImGui::PopFont();
@@ -155,9 +158,9 @@ namespace anm2ed::imgui
DOCUMENT_EDIT(document, "Paste Animation(s)", Document::ANIMATIONS, deserialize());
};
if (shortcut(settings.shortcutCut, shortcut::FOCUSED)) cut();
if (shortcut(settings.shortcutCopy, shortcut::FOCUSED)) copy();
if (shortcut(settings.shortcutPaste, shortcut::FOCUSED)) paste();
if (shortcut(manager.chords[SHORTCUT_CUT], shortcut::FOCUSED)) cut();
if (shortcut(manager.chords[SHORTCUT_COPY], shortcut::FOCUSED)) copy();
if (shortcut(manager.chords[SHORTCUT_PASTE], shortcut::FOCUSED)) paste();
if (ImGui::BeginPopupContextWindow("##Context Menu", ImGuiPopupFlags_MouseButtonRight))
{
@@ -171,7 +174,7 @@ namespace anm2ed::imgui
auto widgetSize = widget_size_with_row_get(5);
shortcut(settings.shortcutAdd);
shortcut(manager.chords[SHORTCUT_ADD]);
if (ImGui::Button("Add", widgetSize))
{
auto add = [&]()
@@ -204,7 +207,7 @@ namespace anm2ed::imgui
ImGui::BeginDisabled(selection.empty());
{
shortcut(settings.shortcutDuplicate);
shortcut(manager.chords[SHORTCUT_DUPLICATE]);
if (ImGui::Button("Duplicate", widgetSize))
{
auto duplicate = [&]()
@@ -225,7 +228,7 @@ namespace anm2ed::imgui
ImGui::SameLine();
if (shortcut(settings.shortcutMerge, shortcut::FOCUSED) && !selection.empty())
if (shortcut(manager.chords[SHORTCUT_MERGE], shortcut::FOCUSED) && !selection.empty())
{
auto merge_quick = [&]()
{
@@ -270,7 +273,7 @@ namespace anm2ed::imgui
ImGui::SameLine();
shortcut(settings.shortcutRemove);
shortcut(manager.chords[SHORTCUT_REMOVE]);
if (ImGui::Button("Remove", widgetSize))
{
auto remove = [&]()
@@ -285,11 +288,11 @@ namespace anm2ed::imgui
DOCUMENT_EDIT(document, "Remove Animation(s)", Document::ANIMATIONS, remove());
}
set_item_tooltip_shortcut("Remove the selected animation(s).", settings.shortcutDuplicate);
set_item_tooltip_shortcut("Remove the selected animation(s).", settings.shortcutRemove);
ImGui::SameLine();
shortcut(settings.shortcutDefault);
shortcut(manager.chords[SHORTCUT_DEFAULT]);
ImGui::BeginDisabled(selection.size() != 1);
if (ImGui::Button("Default", widgetSize))
{
@@ -369,21 +372,25 @@ namespace anm2ed::imgui
auto widgetSize = widget_size_with_row_get(2);
if (ImGui::Button("Merge", widgetSize))
ImGui::BeginDisabled(mergeSelection.empty());
{
auto merge = [&]()
if (ImGui::Button("Merge", widgetSize))
{
if (mergeSelection.contains(overlayIndex)) overlayIndex = -1;
auto merged =
anm2.animations_merge(mergeReference, mergeSelection, (merge::Type)type, isDeleteAnimationsAfter);
auto merge = [&]()
{
if (mergeSelection.contains(overlayIndex)) overlayIndex = -1;
auto merged =
anm2.animations_merge(mergeReference, mergeSelection, (merge::Type)type, isDeleteAnimationsAfter);
selection = {merged};
reference = {merged};
};
selection = {merged};
reference = {merged};
};
DOCUMENT_EDIT(document, "Merge Animations", Document::ANIMATIONS, merge());
merge_close();
DOCUMENT_EDIT(document, "Merge Animations", Document::ANIMATIONS, merge());
merge_close();
}
}
ImGui::EndDisabled();
ImGui::SameLine();
if (ImGui::Button("Close", widgetSize)) merge_close();

View File

@@ -73,8 +73,8 @@ namespace anm2ed::imgui
toasts.error(std::format("Failed to deserialize event(s): {}", errorString));
};
if (shortcut(settings.shortcutCopy, shortcut::FOCUSED)) copy();
if (shortcut(settings.shortcutPaste, shortcut::FOCUSED)) paste(merge::APPEND);
if (shortcut(manager.chords[SHORTCUT_COPY], shortcut::FOCUSED)) copy();
if (shortcut(manager.chords[SHORTCUT_PASTE], shortcut::FOCUSED)) paste(merge::APPEND);
if (ImGui::BeginPopupContextWindow("##Context Menu", ImGuiPopupFlags_MouseButtonRight))
{
@@ -96,7 +96,7 @@ namespace anm2ed::imgui
auto widgetSize = widget_size_with_row_get(2);
shortcut(settings.shortcutAdd);
shortcut(manager.chords[SHORTCUT_ADD]);
if (ImGui::Button("Add", widgetSize))
{
auto add = [&]()
@@ -112,7 +112,7 @@ namespace anm2ed::imgui
set_item_tooltip_shortcut("Add an event.", settings.shortcutAdd);
ImGui::SameLine();
shortcut(settings.shortcutRemove);
shortcut(manager.chords[SHORTCUT_REMOVE]);
ImGui::BeginDisabled(unused.empty());
if (ImGui::Button("Remove Unused", widgetSize))
{

View File

@@ -16,108 +16,217 @@ namespace anm2ed::imgui
if (ImGui::Begin("Frame Properties", &settings.windowIsFrameProperties))
{
auto& document = *manager.get();
auto& frames = document.frames.selection;
auto& type = document.reference.itemType;
auto frame = document.frame_get();
auto useFrame = frame ? *frame : anm2::Frame();
ImGui::BeginDisabled(!frame);
if (frames.size() <= 1)
{
if (type == anm2::TRIGGER)
auto frame = document.frame_get();
auto useFrame = frame ? *frame : anm2::Frame();
ImGui::BeginDisabled(!frame);
{
if (combo_negative_one_indexed("Event", frame ? &useFrame.eventID : &dummy_value<int>(),
document.event.labels))
DOCUMENT_EDIT(document, "Trigger Event", Document::FRAMES, frame->eventID = useFrame.eventID);
ImGui::SetItemTooltip("Change the event this trigger uses.");
if (combo_negative_one_indexed("Sound", frame ? &useFrame.soundID : &dummy_value<int>(),
document.sound.labels))
DOCUMENT_EDIT(document, "Trigger Sound", Document::FRAMES, frame->soundID = useFrame.soundID);
ImGui::SetItemTooltip("Change the sound this trigger uses.");
if (ImGui::InputInt("At Frame", frame ? &useFrame.atFrame : &dummy_value<int>(), imgui::STEP,
imgui::STEP_FAST, !frame ? ImGuiInputTextFlags_DisplayEmptyRefVal : 0))
DOCUMENT_EDIT(document, "Trigger At Frame", Document::FRAMES, frame->atFrame = useFrame.atFrame);
ImGui::SetItemTooltip("Change the frame the trigger will be activated at.");
}
else
{
ImGui::BeginDisabled(type == anm2::ROOT || type == anm2::NULL_);
if (type == anm2::TRIGGER)
{
if (ImGui::InputFloat2("Crop", frame ? value_ptr(useFrame.crop) : &dummy_value<float>(),
frame ? vec2_format_get(useFrame.crop) : ""))
DOCUMENT_EDIT(document, "Frame Crop", Document::FRAMES, frame->crop = useFrame.crop);
ImGui::SetItemTooltip("Change the crop position the frame uses.");
if (combo_negative_one_indexed("Event", frame ? &useFrame.eventID : &dummy_value_negative<int>(),
document.event.labels))
DOCUMENT_EDIT(document, "Trigger Event", Document::FRAMES, frame->eventID = useFrame.eventID);
ImGui::SetItemTooltip("Change the event this trigger uses.");
if (ImGui::InputFloat2("Size", frame ? value_ptr(useFrame.size) : &dummy_value<float>(),
frame ? vec2_format_get(useFrame.size) : ""))
DOCUMENT_EDIT(document, "Frame Size", Document::FRAMES, frame->size = useFrame.size);
ImGui::SetItemTooltip("Change the size of the crop the frame uses.");
if (combo_negative_one_indexed("Sound", frame ? &useFrame.soundID : &dummy_value_negative<int>(),
document.sound.labels))
DOCUMENT_EDIT(document, "Trigger Sound", Document::FRAMES, frame->soundID = useFrame.soundID);
ImGui::SetItemTooltip("Change the sound this trigger uses.");
if (ImGui::InputInt("At Frame", frame ? &useFrame.atFrame : &dummy_value<int>(), STEP, STEP_FAST,
!frame ? ImGuiInputTextFlags_DisplayEmptyRefVal : 0))
DOCUMENT_EDIT(document, "Trigger At Frame", Document::FRAMES, frame->atFrame = useFrame.atFrame);
ImGui::SetItemTooltip("Change the frame the trigger will be activated at.");
if (ImGui::Checkbox("Visible", frame ? &useFrame.isVisible : &dummy_value<bool>()))
DOCUMENT_EDIT(document, "Trigger Visibility", Document::FRAMES, frame->isVisible = useFrame.isVisible);
ImGui::SetItemTooltip("Toggle the trigger's visibility.");
}
ImGui::EndDisabled();
if (ImGui::InputFloat2("Position", frame ? value_ptr(useFrame.position) : &dummy_value<float>(),
frame ? vec2_format_get(useFrame.position) : ""))
DOCUMENT_EDIT(document, "Frame Position", Document::FRAMES, frame->position = useFrame.position);
ImGui::SetItemTooltip("Change the position of the frame.");
ImGui::BeginDisabled(type == anm2::ROOT || type == anm2::NULL_);
else
{
if (ImGui::InputFloat2("Pivot", frame ? value_ptr(useFrame.pivot) : &dummy_value<float>(),
frame ? vec2_format_get(useFrame.pivot) : ""))
DOCUMENT_EDIT(document, "Frame Pivot", Document::FRAMES, frame->pivot = useFrame.pivot);
ImGui::SetItemTooltip("Change the pivot of the frame; i.e., where it is centered.");
ImGui::BeginDisabled(type == anm2::ROOT || type == anm2::NULL_);
{
if (ImGui::InputFloat2("Crop", frame ? value_ptr(useFrame.crop) : &dummy_value<float>(),
frame ? vec2_format_get(useFrame.crop) : ""))
DOCUMENT_EDIT(document, "Frame Crop", Document::FRAMES, frame->crop = useFrame.crop);
ImGui::SetItemTooltip("Change the crop position the frame uses.");
if (ImGui::InputFloat2("Size", frame ? value_ptr(useFrame.size) : &dummy_value<float>(),
frame ? vec2_format_get(useFrame.size) : ""))
DOCUMENT_EDIT(document, "Frame Size", Document::FRAMES, frame->size = useFrame.size);
ImGui::SetItemTooltip("Change the size of the crop the frame uses.");
}
ImGui::EndDisabled();
if (ImGui::InputFloat2("Position", frame ? value_ptr(useFrame.position) : &dummy_value<float>(),
frame ? vec2_format_get(useFrame.position) : ""))
DOCUMENT_EDIT(document, "Frame Position", Document::FRAMES, frame->position = useFrame.position);
ImGui::SetItemTooltip("Change the position of the frame.");
ImGui::BeginDisabled(type == anm2::ROOT || type == anm2::NULL_);
{
if (ImGui::InputFloat2("Pivot", frame ? value_ptr(useFrame.pivot) : &dummy_value<float>(),
frame ? vec2_format_get(useFrame.pivot) : ""))
DOCUMENT_EDIT(document, "Frame Pivot", Document::FRAMES, frame->pivot = useFrame.pivot);
ImGui::SetItemTooltip("Change the pivot of the frame; i.e., where it is centered.");
}
ImGui::EndDisabled();
if (ImGui::InputFloat2("Scale", frame ? value_ptr(useFrame.scale) : &dummy_value<float>(),
frame ? vec2_format_get(useFrame.scale) : ""))
DOCUMENT_EDIT(document, "Frame Scale", Document::FRAMES, frame->scale = useFrame.scale);
ImGui::SetItemTooltip("Change the scale of the frame, in percent.");
if (ImGui::InputFloat("Rotation", frame ? &useFrame.rotation : &dummy_value<float>(), STEP, STEP_FAST,
frame ? float_format_get(useFrame.rotation) : ""))
DOCUMENT_EDIT(document, "Frame Rotation", Document::FRAMES, frame->rotation = useFrame.rotation);
ImGui::SetItemTooltip("Change the rotation of the frame.");
if (input_int_range("Duration", frame ? useFrame.duration : dummy_value<int>(),
frame ? anm2::FRAME_DURATION_MIN : 0, anm2::FRAME_DURATION_MAX, STEP, STEP_FAST,
!frame ? ImGuiInputTextFlags_DisplayEmptyRefVal : 0))
DOCUMENT_EDIT(document, "Frame Duration", Document::FRAMES, frame->duration = useFrame.duration);
ImGui::SetItemTooltip("Change how long the frame lasts.");
if (ImGui::ColorEdit4("Tint", frame ? value_ptr(useFrame.tint) : &dummy_value<float>()))
DOCUMENT_EDIT(document, "Frame Tint", Document::FRAMES, frame->tint = useFrame.tint);
ImGui::SetItemTooltip("Change the tint of the frame.");
if (ImGui::ColorEdit3("Color Offset", frame ? value_ptr(useFrame.colorOffset) : &dummy_value<float>()))
DOCUMENT_EDIT(document, "Frame Color Offset", Document::FRAMES,
frame->colorOffset = useFrame.colorOffset);
ImGui::SetItemTooltip("Change the color added onto the frame.");
if (ImGui::Checkbox("Visible", frame ? &useFrame.isVisible : &dummy_value<bool>()))
DOCUMENT_EDIT(document, "Frame Visibility", Document::FRAMES, frame->isVisible = useFrame.isVisible);
ImGui::SetItemTooltip("Toggle the frame's visibility.");
ImGui::SameLine();
if (ImGui::Checkbox("Interpolated", frame ? &useFrame.isInterpolated : &dummy_value<bool>()))
DOCUMENT_EDIT(document, "Frame Interpolation", Document::FRAMES,
frame->isInterpolated = useFrame.isInterpolated);
ImGui::SetItemTooltip(
"Toggle the frame interpolating; i.e., blending its values into the next frame based on the time.");
auto widgetSize = widget_size_with_row_get(2);
if (ImGui::Button("Flip X", widgetSize))
DOCUMENT_EDIT(document, "Frame Flip X", Document::FRAMES, frame->scale.x = -frame->scale.x);
ImGui::SetItemTooltip("%s", "Flip the horizontal scale of the frame, to cheat mirroring the frame "
"horizontally.\n(Note: the format does not support mirroring.)");
ImGui::SameLine();
if (ImGui::Button("Flip Y", widgetSize))
DOCUMENT_EDIT(document, "Frame Flip Y", Document::FRAMES, frame->scale.y = -frame->scale.y);
ImGui::SetItemTooltip("%s", "Flip the vertical scale of the frame, to cheat mirroring the frame "
"vertically.\n(Note: the format does not support mirroring.)");
}
ImGui::EndDisabled();
if (ImGui::InputFloat2("Scale", frame ? value_ptr(useFrame.scale) : &dummy_value<float>(),
frame ? vec2_format_get(useFrame.scale) : ""))
DOCUMENT_EDIT(document, "Frame Scale", Document::FRAMES, frame->scale = useFrame.scale);
ImGui::SetItemTooltip("Change the scale of the frame, in percent.");
if (ImGui::InputFloat("Rotation", frame ? &useFrame.rotation : &dummy_value<float>(), imgui::STEP,
imgui::STEP_FAST, frame ? float_format_get(useFrame.rotation) : ""))
DOCUMENT_EDIT(document, "Frame Rotation", Document::FRAMES, frame->rotation = useFrame.rotation);
ImGui::SetItemTooltip("Change the rotation of the frame.");
if (ImGui::InputInt("Duration", frame ? &useFrame.delay : &dummy_value<int>(), imgui::STEP, imgui::STEP_FAST,
!frame ? ImGuiInputTextFlags_DisplayEmptyRefVal : 0))
DOCUMENT_EDIT(document, "Frame Duration", Document::FRAMES, frame->delay = useFrame.delay);
ImGui::SetItemTooltip("Change how long the frame lasts.");
if (ImGui::ColorEdit4("Tint", frame ? value_ptr(useFrame.tint) : &dummy_value<float>()))
DOCUMENT_EDIT(document, "Frame Tint", Document::FRAMES, frame->tint = useFrame.tint);
ImGui::SetItemTooltip("Change the tint of the frame.");
if (ImGui::ColorEdit3("Color Offset", frame ? value_ptr(useFrame.colorOffset) : &dummy_value<float>()))
DOCUMENT_EDIT(document, "Frame Color Offset", Document::FRAMES, frame->colorOffset = useFrame.colorOffset);
ImGui::SetItemTooltip("Change the color added onto the frame.");
if (ImGui::Checkbox("Visible", frame ? &useFrame.isVisible : &dummy_value<bool>()))
DOCUMENT_EDIT(document, "Frame Visibility", Document::FRAMES, frame->isVisible = useFrame.isVisible);
ImGui::SetItemTooltip("Toggle the frame's visibility.");
ImGui::SameLine();
if (ImGui::Checkbox("Interpolated", frame ? &useFrame.isInterpolated : &dummy_value<bool>()))
DOCUMENT_EDIT(document, "Frame Interpolation", Document::FRAMES,
frame->isInterpolated = useFrame.isInterpolated);
ImGui::SetItemTooltip(
"Toggle the frame interpolating; i.e., blending its values into the next frame based on the time.");
auto widgetSize = imgui::widget_size_with_row_get(2);
if (ImGui::Button("Flip X", widgetSize))
DOCUMENT_EDIT(document, "Frame Flip X", Document::FRAMES, frame->scale.x = -frame->scale.x);
ImGui::SetItemTooltip("%s", "Flip the horizontal scale of the frame, to cheat mirroring the frame "
"horizontally.\n(Note: the format does not support mirroring.)");
ImGui::SameLine();
if (ImGui::Button("Flip Y", widgetSize))
DOCUMENT_EDIT(document, "Frame Flip Y", Document::FRAMES, frame->scale.y = -frame->scale.y);
ImGui::SetItemTooltip("%s", "Flip the vertical scale of the frame, to cheat mirroring the frame "
"vertically.\n(Note: the format does not support mirroring.)");
}
ImGui::EndDisabled();
}
else
{
auto& isCrop = settings.changeIsCrop;
auto& isSize = settings.changeIsSize;
auto& isPosition = settings.changeIsPosition;
auto& isPivot = settings.changeIsPivot;
auto& isScale = settings.changeIsScale;
auto& isRotation = settings.changeIsRotation;
auto& isDelay = settings.changeIsDelay;
auto& isTint = settings.changeIsTint;
auto& isColorOffset = settings.changeIsColorOffset;
auto& isVisibleSet = settings.changeIsVisibleSet;
auto& isInterpolatedSet = settings.changeIsInterpolatedSet;
auto& crop = settings.changeCrop;
auto& size = settings.changeSize;
auto& position = settings.changePosition;
auto& pivot = settings.changePivot;
auto& scale = settings.changeScale;
auto& rotation = settings.changeRotation;
auto& duration = settings.changeDelay;
auto& tint = settings.changeTint;
auto& colorOffset = settings.changeColorOffset;
auto& isVisible = settings.changeIsVisible;
auto& isInterpolated = settings.changeIsInterpolated;
#define PROPERTIES_WIDGET(body) \
ImGui::Checkbox(checkboxLabel, &isEnabled); \
ImGui::SameLine(); \
ImGui::BeginDisabled(!isEnabled); \
body; \
ImGui::EndDisabled();
auto bool_value = [&](const char* checkboxLabel, const char* valueLabel, bool& isEnabled, bool& value)
{ PROPERTIES_WIDGET(ImGui::Checkbox(valueLabel, &value)); };
auto color3_value = [&](const char* checkboxLabel, const char* valueLabel, bool& isEnabled, vec3& value)
{ PROPERTIES_WIDGET(ImGui::ColorEdit3(valueLabel, value_ptr(value))); };
auto color4_value = [&](const char* checkboxLabel, const char* valueLabel, bool& isEnabled, vec4& value)
{ PROPERTIES_WIDGET(ImGui::ColorEdit4(valueLabel, value_ptr(value))); };
auto float2_value = [&](const char* checkboxLabel, const char* valueLabel, bool& isEnabled, vec2& value)
{ PROPERTIES_WIDGET(ImGui::InputFloat2(valueLabel, value_ptr(value), vec2_format_get(value))); };
auto float_value = [&](const char* checkboxLabel, const char* valueLabel, bool& isEnabled, float& value)
{ PROPERTIES_WIDGET(ImGui::InputFloat(valueLabel, &value, STEP, STEP_FAST, float_format_get(value))); };
auto duration_value = [&](const char* checkboxLabel, const char* valueLabel, bool& isEnabled, int& value)
{
PROPERTIES_WIDGET(
input_int_range(valueLabel, value, anm2::FRAME_DURATION_MIN, anm2::FRAME_DURATION_MAX, STEP, STEP_FAST));
};
#undef PROPERTIES_WIDGET
float2_value("##Is Crop", "Crop", isCrop, crop);
float2_value("##Is Size", "Size", isSize, size);
float2_value("##Is Position", "Position", isPosition, position);
float2_value("##Is Pivot", "Pivot", isPivot, pivot);
float2_value("##Is Scale", "Scale", isScale, scale);
float_value("##Is Rotation", "Rotation", isRotation, rotation);
duration_value("##Is Delay", "Delay", isDelay, duration);
color4_value("##Is Tint", "Tint", isTint, tint);
color3_value("##Is Color Offset", "Color Offset", isColorOffset, colorOffset);
bool_value("##Is Visible", "Visible", isVisibleSet, isVisible);
ImGui::SameLine();
bool_value("##Is Interpolated", "Interpolated", isInterpolatedSet, isInterpolated);
auto frame_change = [&](anm2::ChangeType type)
{
anm2::FrameChange frameChange;
if (isCrop) frameChange.crop = std::make_optional(crop);
if (isSize) frameChange.size = std::make_optional(size);
if (isPosition) frameChange.position = std::make_optional(position);
if (isPivot) frameChange.pivot = std::make_optional(pivot);
if (isScale) frameChange.scale = std::make_optional(scale);
if (isRotation) frameChange.rotation = std::make_optional(rotation);
if (isDelay) frameChange.duration = std::make_optional(duration);
if (isTint) frameChange.tint = std::make_optional(tint);
if (isColorOffset) frameChange.colorOffset = std::make_optional(colorOffset);
if (isVisibleSet) frameChange.isVisible = std::make_optional(isVisible);
if (isInterpolatedSet) frameChange.isInterpolated = std::make_optional(isInterpolated);
DOCUMENT_EDIT(document, "Change Frame Properties", Document::FRAMES,
document.item_get()->frames_change(frameChange, type, *frames.begin(), (int)frames.size()));
};
auto widgetSize = widget_size_with_row_get(3);
if (ImGui::Button("Adjust", widgetSize)) frame_change(anm2::ADJUST);
ImGui::SetItemTooltip("Set the value of each specified value onto the frame's equivalent.");
ImGui::SameLine();
if (ImGui::Button("Add", widgetSize)) frame_change(anm2::ADD);
ImGui::SetItemTooltip("Add the specified values onto each frame.\n(Boolean values will simply be set.)");
ImGui::SameLine();
if (ImGui::Button("Subtract", widgetSize)) frame_change(anm2::SUBTRACT);
ImGui::SetItemTooltip("Subtract the specified values from each frame.\n(Boolean values will simply be set.)");
}
ImGui::EndDisabled();
}
ImGui::End();
}

View File

@@ -84,8 +84,8 @@ namespace anm2ed::imgui
toasts.error(std::format("Failed to deserialize layer(s): {}", errorString));
};
if (shortcut(settings.shortcutCopy, shortcut::FOCUSED)) copy();
if (shortcut(settings.shortcutPaste, shortcut::FOCUSED)) paste(merge::APPEND);
if (shortcut(manager.chords[SHORTCUT_COPY], shortcut::FOCUSED)) copy();
if (shortcut(manager.chords[SHORTCUT_PASTE], shortcut::FOCUSED)) paste(merge::APPEND);
if (ImGui::BeginPopupContextWindow("##Context Menu", ImGuiPopupFlags_MouseButtonRight))
{
@@ -107,12 +107,12 @@ namespace anm2ed::imgui
auto widgetSize = widget_size_with_row_get(2);
shortcut(settings.shortcutAdd);
shortcut(manager.chords[SHORTCUT_ADD]);
if (ImGui::Button("Add", widgetSize)) manager.layer_properties_open();
set_item_tooltip_shortcut("Add a layer.", settings.shortcutAdd);
ImGui::SameLine();
shortcut(settings.shortcutRemove);
shortcut(manager.chords[SHORTCUT_REMOVE]);
ImGui::BeginDisabled(unused.empty());
if (ImGui::Button("Remove Unused", widgetSize))
{

View File

@@ -84,8 +84,8 @@ namespace anm2ed::imgui
toasts.error(std::format("Failed to deserialize null(s): {}", errorString));
};
if (shortcut(settings.shortcutCopy, shortcut::FOCUSED)) copy();
if (shortcut(settings.shortcutPaste, shortcut::FOCUSED)) paste(merge::APPEND);
if (shortcut(manager.chords[SHORTCUT_COPY], shortcut::FOCUSED)) copy();
if (shortcut(manager.chords[SHORTCUT_PASTE], shortcut::FOCUSED)) paste(merge::APPEND);
if (ImGui::BeginPopupContextWindow("##Context Menu", ImGuiPopupFlags_MouseButtonRight))
{
@@ -107,12 +107,12 @@ namespace anm2ed::imgui
auto widgetSize = widget_size_with_row_get(2);
shortcut(settings.shortcutAdd);
shortcut(manager.chords[SHORTCUT_ADD]);
if (ImGui::Button("Add", widgetSize)) manager.null_properties_open();
set_item_tooltip_shortcut("Add a null.", settings.shortcutAdd);
ImGui::SameLine();
shortcut(settings.shortcutRemove);
shortcut(manager.chords[SHORTCUT_REMOVE]);
ImGui::BeginDisabled(unused.empty());
if (ImGui::Button("Remove Unused", widgetSize))
{

View File

@@ -11,7 +11,7 @@ namespace anm2ed::imgui
{
constexpr auto FRAMES_MAX = 100;
void Onionskin::update(Settings& settings)
void Onionskin::update(Manager& manager, Settings& settings)
{
auto& isEnabled = settings.onionskinIsEnabled;
auto& beforeCount = settings.onionskinBeforeCount;
@@ -49,7 +49,7 @@ namespace anm2ed::imgui
}
ImGui::End();
if (shortcut(settings.shortcutOnionskin, shortcut::GLOBAL)) isEnabled = !isEnabled;
if (shortcut(manager.chords[SHORTCUT_ONIONSKIN], shortcut::GLOBAL)) isEnabled = !isEnabled;
}
}

View File

@@ -1,12 +1,12 @@
#pragma once
#include "settings.h"
#include "manager.h"
namespace anm2ed::imgui
{
class Onionskin
{
public:
void update(Settings&);
void update(Manager&, Settings&);
};
}

View File

@@ -79,8 +79,8 @@ namespace anm2ed::imgui
toasts.error(std::format("Failed to deserialize sound(s): {}", errorString));
};
if (imgui::shortcut(settings.shortcutCopy, shortcut::FOCUSED)) copy();
if (imgui::shortcut(settings.shortcutPaste, shortcut::FOCUSED)) paste(merge::APPEND);
if (imgui::shortcut(manager.chords[SHORTCUT_COPY], shortcut::FOCUSED)) copy();
if (imgui::shortcut(manager.chords[SHORTCUT_PASTE], shortcut::FOCUSED)) paste(merge::APPEND);
if (ImGui::BeginPopupContextWindow("##Context Menu", ImGuiPopupFlags_MouseButtonRight))
{
@@ -102,12 +102,12 @@ namespace anm2ed::imgui
auto widgetSize = imgui::widget_size_with_row_get(2);
imgui::shortcut(settings.shortcutAdd);
imgui::shortcut(manager.chords[SHORTCUT_ADD]);
if (ImGui::Button("Add", widgetSize)) dialog.file_open(dialog::SOUND_OPEN);
imgui::set_item_tooltip_shortcut("Add a sound.", settings.shortcutAdd);
ImGui::SameLine();
imgui::shortcut(settings.shortcutRemove);
imgui::shortcut(manager.chords[SHORTCUT_REMOVE]);
ImGui::BeginDisabled(unused.empty());
if (ImGui::Button("Remove Unused", widgetSize))
{

View File

@@ -17,9 +17,7 @@ namespace anm2ed::imgui
{
constexpr auto PIVOT_COLOR = color::PINK;
SpritesheetEditor::SpritesheetEditor() : Canvas(vec2())
{
}
SpritesheetEditor::SpritesheetEditor() : Canvas(vec2()) {}
void SpritesheetEditor::update(Manager& manager, Settings& settings, Resources& resources)
{
@@ -80,13 +78,13 @@ namespace anm2ed::imgui
auto widgetSize = ImVec2(imgui::row_widget_width_get(2), 0);
imgui::shortcut(settings.shortcutCenterView);
imgui::shortcut(manager.chords[SHORTCUT_CENTER_VIEW]);
if (ImGui::Button("Center View", widgetSize)) center_view();
imgui::set_item_tooltip_shortcut("Centers the view.", settings.shortcutCenterView);
ImGui::SameLine();
imgui::shortcut(settings.shortcutFit);
imgui::shortcut(manager.chords[SHORTCUT_FIT]);
if (ImGui::Button("Fit", widgetSize))
if (spritesheet) set_to_rect(zoom, pan, {0, 0, spritesheet->texture.size.x, spritesheet->texture.size.y});
imgui::set_item_tooltip_shortcut("Set the view to match the extent of the spritesheet.", settings.shortcutFit);

View File

@@ -52,8 +52,8 @@ namespace anm2ed::imgui
toasts.error(std::format("Failed to deserialize spritesheet(s): {}", errorString));
};
if (shortcut(settings.shortcutCopy, shortcut::FOCUSED)) copy();
if (shortcut(settings.shortcutPaste, shortcut::FOCUSED)) paste(merge::APPEND);
if (shortcut(manager.chords[SHORTCUT_COPY], shortcut::FOCUSED)) copy();
if (shortcut(manager.chords[SHORTCUT_PASTE], shortcut::FOCUSED)) paste(merge::APPEND);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.WindowPadding);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing);
@@ -181,9 +181,9 @@ namespace anm2ed::imgui
}
ImGui::EndChild();
auto rowOneWidgetSize = widget_size_with_row_get(4);
auto rowOneWidgetSize = widget_size_with_row_get(3);
shortcut(settings.shortcutAdd);
shortcut(manager.chords[SHORTCUT_ADD]);
if (ImGui::Button("Add", rowOneWidgetSize)) dialog.file_open(dialog::SPRITESHEET_OPEN);
set_item_tooltip_shortcut("Add a new spritesheet.", settings.shortcutAdd);
@@ -238,12 +238,12 @@ namespace anm2ed::imgui
dialog.reset();
}
ImGui::SameLine();
auto rowTwoWidgetSize = widget_size_with_row_get(2);
ImGui::BeginDisabled(unused.empty());
{
shortcut(settings.shortcutRemove);
if (ImGui::Button("Remove Unused", rowOneWidgetSize))
shortcut(manager.chords[SHORTCUT_REMOVE]);
if (ImGui::Button("Remove Unused", rowTwoWidgetSize))
{
auto remove_unused = [&]()
{
@@ -263,26 +263,6 @@ namespace anm2ed::imgui
}
ImGui::EndDisabled();
auto rowTwoWidgetSize = widget_size_with_row_get(3);
shortcut(settings.shortcutSelectAll);
ImGui::BeginDisabled(selection.size() == anm2.content.spritesheets.size());
{
if (ImGui::Button("Select All", rowTwoWidgetSize))
for (auto& id : anm2.content.spritesheets | std::views::keys)
selection.insert(id);
}
ImGui::EndDisabled();
set_item_tooltip_shortcut("Select all spritesheets.", settings.shortcutSelectAll);
ImGui::SameLine();
shortcut(settings.shortcutSelectNone);
ImGui::BeginDisabled(selection.empty());
if (ImGui::Button("Select None", rowTwoWidgetSize)) selection.clear();
set_item_tooltip_shortcut("Unselect all spritesheets.", settings.shortcutSelectNone);
ImGui::EndDisabled();
ImGui::SameLine();
ImGui::BeginDisabled(selection.empty());

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,8 @@
#pragma once
#include <set>
#include <vector>
#include "clipboard.h"
#include "manager.h"
#include "resources.h"
@@ -7,6 +10,14 @@
namespace anm2ed::imgui
{
struct FrameDragDrop
{
anm2::Type type{anm2::NONE};
int itemID{-1};
int animationIndex{-1};
std::vector<int> selection{};
};
class Timeline
{
bool isDragging{};
@@ -18,7 +29,16 @@ namespace anm2ed::imgui
bool addItemIsRect{};
int addItemID{-1};
int addItemSpritesheetID{-1};
bool isUnusedItemsSet{};
int hoveredTime{};
anm2::Frame* draggedTrigger{};
int draggedTriggerIndex{-1};
int draggedTriggerAtFrameStart{-1};
bool isDraggedTriggerSnapshot{};
FrameDragDrop frameDragDrop{};
std::vector<int> frameSelectionSnapshot{};
std::vector<int> frameSelectionLocked{};
bool isFrameSelectionLocked{};
anm2::Reference frameSelectionSnapshotReference{};
std::set<int> unusedItems{};
glm::vec2 scroll{};
ImDrawList* pickerLineDrawList{};

View File

@@ -50,9 +50,7 @@ namespace anm2ed::imgui
if (isSelected) ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyleColorVec4(ImGuiCol_ButtonActive));
auto member = SHORTCUT_MEMBERS[info.shortcut];
if (shortcut(settings.*member, shortcut::GLOBAL_SET)) tool_use((tool::Type)i);
if (shortcut(manager.chords[info.shortcut], shortcut::GLOBAL_SET)) tool_use((tool::Type)i);
if (i == tool::COLOR)
{