From a1bdbeba1c95463f9460c0dc15a172910c2605c2 Mon Sep 17 00:00:00 2001 From: shweet Date: Sun, 3 May 2026 11:22:42 -0400 Subject: [PATCH] transparency for animation preview, QoL, change raw animation --- compile_commands.json | 2 +- src/framebuffer.cpp | 2 +- src/imgui/window/animation_preview.cpp | 70 +++++++++++++------ src/imgui/window/timeline.cpp | 5 +- .../wizard/generate_animation_from_grid.cpp | 8 ++- src/resource/strings.hpp | 4 +- src/settings.hpp | 1 + workshop/metadata.xml | 2 +- 8 files changed, 66 insertions(+), 28 deletions(-) diff --git a/compile_commands.json b/compile_commands.json index e2be980..bc0dce8 120000 --- a/compile_commands.json +++ b/compile_commands.json @@ -1 +1 @@ -/home/anon/sda/Personal/Repos/anm2ed/out/build/linux-release/compile_commands.json \ No newline at end of file +/home/anon/sda/Personal/Repos/anm2ed/out/build/linux-debug/compile_commands.json \ No newline at end of file diff --git a/src/framebuffer.cpp b/src/framebuffer.cpp index eb393b7..ce6ab44 100644 --- a/src/framebuffer.cpp +++ b/src/framebuffer.cpp @@ -78,7 +78,7 @@ namespace anm2ed glClearColor(color.r, color.g, color.b, color.a); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - if (color.a == 0.0f) glDisable(GL_BLEND); + if (color.a <= 0.0f) glDisable(GL_BLEND); } bool Framebuffer::is_valid() const { return fbo != 0; } diff --git a/src/imgui/window/animation_preview.cpp b/src/imgui/window/animation_preview.cpp index 9d0047d..5bb262b 100644 --- a/src/imgui/window/animation_preview.cpp +++ b/src/imgui/window/animation_preview.cpp @@ -437,6 +437,7 @@ namespace anm2ed::imgui auto& pan = document.previewPan; auto& zoom = document.previewZoom; auto& backgroundColor = settings.previewBackgroundColor; + auto& isTransparent = settings.animationPreviewTransparent; auto& axesColor = settings.previewAxesColor; auto& gridColor = settings.previewGridColor; auto& gridSize = settings.previewGridSize; @@ -488,10 +489,10 @@ namespace anm2ed::imgui auto center_view = [&]() { pan = vec2(); }; - auto fit_view = [&]() - { - if (animation) set_to_rect(zoom, pan, anm2.animation_rect(*animation, isRootTransform)); - }; + auto fit_view = [&]() + { + if (animation) set_to_rect(zoom, pan, anm2.animation_rect(*animation, isRootTransform)); + }; auto zoom_adjust = [&](float delta) { @@ -548,10 +549,27 @@ namespace anm2ed::imgui if (ImGui::Button(localize.get(LABEL_FIT), widgetSize)) fit_view(); set_item_tooltip_shortcut(localize.get(TOOLTIP_FIT), settings.shortcutFit); + auto readoutSize = ImVec2(row_widget_width_get(2), ImGui::GetTextLineHeightWithSpacing()); auto mousePosInt = ivec2(mousePos); - ImGui::TextUnformatted( - std::vformat(localize.get(FORMAT_POSITION_SPACED), std::make_format_args(mousePosInt.x, mousePosInt.y)) - .c_str()); + auto positionText = + std::vformat(localize.get(FORMAT_POSITION_SPACED), std::make_format_args(mousePosInt.x, mousePosInt.y)); + if (ImGui::BeginChild("##Position Readout", readoutSize, false, ImGuiWindowFlags_NoScrollbar)) + { + ImGui::TextUnformatted(positionText.c_str()); + if (ImGui::IsItemHovered()) ImGui::SetTooltip("%s", positionText.c_str()); + } + ImGui::EndChild(); + + ImGui::SameLine(); + + auto sizeInt = ivec2(size); + auto sizeText = std::vformat(localize.get(FORMAT_SIZE_SPACED), std::make_format_args(sizeInt.x, sizeInt.y)); + if (ImGui::BeginChild("##Size Readout", readoutSize, false, ImGuiWindowFlags_NoScrollbar)) + { + ImGui::TextUnformatted(sizeText.c_str()); + if (ImGui::IsItemHovered()) ImGui::SetTooltip("%s", sizeText.c_str()); + } + ImGui::EndChild(); } ImGui::EndChild(); @@ -559,9 +577,13 @@ namespace anm2ed::imgui if (ImGui::BeginChild("##Background Child", childSize, true, ImGuiWindowFlags_HorizontalScrollbar)) { - ImGui::ColorEdit3(localize.get(LABEL_BACKGROUND_COLOR), value_ptr(backgroundColor), - ImGuiColorEditFlags_NoInputs); - ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_BACKGROUND_COLOR)); + ImGui::BeginDisabled(isTransparent); + { + ImGui::ColorEdit3(localize.get(LABEL_BACKGROUND_COLOR), value_ptr(backgroundColor), + ImGuiColorEditFlags_NoInputs); + ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_BACKGROUND_COLOR)); + } + ImGui::EndDisabled(); ImGui::SameLine(); ImGui::Checkbox(localize.get(LABEL_AXES), &isAxes); ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_AXES)); @@ -589,6 +611,8 @@ namespace anm2ed::imgui ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_ROOT_TRANSFORM)); ImGui::Checkbox(localize.get(LABEL_PIVOTS), &isPivots); ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_PIVOTS)); + ImGui::Checkbox(localize.get(LABEL_TRANSPARENT), &isTransparent); + ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_PREVIEW_TRANSPARENT)); } ImGui::EndChild(); @@ -615,14 +639,6 @@ namespace anm2ed::imgui if (settings.renderIsRawAnimation) { - settings.previewBackgroundColor = vec4(); - settings.previewIsGrid = false; - settings.previewIsAxes = false; - settings.previewIsPivots = false; - settings.previewIsBorder = false; - settings.timelineIsOnlyShowLayers = true; - settings.onionskinIsEnabled = false; - savedOverlayIndex = overlayIndex; savedZoom = zoom; savedPan = pan; @@ -673,11 +689,23 @@ namespace anm2ed::imgui playback.time = manager.recordingStart; } - if (isSizeTrySet) size_set(to_vec2(ImGui::GetContentRegionAvail())); + if (isSizeTrySet) + { + auto nextSize = to_vec2(ImGui::GetContentRegionAvail()); + bool isCanvasResized = ivec2(nextSize) != ivec2(size); + size_set(nextSize); + if (isCanvasResized && ImGui::IsMouseDragging(ImGuiMouseButton_Left)) + { + auto resizeSizeInt = ivec2(size); + auto resizeSizeText = + std::vformat(localize.get(FORMAT_SIZE_SPACED), std::make_format_args(resizeSizeInt.x, resizeSizeInt.y)); + ImGui::SetTooltip("%s", resizeSizeText.c_str()); + } + } bind(); viewport_set(); - clear(manager.isRecording && settings.renderIsRawAnimation ? vec4(0) : vec4(backgroundColor, 1.0f)); + clear(isTransparent ? vec4(0) : vec4(backgroundColor, 1.0f)); if (isAxes) axes_render(shaderAxes, zoom, pan, axesColor); if (isGrid) grid_render(shaderGrid, zoom, pan, gridSize, gridOffset, gridColor); @@ -913,7 +941,7 @@ namespace anm2ed::imgui unbind(); - if (manager.isRecording && settings.renderIsRawAnimation) + if (isTransparent) { sync_checker_pan(); render_checker_background(ImGui::GetWindowDrawList(), min, max, -size - checkerPan, CHECKER_SIZE); diff --git a/src/imgui/window/timeline.cpp b/src/imgui/window/timeline.cpp index dc22786..d8a0e06 100644 --- a/src/imgui/window/timeline.cpp +++ b/src/imgui/window/timeline.cpp @@ -1293,9 +1293,10 @@ namespace anm2ed::imgui } } - if (ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) && ImGui::IsMouseDown(0)) + if (ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) && + ImGui::IsMouseClicked(ImGuiMouseButton_Left)) { - if (!isDragging) playback_stop(); + playback_stop(); isDragging = true; } diff --git a/src/imgui/wizard/generate_animation_from_grid.cpp b/src/imgui/wizard/generate_animation_from_grid.cpp index 6d8bec2..a61852b 100644 --- a/src/imgui/wizard/generate_animation_from_grid.cpp +++ b/src/imgui/wizard/generate_animation_from_grid.cpp @@ -46,14 +46,17 @@ namespace anm2ed::imgui::wizard if (ImGui::BeginChild("##Preview Child", childSize, ImGuiChildFlags_Borders)) { auto& backgroundColor = settings.previewBackgroundColor; + auto& isTransparent = settings.animationPreviewTransparent; auto& shaderTexture = resources.shaders[resource::shader::TEXTURE]; auto previewSize = ImVec2(ImGui::GetContentRegionAvail().x, size_without_footer_get(2).y); + auto previewMin = ImGui::GetCursorScreenPos(); + auto previewMax = to_imvec2(to_vec2(previewMin) + to_vec2(previewSize)); bind(); size_set(to_vec2(previewSize)); viewport_set(); - clear(vec4(backgroundColor, 1.0f)); + clear(isTransparent ? vec4(0) : vec4(backgroundColor, 1.0f)); if (document.reference.itemType == anm2::LAYER) { @@ -82,6 +85,9 @@ namespace anm2ed::imgui::wizard unbind(); + if (isTransparent) + render_checker_background(ImGui::GetWindowDrawList(), previewMin, previewMax, -to_vec2(previewSize) * 0.5f, + CHECKER_SIZE); ImGui::Image(texture, previewSize); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); diff --git a/src/resource/strings.hpp b/src/resource/strings.hpp index 2d4b6b0..c46ac2e 100644 --- a/src/resource/strings.hpp +++ b/src/resource/strings.hpp @@ -200,7 +200,8 @@ namespace anm2ed X(FORMAT_NULL, "#{0} {1}", "#{0} {1}", "#{0} {1}", "#{0} {1}", "#{0} {1}") \ X(FORMAT_PIVOT, "Pivot: ({0}, {1})", "Pivote", "Точка вращения: ({0}, {1})", "枢轴: ({0}, {1})", "중심점: ({0}, {1})") \ X(FORMAT_POSITION, "Position: ({0}, {1})", "Posicion: ({0}, {1})", "Позиция: ({0}, {1})", "位置: ({0}, {1})", "위치: ({0}, {1})") \ - X(FORMAT_POSITION_SPACED, "Position: ({0:8}, {1:8})", "Posicion: ({0:8}, {1:8})", "Позиция: ({0:8}, {1:8})", "位置: ({0:8}, {1:8})", "위치: ({0:8}, {1:8})") \ + X(FORMAT_POSITION_SPACED, "Position: ({0:3}, {1:3})", "Posicion: ({0:3}, {1:3})", "Позиция: ({0:3}, {1:3})", "位置: ({0:3}, {1:3})", "위치: ({0:3}, {1:3})") \ + X(FORMAT_SIZE_SPACED, "Size: ({0:3}, {1:3})", "Tamaño: ({0:3}, {1:3})", "Размер: ({0:3}, {1:3})", "大小: ({0:3}, {1:3})", "크기: ({0:3}, {1:3})") \ X(FORMAT_ROTATION, "Rotation: {0}", "Rotacion: {0}", "Поворот: {0}", "旋转: {0}", "회전: {0}") \ X(FORMAT_SCALE, "Scale: ({0}, {1})", "Escalar: ({0}, {1})", "Масштаб: ({0}, {1})", "缩放: ({0}, {1})", "비율: ({0}, {1})") \ X(FORMAT_SIZE, "Size: ({0}, {1})", "Tamaño: ({0}, {1})", "Размер: ({0}, {1})", "大小: ({0}, {1})", "크기: ({0}, {1})") \ @@ -608,6 +609,7 @@ namespace anm2ed X(TOOLTIP_PLAY_ANIMATION, "Play the animation.", "Reproduce la animacion.", "Возпроизвести анимацию.", "播放动画.", "애니메이션을 재생합니다.") \ X(TOOLTIP_POSITION, "Change the position of the frame.", "Cambia la posicion del Frame.", "Изменить позицию кадра.", "更改此帧的位置.", "프레임의 위치를 변경합니다.") \ X(TOOLTIP_PREVIEW_ZOOM, "Change the zoom of the preview.", "Cambia el zoom de la vista previa.", "Изменить масштаб предпросмотра.", "更改预览视图的缩放.", "미리보기의 줌을 변경합니다.") \ + X(TOOLTIP_PREVIEW_TRANSPARENT, "Toggle the animation preview background being transparent.", "Alterna la transparencia del fondo de la vista previa de animacion.", "Переключить прозрачность фона предпросмотра анимации.", "切换动画预览背景是否透明.", "애니메이션 미리보기 배경을 투명하게 전환합니다.") \ X(TOOLTIP_RAW, "Record only the raw animation; i.e., only its layers, to its bounds.", "Graba solo la animacion cruda; i. e., Solo sus capas.", "Записывать только «сырую» анимацию, т. е. только ее слои.", "仅保存原生动画; 比如只保存动画层.", "Raw 애니메이션만 녹화합니다. 즉, 레이어만 녹화합니다.") \ X(TOOLTIP_RELOAD_SPRITESHEETS, "Reloads the selected spritesheets.", "Recarga la spritesheet seleccionada.", "Перезагружает выбранные спрайт-листы.", "重新加载所选图集.", "선택한 스프라이트 시트를 다시 불러옵니다.") \ X(TOOLTIP_RELOAD_SOUNDS, "Reloads the selected sounds.", "Recarga los sonidos seleccionados.", "Перезагружает выбранные звуки.", "重新加载所选声音.", "선택한 사운드를 다시 불러옵니다.") \ diff --git a/src/settings.hpp b/src/settings.hpp index 2b3dac8..8de04c9 100644 --- a/src/settings.hpp +++ b/src/settings.hpp @@ -123,6 +123,7 @@ namespace anm2ed X(PREVIEW_IS_PIVOTS, previewIsPivots, STRING_UNDEFINED, BOOL, false) \ X(PREVIEW_IS_BORDER, previewIsBorder, STRING_UNDEFINED, BOOL, false) \ X(PREVIEW_IS_ALT_ICONS, previewIsAltIcons, STRING_UNDEFINED, BOOL, false) \ + X(PREVIEW_IS_TRANSPARENT, animationPreviewTransparent, STRING_UNDEFINED, BOOL, false) \ X(PREVIEW_OVERLAY_TRANSPARENCY, previewOverlayTransparency, STRING_UNDEFINED, FLOAT, 255) \ X(PREVIEW_START_ZOOM, previewStartZoom, STRING_UNDEFINED, FLOAT, 200.0f) \ X(PREVIEW_GRID_SIZE, previewGridSize, STRING_UNDEFINED, IVEC2, {32, 32}) \ diff --git a/workshop/metadata.xml b/workshop/metadata.xml index e35f337..74c8703 100644 --- a/workshop/metadata.xml +++ b/workshop/metadata.xml @@ -53,6 +53,6 @@ Alternatively, if you have subscribed to the mod, you can find the latest releas [h3]Happy animating![/h3] [img]https://files.catbox.moe/4auc1c.gif[/img] - 2.18 + 2.19 Public