I N T E R P O L A T I O N
This commit is contained in:
@@ -38,7 +38,9 @@ namespace anm2ed::imgui
|
||||
{
|
||||
document.lastAutosaveTime += ImGui::GetIO().DeltaTime;
|
||||
if (document.lastAutosaveTime > time::SECOND_M)
|
||||
manager.autosave(document, (anm2::Compatibility)settings.fileCompatibility);
|
||||
manager.autosave(document, (anm2::Compatibility)settings.fileCompatibility,
|
||||
settings.fileBakeSpecialInterpolatedFramesOnSave, settings.bakeIsRoundScale,
|
||||
settings.bakeIsRoundRotation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,7 +156,9 @@ namespace anm2ed::imgui
|
||||
if (ImGui::Button(localize.get(BASIC_YES), widgetSize))
|
||||
{
|
||||
if (isDocumentDirty)
|
||||
manager.save(closeDocumentIndex, {}, (anm2::Compatibility)settings.fileCompatibility);
|
||||
manager.save(closeDocumentIndex, {}, (anm2::Compatibility)settings.fileCompatibility,
|
||||
settings.fileBakeSpecialInterpolatedFramesOnSave, settings.bakeIsRoundScale,
|
||||
settings.bakeIsRoundRotation);
|
||||
|
||||
if (isSpritesheetDirty)
|
||||
{
|
||||
|
||||
+108
-2
@@ -18,6 +18,110 @@ namespace anm2ed::imgui
|
||||
{
|
||||
static auto isRenaming = false;
|
||||
|
||||
namespace
|
||||
{
|
||||
const std::vector<std::pair<ImGuiKey, const char*>> CANONICAL_KEY_NAMES = {
|
||||
{ImGuiKey_A, "A"},
|
||||
{ImGuiKey_B, "B"},
|
||||
{ImGuiKey_C, "C"},
|
||||
{ImGuiKey_D, "D"},
|
||||
{ImGuiKey_E, "E"},
|
||||
{ImGuiKey_F, "F"},
|
||||
{ImGuiKey_G, "G"},
|
||||
{ImGuiKey_H, "H"},
|
||||
{ImGuiKey_I, "I"},
|
||||
{ImGuiKey_J, "J"},
|
||||
{ImGuiKey_K, "K"},
|
||||
{ImGuiKey_L, "L"},
|
||||
{ImGuiKey_M, "M"},
|
||||
{ImGuiKey_N, "N"},
|
||||
{ImGuiKey_O, "O"},
|
||||
{ImGuiKey_P, "P"},
|
||||
{ImGuiKey_Q, "Q"},
|
||||
{ImGuiKey_R, "R"},
|
||||
{ImGuiKey_S, "S"},
|
||||
{ImGuiKey_T, "T"},
|
||||
{ImGuiKey_U, "U"},
|
||||
{ImGuiKey_V, "V"},
|
||||
{ImGuiKey_W, "W"},
|
||||
{ImGuiKey_X, "X"},
|
||||
{ImGuiKey_Y, "Y"},
|
||||
{ImGuiKey_Z, "Z"},
|
||||
{ImGuiKey_0, "0"},
|
||||
{ImGuiKey_1, "1"},
|
||||
{ImGuiKey_2, "2"},
|
||||
{ImGuiKey_3, "3"},
|
||||
{ImGuiKey_4, "4"},
|
||||
{ImGuiKey_5, "5"},
|
||||
{ImGuiKey_6, "6"},
|
||||
{ImGuiKey_7, "7"},
|
||||
{ImGuiKey_8, "8"},
|
||||
{ImGuiKey_9, "9"},
|
||||
{ImGuiKey_Keypad0, "Num0"},
|
||||
{ImGuiKey_Keypad1, "Num1"},
|
||||
{ImGuiKey_Keypad2, "Num2"},
|
||||
{ImGuiKey_Keypad3, "Num3"},
|
||||
{ImGuiKey_Keypad4, "Num4"},
|
||||
{ImGuiKey_Keypad5, "Num5"},
|
||||
{ImGuiKey_Keypad6, "Num6"},
|
||||
{ImGuiKey_Keypad7, "Num7"},
|
||||
{ImGuiKey_Keypad8, "Num8"},
|
||||
{ImGuiKey_Keypad9, "Num9"},
|
||||
{ImGuiKey_KeypadAdd, "NumAdd"},
|
||||
{ImGuiKey_KeypadSubtract, "NumSubtract"},
|
||||
{ImGuiKey_KeypadMultiply, "NumMultiply"},
|
||||
{ImGuiKey_KeypadDivide, "NumDivide"},
|
||||
{ImGuiKey_KeypadEnter, "NumEnter"},
|
||||
{ImGuiKey_KeypadDecimal, "NumDecimal"},
|
||||
{ImGuiKey_KeypadEqual, "NumEqual"},
|
||||
{ImGuiKey_F1, "F1"},
|
||||
{ImGuiKey_F2, "F2"},
|
||||
{ImGuiKey_F3, "F3"},
|
||||
{ImGuiKey_F4, "F4"},
|
||||
{ImGuiKey_F5, "F5"},
|
||||
{ImGuiKey_F6, "F6"},
|
||||
{ImGuiKey_F7, "F7"},
|
||||
{ImGuiKey_F8, "F8"},
|
||||
{ImGuiKey_F9, "F9"},
|
||||
{ImGuiKey_F10, "F10"},
|
||||
{ImGuiKey_F11, "F11"},
|
||||
{ImGuiKey_F12, "F12"},
|
||||
{ImGuiKey_UpArrow, "Up"},
|
||||
{ImGuiKey_DownArrow, "Down"},
|
||||
{ImGuiKey_LeftArrow, "Left"},
|
||||
{ImGuiKey_RightArrow, "Right"},
|
||||
{ImGuiKey_Space, "Space"},
|
||||
{ImGuiKey_Enter, "Enter"},
|
||||
{ImGuiKey_Escape, "Escape"},
|
||||
{ImGuiKey_Tab, "Tab"},
|
||||
{ImGuiKey_Backspace, "Backspace"},
|
||||
{ImGuiKey_Delete, "Delete"},
|
||||
{ImGuiKey_Insert, "Insert"},
|
||||
{ImGuiKey_Home, "Home"},
|
||||
{ImGuiKey_End, "End"},
|
||||
{ImGuiKey_PageUp, "PageUp"},
|
||||
{ImGuiKey_PageDown, "PageDown"},
|
||||
{ImGuiKey_Minus, "Minus"},
|
||||
{ImGuiKey_Equal, "Equal"},
|
||||
{ImGuiKey_LeftBracket, "LeftBracket"},
|
||||
{ImGuiKey_RightBracket, "RightBracket"},
|
||||
{ImGuiKey_Semicolon, "Semicolon"},
|
||||
{ImGuiKey_Apostrophe, "Apostrophe"},
|
||||
{ImGuiKey_Comma, "Comma"},
|
||||
{ImGuiKey_Period, "Period"},
|
||||
{ImGuiKey_Slash, "Slash"},
|
||||
{ImGuiKey_Backslash, "Backslash"},
|
||||
{ImGuiKey_GraveAccent, "GraveAccent"},
|
||||
};
|
||||
|
||||
const char* canonical_key_name(ImGuiKey key)
|
||||
{
|
||||
for (const auto& [mappedKey, name] : CANONICAL_KEY_NAMES)
|
||||
if (mappedKey == key) return name;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr ImVec4 COLOR_LIGHT_BUTTON{0.98f, 0.98f, 0.98f, 1.0f};
|
||||
constexpr ImVec4 COLOR_LIGHT_TITLE_BG{0.78f, 0.78f, 0.78f, 1.0f};
|
||||
constexpr ImVec4 COLOR_LIGHT_TITLE_BG_ACTIVE{0.64f, 0.64f, 0.64f, 1.0f};
|
||||
@@ -427,10 +531,10 @@ namespace anm2ed::imgui
|
||||
|
||||
if (auto key = (ImGuiKey)(chord & ~ImGuiMod_Mask_); key != ImGuiKey_None)
|
||||
{
|
||||
if (const char* name = ImGui::GetKeyName(key); name && *name)
|
||||
if (const char* name = canonical_key_name(key); name && *name)
|
||||
result += name;
|
||||
else
|
||||
result += "Unknown";
|
||||
result += ImGui::GetKeyName(key);
|
||||
}
|
||||
|
||||
if (!result.empty() && result.back() == '+') result.pop_back();
|
||||
@@ -499,6 +603,8 @@ namespace anm2ed::imgui
|
||||
|
||||
bool shortcut(ImGuiKeyChord chord, shortcut::Type type)
|
||||
{
|
||||
if (chord == ImGuiKey_None) return false;
|
||||
|
||||
if (ImGui::GetTopMostPopupModal() != nullptr &&
|
||||
(type == shortcut::GLOBAL || type == shortcut::GLOBAL_SET))
|
||||
return false;
|
||||
|
||||
@@ -115,6 +115,7 @@ namespace anm2ed::imgui
|
||||
{"NumDivide", ImGuiKey_KeypadDivide},
|
||||
{"NumEnter", ImGuiKey_KeypadEnter},
|
||||
{"NumDecimal", ImGuiKey_KeypadDecimal},
|
||||
{"NumEqual", ImGuiKey_KeypadEqual},
|
||||
|
||||
{"F1", ImGuiKey_F1},
|
||||
{"F2", ImGuiKey_F2},
|
||||
@@ -157,6 +158,29 @@ namespace anm2ed::imgui
|
||||
{"Slash", ImGuiKey_Slash},
|
||||
{"Backslash", ImGuiKey_Backslash},
|
||||
{"GraveAccent", ImGuiKey_GraveAccent},
|
||||
|
||||
// Legacy aliases for older saved shortcut strings.
|
||||
{"Keypad0", ImGuiKey_Keypad0},
|
||||
{"Keypad1", ImGuiKey_Keypad1},
|
||||
{"Keypad2", ImGuiKey_Keypad2},
|
||||
{"Keypad3", ImGuiKey_Keypad3},
|
||||
{"Keypad4", ImGuiKey_Keypad4},
|
||||
{"Keypad5", ImGuiKey_Keypad5},
|
||||
{"Keypad6", ImGuiKey_Keypad6},
|
||||
{"Keypad7", ImGuiKey_Keypad7},
|
||||
{"Keypad8", ImGuiKey_Keypad8},
|
||||
{"Keypad9", ImGuiKey_Keypad9},
|
||||
{"KeypadAdd", ImGuiKey_KeypadAdd},
|
||||
{"KeypadSubtract", ImGuiKey_KeypadSubtract},
|
||||
{"KeypadMultiply", ImGuiKey_KeypadMultiply},
|
||||
{"KeypadDivide", ImGuiKey_KeypadDivide},
|
||||
{"KeypadEnter", ImGuiKey_KeypadEnter},
|
||||
{"KeypadDecimal", ImGuiKey_KeypadDecimal},
|
||||
{"KeypadEqual", ImGuiKey_KeypadEqual},
|
||||
{"UpArrow", ImGuiKey_UpArrow},
|
||||
{"DownArrow", ImGuiKey_DownArrow},
|
||||
{"LeftArrow", ImGuiKey_LeftArrow},
|
||||
{"RightArrow", ImGuiKey_RightArrow},
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string, ImGuiKey> MOD_MAP = {
|
||||
|
||||
+12
-4
@@ -74,7 +74,9 @@ namespace anm2ed::imgui
|
||||
if (settings.fileIsWarnOverwrite)
|
||||
overwritePopup.open();
|
||||
else
|
||||
manager.save(document->path, (anm2::Compatibility)settings.fileCompatibility);
|
||||
manager.save(document->path, (anm2::Compatibility)settings.fileCompatibility,
|
||||
settings.fileBakeSpecialInterpolatedFramesOnSave, settings.bakeIsRoundScale,
|
||||
settings.bakeIsRoundRotation);
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem(localize.get(LABEL_SAVE_AS), settings.shortcutSaveAs.c_str(), false, document))
|
||||
@@ -100,7 +102,9 @@ namespace anm2ed::imgui
|
||||
|
||||
if (dialog.is_selected(Dialog::ANM2_SAVE))
|
||||
{
|
||||
manager.save(dialog.path, (anm2::Compatibility)settings.fileCompatibility);
|
||||
manager.save(dialog.path, (anm2::Compatibility)settings.fileCompatibility,
|
||||
settings.fileBakeSpecialInterpolatedFramesOnSave, settings.bakeIsRoundScale,
|
||||
settings.bakeIsRoundRotation);
|
||||
dialog.reset();
|
||||
}
|
||||
|
||||
@@ -240,7 +244,9 @@ namespace anm2ed::imgui
|
||||
|
||||
if (ImGui::Button(localize.get(BASIC_YES), widgetSize))
|
||||
{
|
||||
manager.save({}, (anm2::Compatibility)settings.fileCompatibility);
|
||||
manager.save({}, (anm2::Compatibility)settings.fileCompatibility,
|
||||
settings.fileBakeSpecialInterpolatedFramesOnSave, settings.bakeIsRoundScale,
|
||||
settings.bakeIsRoundRotation);
|
||||
overwritePopup.close();
|
||||
}
|
||||
|
||||
@@ -260,7 +266,9 @@ namespace anm2ed::imgui
|
||||
if (settings.fileIsWarnOverwrite)
|
||||
overwritePopup.open();
|
||||
else
|
||||
manager.save({}, (anm2::Compatibility)settings.fileCompatibility);
|
||||
manager.save({}, (anm2::Compatibility)settings.fileCompatibility,
|
||||
settings.fileBakeSpecialInterpolatedFramesOnSave, settings.bakeIsRoundScale,
|
||||
settings.bakeIsRoundRotation);
|
||||
}
|
||||
if (shortcut(manager.chords[SHORTCUT_SAVE_AS], shortcut::GLOBAL)) dialog.file_save(Dialog::ANM2_SAVE);
|
||||
if (shortcut(manager.chords[SHORTCUT_EXIT], shortcut::GLOBAL)) isQuitting = true;
|
||||
|
||||
@@ -25,6 +25,17 @@ namespace anm2ed::imgui
|
||||
auto regionLabelsString = std::vector<std::string>{localize.get(BASIC_NONE)};
|
||||
auto regionLabels = std::vector<const char*>{regionLabelsString[0].c_str()};
|
||||
auto regionIds = std::vector<int>{-1};
|
||||
auto interpolationLabelsString =
|
||||
std::vector<std::string>{localize.get(BASIC_NONE), localize.get(BASIC_LINEAR), localize.get(BASIC_EASE_IN),
|
||||
localize.get(BASIC_EASE_OUT), localize.get(BASIC_EASE_IN_OUT)};
|
||||
auto interpolationLabels =
|
||||
std::vector<const char*>{interpolationLabelsString[0].c_str(), interpolationLabelsString[1].c_str(),
|
||||
interpolationLabelsString[2].c_str(), interpolationLabelsString[3].c_str(),
|
||||
interpolationLabelsString[4].c_str()};
|
||||
auto interpolationValues =
|
||||
std::vector<int>{anm2::Frame::Interpolation::NONE, anm2::Frame::Interpolation::LINEAR,
|
||||
anm2::Frame::Interpolation::EASE_IN, anm2::Frame::Interpolation::EASE_OUT,
|
||||
anm2::Frame::Interpolation::EASE_IN_OUT};
|
||||
|
||||
if (type == anm2::LAYER && document.reference.itemID != -1)
|
||||
{
|
||||
@@ -219,21 +230,20 @@ namespace anm2ed::imgui
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_REGION));
|
||||
ImGui::EndDisabled();
|
||||
|
||||
auto interpolationValue = frame ? static_cast<int>(useFrame.interpolation) : dummy_value<int>();
|
||||
if (combo_id_mapped(localize.get(BASIC_INTERPOLATED), &interpolationValue, interpolationValues,
|
||||
interpolationLabels) &&
|
||||
frame)
|
||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_INTERPOLATION), Document::FRAMES,
|
||||
frame->interpolation = static_cast<anm2::Frame::Interpolation>(interpolationValue));
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_FRAME_INTERPOLATION));
|
||||
|
||||
if (ImGui::Checkbox(localize.get(BASIC_VISIBLE), frame ? &useFrame.isVisible : &dummy_value<bool>()) &&
|
||||
frame)
|
||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_VISIBILITY), Document::FRAMES,
|
||||
frame->isVisible = useFrame.isVisible);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_FRAME_VISIBILITY));
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Checkbox(localize.get(BASIC_INTERPOLATED),
|
||||
frame ? &useFrame.isInterpolated : &dummy_value<bool>()) &&
|
||||
frame)
|
||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_INTERPOLATION), Document::FRAMES,
|
||||
frame->isInterpolated = useFrame.isInterpolated);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_FRAME_INTERPOLATION));
|
||||
|
||||
auto widgetSize = widget_size_with_row_get(2);
|
||||
|
||||
if (ImGui::Button(localize.get(LABEL_FLIP_X), widgetSize) && frame)
|
||||
|
||||
@@ -34,6 +34,17 @@ namespace anm2ed::imgui
|
||||
|
||||
auto spritesheet = map::find(anm2.content.spritesheets, spritesheetReference);
|
||||
|
||||
if (manager.isMakeRegionRequested)
|
||||
{
|
||||
spritesheetReference = manager.makeRegionSpritesheetId;
|
||||
reference = -1;
|
||||
editRegion = manager.makeRegion;
|
||||
isPreserveEditRegionOnOpen = true;
|
||||
propertiesPopup.open();
|
||||
manager.isMakeRegionRequested = false;
|
||||
spritesheet = map::find(anm2.content.spritesheets, spritesheetReference);
|
||||
}
|
||||
|
||||
auto remove_unused = [&]()
|
||||
{
|
||||
if (!spritesheet) return;
|
||||
@@ -474,7 +485,12 @@ namespace anm2ed::imgui
|
||||
auto childSize = child_size_get(5);
|
||||
auto& region = reference == -1 ? editRegion : spritesheet->regions.at(reference);
|
||||
|
||||
if (propertiesPopup.isJustOpened) editRegion = anm2::Spritesheet::Region{};
|
||||
if (propertiesPopup.isJustOpened)
|
||||
{
|
||||
if (!isPreserveEditRegionOnOpen)
|
||||
editRegion = anm2::Spritesheet::Region{};
|
||||
isPreserveEditRegionOnOpen = false;
|
||||
}
|
||||
|
||||
if (ImGui::BeginChild("##Child", childSize, ImGuiChildFlags_Borders))
|
||||
{
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace anm2ed::imgui
|
||||
public:
|
||||
anm2::Spritesheet::Region editRegion{};
|
||||
int newRegionId{-1};
|
||||
bool isPreserveEditRegionOnOpen{};
|
||||
imgui::PopupHelper propertiesPopup{imgui::PopupHelper(LABEL_REGION_PROPERTIES, imgui::POPUP_SMALL_NO_HEIGHT)};
|
||||
|
||||
void update(Manager&, Settings&, Resources&, Clipboard&);
|
||||
|
||||
@@ -292,9 +292,27 @@ namespace anm2ed::imgui
|
||||
auto nextFrame = vector::in_bounds(item->frames, reference.frameIndex + 1)
|
||||
? &item->frames[reference.frameIndex + 1]
|
||||
: nullptr;
|
||||
if (frame->isInterpolated && nextFrame)
|
||||
if (frame->interpolation != anm2::Frame::Interpolation::NONE && nextFrame)
|
||||
{
|
||||
float interpolation = (float)firstDuration / (float)originalDuration;
|
||||
switch (frame->interpolation)
|
||||
{
|
||||
case anm2::Frame::Interpolation::EASE_IN:
|
||||
interpolation *= interpolation;
|
||||
break;
|
||||
case anm2::Frame::Interpolation::EASE_OUT:
|
||||
interpolation = 1.0f - ((1.0f - interpolation) * (1.0f - interpolation));
|
||||
break;
|
||||
case anm2::Frame::Interpolation::EASE_IN_OUT:
|
||||
interpolation = interpolation < 0.5f ? (2.0f * interpolation * interpolation)
|
||||
: (1.0f - std::pow(-2.0f * interpolation + 2.0f, 2.0f) * 0.5f);
|
||||
break;
|
||||
case anm2::Frame::Interpolation::LINEAR:
|
||||
case anm2::Frame::Interpolation::NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
splitFrame.rotation = glm::mix(frame->rotation, nextFrame->rotation, interpolation);
|
||||
splitFrame.position = glm::mix(frame->position, nextFrame->position, interpolation);
|
||||
splitFrame.scale = glm::mix(frame->scale, nextFrame->scale, interpolation);
|
||||
@@ -450,9 +468,37 @@ namespace anm2ed::imgui
|
||||
if (shortcut(manager.chords[SHORTCUT_BAKE], shortcut::FOCUSED)) frames_bake();
|
||||
if (shortcut(manager.chords[SHORTCUT_FIT], shortcut::FOCUSED)) fit_animation_length();
|
||||
|
||||
auto make_region = [&]()
|
||||
{
|
||||
auto frame = document.frame_get();
|
||||
if (!frame || reference.itemType != anm2::LAYER || reference.itemID == -1) return;
|
||||
if (frame->regionID != -1) return;
|
||||
if (!anm2.content.layers.contains(reference.itemID)) return;
|
||||
|
||||
auto spritesheetID = anm2.content.layers.at(reference.itemID).spritesheetID;
|
||||
if (!anm2.content.spritesheets.contains(spritesheetID)) return;
|
||||
|
||||
anm2::Spritesheet::Region region{};
|
||||
region.crop = frame->crop;
|
||||
region.size = frame->size;
|
||||
region.pivot = frame->pivot;
|
||||
region.origin = anm2::Spritesheet::Region::CUSTOM;
|
||||
|
||||
document.spritesheet.reference = spritesheetID;
|
||||
settings.windowIsRegions = true;
|
||||
manager.makeRegionSpritesheetId = spritesheetID;
|
||||
manager.makeRegion = region;
|
||||
manager.isMakeRegionRequested = true;
|
||||
};
|
||||
|
||||
if (ImGui::BeginPopupContextWindow("##Context Menu", ImGuiPopupFlags_MouseButtonRight))
|
||||
{
|
||||
auto item = animation ? animation->item_get(reference.itemType, reference.itemID) : nullptr;
|
||||
auto frame = document.frame_get();
|
||||
bool isMakeRegion =
|
||||
frame && reference.itemType == anm2::LAYER && reference.itemID != -1 && frame->regionID == -1 &&
|
||||
anm2.content.layers.contains(reference.itemID) &&
|
||||
anm2.content.spritesheets.contains(anm2.content.layers.at(reference.itemID).spritesheetID);
|
||||
|
||||
if (ImGui::MenuItem(localize.get(SHORTCUT_STRING_UNDO), settings.shortcutUndo.c_str(), false,
|
||||
document.is_able_to_undo()))
|
||||
@@ -484,6 +530,8 @@ namespace anm2ed::imgui
|
||||
frames.selection.size() == 1))
|
||||
frame_split();
|
||||
|
||||
if (ImGui::MenuItem(localize.get(LABEL_MAKE_REGION), nullptr, false, isMakeRegion)) make_region();
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem(localize.get(BASIC_CUT), settings.shortcutCut.c_str(), false, !frames.selection.empty()))
|
||||
@@ -1130,10 +1178,7 @@ namespace anm2ed::imgui
|
||||
auto buttonPos = ImVec2(cursorPos.x + (frameTime * frameSize.x), cursorPos.y);
|
||||
|
||||
if (frameFocusRequested && frameFocusIndex == (int)i && reference == frameReference)
|
||||
{
|
||||
ImGui::SetKeyboardFocusHere();
|
||||
frameFocusRequested = false;
|
||||
}
|
||||
|
||||
ImGui::SetCursorPos(buttonPos);
|
||||
|
||||
@@ -1161,7 +1206,9 @@ namespace anm2ed::imgui
|
||||
{
|
||||
if (ImGui::IsKeyDown(ImGuiMod_Alt))
|
||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_INTERPOLATION), Document::FRAMES,
|
||||
frame.isInterpolated = !frame.isInterpolated);
|
||||
frame.interpolation = frame.interpolation == anm2::Frame::Interpolation::NONE
|
||||
? anm2::Frame::Interpolation::LINEAR
|
||||
: anm2::Frame::Interpolation::NONE);
|
||||
|
||||
document.frameTime = frameTime;
|
||||
}
|
||||
@@ -1327,9 +1374,33 @@ namespace anm2ed::imgui
|
||||
auto borderThickness = isReferenced ? FRAME_BORDER_THICKNESS_REFERENCED : FRAME_BORDER_THICKNESS;
|
||||
drawList->AddRect(rectMin, rectMax, ImGui::GetColorU32(borderColor), FRAME_ROUNDING, 0, borderThickness);
|
||||
|
||||
auto icon = type == anm2::TRIGGER ? icon::TRIGGER
|
||||
: frame.isInterpolated ? icon::INTERPOLATED
|
||||
: icon::UNINTERPOLATED;
|
||||
auto icon = icon::UNINTERPOLATED;
|
||||
if (type == anm2::TRIGGER)
|
||||
icon = icon::TRIGGER;
|
||||
else
|
||||
{
|
||||
switch (frame.interpolation)
|
||||
{
|
||||
case anm2::Frame::Interpolation::NONE:
|
||||
icon = icon::UNINTERPOLATED;
|
||||
break;
|
||||
case anm2::Frame::Interpolation::LINEAR:
|
||||
icon = icon::INTERPOLATED;
|
||||
break;
|
||||
case anm2::Frame::Interpolation::EASE_IN:
|
||||
icon = icon::EASE_IN;
|
||||
break;
|
||||
case anm2::Frame::Interpolation::EASE_OUT:
|
||||
icon = icon::EASE_OUT;
|
||||
break;
|
||||
case anm2::Frame::Interpolation::EASE_IN_OUT:
|
||||
icon = icon::EASE_IN_OUT;
|
||||
break;
|
||||
default:
|
||||
icon = icon::UNINTERPOLATED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
auto iconPos = ImVec2(cursorPos.x + (frameTime * frameSize.x),
|
||||
cursorPos.y + (frameSize.y / 2) - (icon_size_get().y / 2));
|
||||
ImGui::SetCursorPos(iconPos);
|
||||
@@ -1426,8 +1497,7 @@ namespace anm2ed::imgui
|
||||
auto childWidth = anm2.animations.length() * ImGui::GetTextLineHeight();
|
||||
if (animation && animation->frameNum > anm2.animations.length())
|
||||
childWidth = animation->frameNum * ImGui::GetTextLineHeight();
|
||||
else if (ImGui::GetContentRegionAvail().x > childWidth)
|
||||
childWidth = ImGui::GetContentRegionAvail().x;
|
||||
childWidth = std::max(childWidth, ImGui::GetContentRegionAvail().x);
|
||||
|
||||
childWidth *= WIDTH_MULTIPLIER;
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace anm2ed::imgui::wizard
|
||||
auto& isColorOffsetG = settings.changeIsColorOffsetG;
|
||||
auto& isColorOffsetB = settings.changeIsColorOffsetB;
|
||||
auto& isVisibleSet = settings.changeIsVisibleSet;
|
||||
auto& isInterpolatedSet = settings.changeIsInterpolatedSet;
|
||||
auto& isInterpolationSet = settings.changeIsInterpolationSet;
|
||||
auto& isFlipXSet = settings.changeIsFlipXSet;
|
||||
auto& isFlipYSet = settings.changeIsFlipYSet;
|
||||
auto& isRegion = settings.changeIsRegion;
|
||||
@@ -50,7 +50,7 @@ namespace anm2ed::imgui::wizard
|
||||
auto& colorOffset = settings.changeColorOffset;
|
||||
auto& regionId = settings.changeRegionId;
|
||||
auto& isVisible = settings.changeIsVisible;
|
||||
auto& isInterpolated = settings.changeIsInterpolated;
|
||||
auto& interpolation = settings.changeInterpolation;
|
||||
auto& isFlipX = settings.changeIsFlipX;
|
||||
auto& isFlipY = settings.changeIsFlipY;
|
||||
auto& itemType = document.reference.itemType;
|
||||
@@ -65,6 +65,10 @@ namespace anm2ed::imgui::wizard
|
||||
auto bool_value = [&](const char* checkboxLabel, const char* valueLabel, bool& isEnabled, bool& value)
|
||||
{ PROPERTIES_WIDGET(ImGui::Checkbox(valueLabel, &value), checkboxLabel, isEnabled) };
|
||||
|
||||
auto enum_value = [&](const char* checkboxLabel, const char* valueLabel, bool& isEnabled, int& value,
|
||||
const std::vector<int>& ids, std::vector<const char*>& labels)
|
||||
{ PROPERTIES_WIDGET(combo_id_mapped(valueLabel, &value, ids, labels), checkboxLabel, isEnabled) };
|
||||
|
||||
auto color3_value = [&](const char* checkboxRLabel, const char* checkboxGLabel, const char* checkboxBLabel,
|
||||
const char* valueRLabel, const char* valueGLabel, const char* valueBLabel,
|
||||
const char* label, bool& isREnabled, bool& isGEnabled, bool& isBEnabled, vec3& value)
|
||||
@@ -214,6 +218,17 @@ namespace anm2ed::imgui::wizard
|
||||
std::vector<int> fallbackIds{-1};
|
||||
std::vector<std::string> fallbackLabelsString{localize.get(BASIC_NONE)};
|
||||
std::vector<const char*> fallbackLabels{fallbackLabelsString[0].c_str()};
|
||||
std::vector<int> interpolationIds{anm2::Frame::Interpolation::NONE, anm2::Frame::Interpolation::LINEAR,
|
||||
anm2::Frame::Interpolation::EASE_IN, anm2::Frame::Interpolation::EASE_OUT,
|
||||
anm2::Frame::Interpolation::EASE_IN_OUT};
|
||||
std::vector<std::string> interpolationLabelsString{
|
||||
localize.get(BASIC_NONE), localize.get(BASIC_LINEAR), localize.get(BASIC_EASE_IN),
|
||||
localize.get(BASIC_EASE_OUT), localize.get(BASIC_EASE_IN_OUT)};
|
||||
std::vector<const char*> interpolationLabels{interpolationLabelsString[0].c_str(),
|
||||
interpolationLabelsString[1].c_str(),
|
||||
interpolationLabelsString[2].c_str(),
|
||||
interpolationLabelsString[3].c_str(),
|
||||
interpolationLabelsString[4].c_str()};
|
||||
|
||||
const Storage* regionStorage = nullptr;
|
||||
if (itemType == anm2::LAYER && document.reference.itemID != -1)
|
||||
@@ -228,12 +243,11 @@ namespace anm2ed::imgui::wizard
|
||||
isRegion);
|
||||
ImGui::EndDisabled();
|
||||
|
||||
enum_value("##Is Interpolation", localize.get(BASIC_INTERPOLATED), isInterpolationSet, interpolation,
|
||||
interpolationIds, interpolationLabels);
|
||||
|
||||
bool_value("##Is Visible", localize.get(BASIC_VISIBLE), isVisibleSet, isVisible);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
bool_value("##Is Interpolated", localize.get(BASIC_INTERPOLATED), isInterpolatedSet, isInterpolated);
|
||||
|
||||
bool_value("##Is Flip X", localize.get(LABEL_FLIP_X), isFlipXSet, isFlipX);
|
||||
|
||||
ImGui::SameLine();
|
||||
@@ -268,7 +282,8 @@ namespace anm2ed::imgui::wizard
|
||||
if (isColorOffsetG) frameChange.colorOffsetG = colorOffset.g;
|
||||
if (isColorOffsetB) frameChange.colorOffsetB = colorOffset.b;
|
||||
if (isVisibleSet) frameChange.isVisible = std::make_optional(isVisible);
|
||||
if (isInterpolatedSet) frameChange.isInterpolated = std::make_optional(isInterpolated);
|
||||
if (isInterpolationSet)
|
||||
frameChange.interpolation = std::make_optional(static_cast<anm2::Frame::Interpolation>(interpolation));
|
||||
if (isFlipXSet) frameChange.isFlipX = std::make_optional(isFlipX);
|
||||
if (isFlipYSet) frameChange.isFlipY = std::make_optional(isFlipY);
|
||||
|
||||
@@ -283,7 +298,7 @@ namespace anm2ed::imgui::wizard
|
||||
bool isAnyProperty = isCropX || isCropY || isSizeX || isSizeY || isPositionX || isPositionY || isPivotX ||
|
||||
isPivotY || isScaleX || isScaleY || isRotation || isDuration || isTintR || isTintG ||
|
||||
isTintB || isTintA || isColorOffsetR || isColorOffsetG || isColorOffsetB || isRegion ||
|
||||
isVisibleSet || isInterpolatedSet || isFlipXSet || isFlipYSet;
|
||||
isVisibleSet || isInterpolationSet || isFlipXSet || isFlipYSet;
|
||||
|
||||
auto rowWidgetSize = widget_size_with_row_get(5);
|
||||
|
||||
|
||||
@@ -72,6 +72,10 @@ namespace anm2ed::imgui::wizard
|
||||
ImGui::RadioButton(localize.get(LABEL_ANM2ED_LIMITED), &temporary.fileCompatibility, anm2::ANM2ED_LIMITED);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_COMPATIBILITY_ANM2ED_LIMITED));
|
||||
|
||||
ImGui::Checkbox(localize.get(LABEL_BAKE_SPECIAL_INTERPOLATED_FRAMES_ON_SAVE),
|
||||
&temporary.fileBakeSpecialInterpolatedFramesOnSave);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_BAKE_SPECIAL_INTERPOLATED_FRAMES_ON_SAVE));
|
||||
|
||||
ImGui::SeparatorText(localize.get(LABEL_OPTIONS));
|
||||
ImGui::Checkbox(localize.get(LABEL_OVERWRITE_WARNING), &temporary.fileIsWarnOverwrite);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_OVERWRITE_WARNING));
|
||||
|
||||
Reference in New Issue
Block a user