CHANGES!
This commit is contained in:
+2
-2
@@ -24,7 +24,7 @@ namespace anm2ed::anm2
|
|||||||
XMLDocument document;
|
XMLDocument document;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
auto file = _wfopen(path.string().c_str(), L"rb");
|
auto file = _wfopen(path.wstring().c_str(), L"rb");
|
||||||
#else
|
#else
|
||||||
auto file = fopen(path.c_str(), "rb");
|
auto file = fopen(path.c_str(), "rb");
|
||||||
#endif
|
#endif
|
||||||
@@ -63,7 +63,7 @@ namespace anm2ed::anm2
|
|||||||
document.InsertFirstChild(to_element(document));
|
document.InsertFirstChild(to_element(document));
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
auto file = _wfopen(path.string().c_str(), L"w");
|
auto file = _wfopen(path.wstring().c_str(), L"w");
|
||||||
#else
|
#else
|
||||||
auto file = fopen(path.c_str(), "w");
|
auto file = fopen(path.c_str(), "w");
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -93,6 +93,159 @@ namespace anm2ed::imgui
|
|||||||
return isActivated;
|
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,
|
bool input_int_range(const char* label, int& value, int min, int max, int step, int stepFast,
|
||||||
ImGuiInputTextFlags flags)
|
ImGuiInputTextFlags flags)
|
||||||
{
|
{
|
||||||
|
|||||||
+10
-1
@@ -12,7 +12,8 @@
|
|||||||
|
|
||||||
namespace anm2ed::imgui
|
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 = 1.0f;
|
||||||
constexpr auto STEP_FAST = 5.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_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",
|
bool input_float_range(const char*, float&, float, float, float = STEP, float = STEP_FAST, const char* = "%.3f",
|
||||||
ImGuiInputTextFlags = 0);
|
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*>&);
|
bool combo_negative_one_indexed(const std::string&, int*, std::vector<const char*>&);
|
||||||
std::string& selectable_input_text_id();
|
std::string& selectable_input_text_id();
|
||||||
bool selectable_input_text(const std::string& label, const std::string& id, std::string& text, bool isSelected,
|
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 <cstddef>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <format>
|
#include <format>
|
||||||
|
#include <ranges>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -225,6 +226,7 @@ namespace anm2ed::imgui
|
|||||||
auto document = manager.get();
|
auto document = manager.get();
|
||||||
auto animation = document ? document->animation_get() : nullptr;
|
auto animation = document ? document->animation_get() : nullptr;
|
||||||
auto item = document ? document->item_get() : nullptr;
|
auto item = document ? document->item_get() : nullptr;
|
||||||
|
auto frames = document ? &document->frames : nullptr;
|
||||||
|
|
||||||
if (ImGui::BeginMainMenuBar())
|
if (ImGui::BeginMainMenuBar())
|
||||||
{
|
{
|
||||||
@@ -296,7 +298,12 @@ namespace anm2ed::imgui
|
|||||||
item && document->reference.itemType == anm2::LAYER))
|
item && document->reference.itemType == anm2::LAYER))
|
||||||
generatePopup.open();
|
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();
|
ImGui::Separator();
|
||||||
|
|
||||||
if (ImGui::MenuItem(localize.get(LABEL_TASKBAR_RENDER_ANIMATION), nullptr, false, animation))
|
if (ImGui::MenuItem(localize.get(LABEL_TASKBAR_RENDER_ANIMATION), nullptr, false, animation))
|
||||||
renderPopup.open();
|
renderPopup.open();
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
@@ -337,7 +344,6 @@ namespace anm2ed::imgui
|
|||||||
|
|
||||||
if (ImGui::BeginMenu(localize.get(LABEL_HELP_MENU)))
|
if (ImGui::BeginMenu(localize.get(LABEL_HELP_MENU)))
|
||||||
{
|
{
|
||||||
|
|
||||||
if (ImGui::MenuItem(localize.get(LABEL_TASKBAR_ABOUT))) aboutPopup.open();
|
if (ImGui::MenuItem(localize.get(LABEL_TASKBAR_ABOUT))) aboutPopup.open();
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
@@ -445,6 +451,135 @@ namespace anm2ed::imgui
|
|||||||
ImGui::EndPopup();
|
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();
|
configurePopup.trigger();
|
||||||
|
|
||||||
if (ImGui::BeginPopupModal(configurePopup.label(), &configurePopup.isOpen, ImGuiWindowFlags_NoResize))
|
if (ImGui::BeginPopupModal(configurePopup.label(), &configurePopup.isOpen, ImGuiWindowFlags_NoResize))
|
||||||
@@ -654,6 +789,7 @@ namespace anm2ed::imgui
|
|||||||
auto& columns = settings.renderColumns;
|
auto& columns = settings.renderColumns;
|
||||||
auto& isRange = manager.isRecordingRange;
|
auto& isRange = manager.isRecordingRange;
|
||||||
auto& frames = document->frames.selection;
|
auto& frames = document->frames.selection;
|
||||||
|
auto& reference = document->reference;
|
||||||
int length = std::max(1, end - start + 1);
|
int length = std::max(1, end - start + 1);
|
||||||
|
|
||||||
auto range_to_frames_set = [&]()
|
auto range_to_frames_set = [&]()
|
||||||
@@ -661,17 +797,10 @@ namespace anm2ed::imgui
|
|||||||
if (auto item = document->item_get())
|
if (auto item = document->item_get())
|
||||||
{
|
{
|
||||||
int duration{};
|
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)i == *frames.begin()) start = duration;
|
||||||
|
if ((int)i == *frames.rbegin()) end = duration + frame.duration - 1;
|
||||||
if ((int)index == *frames.begin())
|
|
||||||
start = duration;
|
|
||||||
else if ((int)index == *frames.rbegin())
|
|
||||||
{
|
|
||||||
end = duration;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
duration += frame.duration;
|
duration += frame.duration;
|
||||||
}
|
}
|
||||||
@@ -800,7 +929,7 @@ namespace anm2ed::imgui
|
|||||||
|
|
||||||
ImGui::SameLine();
|
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();
|
if (ImGui::Button(localize.get(LABEL_TO_SELECTED_FRAMES))) range_to_frames_set();
|
||||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_TO_SELECTED_FRAMES));
|
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_TO_SELECTED_FRAMES));
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
|
|||||||
+3
-4
@@ -15,10 +15,9 @@ namespace anm2ed::imgui
|
|||||||
Canvas generate;
|
Canvas generate;
|
||||||
float generateTime{};
|
float generateTime{};
|
||||||
PopupHelper generatePopup{PopupHelper(LABEL_TASKBAR_GENERATE_ANIMATION_FROM_GRID)};
|
PopupHelper generatePopup{PopupHelper(LABEL_TASKBAR_GENERATE_ANIMATION_FROM_GRID)};
|
||||||
PopupHelper overwritePopup{
|
PopupHelper changePopup{PopupHelper(LABEL_CHANGE_ALL_FRAME_PROPERTIES, imgui::POPUP_NORMAL_NO_HEIGHT)};
|
||||||
PopupHelper(LABEL_TASKBAR_OVERWRITE_FILE, imgui::POPUP_SMALL_NO_HEIGHT)};
|
PopupHelper overwritePopup{PopupHelper(LABEL_TASKBAR_OVERWRITE_FILE, imgui::POPUP_SMALL_NO_HEIGHT)};
|
||||||
PopupHelper renderPopup{
|
PopupHelper renderPopup{PopupHelper(LABEL_TASKBAR_RENDER_ANIMATION, imgui::POPUP_SMALL_NO_HEIGHT)};
|
||||||
PopupHelper(LABEL_TASKBAR_RENDER_ANIMATION, imgui::POPUP_SMALL_NO_HEIGHT)};
|
|
||||||
PopupHelper configurePopup{PopupHelper(LABEL_TASKBAR_CONFIGURE)};
|
PopupHelper configurePopup{PopupHelper(LABEL_TASKBAR_CONFIGURE)};
|
||||||
PopupHelper aboutPopup{PopupHelper(LABEL_TASKBAR_ABOUT)};
|
PopupHelper aboutPopup{PopupHelper(LABEL_TASKBAR_ABOUT)};
|
||||||
Settings editSettings{};
|
Settings editSettings{};
|
||||||
|
|||||||
@@ -430,7 +430,7 @@ namespace anm2ed::imgui
|
|||||||
|
|
||||||
bind();
|
bind();
|
||||||
viewport_set();
|
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 (isAxes) axes_render(shaderAxes, zoom, pan, axesColor);
|
||||||
if (isGrid) grid_render(shaderGrid, zoom, pan, gridSize, gridOffset, gridColor);
|
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::MOVE && isMouseRightDown) useTool = tool::SCALE;
|
||||||
if (tool == tool::SCALE && isMouseRightDown) useTool = tool::MOVE;
|
if (tool == tool::SCALE && isMouseRightDown) useTool = tool::MOVE;
|
||||||
|
|
||||||
auto& areaType = tool::INFO[useTool].areaType;
|
auto& toolInfo = tool::INFO[useTool];
|
||||||
auto cursor = areaType == tool::ANIMATION_PREVIEW || areaType == tool::ALL ? tool::INFO[useTool].cursor
|
auto& areaType = toolInfo.areaType;
|
||||||
: ImGuiMouseCursor_NotAllowed;
|
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::SetMouseCursor(cursor);
|
||||||
ImGui::SetKeyboardFocusHere();
|
ImGui::SetKeyboardFocusHere();
|
||||||
if (useTool != tool::MOVE) isMoveDragging = false;
|
if (useTool != tool::MOVE) isMoveDragging = false;
|
||||||
@@ -820,6 +824,26 @@ namespace anm2ed::imgui
|
|||||||
break;
|
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)
|
if (mouseWheel != 0 || isZoomIn || isZoomOut)
|
||||||
{
|
{
|
||||||
auto previousZoom = zoom;
|
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,
|
if (ImGui::MenuItem(localize.get(SHORTCUT_STRING_UNDO), settings.shortcutUndo.c_str(), false,
|
||||||
document.is_able_to_undo()))
|
document.is_able_to_undo()))
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "frame_properties.h"
|
#include "frame_properties.h"
|
||||||
|
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
#include "math_.h"
|
#include "math_.h"
|
||||||
#include "strings.h"
|
#include "strings.h"
|
||||||
@@ -12,6 +13,7 @@ using namespace glm;
|
|||||||
|
|
||||||
namespace anm2ed::imgui
|
namespace anm2ed::imgui
|
||||||
{
|
{
|
||||||
|
|
||||||
void FrameProperties::update(Manager& manager, Settings& settings)
|
void FrameProperties::update(Manager& manager, Settings& settings)
|
||||||
{
|
{
|
||||||
if (ImGui::Begin(localize.get(LABEL_FRAME_PROPERTIES_WINDOW), &settings.windowIsFrameProperties))
|
if (ImGui::Begin(localize.get(LABEL_FRAME_PROPERTIES_WINDOW), &settings.windowIsFrameProperties))
|
||||||
@@ -45,8 +47,9 @@ namespace anm2ed::imgui
|
|||||||
frame->soundID = useFrame.soundID);
|
frame->soundID = useFrame.soundID);
|
||||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_TRIGGER_SOUND));
|
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_TRIGGER_SOUND));
|
||||||
|
|
||||||
if (ImGui::InputInt(localize.get(BASIC_AT_FRAME), frame ? &useFrame.atFrame : &dummy_value<int>(), STEP,
|
if (input_int_range(localize.get(BASIC_AT_FRAME), frame ? useFrame.atFrame : dummy_value<int>(), 0,
|
||||||
STEP_FAST, !frame ? ImGuiInputTextFlags_DisplayEmptyRefVal : 0) &&
|
std::numeric_limits<int>::max(), STEP, STEP_FAST,
|
||||||
|
!frame ? ImGuiInputTextFlags_DisplayEmptyRefVal : 0) &&
|
||||||
frame)
|
frame)
|
||||||
DOCUMENT_EDIT(document, localize.get(EDIT_TRIGGER_AT_FRAME), Document::FRAMES,
|
DOCUMENT_EDIT(document, localize.get(EDIT_TRIGGER_AT_FRAME), Document::FRAMES,
|
||||||
frame->atFrame = useFrame.atFrame);
|
frame->atFrame = useFrame.atFrame);
|
||||||
@@ -62,52 +65,65 @@ namespace anm2ed::imgui
|
|||||||
{
|
{
|
||||||
ImGui::BeginDisabled(type == anm2::ROOT || type == anm2::NULL_);
|
ImGui::BeginDisabled(type == anm2::ROOT || type == anm2::NULL_);
|
||||||
{
|
{
|
||||||
if (ImGui::InputFloat2(localize.get(BASIC_CROP), frame ? value_ptr(useFrame.crop) : &dummy_value<float>(),
|
auto cropEdit =
|
||||||
frame ? vec2_format_get(useFrame.crop) : "") &&
|
drag_float2_persistent(localize.get(BASIC_CROP), frame ? &frame->crop : &dummy_value<vec2>(),
|
||||||
frame)
|
DRAG_SPEED, 0.0f, 0.0f, frame ? vec2_format_get(frame->crop) : "");
|
||||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_CROP), Document::FRAMES, frame->crop = useFrame.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));
|
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_CROP));
|
||||||
|
|
||||||
if (ImGui::InputFloat2(localize.get(BASIC_SIZE), frame ? value_ptr(useFrame.size) : &dummy_value<float>(),
|
auto sizeEdit =
|
||||||
frame ? vec2_format_get(useFrame.size) : "") &&
|
drag_float2_persistent(localize.get(BASIC_SIZE), frame ? &frame->size : &dummy_value<vec2>(),
|
||||||
frame)
|
DRAG_SPEED, 0.0f, 0.0f, frame ? vec2_format_get(frame->size) : "");
|
||||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_SIZE), Document::FRAMES, frame->size = useFrame.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::SetItemTooltip("%s", localize.get(TOOLTIP_SIZE));
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
|
|
||||||
if (ImGui::InputFloat2(localize.get(BASIC_POSITION),
|
auto positionEdit =
|
||||||
frame ? value_ptr(useFrame.position) : &dummy_value<float>(),
|
drag_float2_persistent(localize.get(BASIC_POSITION), frame ? &frame->position : &dummy_value<vec2>(),
|
||||||
frame ? vec2_format_get(useFrame.position) : "") &&
|
DRAG_SPEED, 0.0f, 0.0f, frame ? vec2_format_get(frame->position) : "");
|
||||||
frame)
|
if (positionEdit == edit::START)
|
||||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_POSITION), Document::FRAMES,
|
document.snapshot(localize.get(EDIT_FRAME_POSITION));
|
||||||
frame->position = useFrame.position);
|
else if (positionEdit == edit::END)
|
||||||
|
document.change(Document::FRAMES);
|
||||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_POSITION));
|
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_POSITION));
|
||||||
|
|
||||||
ImGui::BeginDisabled(type == anm2::ROOT || type == anm2::NULL_);
|
ImGui::BeginDisabled(type == anm2::ROOT || type == anm2::NULL_);
|
||||||
{
|
{
|
||||||
if (ImGui::InputFloat2(localize.get(BASIC_PIVOT),
|
auto pivotEdit =
|
||||||
frame ? value_ptr(useFrame.pivot) : &dummy_value<float>(),
|
drag_float2_persistent(localize.get(BASIC_PIVOT), frame ? &frame->pivot : &dummy_value<vec2>(),
|
||||||
frame ? vec2_format_get(useFrame.pivot) : "") &&
|
DRAG_SPEED, 0.0f, 0.0f, frame ? vec2_format_get(frame->pivot) : "");
|
||||||
frame)
|
if (pivotEdit == edit::START)
|
||||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_PIVOT), Document::FRAMES,
|
document.snapshot(localize.get(EDIT_FRAME_PIVOT));
|
||||||
frame->pivot = useFrame.pivot);
|
else if (pivotEdit == edit::END)
|
||||||
|
document.change(Document::FRAMES);
|
||||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_PIVOT));
|
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_PIVOT));
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
|
|
||||||
if (ImGui::InputFloat2(localize.get(BASIC_SCALE), frame ? value_ptr(useFrame.scale) : &dummy_value<float>(),
|
auto scaleEdit =
|
||||||
frame ? vec2_format_get(useFrame.scale) : "") &&
|
drag_float2_persistent(localize.get(BASIC_SCALE), frame ? &frame->scale : &dummy_value<vec2>(),
|
||||||
frame)
|
DRAG_SPEED, 0.0f, 0.0f, frame ? vec2_format_get(frame->scale) : "");
|
||||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_SCALE), Document::FRAMES, frame->scale = useFrame.scale);
|
|
||||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_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>(),
|
auto rotationEdit =
|
||||||
STEP, STEP_FAST, frame ? float_format_get(useFrame.rotation) : "") &&
|
drag_float_persistent(localize.get(BASIC_ROTATION), frame ? &frame->rotation : &dummy_value<float>(),
|
||||||
frame)
|
DRAG_SPEED, 0.0f, 0.0f, frame ? float_format_get(frame->rotation) : "");
|
||||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_ROTATION), Document::FRAMES,
|
|
||||||
frame->rotation = useFrame.rotation);
|
|
||||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_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>(),
|
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,
|
frame ? anm2::FRAME_DURATION_MIN : 0, anm2::FRAME_DURATION_MAX, STEP, STEP_FAST,
|
||||||
@@ -117,17 +133,21 @@ namespace anm2ed::imgui
|
|||||||
frame->duration = useFrame.duration);
|
frame->duration = useFrame.duration);
|
||||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_DURATION));
|
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_DURATION));
|
||||||
|
|
||||||
if (ImGui::ColorEdit4(localize.get(BASIC_TINT), frame ? value_ptr(useFrame.tint) : &dummy_value<float>()) &&
|
auto tintEdit =
|
||||||
frame)
|
color_edit4_persistent(localize.get(BASIC_TINT), frame ? &frame->tint : &dummy_value<vec4>());
|
||||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_TINT), Document::FRAMES, frame->tint = useFrame.tint);
|
|
||||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_TINT));
|
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),
|
auto colorOffsetEdit = color_edit3_persistent(localize.get(BASIC_COLOR_OFFSET),
|
||||||
frame ? value_ptr(useFrame.colorOffset) : &dummy_value<float>()) &&
|
frame ? &frame->colorOffset : &dummy_value<vec3>());
|
||||||
frame)
|
|
||||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_COLOR_OFFSET), Document::FRAMES,
|
|
||||||
frame->colorOffset = useFrame.colorOffset);
|
|
||||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_COLOR_OFFSET));
|
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>()) &&
|
if (ImGui::Checkbox(localize.get(BASIC_VISIBLE), frame ? &useFrame.isVisible : &dummy_value<bool>()) &&
|
||||||
frame)
|
frame)
|
||||||
@@ -246,24 +266,39 @@ namespace anm2ed::imgui
|
|||||||
document.item_get()->frames_change(frameChange, type, *frames.begin(), (int)frames.size()));
|
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));
|
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::SetItemTooltip("%s", localize.get(TOOLTIP_ADD_VALUES));
|
||||||
|
|
||||||
ImGui::SameLine();
|
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::SetItemTooltip("%s", localize.get(TOOLTIP_SUBTRACT_VALUES));
|
||||||
|
|
||||||
ImGui::SameLine();
|
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::SetItemTooltip("%s", localize.get(TOOLTIP_MULTIPLY_VALUES));
|
||||||
|
|
||||||
ImGui::SameLine();
|
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::SetItemTooltip("%s", localize.get(TOOLTIP_DIVIDE_VALUES));
|
||||||
|
|
||||||
|
ImGui::EndDisabled();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|||||||
@@ -1,13 +1,25 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <glm/vec2.hpp>
|
||||||
|
|
||||||
#include "manager.h"
|
#include "manager.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
|
namespace anm2
|
||||||
|
{
|
||||||
|
struct Frame;
|
||||||
|
}
|
||||||
|
|
||||||
namespace anm2ed::imgui
|
namespace anm2ed::imgui
|
||||||
{
|
{
|
||||||
class FrameProperties
|
class FrameProperties
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void update(Manager&, Settings&);
|
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();
|
bool isValid = sound.is_valid();
|
||||||
auto& soundIcon = isValid ? resources.icons[icon::SOUND] : resources.icons[icon::NONE];
|
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 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::SetNextItemSelectionUserData(id);
|
||||||
ImGui::SetNextItemStorageID(id);
|
ImGui::SetNextItemStorageID(id);
|
||||||
@@ -226,7 +226,7 @@ namespace anm2ed::imgui
|
|||||||
newSoundId = -1;
|
newSoundId = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto textWidth = ImGui::CalcTextSize(pathCStr).x;
|
auto textWidth = ImGui::CalcTextSize(pathString.c_str()).x;
|
||||||
auto tooltipPadding = style.WindowPadding.x * 4.0f;
|
auto tooltipPadding = style.WindowPadding.x * 4.0f;
|
||||||
auto minWidth = textWidth + style.ItemSpacing.x + tooltipPadding;
|
auto minWidth = textWidth + style.ItemSpacing.x + tooltipPadding;
|
||||||
|
|
||||||
@@ -236,7 +236,7 @@ namespace anm2ed::imgui
|
|||||||
if (ImGui::BeginItemTooltip())
|
if (ImGui::BeginItemTooltip())
|
||||||
{
|
{
|
||||||
ImGui::PushFont(resources.fonts[font::BOLD].get(), font::SIZE);
|
ImGui::PushFont(resources.fonts[font::BOLD].get(), font::SIZE);
|
||||||
ImGui::TextUnformatted(pathCStr);
|
ImGui::TextUnformatted(pathString.c_str());
|
||||||
ImGui::PopFont();
|
ImGui::PopFont();
|
||||||
ImGui::Text("%s: %d", localize.get(BASIC_ID), id);
|
ImGui::Text("%s: %d", localize.get(BASIC_ID), id);
|
||||||
if (!isValid)
|
if (!isValid)
|
||||||
@@ -261,7 +261,7 @@ namespace anm2ed::imgui
|
|||||||
soundChildSize.y - soundChildSize.y / 2 - ImGui::GetTextLineHeight() / 2));
|
soundChildSize.y - soundChildSize.y / 2 - ImGui::GetTextLineHeight() / 2));
|
||||||
|
|
||||||
ImGui::TextUnformatted(
|
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();
|
ImGui::EndChild();
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ namespace anm2ed::imgui
|
|||||||
|
|
||||||
bind();
|
bind();
|
||||||
viewport_set();
|
viewport_set();
|
||||||
clear(isTransparent ? vec4() : vec4(backgroundColor, 1.0f));
|
clear(isTransparent ? vec4(0) : vec4(backgroundColor, 1.0f));
|
||||||
|
|
||||||
auto frame = document.frame_get();
|
auto frame = document.frame_get();
|
||||||
|
|
||||||
@@ -312,8 +312,15 @@ namespace anm2ed::imgui
|
|||||||
if (tool == tool::DRAW && isMouseRightDown) useTool = tool::ERASE;
|
if (tool == tool::DRAW && isMouseRightDown) useTool = tool::ERASE;
|
||||||
if (tool == tool::ERASE && isMouseRightDown) useTool = tool::DRAW;
|
if (tool == tool::ERASE && isMouseRightDown) useTool = tool::DRAW;
|
||||||
|
|
||||||
auto& areaType = tool::INFO[useTool].areaType;
|
auto& toolInfo = tool::INFO[useTool];
|
||||||
auto cursor = areaType == tool::SPRITESHEET_EDITOR || areaType == tool::ALL ? tool::INFO[useTool].cursor
|
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;
|
: ImGuiMouseCursor_NotAllowed;
|
||||||
ImGui::SetMouseCursor(cursor);
|
ImGui::SetMouseCursor(cursor);
|
||||||
ImGui::SetKeyboardFocusHere();
|
ImGui::SetKeyboardFocusHere();
|
||||||
@@ -429,6 +436,34 @@ namespace anm2ed::imgui
|
|||||||
break;
|
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)
|
if (mouseWheel != 0 || isZoomIn || isZoomOut)
|
||||||
{
|
{
|
||||||
auto focus = mouseWheel != 0 ? vec2(mousePos) : vec2();
|
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,
|
if (ImGui::MenuItem(localize.get(SHORTCUT_STRING_UNDO), settings.shortcutUndo.c_str(), false,
|
||||||
document.is_able_to_undo()))
|
document.is_able_to_undo()))
|
||||||
|
|||||||
+53
-388
@@ -3,7 +3,6 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
#include <imgui_internal.h>
|
#include <imgui_internal.h>
|
||||||
|
|
||||||
@@ -81,7 +80,6 @@ namespace anm2ed::imgui
|
|||||||
constexpr auto FRAME_MULTIPLE = 5;
|
constexpr auto FRAME_MULTIPLE = 5;
|
||||||
constexpr auto FRAME_DRAG_PAYLOAD_ID = "Frame Drag Drop";
|
constexpr auto FRAME_DRAG_PAYLOAD_ID = "Frame Drag Drop";
|
||||||
constexpr auto FRAME_TOOLTIP_HOVER_DELAY = 0.75f; // Extra delay for frame info tooltip.
|
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)
|
void Timeline::update(Manager& manager, Settings& settings, Resources& resources, Clipboard& clipboard)
|
||||||
{
|
{
|
||||||
@@ -90,38 +88,7 @@ namespace anm2ed::imgui
|
|||||||
auto& playback = document.playback;
|
auto& playback = document.playback;
|
||||||
auto& reference = document.reference;
|
auto& reference = document.reference;
|
||||||
auto& frames = document.frames;
|
auto& frames = document.frames;
|
||||||
auto& items = document.items;
|
|
||||||
auto& itemSelection = items.selection;
|
|
||||||
auto animation = document.animation_get();
|
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();
|
style = ImGui::GetStyle();
|
||||||
auto isLightTheme = settings.theme == theme::LIGHT;
|
auto isLightTheme = settings.theme == theme::LIGHT;
|
||||||
@@ -161,113 +128,6 @@ namespace anm2ed::imgui
|
|||||||
return ITEM_COLOR_LIGHT_ACTIVE[type_index(type)];
|
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 iconTintDefault = isLightTheme ? ICON_TINT_DEFAULT_LIGHT : ICON_TINT_DEFAULT_DARK;
|
||||||
auto itemIconTint = isLightTheme ? ICON_TINT_DEFAULT_LIGHT : iconTintDefault;
|
auto itemIconTint = isLightTheme ? ICON_TINT_DEFAULT_LIGHT : iconTintDefault;
|
||||||
auto frameBorderColor = isLightTheme ? FRAME_BORDER_COLOR_LIGHT : FRAME_BORDER_COLOR_DARK;
|
auto frameBorderColor = isLightTheme ? FRAME_BORDER_COLOR_LIGHT : FRAME_BORDER_COLOR_DARK;
|
||||||
@@ -456,8 +316,19 @@ namespace anm2ed::imgui
|
|||||||
{
|
{
|
||||||
reference = {reference.animationIndex, type, id};
|
reference = {reference.animationIndex, type, id};
|
||||||
frames_selection_reset();
|
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 = [&]()
|
auto fit_animation_length = [&]()
|
||||||
@@ -595,6 +466,20 @@ namespace anm2ed::imgui
|
|||||||
ImGui::PopStyleVar(2);
|
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 = [&]()
|
auto item_properties_reset = [&]()
|
||||||
{
|
{
|
||||||
addItemName.clear();
|
addItemName.clear();
|
||||||
@@ -610,94 +495,14 @@ namespace anm2ed::imgui
|
|||||||
return std::set<int>{};
|
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 = [&]()
|
auto item_context_menu = [&]()
|
||||||
{
|
{
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.WindowPadding);
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.WindowPadding);
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing);
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing);
|
||||||
|
|
||||||
auto selectionType = item_selection_type_get();
|
auto& type = reference.itemType;
|
||||||
bool hasSelection = !itemSelection.empty() && (selectionType == anm2::LAYER || selectionType == anm2::NULL_);
|
auto& id = reference.itemID;
|
||||||
auto currentItem = document.item_get();
|
auto item = document.item_get();
|
||||||
|
|
||||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlappedByWindow) &&
|
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlappedByWindow) &&
|
||||||
ImGui::IsMouseClicked(ImGuiMouseButton_Right))
|
ImGui::IsMouseClicked(ImGuiMouseButton_Right))
|
||||||
@@ -715,35 +520,17 @@ namespace anm2ed::imgui
|
|||||||
|
|
||||||
ImGui::Separator();
|
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))
|
if (ImGui::MenuItem(localize.get(BASIC_ADD), settings.shortcutAdd.c_str(), false, animation))
|
||||||
{
|
{
|
||||||
item_properties_reset();
|
item_properties_reset();
|
||||||
propertiesPopup.open();
|
propertiesPopup.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::MenuItem(localize.get(BASIC_REMOVE), settings.shortcutRemove.c_str(), false,
|
if (ImGui::MenuItem(localize.get(BASIC_REMOVE), settings.shortcutRemove.c_str(), false, item)) item_remove();
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
@@ -751,7 +538,7 @@ namespace anm2ed::imgui
|
|||||||
ImGui::PopStyleVar(2);
|
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);
|
ImGui::PushID(index);
|
||||||
|
|
||||||
@@ -759,7 +546,7 @@ namespace anm2ed::imgui
|
|||||||
auto isVisible = item ? item->isVisible : false;
|
auto isVisible = item ? item->isVisible : false;
|
||||||
auto& isOnlyShowLayers = settings.timelineIsOnlyShowLayers;
|
auto& isOnlyShowLayers = settings.timelineIsOnlyShowLayers;
|
||||||
if (isOnlyShowLayers && type != anm2::LAYER) isVisible = false;
|
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),
|
auto label = type == anm2::LAYER ? std::vformat(localize.get(FORMAT_LAYER),
|
||||||
std::make_format_args(id, anm2.content.layers[id].name,
|
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 iconTintCurrent = isLightTheme && type == anm2::NONE ? ImVec4(1.0f, 1.0f, 1.0f, 1.0f) : itemIconTint;
|
||||||
auto baseColorVec = item_color_vec(type);
|
auto baseColorVec = item_color_vec(type);
|
||||||
auto activeColorVec = item_color_active_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;
|
auto colorVec = baseColorVec;
|
||||||
if ((isActive || isMultiSelected) && !isTypeNone)
|
if (isReferenced && type != anm2::NONE)
|
||||||
{
|
{
|
||||||
if (isLightTheme)
|
if (isLightTheme)
|
||||||
colorVec = ITEM_COLOR_LIGHT_SELECTED[type_index(type)];
|
colorVec = ITEM_COLOR_LIGHT_SELECTED[type_index(type)];
|
||||||
@@ -789,12 +570,6 @@ namespace anm2ed::imgui
|
|||||||
color = !isVisible ? to_imvec4(colorVec * COLOR_HIDDEN_MULTIPLIER) : color;
|
color = !isVisible ? to_imvec4(colorVec * COLOR_HIDDEN_MULTIPLIER) : color;
|
||||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, 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_ItemSpacing, style.ItemSpacing);
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.WindowPadding);
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.WindowPadding);
|
||||||
|
|
||||||
@@ -803,63 +578,26 @@ namespace anm2ed::imgui
|
|||||||
|
|
||||||
if (ImGui::BeginChild(label.c_str(), itemSize, ImGuiChildFlags_Borders, ImGuiWindowFlags_NoScrollWithMouse))
|
if (ImGui::BeginChild(label.c_str(), itemSize, ImGuiChildFlags_Borders, ImGuiWindowFlags_NoScrollWithMouse))
|
||||||
{
|
{
|
||||||
auto isReferenced = reference.itemType == type && reference.itemID == id;
|
|
||||||
|
|
||||||
auto cursorPos = ImGui::GetCursorPos();
|
auto cursorPos = ImGui::GetCursorPos();
|
||||||
|
|
||||||
if (!isTypeNone)
|
if (type != anm2::NONE)
|
||||||
{
|
{
|
||||||
ImGui::SetCursorPos(to_imvec2(to_vec2(cursorPos) - to_vec2(style.ItemSpacing)));
|
ImGui::SetCursorPos(to_imvec2(to_vec2(cursorPos) - to_vec2(style.ItemSpacing)));
|
||||||
|
|
||||||
ImGui::SetNextItemAllowOverlap();
|
ImGui::SetNextItemAllowOverlap();
|
||||||
ImGui::PushStyleColor(ImGuiCol_Header, ImVec4());
|
ImGui::PushStyleColor(ImGuiCol_Header, ImVec4());
|
||||||
ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4());
|
ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4());
|
||||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4());
|
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4());
|
||||||
if (isSelectableItem && selectionIndex != -1) ImGui::SetNextItemSelectionUserData(selectionIndex);
|
ImGui::SetNextItemStorageID(id);
|
||||||
bool isRootLike = type == anm2::ROOT || type == anm2::TRIGGER;
|
if (ImGui::Selectable("##Item Button", isReferenced, ImGuiSelectableFlags_SelectOnClick, itemSize))
|
||||||
if (ImGui::Selectable("##Item Button", isSelectableItem && isMultiSelected, ImGuiSelectableFlags_SelectOnNav,
|
|
||||||
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;
|
if (type == anm2::LAYER) document.spritesheet.reference = anm2.content.layers[id].spritesheetID;
|
||||||
|
|
||||||
reference_set_item(type, id);
|
reference_set_item(type, id);
|
||||||
}
|
}
|
||||||
ImGui::PopStyleColor(3);
|
ImGui::PopStyleColor(3);
|
||||||
bool isItemHovered = ImGui::IsItemHovered();
|
if (ImGui::IsItemHovered())
|
||||||
if (isItemHovered) items.hovered = id;
|
|
||||||
if (isItemHovered)
|
|
||||||
{
|
{
|
||||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
|
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) item_base_properties_open(type, id);
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case anm2::LAYER:
|
|
||||||
manager.layer_properties_open(id);
|
|
||||||
break;
|
|
||||||
case anm2::NULL_:
|
|
||||||
manager.null_properties_open(id);
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isItemHovered)
|
|
||||||
{
|
|
||||||
auto& imguiStyle = ImGui::GetStyle();
|
auto& imguiStyle = ImGui::GetStyle();
|
||||||
auto previousTooltipFlags = imguiStyle.HoverFlagsForTooltipMouse;
|
auto previousTooltipFlags = imguiStyle.HoverFlagsForTooltipMouse;
|
||||||
auto previousTooltipDelay = imguiStyle.HoverDelayNormal;
|
auto previousTooltipDelay = imguiStyle.HoverDelayNormal;
|
||||||
@@ -1074,7 +812,6 @@ namespace anm2ed::imgui
|
|||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
ImGui::PopStyleVar(2);
|
ImGui::PopStyleVar(2);
|
||||||
index++;
|
|
||||||
|
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
};
|
};
|
||||||
@@ -1099,44 +836,15 @@ namespace anm2ed::imgui
|
|||||||
{
|
{
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2());
|
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2());
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_ScrollbarSize, 0.0f);
|
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))
|
if (ImGui::BeginTable("##Item Table", 1, ImGuiTableFlags_Borders | ImGuiTableFlags_ScrollY))
|
||||||
{
|
{
|
||||||
ImGui::GetCurrentWindow()->Flags |= ImGuiWindowFlags_NoScrollWithMouse;
|
ImGui::GetCurrentWindow()->Flags |= ImGuiWindowFlags_NoScrollWithMouse;
|
||||||
ImGui::SetScrollY(scroll.y);
|
ImGui::SetScrollY(scroll.y);
|
||||||
|
|
||||||
int index{};
|
|
||||||
|
|
||||||
ImGui::TableSetupScrollFreeze(0, 1);
|
ImGui::TableSetupScrollFreeze(0, 1);
|
||||||
ImGui::TableSetupColumn("##Items");
|
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::TableNextRow();
|
||||||
ImGui::TableSetColumnIndex(0);
|
ImGui::TableSetColumnIndex(0);
|
||||||
@@ -1145,29 +853,24 @@ namespace anm2ed::imgui
|
|||||||
|
|
||||||
item_child_row(anm2::NONE);
|
item_child_row(anm2::NONE);
|
||||||
|
|
||||||
|
int index{};
|
||||||
if (animation)
|
if (animation)
|
||||||
{
|
{
|
||||||
item_selection_prune();
|
item_child_row(anm2::ROOT, -1, index++);
|
||||||
itemSelection.start(itemSelectionIndexMap.size());
|
|
||||||
|
|
||||||
item_child_row(anm2::ROOT);
|
for (auto& id : animation->layerOrder | std::views::reverse)
|
||||||
|
|
||||||
for (auto& id : animation->layerOrder)
|
|
||||||
{
|
{
|
||||||
if (!settings.timelineIsShowUnused && animation->layerAnimations[id].frames.empty()) continue;
|
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)
|
for (auto& [id, nullAnimation] : animation->nullAnimations)
|
||||||
{
|
{
|
||||||
if (!settings.timelineIsShowUnused && nullAnimation.frames.empty()) continue;
|
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);
|
item_child_row(anm2::TRIGGER);
|
||||||
|
|
||||||
itemSelection.finish();
|
|
||||||
item_selection_sync();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isHorizontalScroll && ImGui::GetCurrentWindow()->ScrollbarY)
|
if (isHorizontalScroll && ImGui::GetCurrentWindow()->ScrollbarY)
|
||||||
@@ -1202,36 +905,10 @@ namespace anm2ed::imgui
|
|||||||
set_item_tooltip_shortcut(localize.get(TOOLTIP_ADD_ITEM), settings.shortcutAdd);
|
set_item_tooltip_shortcut(localize.get(TOOLTIP_ADD_ITEM), settings.shortcutAdd);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
auto selectionType = item_selection_type_get();
|
ImGui::BeginDisabled(!document.item_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]);
|
shortcut(manager.chords[SHORTCUT_REMOVE]);
|
||||||
if (ImGui::Button(localize.get(BASIC_REMOVE), widgetSize))
|
if (ImGui::Button(localize.get(BASIC_REMOVE), widgetSize)) item_remove();
|
||||||
{
|
|
||||||
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);
|
set_item_tooltip_shortcut(localize.get(TOOLTIP_REMOVE_ITEMS), settings.shortcutRemove);
|
||||||
}
|
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
@@ -1443,12 +1120,6 @@ namespace anm2ed::imgui
|
|||||||
if (ImGui::Selectable("##Frame Button", isSelected, ImGuiSelectableFlags_None, buttonSize))
|
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) 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)
|
if (type != anm2::TRIGGER)
|
||||||
{
|
{
|
||||||
@@ -1863,7 +1534,7 @@ namespace anm2ed::imgui
|
|||||||
|
|
||||||
frames_child_row(anm2::ROOT);
|
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 (auto item = animation->item_get(anm2::LAYER, id); item)
|
||||||
if (!settings.timelineIsShowUnused && item->frames.empty()) continue;
|
if (!settings.timelineIsShowUnused && item->frames.empty()) continue;
|
||||||
@@ -2173,13 +1844,7 @@ namespace anm2ed::imgui
|
|||||||
|
|
||||||
document.change(Document::ITEMS);
|
document.change(Document::ITEMS);
|
||||||
|
|
||||||
reference = addReference;
|
reference_set_item(addReference.itemType, addReference.itemID);
|
||||||
itemSelection.clear();
|
|
||||||
if (addReference.itemType == anm2::LAYER || addReference.itemType == anm2::NULL_)
|
|
||||||
{
|
|
||||||
itemSelection.insert(item_selection_encode(addReference.itemType, addReference.itemID));
|
|
||||||
item_selection_sync();
|
|
||||||
}
|
|
||||||
|
|
||||||
item_properties_close();
|
item_properties_close();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ namespace anm2ed
|
|||||||
X(LABEL_ANIMATION_PREVIEW_WINDOW, "Animation Preview###Animation Preview", "Vista Previa de Animacion###Animation Preview", "Предпросмотр анимации###Animation Preview", "动画预放###Animation Preview", "애니메이션 프리뷰###Animation Preview") \
|
X(LABEL_ANIMATION_PREVIEW_WINDOW, "Animation Preview###Animation Preview", "Vista Previa de Animacion###Animation Preview", "Предпросмотр анимации###Animation Preview", "动画预放###Animation Preview", "애니메이션 프리뷰###Animation Preview") \
|
||||||
X(LABEL_APPEND_FRAMES, "Append Frames", "Anteponer Frames", "Добавить кадры к концу", "在后面添加帧", "뒷프레임에 추가") \
|
X(LABEL_APPEND_FRAMES, "Append Frames", "Anteponer Frames", "Добавить кадры к концу", "在后面添加帧", "뒷프레임에 추가") \
|
||||||
X(LABEL_APPLICATION_NAME, "Anm2Ed", "Anm2Ed", "Anm2Ed", "Anm2Ed", "Anm2Ed") \
|
X(LABEL_APPLICATION_NAME, "Anm2Ed", "Anm2Ed", "Anm2Ed", "Anm2Ed", "Anm2Ed") \
|
||||||
X(LABEL_APPLICATION_VERSION, "Version 2.1", "Version 2.1", "Версия 2.1", "2.1版本", "버전 2.1") \
|
X(LABEL_APPLICATION_VERSION, "Version 2.2", "Version 2.2", "Версия 2.2", "2.2版本", "버전 2.2") \
|
||||||
X(LABEL_AUTHOR, "Author", "Autor", "Автор", "制作者", "작성자") \
|
X(LABEL_AUTHOR, "Author", "Autor", "Автор", "制作者", "작성자") \
|
||||||
X(LABEL_AUTOSAVE, "Autosave", "Autoguardado", "Автосохранение", "自动保存", "자동저장") \
|
X(LABEL_AUTOSAVE, "Autosave", "Autoguardado", "Автосохранение", "自动保存", "자동저장") \
|
||||||
X(LABEL_AXES, "Axes", "Ejes", "Оси", "坐标轴", "가로/세로 축") \
|
X(LABEL_AXES, "Axes", "Ejes", "Оси", "坐标轴", "가로/세로 축") \
|
||||||
@@ -207,6 +207,7 @@ namespace anm2ed
|
|||||||
X(LABEL_BAKE, "Bake", "Bake", "Запечь", "提前渲染", "베이크") \
|
X(LABEL_BAKE, "Bake", "Bake", "Запечь", "提前渲染", "베이크") \
|
||||||
X(LABEL_SPLIT, "Split", "Dividir", "Разделить", "拆分", "분할") \
|
X(LABEL_SPLIT, "Split", "Dividir", "Разделить", "拆分", "분할") \
|
||||||
X(LABEL_BORDER, "Border", "Borde", "Границы", "边框", "경계선") \
|
X(LABEL_BORDER, "Border", "Borde", "Границы", "边框", "경계선") \
|
||||||
|
X(LABEL_CHANGE_ALL_FRAME_PROPERTIES, "Change All Frame Properties", "Cambiar todas las propiedades de frame", "Изменить все свойства кадра", "更改所有帧属性", "모든 프레임 속성 변경") \
|
||||||
X(LABEL_CENTER_VIEW, "Center View", "Vista de Centro", "Центрировать вид", "视角中心", "가운데서 보기") \
|
X(LABEL_CENTER_VIEW, "Center View", "Vista de Centro", "Центрировать вид", "视角中心", "가운데서 보기") \
|
||||||
X(LABEL_CLAMP, "Clamp", "Clamp", "Ограничить", "限制数值范围", "작업 영역 제한") \
|
X(LABEL_CLAMP, "Clamp", "Clamp", "Ограничить", "限制数值范围", "작업 영역 제한") \
|
||||||
X(LABEL_CLEAR_LIST, "Clear List", "Limpiar Lista", "Стереть список", "清除列表", "기록 삭제") \
|
X(LABEL_CLEAR_LIST, "Clear List", "Limpiar Lista", "Стереть список", "清除列表", "기록 삭제") \
|
||||||
@@ -380,6 +381,10 @@ namespace anm2ed
|
|||||||
X(SHORTCUT_STRING_ZOOM_IN, "Zoom In", "Zoom In", "Увеличить", "视图放大", "확대") \
|
X(SHORTCUT_STRING_ZOOM_IN, "Zoom In", "Zoom In", "Увеличить", "视图放大", "확대") \
|
||||||
X(SHORTCUT_STRING_ZOOM_OUT, "Zoom Out", "Zoom Out", "Уменьшить", "视图缩小", "축소") \
|
X(SHORTCUT_STRING_ZOOM_OUT, "Zoom Out", "Zoom Out", "Уменьшить", "视图缩小", "축소") \
|
||||||
X(SNAPSHOT_RENAME_ANIMATION, "Rename Animation", "Renombrar Animacion", "Переименовать анимацию", "重命名动画", "애니메이션 이름 바꾸기") \
|
X(SNAPSHOT_RENAME_ANIMATION, "Rename Animation", "Renombrar Animacion", "Переименовать анимацию", "重命名动画", "애니메이션 이름 바꾸기") \
|
||||||
|
X(TEXT_SELECT_FRAME, "Select a frame first!", "¡Selecciona primero un frame!", "Сначала выберите кадр!", "请先选择帧!", "먼저 프레임을 선택하세요!") \
|
||||||
|
X(TEXT_SELECT_SPRITESHEET, "Select a spritesheet first!", "¡Selecciona primero un spritesheet!", "Сначала выберите спрайт-лист!", "请先选择图集!", "먼저 스프라이트 시트를 선택하세요!") \
|
||||||
|
X(TEXT_TOOL_ANIMATION_PREVIEW, "This tool can only be used in Animation Preview!", "¡Esta herramienta solo se puede usar en Vista previa de animación!", "Этот инструмент можно использовать только в \"Предпросмотре анимации\"!", "该工具只能在“动画预放”中使用!", "이 도구는 애니메이션 프리뷰에서만 사용할 수 있습니다!") \
|
||||||
|
X(TEXT_TOOL_SPRITESHEET_EDITOR, "This tool can only be used in Spritesheet Editor!", "¡Esta herramienta solo se puede usar en el Editor de spritesheets!", "Этот инструмент можно использовать только в \"Редакторе спрайт-листов\"!", "该工具只能在“图集编辑器”中使用!", "이 도구는 스프라이트 시트 편집기에서만 사용할 수 있습니다!") \
|
||||||
X(TEXT_NEW_ANIMATION, "New Animation", "Nueva Animacion", "Новая анимация", "新动画", "새 애니메이션") \
|
X(TEXT_NEW_ANIMATION, "New Animation", "Nueva Animacion", "Новая анимация", "新动画", "새 애니메이션") \
|
||||||
X(TEXT_NEW_EVENT, "New Event", "Nuevo Evento", "Новое событие", "新事件", "새 이벤트") \
|
X(TEXT_NEW_EVENT, "New Event", "Nuevo Evento", "Новое событие", "新事件", "새 이벤트") \
|
||||||
X(TEXT_RECORDING_PROGRESS, "Once recording is complete, rendering may take some time.\nPlease be patient...", "Una vez que el grabado este completo, renderizar puede tomar algo de tiempo. \nPor favor se paciente...", "Когда запись завершена, рендеринг может занять некоторое время.\nПожалуйста потерпите...", "录制完成时,渲染可能会花一些时间.\n请耐心等待...", "녹화가 완료되면 렌더링에 시간이 걸릴 수 있습니다.\n잠시만 기다려 주세요...") \
|
X(TEXT_RECORDING_PROGRESS, "Once recording is complete, rendering may take some time.\nPlease be patient...", "Una vez que el grabado este completo, renderizar puede tomar algo de tiempo. \nPor favor se paciente...", "Когда запись завершена, рендеринг может занять некоторое время.\nПожалуйста потерпите...", "录制完成时,渲染可能会花一些时间.\n请耐心等待...", "녹화가 완료되면 렌더링에 시간이 걸릴 수 있습니다.\n잠시만 기다려 주세요...") \
|
||||||
|
|||||||
@@ -138,8 +138,11 @@ namespace anm2ed::resource
|
|||||||
auto index = ((size_t)(y) * (size_t)(size.x) + (size_t)(x)) * CHANNELS;
|
auto index = ((size_t)(y) * (size_t)(size.x) + (size_t)(x)) * CHANNELS;
|
||||||
if (index + CHANNELS > pixels.size()) return vec4(0.0f);
|
if (index + CHANNELS > pixels.size()) return vec4(0.0f);
|
||||||
|
|
||||||
return vec4(uint8_to_float(pixels[index + 0]), uint8_to_float(pixels[index + 1]), uint8_to_float(pixels[index + 2]),
|
vec4 color{uint8_to_float(pixels[index + 0]), uint8_to_float(pixels[index + 1]), uint8_to_float(pixels[index + 2]),
|
||||||
uint8_to_float(pixels[index + 3]));
|
uint8_to_float(pixels[index + 3])};
|
||||||
|
|
||||||
|
if (color.a <= 0.0f) color = vec4(0.0f);
|
||||||
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::pixel_set(ivec2 position, vec4 color)
|
void Texture::pixel_set(ivec2 position, vec4 color)
|
||||||
|
|||||||
+11
@@ -70,6 +70,17 @@ namespace anm2ed::types::merge
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace anm2ed::types::edit
|
||||||
|
{
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
NONE,
|
||||||
|
START,
|
||||||
|
DURING,
|
||||||
|
END
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
namespace anm2ed::types::color
|
namespace anm2ed::types::color
|
||||||
{
|
{
|
||||||
using namespace glm;
|
using namespace glm;
|
||||||
|
|||||||
Reference in New Issue
Block a user