Refactor + render animation tweaks + updated frame properties + bug fixes
This commit is contained in:
@@ -3,14 +3,13 @@
|
||||
#include <format>
|
||||
#include <vector>
|
||||
|
||||
#include "filesystem_.h"
|
||||
#include "path_.h"
|
||||
#include "strings.h"
|
||||
#include "time_.h"
|
||||
|
||||
using namespace anm2ed::resource;
|
||||
using namespace anm2ed::types;
|
||||
using namespace anm2ed::util;
|
||||
namespace filesystem = anm2ed::util::filesystem;
|
||||
|
||||
namespace anm2ed::imgui
|
||||
{
|
||||
@@ -88,7 +87,7 @@ namespace anm2ed::imgui
|
||||
|
||||
auto isRequested = i == manager.pendingSelected;
|
||||
auto font = isDirty ? font::ITALICS : font::REGULAR;
|
||||
auto filename = filesystem::path_to_utf8(document.filename_get());
|
||||
auto filename = path::to_utf8(document.filename_get());
|
||||
auto string =
|
||||
isDirty ? std::vformat(localize.get(FORMAT_NOT_SAVED), std::make_format_args(filename)) : filename;
|
||||
auto label = std::format("{}###Document{}", string, i);
|
||||
@@ -105,7 +104,7 @@ namespace anm2ed::imgui
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
auto pathUtf8 = filesystem::path_to_utf8(document.path);
|
||||
auto pathUtf8 = path::to_utf8(document.path);
|
||||
ImGui::SetItemTooltip("%s", pathUtf8.c_str());
|
||||
|
||||
ImGui::PopFont();
|
||||
@@ -128,7 +127,7 @@ namespace anm2ed::imgui
|
||||
{
|
||||
auto& closeDocument = manager.documents[closeDocumentIndex];
|
||||
|
||||
auto filename = filesystem::path_to_utf8(closeDocument.filename_get());
|
||||
auto filename = path::to_utf8(closeDocument.filename_get());
|
||||
auto prompt = std::vformat(localize.get(LABEL_DOCUMENT_MODIFIED_PROMPT), std::make_format_args(filename));
|
||||
ImGui::TextUnformatted(prompt.c_str());
|
||||
|
||||
|
||||
+16
-3
@@ -1,6 +1,3 @@
|
||||
#include "imgui_.h"
|
||||
#include "strings.h"
|
||||
|
||||
#include <imgui/imgui_internal.h>
|
||||
|
||||
#include <cmath>
|
||||
@@ -8,7 +5,12 @@
|
||||
#include <sstream>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "imgui_.h"
|
||||
#include "path_.h"
|
||||
#include "strings.h"
|
||||
|
||||
using namespace anm2ed::types;
|
||||
using namespace anm2ed::util;
|
||||
using namespace glm;
|
||||
|
||||
namespace anm2ed::imgui
|
||||
@@ -84,6 +86,17 @@ namespace anm2ed::imgui
|
||||
return ImGui::InputText(label, string->data(), string->capacity() + 1, flags, input_text_callback, string);
|
||||
}
|
||||
|
||||
bool input_text_path(const char* label, std::filesystem::path* path, ImGuiInputTextFlags flags)
|
||||
{
|
||||
if (!path) return false;
|
||||
|
||||
auto pathUtf8 = path::to_utf8(*path);
|
||||
auto edited = input_text_string(label, &pathUtf8, flags);
|
||||
if (edited) *path = path::from_utf8(pathUtf8);
|
||||
|
||||
return edited;
|
||||
}
|
||||
|
||||
bool combo_negative_one_indexed(const std::string& label, int* index, std::vector<const char*>& strings)
|
||||
{
|
||||
*index += 1;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <glm/glm.hpp>
|
||||
#include <imgui/imgui.h>
|
||||
#include <set>
|
||||
@@ -176,6 +177,7 @@ namespace anm2ed::imgui
|
||||
ImVec2 child_size_get(int = 1);
|
||||
int input_text_callback(ImGuiInputTextCallbackData*);
|
||||
bool input_text_string(const char*, std::string*, ImGuiInputTextFlags = 0);
|
||||
bool input_text_path(const char*, std::filesystem::path*, ImGuiInputTextFlags = 0);
|
||||
bool input_int_range(const char*, int&, int, int, int = STEP, int = STEP_FAST, 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",
|
||||
|
||||
+35
-935
File diff suppressed because it is too large
Load Diff
+12
-4
@@ -8,12 +8,23 @@
|
||||
#include "settings.h"
|
||||
#include "strings.h"
|
||||
|
||||
#include "wizard/about.h"
|
||||
#include "wizard/change_all_frame_properties.h"
|
||||
#include "wizard/configure.h"
|
||||
#include "wizard/generate_animation_from_grid.h"
|
||||
#include "wizard/render_animation.h"
|
||||
|
||||
namespace anm2ed::imgui
|
||||
{
|
||||
class Taskbar
|
||||
{
|
||||
wizard::ChangeAllFrameProperties changeAllFrameProperties{};
|
||||
wizard::About about{};
|
||||
wizard::Configure configure{};
|
||||
wizard::GenerateAnimationFromGrid generateAnimationFromGrid{};
|
||||
wizard::RenderAnimation renderAnimation{};
|
||||
|
||||
Canvas generate;
|
||||
float generateTime{};
|
||||
PopupHelper generatePopup{PopupHelper(LABEL_TASKBAR_GENERATE_ANIMATION_FROM_GRID)};
|
||||
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)};
|
||||
@@ -21,14 +32,11 @@ namespace anm2ed::imgui
|
||||
PopupHelper configurePopup{PopupHelper(LABEL_TASKBAR_CONFIGURE)};
|
||||
PopupHelper aboutPopup{PopupHelper(LABEL_TASKBAR_ABOUT)};
|
||||
Settings editSettings{};
|
||||
int selectedShortcut{-1};
|
||||
int creditsIndex{};
|
||||
bool isQuittingMode{};
|
||||
|
||||
public:
|
||||
float height{};
|
||||
|
||||
Taskbar();
|
||||
void update(Manager&, Settings&, Resources&, Dialog&, bool&);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -11,12 +11,12 @@
|
||||
#include "imgui_.h"
|
||||
#include "log.h"
|
||||
#include "math_.h"
|
||||
#include "path_.h"
|
||||
#include "strings.h"
|
||||
#include "toast.h"
|
||||
#include "tool.h"
|
||||
#include "types.h"
|
||||
|
||||
using namespace anm2ed::canvas;
|
||||
using namespace anm2ed::types;
|
||||
using namespace anm2ed::util;
|
||||
using namespace anm2ed::resource;
|
||||
@@ -48,6 +48,7 @@ namespace anm2ed::imgui
|
||||
{
|
||||
auto& ffmpegPath = settings.renderFFmpegPath;
|
||||
auto& path = settings.renderPath;
|
||||
auto pathString = path::to_utf8(path);
|
||||
auto& type = settings.renderType;
|
||||
|
||||
if (playback.time > end || playback.isFinished)
|
||||
@@ -55,11 +56,11 @@ namespace anm2ed::imgui
|
||||
if (type == render::PNGS)
|
||||
{
|
||||
auto& format = settings.renderFormat;
|
||||
auto formatString = path::to_utf8(format);
|
||||
bool isSuccess{true};
|
||||
for (auto [i, frame] : std::views::enumerate(renderFrames))
|
||||
{
|
||||
std::filesystem::path outputPath =
|
||||
std::filesystem::path(path) / std::vformat(format, std::make_format_args(i));
|
||||
auto outputPath = path / std::vformat(formatString, std::make_format_args(i));
|
||||
|
||||
if (!frame.write_png(outputPath))
|
||||
{
|
||||
@@ -71,15 +72,16 @@ namespace anm2ed::imgui
|
||||
|
||||
if (isSuccess)
|
||||
{
|
||||
toasts.push(std::vformat(localize.get(TOAST_EXPORT_RENDERED_FRAMES), std::make_format_args(path)));
|
||||
logger.info(
|
||||
std::vformat(localize.get(TOAST_EXPORT_RENDERED_FRAMES, anm2ed::ENGLISH), std::make_format_args(path)));
|
||||
toasts.push(std::vformat(localize.get(TOAST_EXPORT_RENDERED_FRAMES), std::make_format_args(pathString)));
|
||||
logger.info(std::vformat(localize.get(TOAST_EXPORT_RENDERED_FRAMES, anm2ed::ENGLISH),
|
||||
std::make_format_args(pathString)));
|
||||
}
|
||||
else
|
||||
{
|
||||
toasts.push(std::vformat(localize.get(TOAST_EXPORT_RENDERED_FRAMES_FAILED), std::make_format_args(path)));
|
||||
toasts.push(
|
||||
std::vformat(localize.get(TOAST_EXPORT_RENDERED_FRAMES_FAILED), std::make_format_args(pathString)));
|
||||
logger.error(std::vformat(localize.get(TOAST_EXPORT_RENDERED_FRAMES_FAILED, anm2ed::ENGLISH),
|
||||
std::make_format_args(path)));
|
||||
std::make_format_args(pathString)));
|
||||
}
|
||||
}
|
||||
else if (type == render::SPRITESHEET)
|
||||
@@ -129,15 +131,16 @@ namespace anm2ed::imgui
|
||||
Texture spritesheetTexture(spritesheet.data(), spritesheetSize);
|
||||
if (spritesheetTexture.write_png(path))
|
||||
{
|
||||
toasts.push(std::vformat(localize.get(TOAST_EXPORT_SPRITESHEET), std::make_format_args(path)));
|
||||
logger.info(
|
||||
std::vformat(localize.get(TOAST_EXPORT_SPRITESHEET, anm2ed::ENGLISH), std::make_format_args(path)));
|
||||
toasts.push(std::vformat(localize.get(TOAST_EXPORT_SPRITESHEET), std::make_format_args(pathString)));
|
||||
logger.info(std::vformat(localize.get(TOAST_EXPORT_SPRITESHEET, anm2ed::ENGLISH),
|
||||
std::make_format_args(pathString)));
|
||||
}
|
||||
else
|
||||
{
|
||||
toasts.push(std::vformat(localize.get(TOAST_EXPORT_SPRITESHEET_FAILED), std::make_format_args(path)));
|
||||
toasts.push(
|
||||
std::vformat(localize.get(TOAST_EXPORT_SPRITESHEET_FAILED), std::make_format_args(pathString)));
|
||||
logger.error(std::vformat(localize.get(TOAST_EXPORT_SPRITESHEET_FAILED, anm2ed::ENGLISH),
|
||||
std::make_format_args(path)));
|
||||
std::make_format_args(pathString)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -146,16 +149,16 @@ namespace anm2ed::imgui
|
||||
{
|
||||
if (animation_render(ffmpegPath, path, renderFrames, audioStream, (render::Type)type, size, anm2.info.fps))
|
||||
{
|
||||
toasts.push(std::vformat(localize.get(TOAST_EXPORT_RENDERED_ANIMATION), std::make_format_args(path)));
|
||||
toasts.push(std::vformat(localize.get(TOAST_EXPORT_RENDERED_ANIMATION), std::make_format_args(pathString)));
|
||||
logger.info(std::vformat(localize.get(TOAST_EXPORT_RENDERED_ANIMATION, anm2ed::ENGLISH),
|
||||
std::make_format_args(path)));
|
||||
std::make_format_args(pathString)));
|
||||
}
|
||||
else
|
||||
{
|
||||
toasts.push(
|
||||
std::vformat(localize.get(TOAST_EXPORT_RENDERED_ANIMATION_FAILED), std::make_format_args(path)));
|
||||
std::vformat(localize.get(TOAST_EXPORT_RENDERED_ANIMATION_FAILED), std::make_format_args(pathString)));
|
||||
logger.error(std::vformat(localize.get(TOAST_EXPORT_RENDERED_ANIMATION_FAILED, anm2ed::ENGLISH),
|
||||
std::make_format_args(path)));
|
||||
std::make_format_args(pathString)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,7 +166,6 @@ namespace anm2ed::imgui
|
||||
|
||||
if (settings.renderIsRawAnimation)
|
||||
{
|
||||
|
||||
settings = savedSettings;
|
||||
|
||||
pan = savedPan;
|
||||
@@ -290,8 +292,12 @@ namespace anm2ed::imgui
|
||||
auto zoom_in = [&]() { zoom_adjust(zoomStep); };
|
||||
auto zoom_out = [&]() { zoom_adjust(-zoomStep); };
|
||||
|
||||
manager.isAbleToRecord = false;
|
||||
|
||||
if (ImGui::Begin(localize.get(LABEL_ANIMATION_PREVIEW_WINDOW), &settings.windowIsAnimationPreview))
|
||||
{
|
||||
manager.isAbleToRecord = true;
|
||||
|
||||
auto childSize = ImVec2(row_widget_width_get(4),
|
||||
(ImGui::GetTextLineHeightWithSpacing() * 4) + (ImGui::GetStyle().WindowPadding.y * 2));
|
||||
|
||||
@@ -402,6 +408,7 @@ namespace anm2ed::imgui
|
||||
settings.previewBackgroundColor = vec4();
|
||||
settings.previewIsGrid = false;
|
||||
settings.previewIsAxes = false;
|
||||
settings.previewIsPivots = false;
|
||||
settings.previewIsBorder = false;
|
||||
settings.timelineIsOnlyShowLayers = true;
|
||||
settings.onionskinIsEnabled = false;
|
||||
@@ -729,7 +736,7 @@ namespace anm2ed::imgui
|
||||
|
||||
auto frame = document.frame_get();
|
||||
auto useTool = tool;
|
||||
auto step = isMod ? canvas::STEP_FAST : canvas::STEP;
|
||||
auto step = isMod ? STEP_FAST : STEP;
|
||||
mousePos = position_translate(zoom, pan, to_vec2(ImGui::GetMousePos()) - to_vec2(cursorScreenPos));
|
||||
|
||||
if (isMouseMiddleDown) useTool = tool::PAN;
|
||||
|
||||
@@ -13,7 +13,6 @@ using namespace glm;
|
||||
|
||||
namespace anm2ed::imgui
|
||||
{
|
||||
|
||||
void FrameProperties::update(Manager& manager, Settings& settings)
|
||||
{
|
||||
if (ImGui::Begin(localize.get(LABEL_FRAME_PROPERTIES_WINDOW), &settings.windowIsFrameProperties))
|
||||
@@ -180,151 +179,16 @@ namespace anm2ed::imgui
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& isCrop = settings.changeIsCrop;
|
||||
auto& isCropX = settings.changeIsCropX;
|
||||
auto& isCropY = settings.changeIsCropY;
|
||||
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, checkboxLabel, isEnabled) \
|
||||
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), checkboxLabel, isEnabled) };
|
||||
|
||||
auto color3_value = [&](const char* checkboxLabel, const char* valueLabel, bool& isEnabled, vec3& value)
|
||||
{ PROPERTIES_WIDGET(ImGui::ColorEdit3(valueLabel, value_ptr(value)), checkboxLabel, isEnabled); };
|
||||
|
||||
auto color4_value = [&](const char* checkboxLabel, const char* valueLabel, bool& isEnabled, vec4& value)
|
||||
{ PROPERTIES_WIDGET(ImGui::ColorEdit4(valueLabel, value_ptr(value)), checkboxLabel, isEnabled); };
|
||||
|
||||
auto float2_value = [&](const char* checkboxLabel, const char* valueLabel, bool& isEnabled, vec2& value)
|
||||
{
|
||||
PROPERTIES_WIDGET(ImGui::InputFloat2(valueLabel, value_ptr(value), vec2_format_get(value)), checkboxLabel,
|
||||
isEnabled);
|
||||
};
|
||||
|
||||
auto float2_value_new = [&](const char* checkboxXLabel, const char* checkboxYLabel, const char* valueXLabel,
|
||||
const char* valueYLabel, bool& isXEnabled, bool& isYEnabled, vec2& value)
|
||||
{
|
||||
auto width =
|
||||
(ImGui::CalcItemWidth() - ImGui::GetTextLineHeight() - (ImGui::GetStyle().ItemInnerSpacing.x * 6)) / 2;
|
||||
|
||||
PROPERTIES_WIDGET(ImGui::PushItemWidth(width);
|
||||
ImGui::DragFloat(valueXLabel, &value.x, DRAG_SPEED, 0.0f, 0.0f, float_format_get(value.x));
|
||||
ImGui::PopItemWidth(), checkboxXLabel, isXEnabled);
|
||||
ImGui::SameLine();
|
||||
PROPERTIES_WIDGET(ImGui::PushItemWidth(width);
|
||||
ImGui::DragFloat(valueYLabel, &value.y, DRAG_SPEED, 0.0f, 0.0f, float_format_get(value.y));
|
||||
ImGui::PopItemWidth(), checkboxYLabel, isYEnabled);
|
||||
};
|
||||
|
||||
auto float_value = [&](const char* checkboxLabel, const char* valueLabel, bool& isEnabled, float& value)
|
||||
{
|
||||
PROPERTIES_WIDGET(ImGui::InputFloat(valueLabel, &value, STEP, STEP_FAST, float_format_get(value)),
|
||||
checkboxLabel, isEnabled);
|
||||
};
|
||||
|
||||
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),
|
||||
checkboxLabel, isEnabled);
|
||||
};
|
||||
|
||||
#undef PROPERTIES_WIDGET
|
||||
|
||||
float2_value_new("##Is Crop X", "##Is Crop Y", "##Crop X", localize.get(BASIC_CROP), isCropX, isCropY, 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(document, localize.get(EDIT_CHANGE_FRAME_PROPERTIES), Document::FRAMES,
|
||||
document.item_get()->frames_change(frameChange, type, *frames.begin(), (int)frames.size()));
|
||||
};
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
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::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();
|
||||
}
|
||||
changeAllFrameProperties.update(document, settings);
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
dummy_value_negative<int>() = -1;
|
||||
dummy_value<float>() = 0;
|
||||
dummy_value<int>() = 0;
|
||||
dummy_value<bool>() = 0;
|
||||
dummy_value<vec2>() = vec2();
|
||||
dummy_value<vec3>() = vec3();
|
||||
dummy_value<vec4>() = vec4();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,23 +3,15 @@
|
||||
#include <glm/vec2.hpp>
|
||||
|
||||
#include "manager.h"
|
||||
#include "settings.h"
|
||||
|
||||
namespace anm2
|
||||
{
|
||||
struct Frame;
|
||||
}
|
||||
#include "wizard/change_all_frame_properties.h"
|
||||
|
||||
namespace anm2ed::imgui
|
||||
{
|
||||
class FrameProperties
|
||||
{
|
||||
wizard::ChangeAllFrameProperties changeAllFrameProperties{};
|
||||
|
||||
public:
|
||||
void update(Manager&, Settings&);
|
||||
|
||||
private:
|
||||
glm::vec2 cropEditingValue{};
|
||||
const anm2::Frame* cropEditingFrame{};
|
||||
bool isCropEditing{};
|
||||
};
|
||||
}
|
||||
|
||||
+11
-12
@@ -2,12 +2,11 @@
|
||||
|
||||
#include <ranges>
|
||||
|
||||
#include "filesystem_.h"
|
||||
#include "log.h"
|
||||
#include "path_.h"
|
||||
#include "strings.h"
|
||||
#include "toast.h"
|
||||
|
||||
using namespace anm2ed::dialog;
|
||||
using namespace anm2ed::util;
|
||||
using namespace anm2ed::types;
|
||||
using namespace anm2ed::resource;
|
||||
@@ -24,8 +23,8 @@ namespace anm2ed::imgui
|
||||
auto& selection = document.sound.selection;
|
||||
auto style = ImGui::GetStyle();
|
||||
|
||||
auto add_open = [&]() { dialog.file_open(dialog::SOUND_OPEN); };
|
||||
auto replace_open = [&]() { dialog.file_open(dialog::SOUND_REPLACE); };
|
||||
auto add_open = [&]() { dialog.file_open(Dialog::SOUND_OPEN); };
|
||||
auto replace_open = [&]() { dialog.file_open(Dialog::SOUND_REPLACE); };
|
||||
|
||||
auto play = [&](anm2::Sound& sound) { sound.play(); };
|
||||
|
||||
@@ -34,7 +33,7 @@ namespace anm2ed::imgui
|
||||
auto behavior = [&]()
|
||||
{
|
||||
int id{};
|
||||
auto pathString = filesystem::path_to_utf8(path);
|
||||
auto pathString = path::to_utf8(path);
|
||||
if (anm2.sound_add(document.directory_get(), path, id))
|
||||
{
|
||||
selection = {id};
|
||||
@@ -76,7 +75,7 @@ namespace anm2ed::imgui
|
||||
{
|
||||
anm2::Sound& sound = anm2.content.sounds[id];
|
||||
sound.reload(document.directory_get());
|
||||
auto pathString = filesystem::path_to_utf8(sound.path);
|
||||
auto pathString = path::to_utf8(sound.path);
|
||||
toasts.push(std::vformat(localize.get(TOAST_RELOAD_SOUND), std::make_format_args(id, pathString)));
|
||||
logger.info(
|
||||
std::vformat(localize.get(TOAST_RELOAD_SOUND, anm2ed::ENGLISH), std::make_format_args(id, pathString)));
|
||||
@@ -95,7 +94,7 @@ namespace anm2ed::imgui
|
||||
auto& id = *selection.begin();
|
||||
anm2::Sound& sound = anm2.content.sounds[id];
|
||||
sound = anm2::Sound(document.directory_get(), path);
|
||||
auto pathString = filesystem::path_to_utf8(sound.path);
|
||||
auto pathString = path::to_utf8(sound.path);
|
||||
toasts.push(std::vformat(localize.get(TOAST_REPLACE_SOUND), std::make_format_args(id, pathString)));
|
||||
logger.info(
|
||||
std::vformat(localize.get(TOAST_REPLACE_SOUND, anm2ed::ENGLISH), std::make_format_args(id, pathString)));
|
||||
@@ -215,7 +214,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 pathString = filesystem::path_to_utf8(sound.path);
|
||||
auto pathString = path::to_utf8(sound.path);
|
||||
|
||||
ImGui::SetNextItemSelectionUserData(id);
|
||||
ImGui::SetNextItemStorageID(id);
|
||||
@@ -271,9 +270,9 @@ namespace anm2ed::imgui
|
||||
|
||||
ImGui::EndChild();
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
context_menu();
|
||||
context_menu();
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
selection.finish();
|
||||
@@ -288,7 +287,7 @@ namespace anm2ed::imgui
|
||||
if (ImGui::Button(localize.get(BASIC_ADD), widgetSize)) add_open();
|
||||
imgui::set_item_tooltip_shortcut(localize.get(TOOLTIP_SOUND_ADD), settings.shortcutAdd);
|
||||
|
||||
if (dialog.is_selected(dialog::SOUND_OPEN))
|
||||
if (dialog.is_selected(Dialog::SOUND_OPEN))
|
||||
{
|
||||
add(dialog.path);
|
||||
dialog.reset();
|
||||
@@ -316,7 +315,7 @@ namespace anm2ed::imgui
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_REPLACE_SOUND));
|
||||
ImGui::EndDisabled();
|
||||
|
||||
if (dialog.is_selected(dialog::SOUND_REPLACE))
|
||||
if (dialog.is_selected(Dialog::SOUND_REPLACE))
|
||||
{
|
||||
replace(dialog.path);
|
||||
dialog.reset();
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "tool.h"
|
||||
#include "types.h"
|
||||
|
||||
using namespace anm2ed::canvas;
|
||||
using namespace anm2ed::types;
|
||||
using namespace anm2ed::resource;
|
||||
using namespace anm2ed::util;
|
||||
@@ -19,12 +18,6 @@ using namespace glm;
|
||||
|
||||
namespace anm2ed::imgui
|
||||
{
|
||||
constexpr auto BORDER_DASH_LENGTH = 1.0f;
|
||||
constexpr auto BORDER_DASH_GAP = 0.5f;
|
||||
constexpr auto BORDER_DASH_OFFSET = 0.0f;
|
||||
|
||||
constexpr auto PIVOT_COLOR = color::PINK;
|
||||
|
||||
SpritesheetEditor::SpritesheetEditor() : Canvas(vec2()) {}
|
||||
|
||||
void SpritesheetEditor::update(Manager& manager, Settings& settings, Resources& resources)
|
||||
@@ -218,7 +211,7 @@ namespace anm2ed::imgui
|
||||
rect_render(dashedShader, cropTransform, cropModel, color::RED);
|
||||
|
||||
auto pivotTransform =
|
||||
transform * math::quad_model_get(canvas::PIVOT_SIZE, frame->crop + frame->pivot, PIVOT_SIZE * 0.5f);
|
||||
transform * math::quad_model_get(PIVOT_SIZE, frame->crop + frame->pivot, PIVOT_SIZE * 0.5f);
|
||||
texture_render(shaderTexture, resources.icons[icon::PIVOT].id, pivotTransform, PIVOT_COLOR);
|
||||
}
|
||||
}
|
||||
@@ -278,7 +271,7 @@ namespace anm2ed::imgui
|
||||
|
||||
auto frame = document.frame_get();
|
||||
auto useTool = tool;
|
||||
auto step = isMod ? canvas::STEP_FAST : canvas::STEP;
|
||||
auto step = isMod ? STEP_FAST : STEP;
|
||||
auto stepX = isGridSnap ? step * gridSize.x : step;
|
||||
auto stepY = isGridSnap ? step * gridSize.y : step;
|
||||
previousMousePos = mousePos;
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#include <format>
|
||||
|
||||
#include "document.h"
|
||||
#include "filesystem_.h"
|
||||
#include "log.h"
|
||||
#include "path_.h"
|
||||
#include "strings.h"
|
||||
#include "toast.h"
|
||||
|
||||
@@ -28,8 +28,8 @@ namespace anm2ed::imgui
|
||||
auto& reference = document.spritesheet.reference;
|
||||
auto style = ImGui::GetStyle();
|
||||
|
||||
auto add_open = [&]() { dialog.file_open(dialog::SPRITESHEET_OPEN); };
|
||||
auto replace_open = [&]() { dialog.file_open(dialog::SPRITESHEET_REPLACE); };
|
||||
auto add_open = [&]() { dialog.file_open(Dialog::SPRITESHEET_OPEN); };
|
||||
auto replace_open = [&]() { dialog.file_open(Dialog::SPRITESHEET_REPLACE); };
|
||||
|
||||
auto add = [&](const std::filesystem::path& path)
|
||||
{
|
||||
@@ -47,7 +47,7 @@ namespace anm2ed::imgui
|
||||
for (auto& id : unused)
|
||||
{
|
||||
anm2::Spritesheet& spritesheet = anm2.content.spritesheets[id];
|
||||
auto pathString = filesystem::path_to_utf8(spritesheet.path);
|
||||
auto pathString = path::to_utf8(spritesheet.path);
|
||||
toasts.push(std::vformat(localize.get(TOAST_REMOVE_SPRITESHEET), std::make_format_args(id, pathString)));
|
||||
logger.info(std::vformat(localize.get(TOAST_REMOVE_SPRITESHEET, anm2ed::ENGLISH),
|
||||
std::make_format_args(id, pathString)));
|
||||
@@ -69,7 +69,7 @@ namespace anm2ed::imgui
|
||||
{
|
||||
anm2::Spritesheet& spritesheet = anm2.content.spritesheets[id];
|
||||
spritesheet.reload(document.directory_get());
|
||||
auto pathString = filesystem::path_to_utf8(spritesheet.path);
|
||||
auto pathString = path::to_utf8(spritesheet.path);
|
||||
toasts.push(std::vformat(localize.get(TOAST_RELOAD_SPRITESHEET), std::make_format_args(id, pathString)));
|
||||
logger.info(std::vformat(localize.get(TOAST_RELOAD_SPRITESHEET, anm2ed::ENGLISH),
|
||||
std::make_format_args(id, pathString)));
|
||||
@@ -88,7 +88,7 @@ namespace anm2ed::imgui
|
||||
auto& id = *selection.begin();
|
||||
anm2::Spritesheet& spritesheet = anm2.content.spritesheets[id];
|
||||
spritesheet = anm2::Spritesheet(document.directory_get(), path);
|
||||
auto pathString = filesystem::path_to_utf8(spritesheet.path);
|
||||
auto pathString = path::to_utf8(spritesheet.path);
|
||||
toasts.push(std::vformat(localize.get(TOAST_REPLACE_SPRITESHEET), std::make_format_args(id, pathString)));
|
||||
logger.info(std::vformat(localize.get(TOAST_REPLACE_SPRITESHEET, anm2ed::ENGLISH),
|
||||
std::make_format_args(id, pathString)));
|
||||
@@ -104,7 +104,7 @@ namespace anm2ed::imgui
|
||||
for (auto& id : selection)
|
||||
{
|
||||
anm2::Spritesheet& spritesheet = anm2.content.spritesheets[id];
|
||||
auto pathString = filesystem::path_to_utf8(spritesheet.path);
|
||||
auto pathString = path::to_utf8(spritesheet.path);
|
||||
if (spritesheet.save(document.directory_get()))
|
||||
{
|
||||
toasts.push(std::vformat(localize.get(TOAST_SAVE_SPRITESHEET), std::make_format_args(id, pathString)));
|
||||
@@ -126,10 +126,9 @@ namespace anm2ed::imgui
|
||||
std::error_code ec{};
|
||||
auto absolutePath = std::filesystem::weakly_canonical(document.directory_get() / spritesheet.path, ec);
|
||||
if (ec) absolutePath = document.directory_get() / spritesheet.path;
|
||||
auto target = std::filesystem::is_directory(absolutePath)
|
||||
? absolutePath
|
||||
: std::filesystem::is_directory(absolutePath.parent_path()) ? absolutePath.parent_path()
|
||||
: document.directory_get();
|
||||
auto target = std::filesystem::is_directory(absolutePath) ? absolutePath
|
||||
: std::filesystem::is_directory(absolutePath.parent_path()) ? absolutePath.parent_path()
|
||||
: document.directory_get();
|
||||
dialog.file_explorer_open(target);
|
||||
};
|
||||
|
||||
@@ -232,7 +231,7 @@ namespace anm2ed::imgui
|
||||
bool isValid = spritesheet.texture.is_valid();
|
||||
auto& texture = isValid ? spritesheet.texture : 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 pathString = filesystem::path_to_utf8(spritesheet.path);
|
||||
auto pathString = path::to_utf8(spritesheet.path);
|
||||
auto pathCStr = pathString.c_str();
|
||||
|
||||
ImGui::SetNextItemSelectionUserData(id);
|
||||
@@ -322,12 +321,12 @@ namespace anm2ed::imgui
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
context_menu();
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
context_menu();
|
||||
selection.finish();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
@@ -339,7 +338,7 @@ namespace anm2ed::imgui
|
||||
if (ImGui::Button(localize.get(BASIC_ADD), rowOneWidgetSize)) add_open();
|
||||
set_item_tooltip_shortcut(localize.get(TOOLTIP_ADD_SPRITESHEET), settings.shortcutAdd);
|
||||
|
||||
if (dialog.is_selected(dialog::SPRITESHEET_OPEN))
|
||||
if (dialog.is_selected(Dialog::SPRITESHEET_OPEN))
|
||||
{
|
||||
add(dialog.path);
|
||||
dialog.reset();
|
||||
@@ -359,7 +358,7 @@ namespace anm2ed::imgui
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_REPLACE_SPRITESHEET));
|
||||
ImGui::EndDisabled();
|
||||
|
||||
if (dialog.is_selected(dialog::SPRITESHEET_REPLACE))
|
||||
if (dialog.is_selected(Dialog::SPRITESHEET_REPLACE))
|
||||
{
|
||||
replace(dialog.path);
|
||||
dialog.reset();
|
||||
|
||||
@@ -1069,7 +1069,7 @@ namespace anm2ed::imgui
|
||||
drawList->AddRectFilled(frameScreenPos, frameRectMax, ImGui::GetColorU32(frameMultipleOverlayColor));
|
||||
}
|
||||
|
||||
frames.selection.start(item->frames.size(), ImGuiMultiSelectFlags_ClearOnEscape);
|
||||
if (type != anm2::TRIGGER) frames.selection.start(item->frames.size(), ImGuiMultiSelectFlags_ClearOnEscape);
|
||||
|
||||
for (auto [i, frame] : std::views::enumerate(item->frames))
|
||||
{
|
||||
@@ -1400,7 +1400,8 @@ namespace anm2ed::imgui
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
frames.selection.finish();
|
||||
if (type != anm2::TRIGGER) frames.selection.finish();
|
||||
|
||||
if (isFrameSelectionLocked)
|
||||
{
|
||||
frames.selection.clear();
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
#include <ranges>
|
||||
|
||||
#include "filesystem_.h"
|
||||
#include "path_.h"
|
||||
#include "strings.h"
|
||||
|
||||
using namespace anm2ed::util;
|
||||
using namespace anm2ed::resource;
|
||||
namespace filesystem = anm2ed::util::filesystem;
|
||||
|
||||
namespace anm2ed::imgui
|
||||
{
|
||||
@@ -34,10 +34,10 @@ namespace anm2ed::imgui
|
||||
auto widgetSize = widget_size_with_row_get(2);
|
||||
|
||||
if (ImGui::Button(localize.get(BASIC_NEW), widgetSize))
|
||||
dialog.file_save(dialog::ANM2_NEW); // handled in taskbar.cpp
|
||||
dialog.file_save(Dialog::ANM2_NEW); // handled in taskbar.cpp
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(localize.get(BASIC_OPEN), widgetSize))
|
||||
dialog.file_open(dialog::ANM2_OPEN); // handled in taskbar.cpp
|
||||
dialog.file_open(Dialog::ANM2_OPEN); // handled in taskbar.cpp
|
||||
|
||||
if (ImGui::BeginChild("##Recent Files Child", {}, ImGuiChildFlags_Borders))
|
||||
{
|
||||
@@ -46,8 +46,7 @@ namespace anm2ed::imgui
|
||||
{
|
||||
ImGui::PushID(i);
|
||||
|
||||
auto label = std::format(FILE_LABEL_FORMAT, filesystem::path_to_utf8(file.filename()),
|
||||
filesystem::path_to_utf8(file));
|
||||
auto label = std::format(FILE_LABEL_FORMAT, path::to_utf8(file.filename()), path::to_utf8(file));
|
||||
|
||||
if (ImGui::Selectable(label.c_str()))
|
||||
{
|
||||
@@ -78,8 +77,7 @@ namespace anm2ed::imgui
|
||||
{
|
||||
for (auto& file : manager.autosaveFiles)
|
||||
{
|
||||
auto label = std::format(FILE_LABEL_FORMAT, filesystem::path_to_utf8(file.filename()),
|
||||
filesystem::path_to_utf8(file));
|
||||
auto label = std::format(FILE_LABEL_FORMAT, path::to_utf8(file.filename()), path::to_utf8(file));
|
||||
ImGui::TextUnformatted(label.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
#include "about.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <imgui.h>
|
||||
#include <vector>
|
||||
|
||||
using namespace anm2ed::resource;
|
||||
|
||||
namespace anm2ed::imgui::wizard
|
||||
{
|
||||
static constexpr auto CREDIT_DELAY = 1.0f;
|
||||
static constexpr auto CREDIT_SCROLL_SPEED = 25.0f;
|
||||
|
||||
static constexpr About::Credit CREDITS[] = {
|
||||
{"Anm2Ed", font::BOLD},
|
||||
{"License: GPLv3"},
|
||||
{""},
|
||||
{"Designer", font::BOLD},
|
||||
{"Shweet"},
|
||||
{""},
|
||||
{"Additional Help", font::BOLD},
|
||||
{"im-tem"},
|
||||
{""},
|
||||
{"Localization", font::BOLD},
|
||||
{"Gabriel Asencio (Spanish (Latin America))"},
|
||||
{"ExtremeThreat (Russian)"},
|
||||
{"CxRedix (Chinese)"},
|
||||
{"sawalk/사왈이 (Korean)"},
|
||||
{""},
|
||||
{"Based on the work of:", font::BOLD},
|
||||
{"Adrian Gavrilita"},
|
||||
{"Simon Parzer"},
|
||||
{"Matt Kapuszczak"},
|
||||
{""},
|
||||
{"XM Music", font::BOLD},
|
||||
{"Drozerix"},
|
||||
{"\"Keygen Wraith\""},
|
||||
{"https://modarchive.org/module.php?207854"},
|
||||
{"License: CC0"},
|
||||
{""},
|
||||
{"Libraries", font::BOLD},
|
||||
{"Dear ImGui"},
|
||||
{"https://github.com/ocornut/imgui"},
|
||||
{"License: MIT"},
|
||||
{""},
|
||||
{"SDL"},
|
||||
{"https://github.com/libsdl-org/SDL"},
|
||||
{"License: zlib"},
|
||||
{""},
|
||||
{"SDL_mixer"},
|
||||
{"https://github.com/libsdl-org/SDL_mixer"},
|
||||
{"License: zlib"},
|
||||
{""},
|
||||
{"tinyxml2"},
|
||||
{"https://github.com/leethomason/tinyxml2"},
|
||||
{"License: zlib"},
|
||||
{""},
|
||||
{"glm"},
|
||||
{"https://github.com/g-truc/glm"},
|
||||
{"License: MIT"},
|
||||
{""},
|
||||
{"lunasvg"},
|
||||
{"https://github.com/sammycage/lunasvg"},
|
||||
{"License: MIT"},
|
||||
{""},
|
||||
{"Icons", font::BOLD},
|
||||
{"Remix Icons"},
|
||||
{"remixicon.com"},
|
||||
{"License: Apache"},
|
||||
{""},
|
||||
{"Font", font::BOLD},
|
||||
{"Noto Sans"},
|
||||
{"https://fonts.google.com/noto/specimen/Noto+Sans"},
|
||||
{"License: OFL"},
|
||||
{""},
|
||||
{"Special Thanks", font::BOLD},
|
||||
{"Edmund McMillen"},
|
||||
{"Florian Himsl"},
|
||||
{"Tyrone Rodriguez"},
|
||||
{"The-Vinh Truong (_kilburn)"},
|
||||
{"Isaac Reflashed team"},
|
||||
{"Everyone who waited patiently for this to be finished"},
|
||||
{"Everyone else who has worked on The Binding of Isaac!"},
|
||||
{""},
|
||||
{""},
|
||||
{""},
|
||||
{""},
|
||||
{""},
|
||||
{""},
|
||||
{""},
|
||||
{""},
|
||||
{""},
|
||||
{"enjoy the jams :)"},
|
||||
{""},
|
||||
{""},
|
||||
{""},
|
||||
{""},
|
||||
{""},
|
||||
{""},
|
||||
{""},
|
||||
{""},
|
||||
{""},
|
||||
{""},
|
||||
};
|
||||
static constexpr auto CREDIT_COUNT = (int)(sizeof(CREDITS) / sizeof(About::Credit));
|
||||
|
||||
void About::reset(Resources& resources)
|
||||
{
|
||||
resources.music_track().play(true);
|
||||
creditsState = {};
|
||||
creditsState.spawnTimer = CREDIT_DELAY;
|
||||
}
|
||||
|
||||
void About::update(Resources& resources)
|
||||
{
|
||||
auto size = ImGui::GetContentRegionAvail();
|
||||
auto applicationLabel = localize.get(LABEL_APPLICATION_NAME);
|
||||
auto versionLabel = localize.get(LABEL_APPLICATION_VERSION);
|
||||
|
||||
ImGui::PushFont(resources.fonts[font::BOLD].get(), font::SIZE_LARGE);
|
||||
|
||||
ImGui::SetCursorPosX((size.x - ImGui::CalcTextSize(applicationLabel).x) / 2);
|
||||
ImGui::TextUnformatted(applicationLabel);
|
||||
|
||||
ImGui::SetCursorPosX((size.x - ImGui::CalcTextSize(versionLabel).x) / 2);
|
||||
ImGui::TextUnformatted(versionLabel);
|
||||
|
||||
ImGui::PopFont();
|
||||
|
||||
auto creditRegionPos = ImGui::GetCursorScreenPos();
|
||||
auto creditRegionSize = ImGui::GetContentRegionAvail();
|
||||
|
||||
if (creditRegionSize.y > 0.0f && creditRegionSize.x > 0.0f)
|
||||
{
|
||||
auto fontSize = ImGui::GetFontSize();
|
||||
auto drawList = ImGui::GetWindowDrawList();
|
||||
auto clipMax = ImVec2(creditRegionPos.x + creditRegionSize.x, creditRegionPos.y + creditRegionSize.y);
|
||||
drawList->PushClipRect(creditRegionPos, clipMax, true);
|
||||
|
||||
auto delta = ImGui::GetIO().DeltaTime;
|
||||
creditsState.spawnTimer -= delta;
|
||||
auto maxVisible = std::max(1, (int)std::floor(creditRegionSize.y / (float)fontSize));
|
||||
|
||||
while (creditsState.active.size() < (size_t)maxVisible && creditsState.spawnTimer <= 0.0f)
|
||||
{
|
||||
creditsState.active.push_back({creditsState.nextIndex, 0.0f});
|
||||
creditsState.nextIndex = (creditsState.nextIndex + 1) % CREDIT_COUNT;
|
||||
creditsState.spawnTimer += CREDIT_DELAY;
|
||||
}
|
||||
|
||||
auto baseY = clipMax.y - (float)fontSize;
|
||||
auto& baseColor = ImGui::GetStyleColorVec4(ImGuiCol_Text);
|
||||
auto fadeSpan = (float)fontSize * 2.0f;
|
||||
|
||||
for (auto it = creditsState.active.begin(); it != creditsState.active.end();)
|
||||
{
|
||||
it->offset += CREDIT_SCROLL_SPEED * delta;
|
||||
auto yPos = baseY - it->offset;
|
||||
if (yPos + fontSize < creditRegionPos.y)
|
||||
{
|
||||
it = creditsState.active.erase(it);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto& credit = CREDITS[it->index];
|
||||
auto fontPtr = resources.fonts[credit.font].get();
|
||||
auto textSize = fontPtr->CalcTextSizeA((float)fontSize, FLT_MAX, 0.0f, credit.string);
|
||||
auto xPos = creditRegionPos.x + (creditRegionSize.x - textSize.x) * 0.5f;
|
||||
|
||||
auto alpha = 1.0f;
|
||||
auto topDist = yPos - creditRegionPos.y;
|
||||
if (topDist < fadeSpan) alpha *= std::clamp(topDist / fadeSpan, 0.0f, 1.0f);
|
||||
auto bottomDist = (creditRegionPos.y + creditRegionSize.y) - (yPos + fontSize);
|
||||
if (bottomDist < fadeSpan) alpha *= std::clamp(bottomDist / fadeSpan, 0.0f, 1.0f);
|
||||
if (alpha <= 0.0f)
|
||||
{
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto color = baseColor;
|
||||
color.w *= alpha;
|
||||
|
||||
drawList->AddText(fontPtr, fontSize, ImVec2(xPos, yPos), ImGui::GetColorU32(color), credit.string);
|
||||
++it;
|
||||
}
|
||||
|
||||
drawList->PopClipRect();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../resources.h"
|
||||
|
||||
namespace anm2ed::imgui::wizard
|
||||
{
|
||||
class About
|
||||
{
|
||||
public:
|
||||
struct Credit
|
||||
{
|
||||
const char* string{};
|
||||
resource::font::Type font{resource::font::REGULAR};
|
||||
};
|
||||
|
||||
struct ScrollingCredit
|
||||
{
|
||||
int index{};
|
||||
float offset{};
|
||||
};
|
||||
|
||||
struct CreditsState
|
||||
{
|
||||
std::vector<ScrollingCredit> active{};
|
||||
float spawnTimer{1.0f};
|
||||
int nextIndex{};
|
||||
};
|
||||
|
||||
int creditsIndex{};
|
||||
CreditsState creditsState{};
|
||||
|
||||
void reset(Resources& resources);
|
||||
void update(Resources& resources);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
#include "change_all_frame_properties.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
|
||||
#include "math_.h"
|
||||
|
||||
using namespace anm2ed::util::math;
|
||||
using namespace glm;
|
||||
|
||||
namespace anm2ed::imgui::wizard
|
||||
{
|
||||
void ChangeAllFrameProperties::update(Document& document, Settings& settings)
|
||||
{
|
||||
isChanged = false;
|
||||
|
||||
auto& frames = document.frames.selection;
|
||||
auto& isCropX = settings.changeIsCropX;
|
||||
auto& isCropY = settings.changeIsCropY;
|
||||
auto& isSizeX = settings.changeIsSizeX;
|
||||
auto& isSizeY = settings.changeIsSizeY;
|
||||
auto& isPositionX = settings.changeIsPositionX;
|
||||
auto& isPositionY = settings.changeIsPositionY;
|
||||
auto& isPivotX = settings.changeIsPivotX;
|
||||
auto& isPivotY = settings.changeIsPivotY;
|
||||
auto& isScaleX = settings.changeIsScaleX;
|
||||
auto& isScaleY = settings.changeIsScaleY;
|
||||
auto& isRotation = settings.changeIsRotation;
|
||||
auto& isDuration = settings.changeIsDuration;
|
||||
auto& isTintR = settings.changeIsTintR;
|
||||
auto& isTintG = settings.changeIsTintG;
|
||||
auto& isTintB = settings.changeIsTintB;
|
||||
auto& isTintA = settings.changeIsTintA;
|
||||
auto& isColorOffsetR = settings.changeIsColorOffsetR;
|
||||
auto& isColorOffsetG = settings.changeIsColorOffsetG;
|
||||
auto& isColorOffsetB = settings.changeIsColorOffsetB;
|
||||
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, checkboxLabel, isEnabled) \
|
||||
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), checkboxLabel, isEnabled) };
|
||||
|
||||
auto color3_value = [&](const char* checkboxRLabel, const char* checkboxGLabel, const char* checkboxBLabel,
|
||||
const char* valueRLabel, const char* valueGLabel, const char* valueBLabel,
|
||||
const char* label, bool& isREnabled, bool& isGEnabled, bool& isBEnabled, vec3& value)
|
||||
{
|
||||
auto style = ImGui::GetStyle();
|
||||
|
||||
auto width = (ImGui::CalcItemWidth() - (ImGui::GetFrameHeightWithSpacing() * 2) - (style.ItemSpacing.x * 2) -
|
||||
ImGui::GetFrameHeight()) /
|
||||
3;
|
||||
|
||||
ivec3 valueAlt = {float_to_uint8(value.r), float_to_uint8(value.g), float_to_uint8(value.b)};
|
||||
|
||||
ImGui::PushItemWidth(width);
|
||||
|
||||
PROPERTIES_WIDGET(ImGui::DragInt(valueRLabel, &valueAlt.r, DRAG_SPEED, 0, 255, "R:%d"), checkboxRLabel,
|
||||
isREnabled);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
PROPERTIES_WIDGET(ImGui::DragInt(valueGLabel, &valueAlt.g, DRAG_SPEED, 0, 255, "G:%d"), checkboxGLabel,
|
||||
isGEnabled);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
PROPERTIES_WIDGET(ImGui::DragInt(valueBLabel, &valueAlt.b, DRAG_SPEED, 0, 255, "B:%d"), checkboxBLabel,
|
||||
isBEnabled);
|
||||
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
value = vec3(uint8_to_float(valueAlt.r), uint8_to_float(valueAlt.g), uint8_to_float(valueAlt.b));
|
||||
|
||||
ImVec4 buttonColor = {isREnabled ? value.r : 0, isGEnabled ? value.g : 0, isBEnabled ? value.b : 0, 1};
|
||||
|
||||
ImGui::ColorButton(label, buttonColor);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::TextUnformatted(label);
|
||||
};
|
||||
|
||||
auto color4_value = [&](const char* checkboxRLabel, const char* checkboxGLabel, const char* checkboxBLabel,
|
||||
const char* checkboxALabel, const char* valueRLabel, const char* valueGLabel,
|
||||
const char* valueBLabel, const char* valueALabel, const char* label, bool& isREnabled,
|
||||
bool& isGEnabled, bool& isBEnabled, bool& isAEnabled, vec4& value)
|
||||
{
|
||||
auto style = ImGui::GetStyle();
|
||||
auto width = (ImGui::CalcItemWidth() - (ImGui::GetFrameHeightWithSpacing() * 3) - (style.ItemSpacing.x * 3) -
|
||||
ImGui::GetFrameHeight()) /
|
||||
4;
|
||||
ivec4 valueAlt = {float_to_uint8(value.r), float_to_uint8(value.g), float_to_uint8(value.b),
|
||||
float_to_uint8(value.a)};
|
||||
|
||||
ImGui::PushItemWidth(width);
|
||||
|
||||
PROPERTIES_WIDGET(ImGui::DragInt(valueRLabel, &valueAlt.r, DRAG_SPEED, 0, 255, "R:%d"), checkboxRLabel,
|
||||
isREnabled);
|
||||
ImGui::SameLine();
|
||||
|
||||
PROPERTIES_WIDGET(ImGui::DragInt(valueGLabel, &valueAlt.g, DRAG_SPEED, 0, 255, "G:%d"), checkboxGLabel,
|
||||
isGEnabled);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
PROPERTIES_WIDGET(ImGui::DragInt(valueBLabel, &valueAlt.b, DRAG_SPEED, 0, 255, "B:%d"), checkboxBLabel,
|
||||
isBEnabled);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
PROPERTIES_WIDGET(ImGui::DragInt(valueALabel, &valueAlt.a, DRAG_SPEED, 0, 255, "A:%d"), checkboxALabel,
|
||||
isAEnabled);
|
||||
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
value = vec4(uint8_to_float(valueAlt.r), uint8_to_float(valueAlt.g), uint8_to_float(valueAlt.b),
|
||||
uint8_to_float(valueAlt.a));
|
||||
|
||||
ImVec4 buttonColor = {isREnabled ? value.r : 0, isGEnabled ? value.g : 0, isBEnabled ? value.b : 0,
|
||||
isAEnabled ? value.a : 1};
|
||||
ImGui::ColorButton(label, buttonColor);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::TextUnformatted(label);
|
||||
};
|
||||
|
||||
auto float_value = [&](const char* checkboxLabel, const char* valueLabel, bool& isEnabled, float& value)
|
||||
{
|
||||
PROPERTIES_WIDGET(ImGui::DragFloat(valueLabel, &value, DRAG_SPEED, 0.0f, 0.0f, float_format_get(value)),
|
||||
checkboxLabel, isEnabled);
|
||||
};
|
||||
|
||||
auto float2_value = [&](const char* checkboxXLabel, const char* checkboxYLabel, const char* valueXLabel,
|
||||
const char* valueYLabel, bool& isXEnabled, bool& isYEnabled, vec2& value)
|
||||
{
|
||||
auto style = ImGui::GetStyle();
|
||||
|
||||
auto width = (ImGui::CalcItemWidth() - ImGui::GetFrameHeightWithSpacing() - style.ItemSpacing.x) / 2;
|
||||
|
||||
ImGui::PushItemWidth(width);
|
||||
PROPERTIES_WIDGET(ImGui::DragFloat(valueXLabel, &value.x, DRAG_SPEED, 0.0f, 0.0f, float_format_get(value.x)),
|
||||
checkboxXLabel, isXEnabled);
|
||||
ImGui::SameLine();
|
||||
PROPERTIES_WIDGET(ImGui::DragFloat(valueYLabel, &value.y, DRAG_SPEED, 0.0f, 0.0f, float_format_get(value.y)),
|
||||
checkboxYLabel, isYEnabled);
|
||||
ImGui::PopItemWidth();
|
||||
};
|
||||
|
||||
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),
|
||||
checkboxLabel, isEnabled);
|
||||
};
|
||||
|
||||
#undef PROPERTIES_WIDGET
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImGui::GetStyle().ItemInnerSpacing);
|
||||
|
||||
float2_value("##Is Crop X", "##Is Crop Y", "##Crop X", localize.get(BASIC_CROP), isCropX, isCropY, crop);
|
||||
float2_value("##Is Size X", "##Is Size Y", "##Size X", localize.get(BASIC_SIZE), isSizeX, isSizeY, size);
|
||||
float2_value("##Is Position X", "##Is Position Y", "##Position X", localize.get(BASIC_POSITION), isPositionX,
|
||||
isPositionY, position);
|
||||
float2_value("##Is Pivot X", "##Is Pivot Y", "##Pivot X", localize.get(BASIC_PIVOT), isPivotX, isPivotY, pivot);
|
||||
float2_value("##Is Scale X", "##Is Scale Y", "##Scale X", localize.get(BASIC_SCALE), isScaleX, isScaleY, 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 R", "##Is Tint G", "##Is Tint B", "##Is Tint A", "##Tint R", "##Tint G", "##Tint B",
|
||||
"##Tint A", localize.get(BASIC_TINT), isTintR, isTintG, isTintB, isTintA, tint);
|
||||
color3_value("##Is Color Offset R", "##Is Color Offset G", "##Is Color Offset B", "##Color Offset R",
|
||||
"##Color Offset B", "##Color Offset G", localize.get(BASIC_COLOR_OFFSET), isColorOffsetR,
|
||||
isColorOffsetG, isColorOffsetB, colorOffset);
|
||||
bool_value("##Is Visible", localize.get(BASIC_VISIBLE), isVisibleSet, isVisible);
|
||||
ImGui::SameLine();
|
||||
bool_value("##Is Interpolated", localize.get(BASIC_INTERPOLATED), isInterpolatedSet, isInterpolated);
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
auto frame_change = [&](anm2::ChangeType type)
|
||||
{
|
||||
anm2::FrameChange frameChange;
|
||||
if (isCropX) frameChange.cropX = crop.x;
|
||||
if (isCropY) frameChange.cropY = crop.y;
|
||||
if (isSizeX) frameChange.sizeX = size.x;
|
||||
if (isSizeY) frameChange.sizeY = size.y;
|
||||
if (isPositionX) frameChange.positionX = position.x;
|
||||
if (isPositionY) frameChange.positionY = position.y;
|
||||
if (isPivotX) frameChange.pivotX = pivot.x;
|
||||
if (isPivotY) frameChange.pivotY = pivot.y;
|
||||
if (isScaleX) frameChange.scaleX = scale.x;
|
||||
if (isScaleY) frameChange.scaleY = scale.y;
|
||||
if (isRotation) frameChange.rotation = std::make_optional(rotation);
|
||||
if (isDuration) frameChange.duration = std::make_optional(duration);
|
||||
if (isTintR) frameChange.tintR = tint.r;
|
||||
if (isTintG) frameChange.tintG = tint.g;
|
||||
if (isTintB) frameChange.tintB = tint.b;
|
||||
if (isTintA) frameChange.tintA = tint.a;
|
||||
if (isColorOffsetR) frameChange.colorOffsetR = colorOffset.r;
|
||||
if (isColorOffsetG) frameChange.colorOffsetG = colorOffset.g;
|
||||
if (isColorOffsetB) frameChange.colorOffsetB = colorOffset.b;
|
||||
if (isVisibleSet) frameChange.isVisible = std::make_optional(isVisible);
|
||||
if (isInterpolatedSet) frameChange.isInterpolated = std::make_optional(isInterpolated);
|
||||
|
||||
DOCUMENT_EDIT(document, localize.get(EDIT_CHANGE_FRAME_PROPERTIES), Document::FRAMES,
|
||||
document.item_get()->frames_change(frameChange, type, *frames.begin(), (int)frames.size()));
|
||||
|
||||
isChanged = true;
|
||||
};
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
bool isAnyProperty = isCropX || isCropY || isSizeX || isSizeY || isPositionX || isPositionY || isPivotX ||
|
||||
isPivotY || isScaleX || isScaleY || isRotation || isDuration || isTintR || isTintG ||
|
||||
isTintB || isTintA || isColorOffsetR || isColorOffsetG || isColorOffsetB || 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::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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "document.h"
|
||||
#include "settings.h"
|
||||
|
||||
namespace anm2ed::imgui::wizard
|
||||
{
|
||||
class ChangeAllFrameProperties
|
||||
{
|
||||
public:
|
||||
bool isChanged{};
|
||||
|
||||
void update(Document&, Settings&);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
#include "configure.h"
|
||||
|
||||
#include "imgui_.h"
|
||||
|
||||
using namespace anm2ed::types;
|
||||
|
||||
namespace anm2ed::imgui::wizard
|
||||
{
|
||||
void Configure::reset(Settings& settings) { temporary = settings; }
|
||||
|
||||
void Configure::update(Manager& manager, Settings& settings)
|
||||
{
|
||||
isSet = false;
|
||||
|
||||
auto childSize = size_without_footer_get(2);
|
||||
|
||||
if (ImGui::BeginTabBar("##Configure Tabs"))
|
||||
{
|
||||
if (ImGui::BeginTabItem(localize.get(LABEL_DISPLAY)))
|
||||
{
|
||||
if (ImGui::BeginChild("##Tab Child", childSize, true))
|
||||
{
|
||||
ImGui::SeparatorText(localize.get(LABEL_WINDOW_MENU));
|
||||
input_float_range(localize.get(LABEL_UI_SCALE), temporary.uiScale, 0.5f, 2.0f, 0.25f, 0.25f, "%.2f");
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_UI_SCALE));
|
||||
ImGui::Checkbox(localize.get(LABEL_VSYNC), &temporary.isVsync);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_VSYNC));
|
||||
|
||||
ImGui::SeparatorText(localize.get(LABEL_LOCALIZATION));
|
||||
ImGui::Combo(localize.get(LABEL_LANGUAGE), &temporary.language, LANGUAGE_STRINGS, LANGUAGE_COUNT);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_LANGUAGE));
|
||||
|
||||
ImGui::SeparatorText(localize.get(LABEL_THEME));
|
||||
|
||||
for (int i = 0; i < theme::COUNT; i++)
|
||||
{
|
||||
ImGui::RadioButton(localize.get(theme::STRINGS[i]), &temporary.theme, i);
|
||||
ImGui::SameLine();
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui::BeginTabItem(localize.get(LABEL_FILE_MENU)))
|
||||
{
|
||||
if (ImGui::BeginChild("##Tab Child", childSize, true))
|
||||
{
|
||||
ImGui::SeparatorText(localize.get(LABEL_AUTOSAVE));
|
||||
|
||||
ImGui::Checkbox(localize.get(BASIC_ENABLED), &temporary.fileIsAutosave);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_AUTOSAVE_ENABLED));
|
||||
|
||||
ImGui::BeginDisabled(!temporary.fileIsAutosave);
|
||||
input_int_range(localize.get(LABEL_TIME_MINUTES), temporary.fileAutosaveTime, 0, 10);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_AUTOSAVE_INTERVAL));
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::SeparatorText(localize.get(LABEL_SNAPSHOTS));
|
||||
input_int_range(localize.get(LABEL_STACK_SIZE), temporary.fileSnapshotStackSize, 0, 100);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_STACK_SIZE));
|
||||
|
||||
ImGui::SeparatorText(localize.get(LABEL_OPTIONS));
|
||||
ImGui::Checkbox(localize.get(LABEL_OVERWRITE_WARNING), &temporary.fileIsWarnOverwrite);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_OVERWRITE_WARNING));
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui::BeginTabItem(localize.get(LABEL_INPUT)))
|
||||
{
|
||||
if (ImGui::BeginChild("##Tab Child", childSize, true))
|
||||
{
|
||||
ImGui::SeparatorText(localize.get(LABEL_KEYBOARD));
|
||||
|
||||
input_float_range(localize.get(LABEL_REPEAT_DELAY), temporary.keyboardRepeatDelay, 0.05f, 1.0f, 0.05f, 0.05f,
|
||||
"%.2f");
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_REPEAT_DELAY));
|
||||
|
||||
input_float_range(localize.get(LABEL_REPEAT_RATE), temporary.keyboardRepeatRate, 0.005f, 1.0f, 0.005f, 0.005f,
|
||||
"%.3f");
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_REPEAT_DELAY));
|
||||
|
||||
ImGui::SeparatorText(localize.get(LABEL_ZOOM));
|
||||
|
||||
input_float_range(localize.get(LABEL_ZOOM_STEP), temporary.inputZoomStep, 10.0f, 250.0f, 10.0f, 10.0f,
|
||||
"%.0f%%");
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_ZOOM_STEP));
|
||||
|
||||
ImGui::SeparatorText(localize.get(LABEL_TOOL));
|
||||
|
||||
ImGui::Checkbox(localize.get(LABEL_MOVE_TOOL_SNAP), &temporary.inputIsMoveToolSnapToMouse);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_MOVE_TOOL_SNAP));
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui::BeginTabItem(localize.get(LABEL_SHORTCUTS_TAB)))
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2());
|
||||
|
||||
if (ImGui::BeginChild("##Tab Child", childSize, true))
|
||||
{
|
||||
if (ImGui::BeginTable(localize.get(LABEL_SHORTCUTS_TAB), 2,
|
||||
ImGuiTableFlags_Borders | ImGuiTableFlags_ScrollY))
|
||||
{
|
||||
ImGui::TableSetupScrollFreeze(0, 1);
|
||||
ImGui::TableSetupColumn(localize.get(LABEL_SHORTCUT_COLUMN));
|
||||
ImGui::TableSetupColumn(localize.get(LABEL_VALUE_COLUMN));
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
for (int i = 0; i < SHORTCUT_COUNT; ++i)
|
||||
{
|
||||
bool isSelected = selectedShortcut == i;
|
||||
|
||||
ShortcutMember member = SHORTCUT_MEMBERS[i];
|
||||
std::string* settingString = &(temporary.*member);
|
||||
std::string chordString = isSelected ? "" : *settingString;
|
||||
|
||||
ImGui::PushID(i);
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
ImGui::TextUnformatted(localize.get(::anm2ed::SHORTCUT_STRING_TYPES[i]));
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
|
||||
if (ImGui::Selectable(chordString.c_str(), isSelected)) selectedShortcut = i;
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
if (isSelected)
|
||||
{
|
||||
ImGuiKeyChord chord{ImGuiKey_None};
|
||||
|
||||
if (ImGui::IsKeyDown(ImGuiMod_Ctrl)) chord |= ImGuiMod_Ctrl;
|
||||
if (ImGui::IsKeyDown(ImGuiMod_Shift)) chord |= ImGuiMod_Shift;
|
||||
if (ImGui::IsKeyDown(ImGuiMod_Alt)) chord |= ImGuiMod_Alt;
|
||||
if (ImGui::IsKeyDown(ImGuiMod_Super)) chord |= ImGuiMod_Super;
|
||||
|
||||
for (const auto& entry : KEY_MAP)
|
||||
{
|
||||
auto key = entry.second;
|
||||
if (ImGui::IsKeyPressed(key))
|
||||
{
|
||||
chord |= key;
|
||||
*settingString = chord_to_string(chord);
|
||||
selectedShortcut = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
|
||||
auto widgetSize = widget_size_with_row_get(3);
|
||||
|
||||
if (ImGui::Button(localize.get(BASIC_SAVE), widgetSize))
|
||||
{
|
||||
settings = temporary;
|
||||
|
||||
ImGui::GetIO().KeyRepeatDelay = settings.keyboardRepeatDelay;
|
||||
ImGui::GetIO().KeyRepeatRate = settings.keyboardRepeatRate;
|
||||
ImGui::GetStyle().FontScaleMain = settings.uiScale;
|
||||
SnapshotStack::max_size_set(settings.fileSnapshotStackSize);
|
||||
imgui::theme_set((theme::Type)settings.theme);
|
||||
localize.language = (Language)settings.language;
|
||||
manager.chords_set(settings);
|
||||
|
||||
for (auto& document : manager.documents)
|
||||
document.snapshots.apply_limit();
|
||||
|
||||
isSet = true;
|
||||
}
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_SETTINGS_SAVE));
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button(localize.get(LABEL_USE_DEFAULT_SETTINGS), widgetSize)) temporary = Settings();
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_USE_DEFAULT_SETTINGS));
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button(localize.get(LABEL_CLOSE), widgetSize)) isSet = true;
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_CLOSE_SETTINGS));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "manager.h"
|
||||
|
||||
namespace anm2ed::imgui::wizard
|
||||
{
|
||||
class Configure
|
||||
{
|
||||
Settings temporary{};
|
||||
int selectedShortcut{-1};
|
||||
|
||||
public:
|
||||
bool isSet{};
|
||||
|
||||
void reset(Settings&);
|
||||
void update(Manager&, Settings&);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
#include "generate_animation_from_grid.h"
|
||||
|
||||
#include "math_.h"
|
||||
#include "types.h"
|
||||
|
||||
using namespace anm2ed::types;
|
||||
using namespace anm2ed::util;
|
||||
using namespace glm;
|
||||
|
||||
namespace anm2ed::imgui::wizard
|
||||
{
|
||||
GenerateAnimationFromGrid::GenerateAnimationFromGrid() : Canvas(vec2()) {}
|
||||
|
||||
void GenerateAnimationFromGrid::update(Document& document, Resources& resources, Settings& settings)
|
||||
{
|
||||
isEnd = false;
|
||||
|
||||
auto& startPosition = settings.generateStartPosition;
|
||||
auto& size = settings.generateSize;
|
||||
auto& pivot = settings.generatePivot;
|
||||
auto& rows = settings.generateRows;
|
||||
auto& columns = settings.generateColumns;
|
||||
auto& count = settings.generateCount;
|
||||
auto& delay = settings.generateDuration;
|
||||
auto& zoom = settings.generateZoom;
|
||||
auto& zoomStep = settings.inputZoomStep;
|
||||
|
||||
auto childSize = ImVec2(row_widget_width_get(2), size_without_footer_get().y);
|
||||
|
||||
if (ImGui::BeginChild("##Options Child", childSize, ImGuiChildFlags_Borders))
|
||||
{
|
||||
ImGui::InputInt2(localize.get(LABEL_GENERATE_START_POSITION), value_ptr(startPosition));
|
||||
ImGui::InputInt2(localize.get(LABEL_GENERATE_FRAME_SIZE), value_ptr(size));
|
||||
ImGui::InputInt2(localize.get(BASIC_PIVOT), value_ptr(pivot));
|
||||
ImGui::InputInt(localize.get(LABEL_GENERATE_ROWS), &rows, STEP, STEP_FAST);
|
||||
ImGui::InputInt(localize.get(LABEL_GENERATE_COLUMNS), &columns, STEP, STEP_FAST);
|
||||
|
||||
input_int_range(localize.get(LABEL_GENERATE_COUNT), count, anm2::FRAME_NUM_MIN, rows * columns);
|
||||
|
||||
ImGui::InputInt(localize.get(BASIC_DURATION), &delay, STEP, STEP_FAST);
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::BeginChild("##Preview Child", childSize, ImGuiChildFlags_Borders))
|
||||
{
|
||||
auto& backgroundColor = settings.previewBackgroundColor;
|
||||
auto& shaderTexture = resources.shaders[resource::shader::TEXTURE];
|
||||
|
||||
auto previewSize = ImVec2(ImGui::GetContentRegionAvail().x, size_without_footer_get(2).y);
|
||||
|
||||
bind();
|
||||
size_set(to_vec2(previewSize));
|
||||
viewport_set();
|
||||
clear(vec4(backgroundColor, 1.0f));
|
||||
|
||||
if (document.reference.itemType == anm2::LAYER)
|
||||
{
|
||||
auto& texture =
|
||||
document.anm2.content.spritesheets[document.anm2.content.layers[document.reference.itemID].spritesheetID]
|
||||
.texture;
|
||||
|
||||
auto index = std::clamp((int)(time * (count - 1)), 0, (count - 1));
|
||||
auto row = index / columns;
|
||||
auto column = index % columns;
|
||||
auto crop = startPosition + ivec2(size.x * column, size.y * row);
|
||||
auto uvMin = (vec2(crop) + vec2(0.5f)) / vec2(texture.size);
|
||||
auto uvMax = (vec2(crop) + vec2(size) - vec2(0.5f)) / vec2(texture.size);
|
||||
|
||||
mat4 transform = transform_get(zoom) * math::quad_model_get(size, {}, pivot);
|
||||
|
||||
texture_render(shaderTexture, texture.id, transform, vec4(1.0f), {},
|
||||
math::uv_vertices_get(uvMin, uvMax).data());
|
||||
}
|
||||
|
||||
unbind();
|
||||
|
||||
ImGui::Image(texture, previewSize);
|
||||
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
ImGui::SliderFloat("##Time", &time, 0.0f, 1.0f, "");
|
||||
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
ImGui::InputFloat("##Zoom", &zoom, zoomStep, zoomStep, "%.0f%%");
|
||||
zoom = glm::clamp(zoom, ZOOM_MIN, ZOOM_MAX);
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
|
||||
auto widgetSize = widget_size_with_row_get(2);
|
||||
|
||||
if (ImGui::Button(localize.get(LABEL_GENERATE), widgetSize))
|
||||
{
|
||||
auto generate_from_grid = [&]()
|
||||
{
|
||||
auto item = document.item_get();
|
||||
auto animation = document.animation_get();
|
||||
|
||||
if (item && animation)
|
||||
{
|
||||
item->frames_generate_from_grid(startPosition, size, pivot, columns, count, delay);
|
||||
animation->frameNum = animation->length();
|
||||
}
|
||||
};
|
||||
|
||||
DOCUMENT_EDIT(document, localize.get(EDIT_GENERATE_ANIMATION_FROM_GRID), Document::FRAMES, generate_from_grid());
|
||||
isEnd = true;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button(localize.get(BASIC_CANCEL), widgetSize)) isEnd = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "canvas.h"
|
||||
#include "document.h"
|
||||
#include "resources.h"
|
||||
#include "settings.h"
|
||||
|
||||
namespace anm2ed::imgui::wizard
|
||||
{
|
||||
class GenerateAnimationFromGrid : public Canvas
|
||||
{
|
||||
float time{};
|
||||
|
||||
public:
|
||||
bool isEnd{};
|
||||
|
||||
GenerateAnimationFromGrid();
|
||||
void update(Document&, Resources&, Settings&);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
#include "render_animation.h"
|
||||
|
||||
#include <ranges>
|
||||
|
||||
#include "log.h"
|
||||
#include "path_.h"
|
||||
#include "process_.h"
|
||||
#include "toast.h"
|
||||
|
||||
#include <ranges>
|
||||
|
||||
using namespace anm2ed::resource;
|
||||
using namespace anm2ed::util;
|
||||
|
||||
namespace anm2ed::imgui::wizard
|
||||
{
|
||||
void RenderAnimation::range_to_animation_set(Manager& manager, Document& document)
|
||||
{
|
||||
if (auto animation = document.animation_get())
|
||||
{
|
||||
manager.recordingStart = 0;
|
||||
manager.recordingEnd = animation->frameNum - 1;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderAnimation::range_to_frames_set(Manager& manager, Document& document)
|
||||
{
|
||||
auto& frames = document.frames.selection;
|
||||
if (!frames.empty())
|
||||
{
|
||||
if (auto item = document.item_get())
|
||||
{
|
||||
int duration{};
|
||||
for (auto [i, frame] : std::views::enumerate(item->frames))
|
||||
{
|
||||
if ((int)i == *frames.begin()) manager.recordingStart = duration;
|
||||
if ((int)i == *frames.rbegin()) manager.recordingEnd = duration + frame.duration - 1;
|
||||
|
||||
duration += frame.duration;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderAnimation::reset(Manager& manager, Document& document, Settings& settings)
|
||||
{
|
||||
if (!manager.isRecordingRange) range_to_animation_set(manager, document);
|
||||
settings.renderPath.replace_extension(render::EXTENSIONS[settings.renderType]);
|
||||
}
|
||||
|
||||
void RenderAnimation::update(Manager& manager, Document& document, Resources& resources, Settings& settings,
|
||||
Dialog& dialog)
|
||||
{
|
||||
isEnd = false;
|
||||
|
||||
auto animation = document.animation_get();
|
||||
if (!animation) return;
|
||||
|
||||
auto& ffmpegPath = settings.renderFFmpegPath;
|
||||
auto& path = settings.renderPath;
|
||||
auto& format = settings.renderFormat;
|
||||
auto& scale = settings.renderScale;
|
||||
auto& isRaw = settings.renderIsRawAnimation;
|
||||
auto& type = settings.renderType;
|
||||
auto& start = manager.recordingStart;
|
||||
auto& end = manager.recordingEnd;
|
||||
auto& rows = settings.renderRows;
|
||||
auto& columns = settings.renderColumns;
|
||||
auto& isRange = manager.isRecordingRange;
|
||||
auto& frames = document.frames.selection;
|
||||
auto& reference = document.reference;
|
||||
auto& frameNum = animation->frameNum;
|
||||
|
||||
auto widgetSize = widget_size_with_row_get(2);
|
||||
auto dialogType = type == render::PNGS ? Dialog::PNG_DIRECTORY_SET
|
||||
: type == render::SPRITESHEET ? Dialog::PNG_PATH_SET
|
||||
: type == render::GIF ? Dialog::GIF_PATH_SET
|
||||
: type == render::WEBM ? Dialog::WEBM_PATH_SET
|
||||
: Dialog::NONE;
|
||||
|
||||
if (ImGui::ImageButton("##FFmpeg Path Set", resources.icons[icon::FOLDER].id, icon_size_get()))
|
||||
dialog.file_open(Dialog::FFMPEG_PATH_SET);
|
||||
ImGui::SameLine();
|
||||
input_text_path(localize.get(LABEL_FFMPEG_PATH), &ffmpegPath);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_FFMPEG_PATH));
|
||||
|
||||
if (dialog.is_selected(Dialog::FFMPEG_PATH_SET))
|
||||
{
|
||||
ffmpegPath = path::to_utf8(dialog.path);
|
||||
dialog.reset();
|
||||
}
|
||||
|
||||
if (ImGui::ImageButton("##Path Set", resources.icons[icon::FOLDER].id, icon_size_get()))
|
||||
{
|
||||
if (dialogType == Dialog::PNG_DIRECTORY_SET)
|
||||
dialog.folder_open(dialogType);
|
||||
else
|
||||
dialog.file_save(dialogType);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
auto pathLabel = type == render::PNGS ? LABEL_OUTPUT_DIRECTORY : LABEL_OUTPUT_PATH;
|
||||
input_text_path(localize.get(pathLabel), &path);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_OUTPUT_PATH));
|
||||
|
||||
if (dialog.is_selected(dialogType))
|
||||
{
|
||||
path = path::to_utf8(dialog.path);
|
||||
dialog.reset();
|
||||
}
|
||||
|
||||
if (ImGui::Combo(localize.get(LABEL_TYPE), &type, render::STRINGS, render::COUNT))
|
||||
path.replace_extension(render::EXTENSIONS[type]);
|
||||
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_RENDER_TYPE));
|
||||
|
||||
if (type == render::PNGS || type == render::SPRITESHEET) ImGui::Separator();
|
||||
|
||||
if (type == render::PNGS)
|
||||
{
|
||||
input_text_path(localize.get(LABEL_FORMAT), &format);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_FORMAT));
|
||||
}
|
||||
else if (type == render::SPRITESHEET)
|
||||
{
|
||||
input_int_range(localize.get(LABEL_GENERATE_ROWS), rows, 1, frameNum - 1);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_ROWS));
|
||||
|
||||
input_int_range(localize.get(LABEL_GENERATE_COLUMNS), columns, 1, frameNum - 1);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_COLUMNS));
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Checkbox(localize.get(LABEL_CUSTOM_RANGE), &isRange);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_CUSTOM_RANGE));
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::BeginDisabled(frames.empty() || reference.itemID == anm2::TRIGGER);
|
||||
if (ImGui::Button(localize.get(LABEL_TO_SELECTED_FRAMES))) range_to_frames_set(manager, document);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_TO_SELECTED_FRAMES));
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button(localize.get(LABEL_TO_ANIMATION_RANGE))) range_to_animation_set(manager, document);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_TO_ANIMATION_RANGE));
|
||||
|
||||
ImGui::BeginDisabled(!isRange);
|
||||
{
|
||||
input_int_range(localize.get(LABEL_START), start, 0, frameNum - 1);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_START));
|
||||
input_int_range(localize.get(LABEL_END), end, start, frameNum - 1);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_END));
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Checkbox(localize.get(LABEL_RAW), &isRaw);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_RAW));
|
||||
|
||||
ImGui::BeginDisabled(!isRaw);
|
||||
{
|
||||
input_float_range(localize.get(BASIC_SCALE), scale, 1.0f, 100.0f, STEP, STEP_FAST, "%.1fx");
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_SCALE_OUTPUT));
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Checkbox(localize.get(LABEL_SOUND), &settings.timelineIsSound);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_SOUND));
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::Button(localize.get(LABEL_RENDER), widgetSize))
|
||||
{
|
||||
path.replace_extension(render::EXTENSIONS[type]);
|
||||
|
||||
auto render_is_valid = [&]()
|
||||
{
|
||||
auto ffmpeg_is_valid = [&]()
|
||||
{
|
||||
if (!path::is_executable(ffmpegPath)) return false;
|
||||
|
||||
auto testCommand = ffmpegPath.string() + " -version";
|
||||
Process process(testCommand.c_str(), "r");
|
||||
auto result = process.output_get_and_close();
|
||||
|
||||
if (!result.contains("ffmpeg version")) return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
auto ffmpeg_valid_check = [&]()
|
||||
{
|
||||
if (!ffmpeg_is_valid())
|
||||
{
|
||||
toasts.push(localize.get(TOAST_INVALID_FFMPEG));
|
||||
logger.error(localize.get(TOAST_INVALID_FFMPEG, anm2ed::ENGLISH));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
auto png_format_valid_check = [&]()
|
||||
{
|
||||
if (!format.string().contains("{}"))
|
||||
{
|
||||
toasts.push(localize.get(TOAST_PNG_FORMAT_INVALID));
|
||||
logger.error(localize.get(TOAST_PNG_FORMAT_INVALID, anm2ed::ENGLISH));
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
auto path_valid_check = [&]()
|
||||
{
|
||||
if (path.empty())
|
||||
{
|
||||
toasts.push(localize.get(TOAST_RENDER_PATH_EMPTY));
|
||||
logger.error(localize.get(TOAST_RENDER_PATH_EMPTY, anm2ed::ENGLISH));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
auto png_directory_valid_check = [&]()
|
||||
{
|
||||
if (!path::ensure_directory(path))
|
||||
{
|
||||
toasts.push(localize.get(TOAST_PNG_DIRECTORY_INVALID));
|
||||
logger.error(localize.get(TOAST_PNG_DIRECTORY_INVALID, anm2ed::ENGLISH));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
auto spritesheet_valid_check = [&]()
|
||||
{
|
||||
if (rows <= 0 && columns <= 0)
|
||||
{
|
||||
toasts.push(localize.get(TOAST_RENDER_PATH_EMPTY));
|
||||
logger.error(localize.get(TOAST_RENDER_PATH_EMPTY, anm2ed::ENGLISH));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
if (!path_valid_check()) return false;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case render::PNGS:
|
||||
if (!png_directory_valid_check()) return false;
|
||||
if (!png_format_valid_check()) return false;
|
||||
format.replace_extension(render::EXTENSIONS[render::SPRITESHEET]);
|
||||
break;
|
||||
case render::SPRITESHEET:
|
||||
if (!spritesheet_valid_check()) return false;
|
||||
break;
|
||||
case render::GIF:
|
||||
case render::WEBM:
|
||||
case render::MP4:
|
||||
if (!ffmpeg_valid_check()) return false;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
if (render_is_valid())
|
||||
{
|
||||
manager.isRecordingStart = true;
|
||||
manager.progressPopup.open();
|
||||
}
|
||||
|
||||
isEnd = true;
|
||||
}
|
||||
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_RENDER_BUTTON));
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button(localize.get(BASIC_CANCEL), widgetSize)) isEnd = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "dialog.h"
|
||||
#include "manager.h"
|
||||
#include "resources.h"
|
||||
|
||||
namespace anm2ed::imgui::wizard
|
||||
{
|
||||
class RenderAnimation
|
||||
{
|
||||
|
||||
public:
|
||||
bool isEnd{};
|
||||
|
||||
void range_to_frames_set(Manager&, Document&);
|
||||
void range_to_animation_set(Manager&, Document&);
|
||||
void reset(Manager&, Document&, Settings&);
|
||||
void update(Manager&, Document&, Resources&, Settings&, Dialog&);
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user