Centralize legacy animation bridge
This commit is contained in:
@@ -88,6 +88,8 @@ set(PP_PANOPAINTER_APP_SOURCES
|
||||
set(PP_PANOPAINTER_UI_SOURCES
|
||||
src/legacy_brush_ui_services.cpp
|
||||
src/legacy_brush_ui_services.h
|
||||
src/legacy_document_animation_services.cpp
|
||||
src/legacy_document_animation_services.h
|
||||
src/node_about.cpp
|
||||
src/node_canvas.cpp
|
||||
src/node_changelog.cpp
|
||||
|
||||
@@ -173,6 +173,12 @@ Known local toolchain state:
|
||||
contracts while legacy `Canvas` mode state, transform actions, picking,
|
||||
touch-lock, save/UI/cursor calls, brush-size controls, and history execution
|
||||
remain tracked by `DEBT-0027`.
|
||||
- `src/legacy_document_animation_services.*` is the current UI-shell bridge for
|
||||
animation frame commands, timeline/selected-frame execution, playback ticks,
|
||||
onion-size updates, and play-mode toggles. It keeps those live paths on the
|
||||
`pp_app_core` contracts while legacy `Canvas`/`Layer` frame state, canvas
|
||||
mode, animation-panel timeline/playback fields, and the temporary
|
||||
`NodePanelAnimation` friend adapter remain tracked by `DEBT-0022`.
|
||||
- `src/legacy_brush_ui_services.*` is the current UI-shell bridge for brush
|
||||
color, texture, preset, stroke-refresh, brush texture-list, and stroke-control
|
||||
execution. It keeps those live paths on the `pp_app_core` contracts while
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Modernization Debt Log
|
||||
|
||||
Status: live
|
||||
Last updated: 2026-06-03
|
||||
Last updated: 2026-06-04
|
||||
|
||||
Every shortcut, temporary adapter, retained vendored dependency, skipped
|
||||
platform gate, compatibility shim, or incomplete automation path must be
|
||||
@@ -39,7 +39,7 @@ agent or engineer to remove them without reconstructing context from chat.
|
||||
| DEBT-0019 | Open | Modernization | Unreferenced-parameter warnings are muted globally through `pp_project_warnings` with MSVC `/wd4100` and Clang/GCC `-Wno-unused-parameter` | Legacy callbacks, virtual hooks, serializer methods, and platform/API compatibility functions carry many intentionally unused parameters during the component split; muting this keeps stricter warning builds focused on higher-signal migration issues | `cmake --build --preset windows-msvc-default --config Debug --target PanoPainter`; `ctest --preset desktop-fast --build-config Debug`; `cmake --build --preset linux-clang --target pp_foundation` | Remove `/wd4100` and `-Wno-unused-parameter`, mark intentionally unused parameters with names/comments or `[[maybe_unused]]`, and make the Windows app plus headless Clang/GCC tests pass without unreferenced-parameter warnings |
|
||||
| DEBT-0020 | Open | Modernization | Document resize dialog state, selected-resolution planning, and execution dispatch now consume pure `pp_app_core` through `NodeDialogResize`, `App::dialog_resize`, `pano_cli plan-document-resize`, and the `DocumentResizeServices` boundary, and live resize shares `src/legacy_document_canvas_services.*` with canvas clear commands, but the shared live bridge still calls legacy `Canvas::resize`, updates the legacy app title, and clears legacy `ActionManager` history through the history bridge | Preserve existing layer/frame GPU resize behavior while the document model and canvas execution boundary are extracted incrementally | `pp_app_core_document_resize_tests`; `pano_cli plan-document-resize --current-resolution 2048 --selected-resolution-index 4`; `ctest --preset desktop-fast --build-config Debug` | Document resize execution is owned by injected document/app services with no legacy resize adapter, title shim, or direct `ActionManager` history clearing |
|
||||
| DEBT-0021 | Open | Modernization | Layer rename planning/execution dispatch and layer panel operation planning/execution dispatch now consume pure `pp_app_core` through `App::dialog_layer_rename`, `App::init_sidebar` layer callbacks, `pano_cli plan-layer-rename`, `pano_cli plan-layer-operation`, `DocumentLayerRenameServices`, and `DocumentLayerOperationServices`, and the live execution adapters are centralized in `src/legacy_document_layer_services.*`, but that shared bridge still mutates legacy `Canvas` layer state, `NodeLayer`/`NodePanelLayer`, and `ActionManager` undo entries | Preserve existing UI/canvas behavior while document layer commands and undo history are extracted incrementally | `pp_app_core_document_layer_tests`; `pano_cli plan-layer-rename --old-name Base --new-name Paint`; `pano_cli plan-layer-operation --kind add --layer-count 2 --index 1 --name Paint`; `ctest --preset desktop-fast --build-config Debug` | Layer command execution is owned by the document/app command boundary with legacy `Canvas`/UI nodes acting only as adapters or removed entirely |
|
||||
| DEBT-0022 | Open | Modernization | Animation panel frame command planning, panel action planning, panel-control/timeline execution dispatch, selected-frame click dispatch, playback tick stepping, and play-mode toggles now consume pure `pp_app_core` through `NodePanelAnimation`, `pano_cli plan-animation-operation`, `pano_cli plan-animation-panel-action`, and `DocumentAnimationServices`, and `pp_legacy_ui_core` temporarily links `pp_app_core`, but the live adapter still mutates or reads legacy `Canvas`/`Layer` frame state and canvas mode directly | Preserve existing animation panel behavior while timeline/frame commands move toward the document/app command boundary | `pp_app_core_document_animation_tests`; `pano_cli plan-animation-operation --kind add --frame-count 2 --current-frame 0`; `pano_cli plan-animation-operation --kind select --frame-count 3 --selected-frame 1 --layer-index 2 --layer-id 42`; `pano_cli plan-animation-operation --kind playback --total-duration 5 --current-frame 4 --offset 1`; `pano_cli plan-animation-operation --kind toggle-playback --playing`; `pano_cli plan-animation-panel-action --action next --total-duration 5 --current-frame 4`; `ctest --preset desktop-fast --build-config Debug` | Animation frame/timeline/playback execution is owned by injected document/app timeline services with no legacy `Canvas`/`Layer`/canvas-mode adapter and UI nodes acting only as adapters or removed entirely |
|
||||
| DEBT-0022 | Open | Modernization | Animation panel frame command planning, panel action planning, panel-control/timeline execution dispatch, selected-frame click dispatch, playback tick stepping, and play-mode toggles now consume pure `pp_app_core` through `NodePanelAnimation`, `pano_cli plan-animation-operation`, `pano_cli plan-animation-panel-action`, and `DocumentAnimationServices`; live execution is centralized in `src/legacy_document_animation_services.*`, but that bridge still mutates or reads legacy `Canvas`/`Layer` frame state, canvas mode, animation-panel timeline/playback fields, and uses a temporary `NodePanelAnimation` friend adapter | Preserve existing animation panel behavior while timeline/frame commands move toward the document/app command boundary | `pp_app_core_document_animation_tests`; `pano_cli plan-animation-operation --kind add --frame-count 2 --current-frame 0`; `pano_cli plan-animation-operation --kind select --frame-count 3 --selected-frame 1 --layer-index 2 --layer-id 42`; `pano_cli plan-animation-operation --kind playback --total-duration 5 --current-frame 4 --offset 1`; `pano_cli plan-animation-operation --kind toggle-playback --playing`; `pano_cli plan-animation-panel-action --action next --total-duration 5 --current-frame 4`; `ctest --preset desktop-fast --build-config Debug` | Animation frame/timeline/playback execution is owned by injected document/app timeline services with no legacy `Canvas`/`Layer`/canvas-mode adapter and UI nodes acting only as adapters or removed entirely |
|
||||
| DEBT-0023 | Open | Modernization | Brush/color/preset/stroke-settings UI planning, texture-list add/remove/reorder planning, stroke-panel slider/toggle/blend/reset planning, and execution dispatch now consume pure `pp_app_core` through `App::init_sidebar`, `NodePanelBrush`, `NodePanelStroke`, restored/docked floating-panel callbacks, `pano_cli plan-brush-operation`, `pano_cli plan-brush-texture-list`, `pano_cli plan-brush-stroke-control`, `BrushUiServices`, `BrushTextureListServices`, and `BrushStrokeControlServices`, and live execution is centralized in `src/legacy_brush_ui_services.*`, but the bridge still mutates legacy `Brush`/`Canvas::I`, loads/saves legacy brush texture images, refreshes legacy quick/stroke/color widgets, and uses a temporary `NodePanelBrush` friend adapter to reach private list state | Preserve existing brush UI behavior while brush commands move toward a brush/app/asset command boundary and asset-managed texture selection | `pp_app_core_brush_ui_tests`; `pano_cli plan-brush-operation --kind color --r 0.25 --g 0.5 --b 0.75 --a 1`; `pano_cli plan-brush-operation --kind pattern --path data/patterns/noise.png --thumb data/patterns/thumbs/noise.png`; `pano_cli plan-brush-texture-list --kind add --dir brushes --data-path data --source C:/Temp/soft.png`; `pano_cli plan-brush-stroke-control --kind float --setting tip-size --value 42.5`; `pano_cli plan-brush-stroke-control --kind blend --setting pattern --blend-mode 3`; `ctest --preset desktop-fast --build-config Debug` | Brush color/texture/preset/stroke-settings, texture-list, and stroke-control execution are owned by injected brush/app/asset/UI services with no legacy brush/canvas adapter or `NodePanelBrush` friend access |
|
||||
| DEBT-0024 | Open | Modernization | Grid/heightmap/lightmap UI planning now consumes pure `pp_app_core` through `NodePanelGrid` and `pano_cli plan-grid-operation`, but live execution still performs legacy image loading, OpenGL texture updates, nanort lightmap baking, progress UI, and `Canvas::draw_objects` commit directly | Preserve grid/lightmap behavior while moving renderable grid commands toward app/renderer/document boundaries | `pp_app_core_grid_ui_tests`; `pano_cli plan-grid-operation --kind render --float32 --texture-resolution 1024 --samples 32`; `ctest --preset desktop-fast --build-config Debug` | Grid heightmap/lightmap execution is owned by app/renderer/document services with `NodePanelGrid` acting only as UI adapter |
|
||||
| DEBT-0025 | Open | Modernization | Quick brush/color slot and mini-state planning and execution dispatch now consume pure `pp_app_core` through `NodePanelQuick`, `pano_cli plan-quick-operation`, and the `QuickUiServices` boundary, but the live adapter still mutates legacy quick UI widgets, `Brush` previews, color picker popup state, and preset popup state | Preserve quick-panel behavior while quick brush/color commands move toward a brush/app command boundary with safer automation coverage | `pp_app_core_quick_ui_tests`; `pano_cli plan-quick-operation --kind brush --current-index 0 --slot-index 2`; `pano_cli plan-quick-operation --kind restore --brush-index 2 --color-index 1 --fire-event`; `ctest --preset desktop-fast --build-config Debug` | Quick-panel selection, popup, restore, reset, brush preview, and color execution are owned by injected app/brush/UI services with no legacy quick-panel adapter |
|
||||
|
||||
@@ -515,7 +515,8 @@ state/action planner for goto, next, previous, playback-step, and play-toggle
|
||||
automation without requiring the legacy UI or canvas.
|
||||
Panel-control, timeline, selected-frame click, playback tick, and play-button
|
||||
toggle execution now dispatch through `DocumentAnimationServices` before the
|
||||
legacy `Canvas`/`Layer`/canvas-mode adapter continues.
|
||||
shared `src/legacy_document_animation_services.*` bridge continues legacy
|
||||
`Canvas`/`Layer`/canvas-mode and animation-panel state execution.
|
||||
`pano_cli plan-brush-operation` exposes app-core planning for brush color
|
||||
changes, tip/pattern/dual texture changes, preset brush replacement, and stroke
|
||||
settings refreshes used by the live brush, quick, color, and floating panel
|
||||
|
||||
149
src/legacy_document_animation_services.cpp
Normal file
149
src/legacy_document_animation_services.cpp
Normal file
@@ -0,0 +1,149 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "legacy_document_animation_services.h"
|
||||
|
||||
#include "app.h"
|
||||
#include "canvas.h"
|
||||
#include "node_panel_animation.h"
|
||||
|
||||
namespace pp::panopainter {
|
||||
|
||||
class LegacyDocumentAnimationServices final : public pp::app::DocumentAnimationServices {
|
||||
public:
|
||||
LegacyDocumentAnimationServices(NodePanelAnimation& panel, Layer* layer) noexcept
|
||||
: panel_(panel)
|
||||
, layer_(layer)
|
||||
{
|
||||
}
|
||||
|
||||
void add_frame() override
|
||||
{
|
||||
Canvas::I->layer().add_frame();
|
||||
}
|
||||
|
||||
void duplicate_frame(int selected_frame) override
|
||||
{
|
||||
if (layer_)
|
||||
layer_->duplicate_frame(selected_frame);
|
||||
}
|
||||
|
||||
void remove_frame(int selected_frame, int target_frame) override
|
||||
{
|
||||
if (!layer_)
|
||||
return;
|
||||
layer_->remove_frame(selected_frame);
|
||||
panel_.m_selected_frame_index = target_frame;
|
||||
}
|
||||
|
||||
void set_frame_duration(int selected_frame, int duration) override
|
||||
{
|
||||
if (layer_)
|
||||
layer_->set_frame_duration(selected_frame, duration);
|
||||
}
|
||||
|
||||
int move_frame(int selected_frame, int move_offset) override
|
||||
{
|
||||
if (!layer_)
|
||||
return selected_frame;
|
||||
panel_.m_selected_frame_index = layer_->move_frame_offset(selected_frame, move_offset);
|
||||
return panel_.m_selected_frame_index;
|
||||
}
|
||||
|
||||
void select_frame(std::uint32_t layer_id, int layer_index, int selected_frame) override
|
||||
{
|
||||
panel_.m_selected_frame_layer_id = layer_id;
|
||||
panel_.m_selected_frame_index = selected_frame;
|
||||
panel_.m_timeline->m_frame = selected_frame;
|
||||
}
|
||||
|
||||
void select_layer(int layer_index) override
|
||||
{
|
||||
App::I->layers->handle_layer_selected(App::I->layers->get_layer_at(layer_index));
|
||||
}
|
||||
|
||||
void goto_frame(int target_frame) override
|
||||
{
|
||||
Canvas::I->anim_goto_frame(target_frame);
|
||||
}
|
||||
|
||||
void set_timeline_frame(int target_frame) override
|
||||
{
|
||||
panel_.m_timeline->m_frame = target_frame;
|
||||
}
|
||||
|
||||
void set_onion_size(int onion_size) override
|
||||
{
|
||||
panel_.m_timeline->m_onion_size = onion_size;
|
||||
}
|
||||
|
||||
void capture_playback_restore_mode() override
|
||||
{
|
||||
playback_restore_mode() = Canvas::I->m_current_mode;
|
||||
}
|
||||
|
||||
void enter_playback_camera_mode() override
|
||||
{
|
||||
Canvas::set_mode(kCanvasMode::Camera);
|
||||
}
|
||||
|
||||
void restore_playback_canvas_mode() override
|
||||
{
|
||||
Canvas::set_mode(playback_restore_mode());
|
||||
}
|
||||
|
||||
void set_playback_active(bool active) override
|
||||
{
|
||||
panel_.btn_play->set_active(active);
|
||||
}
|
||||
|
||||
void reset_playback_timer() override
|
||||
{
|
||||
panel_.m_playback_timer = 0;
|
||||
}
|
||||
|
||||
void set_playback_idle_ms(int idle_ms) override
|
||||
{
|
||||
App::I->idle_ms = idle_ms;
|
||||
}
|
||||
|
||||
void update_canvas_animation() override
|
||||
{
|
||||
Canvas::I->anim_update();
|
||||
}
|
||||
|
||||
void update_frame_status() override
|
||||
{
|
||||
panel_.update_frames();
|
||||
}
|
||||
|
||||
void reload_animation_layers() override
|
||||
{
|
||||
panel_.load_layers();
|
||||
}
|
||||
|
||||
void mark_unsaved() override
|
||||
{
|
||||
Canvas::I->m_unsaved = true;
|
||||
}
|
||||
|
||||
private:
|
||||
static kCanvasMode& playback_restore_mode()
|
||||
{
|
||||
static auto mode = Canvas::I->m_current_mode;
|
||||
return mode;
|
||||
}
|
||||
|
||||
NodePanelAnimation& panel_;
|
||||
Layer* layer_ = nullptr;
|
||||
};
|
||||
|
||||
pp::foundation::Status execute_legacy_document_animation_plan(
|
||||
NodePanelAnimation& panel,
|
||||
const pp::app::DocumentAnimationOperationPlan& plan,
|
||||
Layer* layer)
|
||||
{
|
||||
LegacyDocumentAnimationServices services(panel, layer);
|
||||
return pp::app::execute_animation_operation_plan(plan, services);
|
||||
}
|
||||
|
||||
} // namespace pp::panopainter
|
||||
18
src/legacy_document_animation_services.h
Normal file
18
src/legacy_document_animation_services.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "app_core/document_animation.h"
|
||||
#include "foundation/result.h"
|
||||
|
||||
class Layer;
|
||||
class NodePanelAnimation;
|
||||
|
||||
namespace pp::panopainter {
|
||||
|
||||
class LegacyDocumentAnimationServices;
|
||||
|
||||
[[nodiscard]] pp::foundation::Status execute_legacy_document_animation_plan(
|
||||
NodePanelAnimation& panel,
|
||||
const pp::app::DocumentAnimationOperationPlan& plan,
|
||||
Layer* layer = nullptr);
|
||||
|
||||
} // namespace pp::panopainter
|
||||
@@ -1,11 +1,11 @@
|
||||
#include "pch.h"
|
||||
#include "node_panel_animation.h"
|
||||
#include "app_core/document_animation.h"
|
||||
#include "legacy_document_animation_services.h"
|
||||
#include "node_button.h"
|
||||
#include "node_button_custom.h"
|
||||
#include "renderer_gl/opengl_capabilities.h"
|
||||
#include "canvas.h"
|
||||
#include "app.h"
|
||||
|
||||
Node* NodePanelAnimation::clone_instantiate() const
|
||||
{
|
||||
@@ -28,137 +28,7 @@ void NodePanelAnimation::init()
|
||||
|
||||
void NodePanelAnimation::execute_animation_plan(const pp::app::DocumentAnimationOperationPlan& plan, Layer* layer)
|
||||
{
|
||||
class LegacyAnimationServices final : public pp::app::DocumentAnimationServices {
|
||||
public:
|
||||
LegacyAnimationServices(NodePanelAnimation& panel, Layer* layer) noexcept
|
||||
: panel_(panel)
|
||||
, layer_(layer)
|
||||
{
|
||||
}
|
||||
|
||||
void add_frame() override
|
||||
{
|
||||
Canvas::I->layer().add_frame();
|
||||
}
|
||||
|
||||
void duplicate_frame(int selected_frame) override
|
||||
{
|
||||
if (layer_)
|
||||
layer_->duplicate_frame(selected_frame);
|
||||
}
|
||||
|
||||
void remove_frame(int selected_frame, int target_frame) override
|
||||
{
|
||||
if (!layer_)
|
||||
return;
|
||||
layer_->remove_frame(selected_frame);
|
||||
panel_.m_selected_frame_index = target_frame;
|
||||
}
|
||||
|
||||
void set_frame_duration(int selected_frame, int duration) override
|
||||
{
|
||||
if (layer_)
|
||||
layer_->set_frame_duration(selected_frame, duration);
|
||||
}
|
||||
|
||||
int move_frame(int selected_frame, int move_offset) override
|
||||
{
|
||||
if (!layer_)
|
||||
return selected_frame;
|
||||
panel_.m_selected_frame_index = layer_->move_frame_offset(selected_frame, move_offset);
|
||||
return panel_.m_selected_frame_index;
|
||||
}
|
||||
|
||||
void select_frame(std::uint32_t layer_id, int layer_index, int selected_frame) override
|
||||
{
|
||||
panel_.m_selected_frame_layer_id = layer_id;
|
||||
panel_.m_selected_frame_index = selected_frame;
|
||||
panel_.m_timeline->m_frame = selected_frame;
|
||||
}
|
||||
|
||||
void select_layer(int layer_index) override
|
||||
{
|
||||
App::I->layers->handle_layer_selected(App::I->layers->get_layer_at(layer_index));
|
||||
}
|
||||
|
||||
void goto_frame(int target_frame) override
|
||||
{
|
||||
Canvas::I->anim_goto_frame(target_frame);
|
||||
}
|
||||
|
||||
void set_timeline_frame(int target_frame) override
|
||||
{
|
||||
panel_.m_timeline->m_frame = target_frame;
|
||||
}
|
||||
|
||||
void set_onion_size(int onion_size) override
|
||||
{
|
||||
panel_.m_timeline->m_onion_size = onion_size;
|
||||
}
|
||||
|
||||
void capture_playback_restore_mode() override
|
||||
{
|
||||
playback_restore_mode() = Canvas::I->m_current_mode;
|
||||
}
|
||||
|
||||
void enter_playback_camera_mode() override
|
||||
{
|
||||
Canvas::set_mode(kCanvasMode::Camera);
|
||||
}
|
||||
|
||||
void restore_playback_canvas_mode() override
|
||||
{
|
||||
Canvas::set_mode(playback_restore_mode());
|
||||
}
|
||||
|
||||
void set_playback_active(bool active) override
|
||||
{
|
||||
panel_.btn_play->set_active(active);
|
||||
}
|
||||
|
||||
void reset_playback_timer() override
|
||||
{
|
||||
panel_.m_playback_timer = 0;
|
||||
}
|
||||
|
||||
void set_playback_idle_ms(int idle_ms) override
|
||||
{
|
||||
App::I->idle_ms = idle_ms;
|
||||
}
|
||||
|
||||
void update_canvas_animation() override
|
||||
{
|
||||
Canvas::I->anim_update();
|
||||
}
|
||||
|
||||
void update_frame_status() override
|
||||
{
|
||||
panel_.update_frames();
|
||||
}
|
||||
|
||||
void reload_animation_layers() override
|
||||
{
|
||||
panel_.load_layers();
|
||||
}
|
||||
|
||||
void mark_unsaved() override
|
||||
{
|
||||
Canvas::I->m_unsaved = true;
|
||||
}
|
||||
|
||||
private:
|
||||
static kCanvasMode& playback_restore_mode()
|
||||
{
|
||||
static auto mode = Canvas::I->m_current_mode;
|
||||
return mode;
|
||||
}
|
||||
|
||||
NodePanelAnimation& panel_;
|
||||
Layer* layer_ = nullptr;
|
||||
};
|
||||
|
||||
LegacyAnimationServices services(*this, layer);
|
||||
const auto status = pp::app::execute_animation_operation_plan(plan, services);
|
||||
const auto status = pp::panopainter::execute_legacy_document_animation_plan(*this, plan, layer);
|
||||
if (!status.ok())
|
||||
LOG("Animation panel action failed: %s", status.message);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
|
||||
class Layer;
|
||||
|
||||
namespace pp::panopainter {
|
||||
class LegacyDocumentAnimationServices;
|
||||
}
|
||||
|
||||
namespace pp::app {
|
||||
struct DocumentAnimationPanelState;
|
||||
struct DocumentAnimationOperationPlan;
|
||||
@@ -52,6 +56,8 @@ public:
|
||||
|
||||
class NodePanelAnimation : public Node
|
||||
{
|
||||
friend class pp::panopainter::LegacyDocumentAnimationServices;
|
||||
|
||||
NodeButtonCustom* btn_next = nullptr;
|
||||
NodeButtonCustom* btn_prev = nullptr;
|
||||
NodeButtonCustom* btn_play = nullptr;
|
||||
|
||||
Reference in New Issue
Block a user