CHANGES!
This commit is contained in:
@@ -93,6 +93,159 @@ namespace anm2ed::imgui
|
||||
return isActivated;
|
||||
}
|
||||
|
||||
edit::Type drag_int_persistent(const char* label, int* value, float speed, int min, int max, const char* format,
|
||||
ImGuiSliderFlags flags)
|
||||
{
|
||||
static bool isEditing{};
|
||||
static int start{INT_MAX};
|
||||
auto persistent = value ? *value : 0;
|
||||
|
||||
ImGui::DragInt(label, &persistent, speed, min, max, format, flags);
|
||||
if (!value) return edit::NONE;
|
||||
if (ImGui::IsItemActivated() && persistent != start)
|
||||
{
|
||||
isEditing = true;
|
||||
start = *value;
|
||||
return edit::START;
|
||||
}
|
||||
else if (ImGui::IsItemDeactivatedAfterEdit())
|
||||
{
|
||||
isEditing = false;
|
||||
*value = persistent;
|
||||
start = INT_MAX;
|
||||
return edit::END;
|
||||
}
|
||||
else if (isEditing)
|
||||
{
|
||||
*value = persistent;
|
||||
return edit::DURING;
|
||||
}
|
||||
|
||||
return edit::NONE;
|
||||
}
|
||||
|
||||
edit::Type drag_float_persistent(const char* label, float* value, float speed, float min, float max,
|
||||
const char* format, ImGuiSliderFlags flags)
|
||||
{
|
||||
static bool isEditing{};
|
||||
static float start{NAN};
|
||||
auto persistent = value ? *value : 0;
|
||||
|
||||
ImGui::DragFloat(label, &persistent, speed, min, max, format, flags);
|
||||
if (!value) return edit::NONE;
|
||||
if (ImGui::IsItemActivated() && persistent != start)
|
||||
{
|
||||
isEditing = true;
|
||||
start = *value;
|
||||
return edit::START;
|
||||
}
|
||||
else if (ImGui::IsItemDeactivatedAfterEdit())
|
||||
{
|
||||
isEditing = false;
|
||||
*value = persistent;
|
||||
start = NAN;
|
||||
return edit::END;
|
||||
}
|
||||
else if (isEditing)
|
||||
{
|
||||
*value = persistent;
|
||||
return edit::DURING;
|
||||
}
|
||||
|
||||
return edit::NONE;
|
||||
}
|
||||
|
||||
edit::Type drag_float2_persistent(const char* label, vec2* value, float speed, float min, float max,
|
||||
const char* format, ImGuiSliderFlags flags)
|
||||
{
|
||||
static bool isEditing{};
|
||||
static vec2 start{NAN};
|
||||
auto persistent = value ? *value : vec2();
|
||||
|
||||
ImGui::DragFloat2(label, value_ptr(persistent), speed, min, max, format, flags);
|
||||
if (!value) return edit::NONE;
|
||||
if (ImGui::IsItemActivated() && persistent != start)
|
||||
{
|
||||
isEditing = true;
|
||||
start = *value;
|
||||
return edit::START;
|
||||
}
|
||||
else if (ImGui::IsItemDeactivatedAfterEdit())
|
||||
{
|
||||
isEditing = false;
|
||||
*value = persistent;
|
||||
start = vec2{NAN};
|
||||
return edit::END;
|
||||
}
|
||||
else if (isEditing)
|
||||
{
|
||||
*value = persistent;
|
||||
return edit::DURING;
|
||||
}
|
||||
|
||||
return edit::NONE;
|
||||
}
|
||||
|
||||
edit::Type color_edit3_persistent(const char* label, vec3* value, ImGuiColorEditFlags flags)
|
||||
{
|
||||
static bool isEditing{};
|
||||
static vec3 start{NAN};
|
||||
auto persistent = value ? *value : vec4();
|
||||
|
||||
ImGui::ColorEdit3(label, value_ptr(persistent), flags);
|
||||
if (!value) return edit::NONE;
|
||||
if (ImGui::IsItemActivated() && persistent != start)
|
||||
{
|
||||
isEditing = true;
|
||||
start = *value;
|
||||
return edit::START;
|
||||
}
|
||||
else if (ImGui::IsItemDeactivatedAfterEdit())
|
||||
{
|
||||
isEditing = false;
|
||||
*value = persistent;
|
||||
start = vec4{NAN};
|
||||
return edit::END;
|
||||
}
|
||||
else if (isEditing)
|
||||
{
|
||||
*value = persistent;
|
||||
return edit::DURING;
|
||||
}
|
||||
|
||||
return edit::NONE;
|
||||
}
|
||||
|
||||
edit::Type color_edit4_persistent(const char* label, vec4* value, ImGuiColorEditFlags flags)
|
||||
{
|
||||
static bool isEditing{};
|
||||
static vec4 start{NAN};
|
||||
auto persistent = value ? *value : vec4();
|
||||
|
||||
ImGui::ColorEdit4(label, value_ptr(persistent), flags);
|
||||
if (!value) return edit::NONE;
|
||||
if (ImGui::IsItemActivated() && persistent != start)
|
||||
{
|
||||
isEditing = true;
|
||||
start = *value;
|
||||
return edit::START;
|
||||
}
|
||||
else if (ImGui::IsItemDeactivatedAfterEdit())
|
||||
{
|
||||
isEditing = false;
|
||||
*value = persistent;
|
||||
start = vec4{NAN};
|
||||
return edit::END;
|
||||
}
|
||||
else if (isEditing)
|
||||
{
|
||||
*value = persistent;
|
||||
return edit::DURING;
|
||||
}
|
||||
|
||||
return edit::NONE;
|
||||
}
|
||||
|
||||
bool input_int_range(const char* label, int& value, int min, int max, int step, int stepFast,
|
||||
ImGuiInputTextFlags flags)
|
||||
{
|
||||
|
||||
+10
-1
@@ -12,7 +12,8 @@
|
||||
|
||||
namespace anm2ed::imgui
|
||||
{
|
||||
constexpr auto DRAG_SPEED = 1.0f;
|
||||
constexpr auto DRAG_SPEED = 0.25f;
|
||||
constexpr auto DRAG_SPEED_FAST = 1.00f;
|
||||
constexpr auto STEP = 1.0f;
|
||||
constexpr auto STEP_FAST = 5.0f;
|
||||
|
||||
@@ -179,6 +180,14 @@ namespace anm2ed::imgui
|
||||
bool input_int2_range(const char*, glm::ivec2&, glm::ivec2, glm::ivec2, ImGuiInputTextFlags = 0);
|
||||
bool input_float_range(const char*, float&, float, float, float = STEP, float = STEP_FAST, const char* = "%.3f",
|
||||
ImGuiInputTextFlags = 0);
|
||||
types::edit::Type drag_int_persistent(const char*, int*, float = DRAG_SPEED, int = {}, int = {}, const char* = "%d",
|
||||
ImGuiSliderFlags = 0);
|
||||
types::edit::Type drag_float_persistent(const char*, float*, float = DRAG_SPEED, float = {}, float = {},
|
||||
const char* = "%.3f", ImGuiSliderFlags = 0);
|
||||
types::edit::Type drag_float2_persistent(const char*, glm::vec2*, float = DRAG_SPEED, float = {}, float = {},
|
||||
const char* = "%.3f", ImGuiSliderFlags = 0);
|
||||
types::edit::Type color_edit3_persistent(const char*, glm::vec3*, ImGuiColorEditFlags = 0);
|
||||
types::edit::Type color_edit4_persistent(const char*, glm::vec4*, ImGuiColorEditFlags = 0);
|
||||
bool combo_negative_one_indexed(const std::string&, int*, std::vector<const char*>&);
|
||||
std::string& selectable_input_text_id();
|
||||
bool selectable_input_text(const std::string& label, const std::string& id, std::string& text, bool isSelected,
|
||||
|
||||
+141
-12
@@ -7,6 +7,7 @@
|
||||
#include <cstddef>
|
||||
#include <filesystem>
|
||||
#include <format>
|
||||
#include <ranges>
|
||||
#include <system_error>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
@@ -225,6 +226,7 @@ namespace anm2ed::imgui
|
||||
auto document = manager.get();
|
||||
auto animation = document ? document->animation_get() : nullptr;
|
||||
auto item = document ? document->item_get() : nullptr;
|
||||
auto frames = document ? &document->frames : nullptr;
|
||||
|
||||
if (ImGui::BeginMainMenuBar())
|
||||
{
|
||||
@@ -296,7 +298,12 @@ namespace anm2ed::imgui
|
||||
item && document->reference.itemType == anm2::LAYER))
|
||||
generatePopup.open();
|
||||
|
||||
if (ImGui::MenuItem(localize.get(LABEL_CHANGE_ALL_FRAME_PROPERTIES), nullptr, false,
|
||||
frames && !frames->selection.empty() && document->reference.itemType != anm2::TRIGGER))
|
||||
changePopup.open();
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem(localize.get(LABEL_TASKBAR_RENDER_ANIMATION), nullptr, false, animation))
|
||||
renderPopup.open();
|
||||
ImGui::EndMenu();
|
||||
@@ -337,7 +344,6 @@ namespace anm2ed::imgui
|
||||
|
||||
if (ImGui::BeginMenu(localize.get(LABEL_HELP_MENU)))
|
||||
{
|
||||
|
||||
if (ImGui::MenuItem(localize.get(LABEL_TASKBAR_ABOUT))) aboutPopup.open();
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
@@ -445,6 +451,135 @@ namespace anm2ed::imgui
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
changePopup.trigger();
|
||||
|
||||
if (ImGui::BeginPopupModal(changePopup.label(), &changePopup.isOpen, ImGuiWindowFlags_NoResize))
|
||||
{
|
||||
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& isDuration = settings.changeIsDuration;
|
||||
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.changeDuration;
|
||||
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), math::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, math::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", localize.get(BASIC_CROP), isCrop, crop);
|
||||
float2_value("##Is Size", localize.get(BASIC_SIZE), isSize, size);
|
||||
float2_value("##Is Position", localize.get(BASIC_POSITION), isPosition, position);
|
||||
float2_value("##Is Pivot", localize.get(BASIC_PIVOT), isPivot, pivot);
|
||||
float2_value("##Is Scale", localize.get(BASIC_SCALE), isScale, scale);
|
||||
float_value("##Is Rotation", localize.get(BASIC_ROTATION), isRotation, rotation);
|
||||
duration_value("##Is Duration", localize.get(BASIC_DURATION), isDuration, duration);
|
||||
color4_value("##Is Tint", localize.get(BASIC_TINT), isTint, tint);
|
||||
color3_value("##Is Color Offset", localize.get(BASIC_COLOR_OFFSET), isColorOffset, colorOffset);
|
||||
bool_value("##Is Visible", localize.get(BASIC_VISIBLE), isVisibleSet, isVisible);
|
||||
ImGui::SameLine();
|
||||
bool_value("##Is Interpolated", localize.get(BASIC_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 (isDuration) 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_PTR(
|
||||
document, localize.get(EDIT_CHANGE_FRAME_PROPERTIES), Document::FRAMES,
|
||||
item->frames_change(frameChange, type, *frames->selection.begin(), (int)frames->selection.size()));
|
||||
|
||||
changePopup.close();
|
||||
};
|
||||
|
||||
bool isAnyProperty = isCrop || isSize || isPosition || isPivot || isScale || isRotation || isDuration || isTint ||
|
||||
isColorOffset || isVisibleSet || isInterpolatedSet;
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
auto rowWidgetSize = widget_size_with_row_get(5);
|
||||
|
||||
ImGui::BeginDisabled(!isAnyProperty);
|
||||
|
||||
if (ImGui::Button(localize.get(LABEL_ADJUST), rowWidgetSize)) frame_change(anm2::ADJUST);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_ADJUST));
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button(localize.get(BASIC_ADD), rowWidgetSize)) frame_change(anm2::ADD);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_ADD_VALUES));
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button(localize.get(LABEL_SUBTRACT), rowWidgetSize)) frame_change(anm2::SUBTRACT);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_SUBTRACT_VALUES));
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button(localize.get(LABEL_MULTIPLY), rowWidgetSize)) frame_change(anm2::MULTIPLY);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_MULTIPLY_VALUES));
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button(localize.get(LABEL_DIVIDE), rowWidgetSize)) frame_change(anm2::DIVIDE);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_DIVIDE_VALUES));
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
configurePopup.trigger();
|
||||
|
||||
if (ImGui::BeginPopupModal(configurePopup.label(), &configurePopup.isOpen, ImGuiWindowFlags_NoResize))
|
||||
@@ -654,6 +789,7 @@ namespace anm2ed::imgui
|
||||
auto& columns = settings.renderColumns;
|
||||
auto& isRange = manager.isRecordingRange;
|
||||
auto& frames = document->frames.selection;
|
||||
auto& reference = document->reference;
|
||||
int length = std::max(1, end - start + 1);
|
||||
|
||||
auto range_to_frames_set = [&]()
|
||||
@@ -661,17 +797,10 @@ namespace anm2ed::imgui
|
||||
if (auto item = document->item_get())
|
||||
{
|
||||
int duration{};
|
||||
for (std::size_t index = 0; index < item->frames.size(); ++index)
|
||||
for (auto [i, frame] : std::views::enumerate(item->frames))
|
||||
{
|
||||
const auto& frame = item->frames[index];
|
||||
|
||||
if ((int)index == *frames.begin())
|
||||
start = duration;
|
||||
else if ((int)index == *frames.rbegin())
|
||||
{
|
||||
end = duration;
|
||||
break;
|
||||
}
|
||||
if ((int)i == *frames.begin()) start = duration;
|
||||
if ((int)i == *frames.rbegin()) end = duration + frame.duration - 1;
|
||||
|
||||
duration += frame.duration;
|
||||
}
|
||||
@@ -800,7 +929,7 @@ namespace anm2ed::imgui
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::BeginDisabled(frames.empty());
|
||||
ImGui::BeginDisabled(frames.empty() || reference.itemID == anm2::TRIGGER);
|
||||
if (ImGui::Button(localize.get(LABEL_TO_SELECTED_FRAMES))) range_to_frames_set();
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_TO_SELECTED_FRAMES));
|
||||
ImGui::EndDisabled();
|
||||
|
||||
+3
-4
@@ -15,10 +15,9 @@ namespace anm2ed::imgui
|
||||
Canvas generate;
|
||||
float generateTime{};
|
||||
PopupHelper generatePopup{PopupHelper(LABEL_TASKBAR_GENERATE_ANIMATION_FROM_GRID)};
|
||||
PopupHelper overwritePopup{
|
||||
PopupHelper(LABEL_TASKBAR_OVERWRITE_FILE, imgui::POPUP_SMALL_NO_HEIGHT)};
|
||||
PopupHelper renderPopup{
|
||||
PopupHelper(LABEL_TASKBAR_RENDER_ANIMATION, imgui::POPUP_SMALL_NO_HEIGHT)};
|
||||
PopupHelper changePopup{PopupHelper(LABEL_CHANGE_ALL_FRAME_PROPERTIES, imgui::POPUP_NORMAL_NO_HEIGHT)};
|
||||
PopupHelper overwritePopup{PopupHelper(LABEL_TASKBAR_OVERWRITE_FILE, imgui::POPUP_SMALL_NO_HEIGHT)};
|
||||
PopupHelper renderPopup{PopupHelper(LABEL_TASKBAR_RENDER_ANIMATION, imgui::POPUP_SMALL_NO_HEIGHT)};
|
||||
PopupHelper configurePopup{PopupHelper(LABEL_TASKBAR_CONFIGURE)};
|
||||
PopupHelper aboutPopup{PopupHelper(LABEL_TASKBAR_ABOUT)};
|
||||
Settings editSettings{};
|
||||
|
||||
@@ -430,7 +430,7 @@ namespace anm2ed::imgui
|
||||
|
||||
bind();
|
||||
viewport_set();
|
||||
clear(manager.isRecording && settings.renderIsRawAnimation ? vec4() : vec4(backgroundColor, 1.0f));
|
||||
clear(manager.isRecording && settings.renderIsRawAnimation ? vec4(0) : vec4(backgroundColor, 1.0f));
|
||||
|
||||
if (isAxes) axes_render(shaderAxes, zoom, pan, axesColor);
|
||||
if (isGrid) grid_render(shaderGrid, zoom, pan, gridSize, gridOffset, gridColor);
|
||||
@@ -731,9 +731,13 @@ namespace anm2ed::imgui
|
||||
if (tool == tool::MOVE && isMouseRightDown) useTool = tool::SCALE;
|
||||
if (tool == tool::SCALE && isMouseRightDown) useTool = tool::MOVE;
|
||||
|
||||
auto& areaType = tool::INFO[useTool].areaType;
|
||||
auto cursor = areaType == tool::ANIMATION_PREVIEW || areaType == tool::ALL ? tool::INFO[useTool].cursor
|
||||
: ImGuiMouseCursor_NotAllowed;
|
||||
auto& toolInfo = tool::INFO[useTool];
|
||||
auto& areaType = toolInfo.areaType;
|
||||
bool isAreaAllowed = areaType == tool::ALL || areaType == tool::ANIMATION_PREVIEW;
|
||||
bool isFrameRequired =
|
||||
!(useTool == tool::PAN || useTool == tool::DRAW || useTool == tool::ERASE || useTool == tool::COLOR_PICKER);
|
||||
bool isFrameAvailable = !isFrameRequired || frame;
|
||||
auto cursor = (isAreaAllowed && isFrameAvailable) ? toolInfo.cursor : ImGuiMouseCursor_NotAllowed;
|
||||
ImGui::SetMouseCursor(cursor);
|
||||
ImGui::SetKeyboardFocusHere();
|
||||
if (useTool != tool::MOVE) isMoveDragging = false;
|
||||
@@ -820,6 +824,26 @@ namespace anm2ed::imgui
|
||||
break;
|
||||
}
|
||||
|
||||
if ((isMouseDown || isKeyDown) && useTool != tool::PAN)
|
||||
{
|
||||
if (!isAreaAllowed && areaType == tool::SPRITESHEET_EDITOR)
|
||||
{
|
||||
if (ImGui::BeginTooltip())
|
||||
{
|
||||
ImGui::TextUnformatted(localize.get(TEXT_TOOL_SPRITESHEET_EDITOR));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
else if (isFrameRequired && !isFrameAvailable)
|
||||
{
|
||||
if (ImGui::BeginTooltip())
|
||||
{
|
||||
ImGui::TextUnformatted(localize.get(TEXT_SELECT_FRAME));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mouseWheel != 0 || isZoomIn || isZoomOut)
|
||||
{
|
||||
auto previousZoom = zoom;
|
||||
@@ -829,7 +853,7 @@ namespace anm2ed::imgui
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::BeginPopupContextWindow("##Animation Preview Context Menu", ImGuiMouseButton_Right))
|
||||
if (tool == tool::PAN && ImGui::BeginPopupContextWindow("##Animation Preview Context Menu", ImGuiMouseButton_Right))
|
||||
{
|
||||
if (ImGui::MenuItem(localize.get(SHORTCUT_STRING_UNDO), settings.shortcutUndo.c_str(), false,
|
||||
document.is_able_to_undo()))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "frame_properties.h"
|
||||
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <limits>
|
||||
|
||||
#include "math_.h"
|
||||
#include "strings.h"
|
||||
@@ -12,6 +13,7 @@ using namespace glm;
|
||||
|
||||
namespace anm2ed::imgui
|
||||
{
|
||||
|
||||
void FrameProperties::update(Manager& manager, Settings& settings)
|
||||
{
|
||||
if (ImGui::Begin(localize.get(LABEL_FRAME_PROPERTIES_WINDOW), &settings.windowIsFrameProperties))
|
||||
@@ -45,8 +47,9 @@ namespace anm2ed::imgui
|
||||
frame->soundID = useFrame.soundID);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_TRIGGER_SOUND));
|
||||
|
||||
if (ImGui::InputInt(localize.get(BASIC_AT_FRAME), frame ? &useFrame.atFrame : &dummy_value<int>(), STEP,
|
||||
STEP_FAST, !frame ? ImGuiInputTextFlags_DisplayEmptyRefVal : 0) &&
|
||||
if (input_int_range(localize.get(BASIC_AT_FRAME), frame ? useFrame.atFrame : dummy_value<int>(), 0,
|
||||
std::numeric_limits<int>::max(), STEP, STEP_FAST,
|
||||
!frame ? ImGuiInputTextFlags_DisplayEmptyRefVal : 0) &&
|
||||
frame)
|
||||
DOCUMENT_EDIT(document, localize.get(EDIT_TRIGGER_AT_FRAME), Document::FRAMES,
|
||||
frame->atFrame = useFrame.atFrame);
|
||||
@@ -62,52 +65,65 @@ namespace anm2ed::imgui
|
||||
{
|
||||
ImGui::BeginDisabled(type == anm2::ROOT || type == anm2::NULL_);
|
||||
{
|
||||
if (ImGui::InputFloat2(localize.get(BASIC_CROP), frame ? value_ptr(useFrame.crop) : &dummy_value<float>(),
|
||||
frame ? vec2_format_get(useFrame.crop) : "") &&
|
||||
frame)
|
||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_CROP), Document::FRAMES, frame->crop = useFrame.crop);
|
||||
auto cropEdit =
|
||||
drag_float2_persistent(localize.get(BASIC_CROP), frame ? &frame->crop : &dummy_value<vec2>(),
|
||||
DRAG_SPEED, 0.0f, 0.0f, frame ? vec2_format_get(frame->crop) : "");
|
||||
if (cropEdit == edit::START)
|
||||
document.snapshot(localize.get(EDIT_FRAME_CROP));
|
||||
else if (cropEdit == edit::END)
|
||||
document.change(Document::FRAMES);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_CROP));
|
||||
|
||||
if (ImGui::InputFloat2(localize.get(BASIC_SIZE), frame ? value_ptr(useFrame.size) : &dummy_value<float>(),
|
||||
frame ? vec2_format_get(useFrame.size) : "") &&
|
||||
frame)
|
||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_SIZE), Document::FRAMES, frame->size = useFrame.size);
|
||||
auto sizeEdit =
|
||||
drag_float2_persistent(localize.get(BASIC_SIZE), frame ? &frame->size : &dummy_value<vec2>(),
|
||||
DRAG_SPEED, 0.0f, 0.0f, frame ? vec2_format_get(frame->size) : "");
|
||||
if (sizeEdit == edit::START)
|
||||
document.snapshot(localize.get(EDIT_FRAME_SIZE));
|
||||
else if (sizeEdit == edit::END)
|
||||
document.change(Document::FRAMES);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_SIZE));
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
if (ImGui::InputFloat2(localize.get(BASIC_POSITION),
|
||||
frame ? value_ptr(useFrame.position) : &dummy_value<float>(),
|
||||
frame ? vec2_format_get(useFrame.position) : "") &&
|
||||
frame)
|
||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_POSITION), Document::FRAMES,
|
||||
frame->position = useFrame.position);
|
||||
auto positionEdit =
|
||||
drag_float2_persistent(localize.get(BASIC_POSITION), frame ? &frame->position : &dummy_value<vec2>(),
|
||||
DRAG_SPEED, 0.0f, 0.0f, frame ? vec2_format_get(frame->position) : "");
|
||||
if (positionEdit == edit::START)
|
||||
document.snapshot(localize.get(EDIT_FRAME_POSITION));
|
||||
else if (positionEdit == edit::END)
|
||||
document.change(Document::FRAMES);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_POSITION));
|
||||
|
||||
ImGui::BeginDisabled(type == anm2::ROOT || type == anm2::NULL_);
|
||||
{
|
||||
if (ImGui::InputFloat2(localize.get(BASIC_PIVOT),
|
||||
frame ? value_ptr(useFrame.pivot) : &dummy_value<float>(),
|
||||
frame ? vec2_format_get(useFrame.pivot) : "") &&
|
||||
frame)
|
||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_PIVOT), Document::FRAMES,
|
||||
frame->pivot = useFrame.pivot);
|
||||
auto pivotEdit =
|
||||
drag_float2_persistent(localize.get(BASIC_PIVOT), frame ? &frame->pivot : &dummy_value<vec2>(),
|
||||
DRAG_SPEED, 0.0f, 0.0f, frame ? vec2_format_get(frame->pivot) : "");
|
||||
if (pivotEdit == edit::START)
|
||||
document.snapshot(localize.get(EDIT_FRAME_PIVOT));
|
||||
else if (pivotEdit == edit::END)
|
||||
document.change(Document::FRAMES);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_PIVOT));
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
if (ImGui::InputFloat2(localize.get(BASIC_SCALE), frame ? value_ptr(useFrame.scale) : &dummy_value<float>(),
|
||||
frame ? vec2_format_get(useFrame.scale) : "") &&
|
||||
frame)
|
||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_SCALE), Document::FRAMES, frame->scale = useFrame.scale);
|
||||
auto scaleEdit =
|
||||
drag_float2_persistent(localize.get(BASIC_SCALE), frame ? &frame->scale : &dummy_value<vec2>(),
|
||||
DRAG_SPEED, 0.0f, 0.0f, frame ? vec2_format_get(frame->scale) : "");
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_SCALE));
|
||||
if (scaleEdit == edit::START)
|
||||
document.snapshot(localize.get(EDIT_FRAME_SCALE));
|
||||
else if (scaleEdit == edit::END)
|
||||
document.change(Document::FRAMES);
|
||||
|
||||
if (ImGui::InputFloat(localize.get(BASIC_ROTATION), frame ? &useFrame.rotation : &dummy_value<float>(),
|
||||
STEP, STEP_FAST, frame ? float_format_get(useFrame.rotation) : "") &&
|
||||
frame)
|
||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_ROTATION), Document::FRAMES,
|
||||
frame->rotation = useFrame.rotation);
|
||||
auto rotationEdit =
|
||||
drag_float_persistent(localize.get(BASIC_ROTATION), frame ? &frame->rotation : &dummy_value<float>(),
|
||||
DRAG_SPEED, 0.0f, 0.0f, frame ? float_format_get(frame->rotation) : "");
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_ROTATION));
|
||||
if (rotationEdit == edit::START)
|
||||
document.snapshot(localize.get(EDIT_FRAME_ROTATION));
|
||||
else if (rotationEdit == edit::END)
|
||||
document.change(Document::FRAMES);
|
||||
|
||||
if (input_int_range(localize.get(BASIC_DURATION), frame ? useFrame.duration : dummy_value<int>(),
|
||||
frame ? anm2::FRAME_DURATION_MIN : 0, anm2::FRAME_DURATION_MAX, STEP, STEP_FAST,
|
||||
@@ -117,17 +133,21 @@ namespace anm2ed::imgui
|
||||
frame->duration = useFrame.duration);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_DURATION));
|
||||
|
||||
if (ImGui::ColorEdit4(localize.get(BASIC_TINT), frame ? value_ptr(useFrame.tint) : &dummy_value<float>()) &&
|
||||
frame)
|
||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_TINT), Document::FRAMES, frame->tint = useFrame.tint);
|
||||
auto tintEdit =
|
||||
color_edit4_persistent(localize.get(BASIC_TINT), frame ? &frame->tint : &dummy_value<vec4>());
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_TINT));
|
||||
if (tintEdit == edit::START)
|
||||
document.snapshot(localize.get(EDIT_FRAME_TINT));
|
||||
else if (tintEdit == edit::END)
|
||||
document.change(Document::FRAMES);
|
||||
|
||||
if (ImGui::ColorEdit3(localize.get(BASIC_COLOR_OFFSET),
|
||||
frame ? value_ptr(useFrame.colorOffset) : &dummy_value<float>()) &&
|
||||
frame)
|
||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_COLOR_OFFSET), Document::FRAMES,
|
||||
frame->colorOffset = useFrame.colorOffset);
|
||||
auto colorOffsetEdit = color_edit3_persistent(localize.get(BASIC_COLOR_OFFSET),
|
||||
frame ? &frame->colorOffset : &dummy_value<vec3>());
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_COLOR_OFFSET));
|
||||
if (colorOffsetEdit == edit::START)
|
||||
document.snapshot(localize.get(EDIT_FRAME_COLOR_OFFSET));
|
||||
else if (colorOffsetEdit == edit::END)
|
||||
document.change(Document::FRAMES);
|
||||
|
||||
if (ImGui::Checkbox(localize.get(BASIC_VISIBLE), frame ? &useFrame.isVisible : &dummy_value<bool>()) &&
|
||||
frame)
|
||||
@@ -246,24 +266,39 @@ namespace anm2ed::imgui
|
||||
document.item_get()->frames_change(frameChange, type, *frames.begin(), (int)frames.size()));
|
||||
};
|
||||
|
||||
auto rowOneWidgetSize = widget_size_with_row_get(1);
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::Button(localize.get(LABEL_ADJUST), rowOneWidgetSize)) frame_change(anm2::ADJUST);
|
||||
bool isAnyProperty = isCrop || isSize || isPosition || isPivot || isScale || isRotation || isDuration ||
|
||||
isTint || isColorOffset || isVisibleSet || isInterpolatedSet;
|
||||
|
||||
auto rowWidgetSize = widget_size_with_row_get(5);
|
||||
|
||||
ImGui::BeginDisabled(!isAnyProperty);
|
||||
|
||||
if (ImGui::Button(localize.get(LABEL_ADJUST), rowWidgetSize)) frame_change(anm2::ADJUST);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_ADJUST));
|
||||
|
||||
auto rowTwoWidgetSize = widget_size_with_row_get(4);
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button(localize.get(BASIC_ADD), rowTwoWidgetSize)) frame_change(anm2::ADD);
|
||||
if (ImGui::Button(localize.get(BASIC_ADD), rowWidgetSize)) frame_change(anm2::ADD);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_ADD_VALUES));
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(localize.get(LABEL_SUBTRACT), rowTwoWidgetSize)) frame_change(anm2::SUBTRACT);
|
||||
|
||||
if (ImGui::Button(localize.get(LABEL_SUBTRACT), rowWidgetSize)) frame_change(anm2::SUBTRACT);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_SUBTRACT_VALUES));
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(localize.get(LABEL_MULTIPLY), rowTwoWidgetSize)) frame_change(anm2::MULTIPLY);
|
||||
|
||||
if (ImGui::Button(localize.get(LABEL_MULTIPLY), rowWidgetSize)) frame_change(anm2::MULTIPLY);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_MULTIPLY_VALUES));
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(localize.get(LABEL_DIVIDE), rowTwoWidgetSize)) frame_change(anm2::DIVIDE);
|
||||
|
||||
if (ImGui::Button(localize.get(LABEL_DIVIDE), rowWidgetSize)) frame_change(anm2::DIVIDE);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_DIVIDE_VALUES));
|
||||
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
@@ -1,13 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <glm/vec2.hpp>
|
||||
|
||||
#include "manager.h"
|
||||
#include "settings.h"
|
||||
|
||||
namespace anm2
|
||||
{
|
||||
struct Frame;
|
||||
}
|
||||
|
||||
namespace anm2ed::imgui
|
||||
{
|
||||
class FrameProperties
|
||||
{
|
||||
public:
|
||||
void update(Manager&, Settings&);
|
||||
|
||||
private:
|
||||
glm::vec2 cropEditingValue{};
|
||||
const anm2::Frame* cropEditingFrame{};
|
||||
bool isCropEditing{};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ namespace anm2ed::imgui
|
||||
bool isValid = sound.is_valid();
|
||||
auto& soundIcon = isValid ? resources.icons[icon::SOUND] : resources.icons[icon::NONE];
|
||||
auto tintColor = !isValid ? ImVec4(1.0f, 0.25f, 0.25f, 1.0f) : ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
auto pathCStr = sound.path.string().c_str();
|
||||
auto pathString = sound.path.string();
|
||||
|
||||
ImGui::SetNextItemSelectionUserData(id);
|
||||
ImGui::SetNextItemStorageID(id);
|
||||
@@ -226,7 +226,7 @@ namespace anm2ed::imgui
|
||||
newSoundId = -1;
|
||||
}
|
||||
|
||||
auto textWidth = ImGui::CalcTextSize(pathCStr).x;
|
||||
auto textWidth = ImGui::CalcTextSize(pathString.c_str()).x;
|
||||
auto tooltipPadding = style.WindowPadding.x * 4.0f;
|
||||
auto minWidth = textWidth + style.ItemSpacing.x + tooltipPadding;
|
||||
|
||||
@@ -236,7 +236,7 @@ namespace anm2ed::imgui
|
||||
if (ImGui::BeginItemTooltip())
|
||||
{
|
||||
ImGui::PushFont(resources.fonts[font::BOLD].get(), font::SIZE);
|
||||
ImGui::TextUnformatted(pathCStr);
|
||||
ImGui::TextUnformatted(pathString.c_str());
|
||||
ImGui::PopFont();
|
||||
ImGui::Text("%s: %d", localize.get(BASIC_ID), id);
|
||||
if (!isValid)
|
||||
@@ -261,7 +261,7 @@ namespace anm2ed::imgui
|
||||
soundChildSize.y - soundChildSize.y / 2 - ImGui::GetTextLineHeight() / 2));
|
||||
|
||||
ImGui::TextUnformatted(
|
||||
std::vformat(localize.get(FORMAT_SOUND), std::make_format_args(id, pathCStr)).c_str());
|
||||
std::vformat(localize.get(FORMAT_SOUND), std::make_format_args(id, pathString)).c_str());
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
|
||||
@@ -190,7 +190,7 @@ namespace anm2ed::imgui
|
||||
|
||||
bind();
|
||||
viewport_set();
|
||||
clear(isTransparent ? vec4() : vec4(backgroundColor, 1.0f));
|
||||
clear(isTransparent ? vec4(0) : vec4(backgroundColor, 1.0f));
|
||||
|
||||
auto frame = document.frame_get();
|
||||
|
||||
@@ -312,8 +312,15 @@ namespace anm2ed::imgui
|
||||
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
|
||||
auto& toolInfo = tool::INFO[useTool];
|
||||
auto& areaType = toolInfo.areaType;
|
||||
bool isAreaAllowed = areaType == tool::ALL || areaType == tool::SPRITESHEET_EDITOR;
|
||||
bool isFrameRequired =
|
||||
!(useTool == tool::PAN || useTool == tool::DRAW || useTool == tool::ERASE || useTool == tool::COLOR_PICKER);
|
||||
bool isFrameAvailable = !isFrameRequired || frame;
|
||||
bool isSpritesheetRequired = useTool == tool::DRAW || useTool == tool::ERASE || useTool == tool::COLOR_PICKER;
|
||||
bool isSpritesheetAvailable = !isSpritesheetRequired || (spritesheet && spritesheet->texture.is_valid());
|
||||
auto cursor = (isAreaAllowed && isFrameAvailable && isSpritesheetAvailable) ? toolInfo.cursor
|
||||
: ImGuiMouseCursor_NotAllowed;
|
||||
ImGui::SetMouseCursor(cursor);
|
||||
ImGui::SetKeyboardFocusHere();
|
||||
@@ -429,6 +436,34 @@ namespace anm2ed::imgui
|
||||
break;
|
||||
}
|
||||
|
||||
if ((isMouseDown || isKeyDown) && useTool != tool::PAN)
|
||||
{
|
||||
if (!isAreaAllowed && areaType == tool::ANIMATION_PREVIEW)
|
||||
{
|
||||
if (ImGui::BeginTooltip())
|
||||
{
|
||||
ImGui::TextUnformatted(localize.get(TEXT_TOOL_ANIMATION_PREVIEW));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
else if (isSpritesheetRequired && !isSpritesheetAvailable)
|
||||
{
|
||||
if (ImGui::BeginTooltip())
|
||||
{
|
||||
ImGui::TextUnformatted(localize.get(TEXT_SELECT_SPRITESHEET));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
else if (isFrameRequired && !isFrameAvailable)
|
||||
{
|
||||
if (ImGui::BeginTooltip())
|
||||
{
|
||||
ImGui::TextUnformatted(localize.get(TEXT_SELECT_FRAME));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mouseWheel != 0 || isZoomIn || isZoomOut)
|
||||
{
|
||||
auto focus = mouseWheel != 0 ? vec2(mousePos) : vec2();
|
||||
@@ -442,7 +477,8 @@ namespace anm2ed::imgui
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::BeginPopupContextWindow("##Spritesheet Editor Context Menu", ImGuiMouseButton_Right))
|
||||
if (tool == tool::PAN &&
|
||||
ImGui::BeginPopupContextWindow("##Spritesheet Editor Context Menu", ImGuiMouseButton_Right))
|
||||
{
|
||||
if (ImGui::MenuItem(localize.get(SHORTCUT_STRING_UNDO), settings.shortcutUndo.c_str(), false,
|
||||
document.is_able_to_undo()))
|
||||
|
||||
+55
-390
@@ -3,7 +3,6 @@
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <imgui_internal.h>
|
||||
|
||||
@@ -81,7 +80,6 @@ namespace anm2ed::imgui
|
||||
constexpr auto FRAME_MULTIPLE = 5;
|
||||
constexpr auto FRAME_DRAG_PAYLOAD_ID = "Frame Drag Drop";
|
||||
constexpr auto FRAME_TOOLTIP_HOVER_DELAY = 0.75f; // Extra delay for frame info tooltip.
|
||||
constexpr int ITEM_SELECTION_NULL_FLAG = 1 << 30;
|
||||
|
||||
void Timeline::update(Manager& manager, Settings& settings, Resources& resources, Clipboard& clipboard)
|
||||
{
|
||||
@@ -90,38 +88,7 @@ namespace anm2ed::imgui
|
||||
auto& playback = document.playback;
|
||||
auto& reference = document.reference;
|
||||
auto& frames = document.frames;
|
||||
auto& items = document.items;
|
||||
auto& itemSelection = items.selection;
|
||||
auto animation = document.animation_get();
|
||||
auto item_selection_encode = [&](anm2::Type type, int id) -> int
|
||||
{
|
||||
if (type == anm2::NULL_) return id | ITEM_SELECTION_NULL_FLAG;
|
||||
return id;
|
||||
};
|
||||
auto item_selection_decode = [&](int value) -> int { return value & ~ITEM_SELECTION_NULL_FLAG; };
|
||||
auto item_selection_value_type = [&](int value) -> anm2::Type
|
||||
{ return (value & ITEM_SELECTION_NULL_FLAG) ? anm2::NULL_ : anm2::LAYER; };
|
||||
std::vector<int> itemSelectionIndexMap{};
|
||||
std::unordered_map<int, int> layerSelectionIndex{};
|
||||
std::unordered_map<int, int> nullSelectionIndex{};
|
||||
if (animation)
|
||||
{
|
||||
itemSelectionIndexMap.reserve(animation->layerOrder.size() + animation->nullAnimations.size());
|
||||
for (auto id : animation->layerOrder)
|
||||
{
|
||||
layerSelectionIndex[id] = (int)itemSelectionIndexMap.size();
|
||||
itemSelectionIndexMap.push_back(item_selection_encode(anm2::LAYER, id));
|
||||
}
|
||||
for (auto& [id, nullAnimation] : animation->nullAnimations)
|
||||
{
|
||||
(void)nullAnimation;
|
||||
nullSelectionIndex[id] = (int)itemSelectionIndexMap.size();
|
||||
itemSelectionIndexMap.push_back(item_selection_encode(anm2::NULL_, id));
|
||||
}
|
||||
itemSelection.set_index_map(&itemSelectionIndexMap);
|
||||
}
|
||||
else
|
||||
itemSelection.set_index_map(nullptr);
|
||||
|
||||
style = ImGui::GetStyle();
|
||||
auto isLightTheme = settings.theme == theme::LIGHT;
|
||||
@@ -161,113 +128,6 @@ namespace anm2ed::imgui
|
||||
return ITEM_COLOR_LIGHT_ACTIVE[type_index(type)];
|
||||
};
|
||||
|
||||
items.hovered = -1;
|
||||
|
||||
auto item_selection_type_get = [&](anm2::Type preferredType = anm2::NONE) -> anm2::Type
|
||||
{
|
||||
if (itemSelection.empty() || !animation) return anm2::NONE;
|
||||
|
||||
bool hasLayer = false;
|
||||
bool hasNull = false;
|
||||
|
||||
for (auto encoded : itemSelection)
|
||||
{
|
||||
auto valueType = item_selection_value_type(encoded);
|
||||
auto valueID = item_selection_decode(encoded);
|
||||
if (valueType == anm2::LAYER && animation->layerAnimations.contains(valueID)) hasLayer = true;
|
||||
if (valueType == anm2::NULL_ && animation->nullAnimations.contains(valueID)) hasNull = true;
|
||||
}
|
||||
|
||||
auto type_available = [&](anm2::Type type)
|
||||
{
|
||||
if (type == anm2::LAYER) return hasLayer;
|
||||
if (type == anm2::NULL_) return hasNull;
|
||||
return false;
|
||||
};
|
||||
|
||||
if (preferredType != anm2::NONE && type_available(preferredType)) return preferredType;
|
||||
if (hasLayer) return anm2::LAYER;
|
||||
if (hasNull) return anm2::NULL_;
|
||||
return anm2::NONE;
|
||||
};
|
||||
|
||||
auto item_selection_clear = [&]() { itemSelection.clear(); };
|
||||
|
||||
auto item_selection_sync = [&]()
|
||||
{
|
||||
if (itemSelection.empty())
|
||||
{
|
||||
item_selection_clear();
|
||||
return;
|
||||
}
|
||||
|
||||
auto preferredType = items.reference == (int)anm2::LAYER || items.reference == (int)anm2::NULL_
|
||||
? (anm2::Type)items.reference
|
||||
: anm2::NONE;
|
||||
auto type = item_selection_type_get(preferredType);
|
||||
|
||||
if (type == anm2::NONE)
|
||||
{
|
||||
item_selection_clear();
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto it = itemSelection.begin(); it != itemSelection.end();)
|
||||
{
|
||||
if (item_selection_value_type(*it) != type)
|
||||
it = itemSelection.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
items.reference = (int)type;
|
||||
};
|
||||
|
||||
auto item_selection_prune = [&]()
|
||||
{
|
||||
if (itemSelection.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!animation)
|
||||
{
|
||||
item_selection_clear();
|
||||
return;
|
||||
}
|
||||
|
||||
auto type = item_selection_type_get();
|
||||
if (type != anm2::LAYER && type != anm2::NULL_)
|
||||
{
|
||||
item_selection_clear();
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto it = itemSelection.begin(); it != itemSelection.end();)
|
||||
{
|
||||
if (item_selection_value_type(*it) != type)
|
||||
{
|
||||
it = itemSelection.erase(it);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto valueID = item_selection_decode(*it);
|
||||
bool exists = type == anm2::LAYER ? animation->layerAnimations.contains(valueID)
|
||||
: animation->nullAnimations.contains(valueID);
|
||||
if (!exists)
|
||||
it = itemSelection.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
if (itemSelection.empty())
|
||||
item_selection_clear();
|
||||
else
|
||||
item_selection_sync();
|
||||
};
|
||||
|
||||
item_selection_prune();
|
||||
|
||||
auto iconTintDefault = isLightTheme ? ICON_TINT_DEFAULT_LIGHT : ICON_TINT_DEFAULT_DARK;
|
||||
auto itemIconTint = isLightTheme ? ICON_TINT_DEFAULT_LIGHT : iconTintDefault;
|
||||
auto frameBorderColor = isLightTheme ? FRAME_BORDER_COLOR_LIGHT : FRAME_BORDER_COLOR_DARK;
|
||||
@@ -456,8 +316,19 @@ namespace anm2ed::imgui
|
||||
{
|
||||
reference = {reference.animationIndex, type, id};
|
||||
frames_selection_reset();
|
||||
if (type == anm2::LAYER || type == anm2::NULL_) items.reference = (int)type;
|
||||
items.selection = {(int)id};
|
||||
};
|
||||
|
||||
auto item_remove = [&]()
|
||||
{
|
||||
auto behavior = [&]()
|
||||
{
|
||||
if (!animation) return;
|
||||
if (reference.itemType == anm2::LAYER || reference.itemType == anm2::NULL_)
|
||||
animation->item_remove(reference.itemType, reference.itemID);
|
||||
reference_clear();
|
||||
};
|
||||
|
||||
DOCUMENT_EDIT(document, localize.get(EDIT_REMOVE_ITEMS), Document::ITEMS, behavior());
|
||||
};
|
||||
|
||||
auto fit_animation_length = [&]()
|
||||
@@ -595,6 +466,20 @@ namespace anm2ed::imgui
|
||||
ImGui::PopStyleVar(2);
|
||||
};
|
||||
|
||||
auto item_base_properties_open = [&](anm2::Type type, int id)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case anm2::LAYER:
|
||||
manager.layer_properties_open(id);
|
||||
break;
|
||||
case anm2::NULL_:
|
||||
manager.null_properties_open(id);
|
||||
default:
|
||||
break;
|
||||
};
|
||||
};
|
||||
|
||||
auto item_properties_reset = [&]()
|
||||
{
|
||||
addItemName.clear();
|
||||
@@ -610,94 +495,14 @@ namespace anm2ed::imgui
|
||||
return std::set<int>{};
|
||||
};
|
||||
|
||||
auto item_selection_index_get = [&](anm2::Type type, int id)
|
||||
{
|
||||
if (type == anm2::LAYER)
|
||||
{
|
||||
if (auto it = layerSelectionIndex.find(id); it != layerSelectionIndex.end()) return it->second;
|
||||
}
|
||||
else if (type == anm2::NULL_)
|
||||
{
|
||||
if (auto it = nullSelectionIndex.find(id); it != nullSelectionIndex.end()) return it->second;
|
||||
}
|
||||
|
||||
return -1;
|
||||
};
|
||||
|
||||
auto item_type_has_visible = [&](anm2::Type type)
|
||||
{
|
||||
if (!animation) return false;
|
||||
auto& showUnused = settings.timelineIsShowUnused;
|
||||
if (type == anm2::LAYER)
|
||||
{
|
||||
for (auto id : animation->layerOrder)
|
||||
{
|
||||
if (!showUnused && animation->layerAnimations[id].frames.empty()) continue;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (type == anm2::NULL_)
|
||||
{
|
||||
for (auto& [id, nullAnimation] : animation->nullAnimations)
|
||||
{
|
||||
if (!showUnused && nullAnimation.frames.empty()) continue;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
auto item_selection_select_all = [&](anm2::Type type)
|
||||
{
|
||||
if (!animation || (type != anm2::LAYER && type != anm2::NULL_)) return;
|
||||
|
||||
auto& showUnused = settings.timelineIsShowUnused;
|
||||
|
||||
itemSelection.clear();
|
||||
bool hasInserted = false;
|
||||
|
||||
auto try_insert = [&](int id)
|
||||
{
|
||||
itemSelection.insert(item_selection_encode(type, id));
|
||||
hasInserted = true;
|
||||
};
|
||||
|
||||
if (type == anm2::LAYER)
|
||||
{
|
||||
for (auto id : animation->layerOrder)
|
||||
{
|
||||
if (!showUnused && animation->layerAnimations[id].frames.empty()) continue;
|
||||
try_insert(id);
|
||||
}
|
||||
}
|
||||
else if (type == anm2::NULL_)
|
||||
{
|
||||
for (auto& [id, nullAnimation] : animation->nullAnimations)
|
||||
{
|
||||
if (!showUnused && nullAnimation.frames.empty()) continue;
|
||||
try_insert(id);
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasInserted)
|
||||
{
|
||||
item_selection_clear();
|
||||
return;
|
||||
}
|
||||
|
||||
item_selection_sync();
|
||||
};
|
||||
|
||||
auto item_context_menu = [&]()
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.WindowPadding);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing);
|
||||
|
||||
auto selectionType = item_selection_type_get();
|
||||
bool hasSelection = !itemSelection.empty() && (selectionType == anm2::LAYER || selectionType == anm2::NULL_);
|
||||
auto currentItem = document.item_get();
|
||||
auto& type = reference.itemType;
|
||||
auto& id = reference.itemID;
|
||||
auto item = document.item_get();
|
||||
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlappedByWindow) &&
|
||||
ImGui::IsMouseClicked(ImGuiMouseButton_Right))
|
||||
@@ -715,35 +520,17 @@ namespace anm2ed::imgui
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem(localize.get(BASIC_PROPERTIES), nullptr, false,
|
||||
item && (type == anm2::LAYER || type == anm2::NULL_)))
|
||||
item_base_properties_open(type, id);
|
||||
|
||||
if (ImGui::MenuItem(localize.get(BASIC_ADD), settings.shortcutAdd.c_str(), false, animation))
|
||||
{
|
||||
item_properties_reset();
|
||||
propertiesPopup.open();
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem(localize.get(BASIC_REMOVE), settings.shortcutRemove.c_str(), false,
|
||||
hasSelection || currentItem))
|
||||
{
|
||||
auto remove = [&]()
|
||||
{
|
||||
if (hasSelection)
|
||||
{
|
||||
std::vector<int> ids{};
|
||||
ids.reserve(itemSelection.size());
|
||||
for (auto value : itemSelection)
|
||||
ids.push_back(item_selection_decode(value));
|
||||
std::sort(ids.begin(), ids.end());
|
||||
for (auto id : ids)
|
||||
animation->item_remove(selectionType, id);
|
||||
item_selection_clear();
|
||||
}
|
||||
else if (reference.itemType == anm2::LAYER || reference.itemType == anm2::NULL_)
|
||||
animation->item_remove(reference.itemType, reference.itemID);
|
||||
reference_clear();
|
||||
};
|
||||
|
||||
DOCUMENT_EDIT(document, localize.get(EDIT_REMOVE_ITEMS), Document::ITEMS, remove());
|
||||
}
|
||||
if (ImGui::MenuItem(localize.get(BASIC_REMOVE), settings.shortcutRemove.c_str(), false, item)) item_remove();
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
@@ -751,7 +538,7 @@ namespace anm2ed::imgui
|
||||
ImGui::PopStyleVar(2);
|
||||
};
|
||||
|
||||
auto item_child = [&](anm2::Type type, int id, int& index)
|
||||
auto item_child = [&](anm2::Type type, int id, int index)
|
||||
{
|
||||
ImGui::PushID(index);
|
||||
|
||||
@@ -759,7 +546,7 @@ namespace anm2ed::imgui
|
||||
auto isVisible = item ? item->isVisible : false;
|
||||
auto& isOnlyShowLayers = settings.timelineIsOnlyShowLayers;
|
||||
if (isOnlyShowLayers && type != anm2::LAYER) isVisible = false;
|
||||
auto isActive = reference.itemType == type && reference.itemID == id;
|
||||
auto isReferenced = reference.itemType == type && reference.itemID == id;
|
||||
|
||||
auto label = type == anm2::LAYER ? std::vformat(localize.get(FORMAT_LAYER),
|
||||
std::make_format_args(id, anm2.content.layers[id].name,
|
||||
@@ -771,14 +558,8 @@ namespace anm2ed::imgui
|
||||
auto iconTintCurrent = isLightTheme && type == anm2::NONE ? ImVec4(1.0f, 1.0f, 1.0f, 1.0f) : itemIconTint;
|
||||
auto baseColorVec = item_color_vec(type);
|
||||
auto activeColorVec = item_color_active_vec(type);
|
||||
auto selectionType = item_selection_type_get();
|
||||
bool isSelectableItem = type == anm2::LAYER || type == anm2::NULL_;
|
||||
auto selectionIndex = item_selection_index_get(type, id);
|
||||
int selectionValue = item_selection_encode(type, id);
|
||||
bool isMultiSelected = isSelectableItem && selectionType == type && itemSelection.contains(selectionValue);
|
||||
bool isTypeNone = type == anm2::NONE;
|
||||
auto colorVec = baseColorVec;
|
||||
if ((isActive || isMultiSelected) && !isTypeNone)
|
||||
if (isReferenced && type != anm2::NONE)
|
||||
{
|
||||
if (isLightTheme)
|
||||
colorVec = ITEM_COLOR_LIGHT_SELECTED[type_index(type)];
|
||||
@@ -789,12 +570,6 @@ namespace anm2ed::imgui
|
||||
color = !isVisible ? to_imvec4(colorVec * COLOR_HIDDEN_MULTIPLIER) : color;
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, color);
|
||||
|
||||
if (index == 1 && type != anm2::NONE)
|
||||
{
|
||||
auto cursor = ImGui::GetCursorPos();
|
||||
ImGui::SetCursorPos(ImVec2(cursor.x, cursor.y - style.ItemSpacing.y));
|
||||
}
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.WindowPadding);
|
||||
|
||||
@@ -803,63 +578,26 @@ namespace anm2ed::imgui
|
||||
|
||||
if (ImGui::BeginChild(label.c_str(), itemSize, ImGuiChildFlags_Borders, ImGuiWindowFlags_NoScrollWithMouse))
|
||||
{
|
||||
auto isReferenced = reference.itemType == type && reference.itemID == id;
|
||||
|
||||
auto cursorPos = ImGui::GetCursorPos();
|
||||
|
||||
if (!isTypeNone)
|
||||
if (type != anm2::NONE)
|
||||
{
|
||||
ImGui::SetCursorPos(to_imvec2(to_vec2(cursorPos) - to_vec2(style.ItemSpacing)));
|
||||
|
||||
ImGui::SetNextItemAllowOverlap();
|
||||
ImGui::PushStyleColor(ImGuiCol_Header, ImVec4());
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4());
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4());
|
||||
if (isSelectableItem && selectionIndex != -1) ImGui::SetNextItemSelectionUserData(selectionIndex);
|
||||
bool isRootLike = type == anm2::ROOT || type == anm2::TRIGGER;
|
||||
if (ImGui::Selectable("##Item Button", isSelectableItem && isMultiSelected, ImGuiSelectableFlags_SelectOnNav,
|
||||
itemSize))
|
||||
ImGui::SetNextItemStorageID(id);
|
||||
if (ImGui::Selectable("##Item Button", isReferenced, ImGuiSelectableFlags_SelectOnClick, itemSize))
|
||||
{
|
||||
if (isSelectableItem)
|
||||
{
|
||||
auto previousType = item_selection_type_get();
|
||||
bool typeMismatch = !itemSelection.empty() && previousType != anm2::NONE && previousType != type;
|
||||
if (typeMismatch)
|
||||
{
|
||||
itemSelection.clear();
|
||||
itemSelection.insert(selectionValue);
|
||||
}
|
||||
item_selection_sync();
|
||||
}
|
||||
else if (isRootLike)
|
||||
item_selection_clear();
|
||||
|
||||
if (type == anm2::LAYER) document.spritesheet.reference = anm2.content.layers[id].spritesheetID;
|
||||
|
||||
reference_set_item(type, id);
|
||||
}
|
||||
ImGui::PopStyleColor(3);
|
||||
bool isItemHovered = ImGui::IsItemHovered();
|
||||
if (isItemHovered) items.hovered = id;
|
||||
if (isItemHovered)
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case anm2::LAYER:
|
||||
manager.layer_properties_open(id);
|
||||
break;
|
||||
case anm2::NULL_:
|
||||
manager.null_properties_open(id);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) item_base_properties_open(type, id);
|
||||
|
||||
if (isItemHovered)
|
||||
{
|
||||
auto& imguiStyle = ImGui::GetStyle();
|
||||
auto previousTooltipFlags = imguiStyle.HoverFlagsForTooltipMouse;
|
||||
auto previousTooltipDelay = imguiStyle.HoverDelayNormal;
|
||||
@@ -1074,7 +812,6 @@ namespace anm2ed::imgui
|
||||
ImGui::EndChild();
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::PopStyleVar(2);
|
||||
index++;
|
||||
|
||||
ImGui::PopID();
|
||||
};
|
||||
@@ -1099,44 +836,15 @@ namespace anm2ed::imgui
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2());
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ScrollbarSize, 0.0f);
|
||||
if (animation && ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) &&
|
||||
ImGui::Shortcut(ImGuiMod_Ctrl | ImGuiKey_A, ImGuiInputFlags_RouteFocused))
|
||||
{
|
||||
auto preferredType = reference.itemType == anm2::LAYER || reference.itemType == anm2::NULL_
|
||||
? reference.itemType
|
||||
: (items.reference == (int)anm2::LAYER || items.reference == (int)anm2::NULL_
|
||||
? (anm2::Type)items.reference
|
||||
: item_selection_type_get());
|
||||
auto targetType = preferredType;
|
||||
if (targetType == anm2::NONE || !item_type_has_visible(targetType))
|
||||
{
|
||||
if (item_type_has_visible(anm2::LAYER))
|
||||
targetType = anm2::LAYER;
|
||||
else if (item_type_has_visible(anm2::NULL_))
|
||||
targetType = anm2::NULL_;
|
||||
else
|
||||
targetType = anm2::NONE;
|
||||
}
|
||||
|
||||
if (targetType != anm2::NONE) item_selection_select_all(targetType);
|
||||
}
|
||||
if (animation && ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) &&
|
||||
ImGui::Shortcut(ImGuiKey_Escape, ImGuiInputFlags_RouteFocused))
|
||||
{
|
||||
item_selection_clear();
|
||||
reference_clear();
|
||||
}
|
||||
if (ImGui::BeginTable("##Item Table", 1, ImGuiTableFlags_Borders | ImGuiTableFlags_ScrollY))
|
||||
{
|
||||
ImGui::GetCurrentWindow()->Flags |= ImGuiWindowFlags_NoScrollWithMouse;
|
||||
ImGui::SetScrollY(scroll.y);
|
||||
|
||||
int index{};
|
||||
|
||||
ImGui::TableSetupScrollFreeze(0, 1);
|
||||
ImGui::TableSetupColumn("##Items");
|
||||
|
||||
auto item_child_row = [&](anm2::Type type, int id = -1)
|
||||
auto item_child_row = [&](anm2::Type type, int id = -1, int index = 0)
|
||||
{
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
@@ -1145,29 +853,24 @@ namespace anm2ed::imgui
|
||||
|
||||
item_child_row(anm2::NONE);
|
||||
|
||||
int index{};
|
||||
if (animation)
|
||||
{
|
||||
item_selection_prune();
|
||||
itemSelection.start(itemSelectionIndexMap.size());
|
||||
item_child_row(anm2::ROOT, -1, index++);
|
||||
|
||||
item_child_row(anm2::ROOT);
|
||||
|
||||
for (auto& id : animation->layerOrder)
|
||||
for (auto& id : animation->layerOrder | std::views::reverse)
|
||||
{
|
||||
if (!settings.timelineIsShowUnused && animation->layerAnimations[id].frames.empty()) continue;
|
||||
item_child_row(anm2::LAYER, id);
|
||||
item_child_row(anm2::LAYER, id, index++);
|
||||
}
|
||||
|
||||
for (auto& [id, nullAnimation] : animation->nullAnimations)
|
||||
{
|
||||
if (!settings.timelineIsShowUnused && nullAnimation.frames.empty()) continue;
|
||||
item_child_row(anm2::NULL_, id);
|
||||
item_child_row(anm2::NULL_, id, index++);
|
||||
}
|
||||
|
||||
item_child_row(anm2::TRIGGER);
|
||||
|
||||
itemSelection.finish();
|
||||
item_selection_sync();
|
||||
}
|
||||
|
||||
if (isHorizontalScroll && ImGui::GetCurrentWindow()->ScrollbarY)
|
||||
@@ -1202,36 +905,10 @@ namespace anm2ed::imgui
|
||||
set_item_tooltip_shortcut(localize.get(TOOLTIP_ADD_ITEM), settings.shortcutAdd);
|
||||
ImGui::SameLine();
|
||||
|
||||
auto selectionType = item_selection_type_get();
|
||||
bool hasSelection = !itemSelection.empty() && (selectionType == anm2::LAYER || selectionType == anm2::NULL_);
|
||||
bool hasReferenceItem = document.item_get() != nullptr;
|
||||
ImGui::BeginDisabled(!hasSelection && !hasReferenceItem);
|
||||
{
|
||||
shortcut(manager.chords[SHORTCUT_REMOVE]);
|
||||
if (ImGui::Button(localize.get(BASIC_REMOVE), widgetSize))
|
||||
{
|
||||
auto remove = [&]()
|
||||
{
|
||||
if (hasSelection)
|
||||
{
|
||||
std::vector<int> ids{};
|
||||
ids.reserve(itemSelection.size());
|
||||
for (auto value : itemSelection)
|
||||
ids.push_back(item_selection_decode(value));
|
||||
std::sort(ids.begin(), ids.end());
|
||||
for (auto id : ids)
|
||||
animation->item_remove(selectionType, id);
|
||||
item_selection_clear();
|
||||
}
|
||||
else if (reference.itemType == anm2::LAYER || reference.itemType == anm2::NULL_)
|
||||
animation->item_remove(reference.itemType, reference.itemID);
|
||||
reference_clear();
|
||||
};
|
||||
|
||||
DOCUMENT_EDIT(document, localize.get(EDIT_REMOVE_ITEMS), Document::ITEMS, remove());
|
||||
}
|
||||
set_item_tooltip_shortcut(localize.get(TOOLTIP_REMOVE_ITEMS), settings.shortcutRemove);
|
||||
}
|
||||
ImGui::BeginDisabled(!document.item_get());
|
||||
shortcut(manager.chords[SHORTCUT_REMOVE]);
|
||||
if (ImGui::Button(localize.get(BASIC_REMOVE), widgetSize)) item_remove();
|
||||
set_item_tooltip_shortcut(localize.get(TOOLTIP_REMOVE_ITEMS), settings.shortcutRemove);
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
@@ -1443,12 +1120,6 @@ namespace anm2ed::imgui
|
||||
if (ImGui::Selectable("##Frame Button", isSelected, ImGuiSelectableFlags_None, buttonSize))
|
||||
{
|
||||
if (type == anm2::LAYER) document.spritesheet.reference = anm2.content.layers[id].spritesheetID;
|
||||
if (type == anm2::LAYER || type == anm2::NULL_)
|
||||
{
|
||||
itemSelection.clear();
|
||||
itemSelection.insert(item_selection_encode(type, id));
|
||||
item_selection_sync();
|
||||
}
|
||||
|
||||
if (type != anm2::TRIGGER)
|
||||
{
|
||||
@@ -1863,7 +1534,7 @@ namespace anm2ed::imgui
|
||||
|
||||
frames_child_row(anm2::ROOT);
|
||||
|
||||
for (auto& id : animation->layerOrder)
|
||||
for (auto& id : animation->layerOrder | std::views::reverse)
|
||||
{
|
||||
if (auto item = animation->item_get(anm2::LAYER, id); item)
|
||||
if (!settings.timelineIsShowUnused && item->frames.empty()) continue;
|
||||
@@ -2173,13 +1844,7 @@ namespace anm2ed::imgui
|
||||
|
||||
document.change(Document::ITEMS);
|
||||
|
||||
reference = addReference;
|
||||
itemSelection.clear();
|
||||
if (addReference.itemType == anm2::LAYER || addReference.itemType == anm2::NULL_)
|
||||
{
|
||||
itemSelection.insert(item_selection_encode(addReference.itemType, addReference.itemID));
|
||||
item_selection_sync();
|
||||
}
|
||||
reference_set_item(addReference.itemType, addReference.itemID);
|
||||
|
||||
item_properties_close();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user