diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index 37679d7f..9d12b11b 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -82,14 +82,29 @@ Current hotspot files: - `src/canvas.cpp`: 17 lines - `src/app_layout.cpp`: 125 lines - `src/canvas_modes.cpp`: 176 lines -- `src/node.cpp`: 260 lines +- `src/node.cpp`: 222 lines - `src/main.cpp`: 130 lines - `src/node_panel_brush.cpp`: 189 lines -- `src/node_stroke_preview.cpp`: 280 lines -- `src/node_canvas.cpp`: 219 lines +- `src/node_stroke_preview.cpp`: 192 lines +- `src/node_canvas.cpp`: 69 lines - `src/app.cpp`: 113 lines - `src/app_dialogs.cpp`: 168 lines +Latest slice: + +- `NodeCanvas::handle_event()` now routes through + `handle_legacy_node_canvas_event(...)` in + `src/legacy_canvas_tool_services.*`, leaving `src/node_canvas.cpp` as a much + thinner controller shell. +- The remaining low-level `NodeStrokePreview` viewport/query and texture-slot + plumbing now lives in + `src/legacy_node_stroke_preview_runtime_services.*` instead of staying + inline in `src/node_stroke_preview.cpp`. +- The remaining generic `Node` geometry/state pocket for `SetSize(...)`, + `SetMinSize(...)`, `SetMaxSize(...)`, and `SetPosition(const glm::vec2)` now + lives in `src/legacy_ui_node_style.*` instead of staying inline in + `src/node.cpp`. + Current architecture mismatches that must be treated as real blockers: - `pp_platform_api` still compiles Apple implementation files instead of only @@ -262,6 +277,9 @@ Current architecture mismatches that must be treated as real blockers: pass planning, shader setup, and live render request assembly now also routes through `src/legacy_node_stroke_preview_runtime_services.*` instead of staying inline in `src/node_stroke_preview.cpp`, while + the low-level preview GL dispatch and texture-slot binding pocket now also + routes through `src/legacy_node_stroke_preview_runtime_services.*` instead + of staying inline in `src/node_stroke_preview.cpp`, while `NodeStrokePreview` remaining mix-pass planning and execution now also route through `src/legacy_node_stroke_preview_draw_services.*`, which trims the last dedicated mix-orchestration pocket from `src/node_stroke_preview.cpp`, diff --git a/docs/modernization/tasks.md b/docs/modernization/tasks.md index b5c7724f..a523baae 100644 --- a/docs/modernization/tasks.md +++ b/docs/modernization/tasks.md @@ -235,8 +235,8 @@ Current slice: which trims another coherent setup pocket from `src/node_stroke_preview.cpp` even though worker/readback ownership and broader preview flow still remain inline. -- `src/node_stroke_preview.cpp` is now 280 lines after moving the preview - background-capture and stroke-frame planning pocket into +- `src/node_stroke_preview.cpp` is now 192 lines after moving the remaining + preview GL dispatch and texture-slot binding pocket into `legacy_node_stroke_preview_runtime_services.*`. - The remaining immediate preview pass shell in `NodeStrokePreview::draw_stroke_immediate()` now also routes through @@ -337,10 +337,10 @@ Current slice: route through `execute_node_canvas_draw_merged_pass(...)`, which trims another coherent merged draw-orchestration block from the live node even though the broader draw loop still remains inline. -- `NodeCanvas::handle_event()` now also routes through the local - `execute_node_canvas_handle_event(...)` helper, which trims another coherent - input-routing block from `src/node_canvas.cpp` even though the node still - owns broader canvas/controller behavior. +- `NodeCanvas::handle_event()` now routes through + `handle_legacy_node_canvas_event(...)` in + `src/legacy_canvas_tool_services.*`, which moves the live input/controller + pocket out of `src/node_canvas.cpp` and keeps the node on a thinner shell. - `NodeCanvas` restore/clear context, resize handling, camera reset, buffer creation, cursor visibility/update, tick, and destroy ownership now also live in `src/legacy_node_canvas_state_services.*` instead of staying inline @@ -352,6 +352,12 @@ Current slice: inline in `src/node_stroke_preview.cpp`, which materially thins the preview node around its runtime-facing shell even though live pass execution still remains. +- The remaining low-level preview GL/runtime pocket for viewport queries, + clear-color restore, texture-slot binding, mixer unbind, and + destination/pattern texture plumbing now also lives in + `src/legacy_node_stroke_preview_runtime_services.*` instead of staying + inline in `src/node_stroke_preview.cpp`, which trims another coherent + runtime-facing shell pocket from the live node. - The remaining live render/pass orchestration in `NodeStrokePreview::draw_stroke_immediate()` now also lives in `src/legacy_node_stroke_preview_draw_services.*` instead of staying inline in @@ -374,6 +380,11 @@ Current slice: also live in `src/legacy_node_canvas_draw_services.*` instead of staying inline in `src/node_canvas.cpp`, which materially reduces the live node to a thinner controller surface around event routing and state wrappers. +- The remaining generic node geometry/state pocket for `Node::SetSize(...)`, + `SetMinSize(...)`, `SetMaxSize(...)`, and `SetPosition(const glm::vec2)` + now also lives in `src/legacy_ui_node_style.*` instead of staying inline in + `src/node.cpp`, which trims another coherent base scene-graph shell pocket + without changing the public surface. Write scope: - `src/node_stroke_preview.cpp` @@ -848,6 +859,12 @@ Current slice: `Node::GetRTL()` now also lives in `src/legacy_ui_node_style.*` instead of staying inline in `src/node.cpp`, which trims another coherent generic node shell pocket without changing the public surface. +- The remaining geometry/state pocket for `Node::SetSize(...)`, + `Node::SetMinSize(...)`, `Node::SetMaxSize(...)`, and + `Node::SetPosition(const glm::vec2)` now also lives in + `src/legacy_ui_node_style.*` instead of staying inline in `src/node.cpp`, + which materially thins the live base shell by moving the cached size/position + mutation and redraw signaling out of the node file. - The remaining generic `Node` lifecycle/state pocket for no-op lifecycle hooks, add/remove propagation, move construction, destruction cleanup, and base clone plumbing now also lives in `src/legacy_ui_node_lifecycle.*` diff --git a/src/legacy_canvas_tool_services.cpp b/src/legacy_canvas_tool_services.cpp index 92224b9d..6fbd1452 100644 --- a/src/legacy_canvas_tool_services.cpp +++ b/src/legacy_canvas_tool_services.cpp @@ -4,6 +4,8 @@ #include "app.h" #include "legacy_history_services.h" +#include "legacy_ui_overlay_services.h" +#include "node_canvas.h" namespace pp::panopainter { namespace { @@ -196,6 +198,156 @@ public: } }; +pp::app::CanvasHotkeyKey canvas_hotkey_key(kKey key) noexcept +{ + switch (key) { + case kKey::AndroidBack: + return pp::app::CanvasHotkeyKey::android_back; + case kKey::KeyAlt: + return pp::app::CanvasHotkeyKey::alt; + case kKey::KeyE: + return pp::app::CanvasHotkeyKey::e; + case kKey::KeyS: + return pp::app::CanvasHotkeyKey::s; + case kKey::KeyTab: + return pp::app::CanvasHotkeyKey::tab; + case kKey::KeyZ: + return pp::app::CanvasHotkeyKey::z; + case kKey::KeyBracketLeft: + return pp::app::CanvasHotkeyKey::bracket_left; + case kKey::KeyBracketRight: + return pp::app::CanvasHotkeyKey::bracket_right; + default: + return pp::app::CanvasHotkeyKey::other; + } +} + +pp::app::CanvasHotkeyState canvas_hotkey_state(bool mouse_focused, int touch_finger_count = 0) noexcept +{ + pp::app::CanvasHotkeyState state; + state.ctrl_down = App::I && App::I->keys[(int)kKey::KeyCtrl]; + state.shift_down = App::I && App::I->keys[(int)kKey::KeyShift]; + state.mouse_focused = mouse_focused; + const auto history = pp::panopainter::legacy_history_snapshot(); + state.undo_count = history.undo_count; + state.redo_count = history.redo_count; + state.touch_finger_count = touch_finger_count; + return state; +} + +void execute_canvas_hotkey_plan(const pp::app::CanvasHotkeyPlan& plan) +{ + const auto status = pp::panopainter::execute_legacy_canvas_hotkey_plan(plan); + if (!status.ok()) + LOG("Canvas hotkey action failed: %s", status.message); +} + +void run_canvas_hotkey( + pp::app::CanvasHotkeyEvent event, + kKey key, + bool mouse_focused, + int touch_finger_count = 0) +{ + const auto plan = pp::app::plan_canvas_hotkey( + event, + canvas_hotkey_key(key), + canvas_hotkey_state(mouse_focused, touch_finger_count)); + if (plan) + execute_canvas_hotkey_plan(plan.value()); + else + LOG("Canvas hotkey planning failed: %s", plan.status().message); +} + +void run_canvas_tool_mode(pp::app::CanvasToolMode mode) +{ + const auto plan = pp::app::plan_canvas_tool_select(mode); + const auto status = pp::panopainter::execute_legacy_canvas_input_tool_plan(plan); + if (!status.ok()) + LOG("Canvas input tool action failed: %s", status.message); +} + +[[nodiscard]] kEventResult execute_node_canvas_handle_event(NodeCanvas& node_canvas, Event* e) +{ + static bool stylus_eraser = false; + MouseEvent* me = static_cast(e); + KeyEvent* ke = static_cast(e); + GestureEvent* ge = static_cast(e); + TouchEvent* te = static_cast(e); + auto loc = (me->m_pos - node_canvas.m_pos) * node_canvas.root()->m_zoom; + + switch (e->m_type) + { + case kEventType::MouseMove: + if (stylus_eraser != me->m_eraser) + { + run_canvas_tool_mode(me->m_eraser ? + pp::app::CanvasToolMode::erase : + pp::app::CanvasToolMode::draw); + stylus_eraser = me->m_eraser; + } + case kEventType::MouseScroll: + case kEventType::MouseDownL: + case kEventType::MouseUpL: + case kEventType::MouseDownR: + case kEventType::MouseUpR: + case kEventType::MouseCancel: + node_canvas.m_canvas->m_cur_pos = loc; + node_canvas.update_cursor(); + for (auto& mode : *node_canvas.m_canvas->m_mode) + mode->on_MouseEvent(me, loc); + break; + case kEventType::MouseUnfocus: + (*node_canvas.m_canvas->m_mode)[0]->m_draw_tip = false; + App::I->show_cursor(); + break; + case kEventType::MouseFocus: + node_canvas.update_cursor(); + break; + case kEventType::KeyDown: + run_canvas_hotkey( + pp::app::CanvasHotkeyEvent::key_down, + ke->m_key, + node_canvas.m_mouse_focus); + for (auto& mode : *node_canvas.m_canvas->m_mode) + mode->on_KeyEvent(ke); + break; + case kEventType::KeyUp: + node_canvas.update_cursor(); + run_canvas_hotkey( + pp::app::CanvasHotkeyEvent::key_up, + ke->m_key, + node_canvas.m_mouse_focus); + for (auto& mode : *node_canvas.m_canvas->m_mode) + mode->on_KeyEvent(ke); + break; + case kEventType::GestureStart: + node_canvas.mouse_capture(); + for (auto& mode : *node_canvas.m_canvas->m_mode) + mode->on_GestureEvent(ge); + break; + case kEventType::GestureMove: + for (auto& mode : *node_canvas.m_canvas->m_mode) + mode->on_GestureEvent(ge); + break; + case kEventType::GestureEnd: + pp::panopainter::release_legacy_mouse_capture(node_canvas); + for (auto& mode : *node_canvas.m_canvas->m_mode) + mode->on_GestureEvent(ge); + break; + case kEventType::TouchTap: + run_canvas_hotkey( + pp::app::CanvasHotkeyEvent::touch_tap, + kKey::Unknown, + node_canvas.m_mouse_focus, + te->m_finger_count); + break; + default: + return kEventResult::Available; + break; + } + return kEventResult::Consumed; +} + } // namespace pp::foundation::Status execute_legacy_canvas_tool_plan( @@ -221,4 +373,9 @@ pp::foundation::Status execute_legacy_canvas_hotkey_plan( return pp::app::execute_canvas_hotkey_plan(plan, services); } +kEventResult handle_legacy_node_canvas_event(NodeCanvas& node_canvas, Event* e) +{ + return execute_node_canvas_handle_event(node_canvas, e); +} + } // namespace pp::panopainter diff --git a/src/legacy_canvas_tool_services.h b/src/legacy_canvas_tool_services.h index 4c4c0423..43dd33fc 100644 --- a/src/legacy_canvas_tool_services.h +++ b/src/legacy_canvas_tool_services.h @@ -1,11 +1,16 @@ #pragma once +#include + #include "app_core/canvas_hotkey.h" #include "app_core/canvas_tool_ui.h" #include "foundation/result.h" class App; +class NodeCanvas; class Node; +class Event; +enum class kEventResult : uint8_t; namespace pp::panopainter { @@ -17,5 +22,6 @@ namespace pp::panopainter { const pp::app::CanvasToolPlan& plan); [[nodiscard]] pp::foundation::Status execute_legacy_canvas_hotkey_plan( const pp::app::CanvasHotkeyPlan& plan); +[[nodiscard]] kEventResult handle_legacy_node_canvas_event(NodeCanvas& node_canvas, Event* e); } // namespace pp::panopainter diff --git a/src/legacy_node_stroke_preview_runtime_services.cpp b/src/legacy_node_stroke_preview_runtime_services.cpp index c6c0cee4..0e5a243b 100644 --- a/src/legacy_node_stroke_preview_runtime_services.cpp +++ b/src/legacy_node_stroke_preview_runtime_services.cpp @@ -24,6 +24,118 @@ namespace pp::panopainter { +pp::renderer::RenderDeviceFeatures stroke_preview_render_device_features() noexcept +{ + return ShaderManager::render_device_features(); +} + +void apply_legacy_node_stroke_preview_viewport(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height) +{ + pp::legacy::ui_gl::apply_viewport(x, y, width, height, "NodeStrokePreview"); +} + +pp::renderer::gl::OpenGlViewportRect query_legacy_node_stroke_preview_viewport() +{ + return pp::legacy::ui_gl::query_viewport_rect("NodeStrokePreview"); +} + +std::array query_legacy_node_stroke_preview_clear_color() +{ + return pp::legacy::ui_gl::query_clear_color("NodeStrokePreview"); +} + +void apply_legacy_node_stroke_preview_clear_color(std::array color) +{ + pp::legacy::ui_gl::set_clear_color(color, "NodeStrokePreview"); +} + +void apply_legacy_node_stroke_preview_scissor(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height) +{ + pp::legacy::ui_gl::apply_scissor_rect(x, y, width, height, "NodeStrokePreview"); +} + +void apply_legacy_node_stroke_preview_capability(std::uint32_t state, bool enabled) +{ + pp::legacy::ui_gl::set_capability(state, enabled, "NodeStrokePreview"); +} + +namespace { + +namespace stroke_preview_live_slots { +constexpr std::uint32_t kTip = 0U; +constexpr std::uint32_t kDestination = 1U; +constexpr std::uint32_t kPattern = 2U; +constexpr std::uint32_t kMixer = 3U; +constexpr std::uint32_t kReservedLinear = 4U; +} + +void set_active_texture_unit(std::uint32_t unit_index) +{ + pp::legacy::ui_gl::activate_texture_unit(unit_index, "NodeStrokePreview"); +} + +void unbind_texture_2d() +{ + pp::legacy::ui_gl::unbind_texture_2d("NodeStrokePreview"); +} + +} // namespace + +void bind_legacy_node_stroke_preview_live_samplers( + Sampler& mipmap_sampler, + Sampler& linear_sampler, + Sampler& repeat_sampler) +{ + mipmap_sampler.bind(stroke_preview_live_slots::kTip); + linear_sampler.bind(stroke_preview_live_slots::kDestination); + repeat_sampler.bind(stroke_preview_live_slots::kPattern); + linear_sampler.bind(stroke_preview_live_slots::kMixer); + linear_sampler.bind(stroke_preview_live_slots::kReservedLinear); +} + +void bind_legacy_node_stroke_preview_dual_pass_textures(const Brush& dual_brush) +{ + set_active_texture_unit(stroke_preview_live_slots::kTip); + dual_brush.m_tip_texture ? + dual_brush.m_tip_texture->bind() : + unbind_texture_2d(); +} + +void bind_legacy_node_stroke_preview_pattern_texture(const Brush& brush) +{ + set_active_texture_unit(stroke_preview_live_slots::kPattern); + brush.m_pattern_texture ? brush.m_pattern_texture->bind() : unbind_texture_2d(); +} + +void bind_legacy_node_stroke_preview_destination_texture(Texture2D& texture) +{ + set_active_texture_unit(stroke_preview_live_slots::kDestination); + texture.bind(); +} + +void unbind_legacy_node_stroke_preview_destination_texture(Texture2D& texture) +{ + set_active_texture_unit(stroke_preview_live_slots::kDestination); + texture.unbind(); +} + +void unbind_legacy_node_stroke_preview_mixer_texture(RTT& mixer_rtt) +{ + set_active_texture_unit(stroke_preview_live_slots::kMixer); + mixer_rtt.unbindTexture(); +} + +void copy_legacy_node_stroke_preview_destination_texture_region( + int src_x, + int src_y, + int dst_x, + int dst_y, + int width, + int height) +{ + copy_framebuffer_to_texture_2d(src_x, src_y, dst_x, dst_y, width, height); +} + void execute_legacy_node_stroke_preview_background_capture_pass( const LegacyNodeStrokePreviewBackgroundCaptureRequest& request) { diff --git a/src/legacy_node_stroke_preview_runtime_services.h b/src/legacy_node_stroke_preview_runtime_services.h index 233d015c..b5ff1e78 100644 --- a/src/legacy_node_stroke_preview_runtime_services.h +++ b/src/legacy_node_stroke_preview_runtime_services.h @@ -9,13 +9,41 @@ #include "rtt.h" #include "texture.h" +#include #include +#include #include #include #include namespace pp::panopainter { +[[nodiscard]] pp::renderer::RenderDeviceFeatures stroke_preview_render_device_features() noexcept; + +void apply_legacy_node_stroke_preview_viewport(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height); +[[nodiscard]] pp::renderer::gl::OpenGlViewportRect query_legacy_node_stroke_preview_viewport(); +[[nodiscard]] std::array query_legacy_node_stroke_preview_clear_color(); +void apply_legacy_node_stroke_preview_clear_color(std::array color); +void apply_legacy_node_stroke_preview_scissor(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height); +void apply_legacy_node_stroke_preview_capability(std::uint32_t state, bool enabled); + +void bind_legacy_node_stroke_preview_live_samplers( + Sampler& mipmap_sampler, + Sampler& linear_sampler, + Sampler& repeat_sampler); +void bind_legacy_node_stroke_preview_dual_pass_textures(const Brush& dual_brush); +void bind_legacy_node_stroke_preview_pattern_texture(const Brush& brush); +void bind_legacy_node_stroke_preview_destination_texture(Texture2D& texture); +void unbind_legacy_node_stroke_preview_destination_texture(Texture2D& texture); +void unbind_legacy_node_stroke_preview_mixer_texture(RTT& mixer_rtt); +void copy_legacy_node_stroke_preview_destination_texture_region( + int src_x, + int src_y, + int dst_x, + int dst_y, + int width, + int height); + struct LegacyNodeStrokePreviewBackgroundCaptureRequest { glm::vec2 size {}; bool colorize = false; diff --git a/src/legacy_ui_node_style.cpp b/src/legacy_ui_node_style.cpp index 4eb1fa23..ae690de2 100644 --- a/src/legacy_ui_node_style.cpp +++ b/src/legacy_ui_node_style.cpp @@ -36,6 +36,41 @@ void legacy_ui_node_set_height_percent(Node& node, float value) node.app_redraw(); } +void legacy_ui_node_set_size(Node& node, float w, float h) +{ + legacy_ui_node_set_width(node, w); + legacy_ui_node_set_height(node, h); + node.m_size = { w, h }; + node.app_redraw(); +} + +void legacy_ui_node_set_size(Node& node, glm::vec2 value) +{ + legacy_ui_node_set_size(node, value.x, value.y); +} + +void legacy_ui_node_set_min_size(Node& node, float w, float h) +{ + legacy_ui_node_set_min_width(node, w); + legacy_ui_node_set_min_height(node, h); +} + +void legacy_ui_node_set_min_size(Node& node, glm::vec2 value) +{ + legacy_ui_node_set_min_size(node, value.x, value.y); +} + +void legacy_ui_node_set_max_size(Node& node, float w, float h) +{ + legacy_ui_node_set_max_width(node, w); + legacy_ui_node_set_max_height(node, h); +} + +void legacy_ui_node_set_max_size(Node& node, glm::vec2 value) +{ + legacy_ui_node_set_max_size(node, value.x, value.y); +} + void legacy_ui_node_set_max_width(Node& node, float value) { YGNodeStyleSetMaxWidth(node.y_node, value); @@ -137,6 +172,13 @@ void legacy_ui_node_set_position(Node& node, float l, float t, float r, float b) node.app_redraw(); } +void legacy_ui_node_set_position(Node& node, glm::vec2 value) +{ + legacy_ui_node_set_position(node, value.x, value.y); + node.m_pos = value; + node.app_redraw(); +} + void legacy_ui_node_set_flex_grow(Node& node, float value) { YGNodeStyleSetFlexGrow(node.y_node, value); @@ -248,3 +290,38 @@ YGDirection legacy_ui_node_get_rtl(const Node& node) } } // namespace pp::panopainter + +void Node::SetSize(float w, float h) +{ + pp::panopainter::legacy_ui_node_set_size(*this, w, h); +} + +void Node::SetSize(glm::vec2 value) +{ + pp::panopainter::legacy_ui_node_set_size(*this, value); +} + +void Node::SetMinSize(float w, float h) +{ + pp::panopainter::legacy_ui_node_set_min_size(*this, w, h); +} + +void Node::SetMinSize(glm::vec2 value) +{ + pp::panopainter::legacy_ui_node_set_min_size(*this, value); +} + +void Node::SetMaxSize(float w, float h) +{ + pp::panopainter::legacy_ui_node_set_max_size(*this, w, h); +} + +void Node::SetMaxSize(glm::vec2 value) +{ + pp::panopainter::legacy_ui_node_set_max_size(*this, value); +} + +void Node::SetPosition(const glm::vec2 pos) +{ + pp::panopainter::legacy_ui_node_set_position(*this, pos); +} diff --git a/src/legacy_ui_node_style.h b/src/legacy_ui_node_style.h index 8562d5d0..95520e7b 100644 --- a/src/legacy_ui_node_style.h +++ b/src/legacy_ui_node_style.h @@ -12,6 +12,12 @@ void legacy_ui_node_set_width(Node& node, float value); void legacy_ui_node_set_width_percent(Node& node, float value); void legacy_ui_node_set_height(Node& node, float value); void legacy_ui_node_set_height_percent(Node& node, float value); +void legacy_ui_node_set_size(Node& node, float w, float h); +void legacy_ui_node_set_size(Node& node, glm::vec2 value); +void legacy_ui_node_set_min_size(Node& node, float w, float h); +void legacy_ui_node_set_min_size(Node& node, glm::vec2 value); +void legacy_ui_node_set_max_size(Node& node, float w, float h); +void legacy_ui_node_set_max_size(Node& node, glm::vec2 value); void legacy_ui_node_set_max_width(Node& node, float value); void legacy_ui_node_set_max_width_percent(Node& node, float value); void legacy_ui_node_set_max_height(Node& node, float value); @@ -26,6 +32,7 @@ void legacy_ui_node_set_margin(Node& node, float t, float r, float b, float l); glm::vec4 legacy_ui_node_get_margin(const Node& node); void legacy_ui_node_set_position(Node& node, float l, float t); void legacy_ui_node_set_position(Node& node, float l, float t, float r, float b); +void legacy_ui_node_set_position(Node& node, glm::vec2 value); void legacy_ui_node_set_flex_grow(Node& node, float value); void legacy_ui_node_set_flex_shrink(Node& node, float value); void legacy_ui_node_set_flex_dir(Node& node, YGFlexDirection value); diff --git a/src/node.cpp b/src/node.cpp index 2c611af3..5d36dba3 100644 --- a/src/node.cpp +++ b/src/node.cpp @@ -89,44 +89,6 @@ void Node::SetHeightP(float value) pp::panopainter::legacy_ui_node_set_height_percent(*this, value); } -void Node::SetSize(float w, float h) -{ - SetWidth(w); SetHeight(h); - m_size = {w, h}; - app_redraw(); -} - -void Node::SetSize(glm::vec2 value) -{ - SetWidth(value.x); SetHeight(value.y); - m_size = value; - app_redraw(); -} - -void Node::SetMinSize(float w, float h) -{ - SetMinWidth(w); - SetMinHeight(h); -} - -void Node::SetMinSize(glm::vec2 value) -{ - SetMinWidth(value.x); - SetMinHeight(value.y); -} - -void Node::SetMaxSize(float w, float h) -{ - SetMaxWidth(w); - SetMaxHeight(h); -} - -void Node::SetMaxSize(glm::vec2 value) -{ - SetMaxWidth(value.x); - SetMaxHeight(value.y); -} - void Node::SetMaxWidth(float value) { pp::panopainter::legacy_ui_node_set_max_width(*this, value); @@ -187,13 +149,6 @@ glm::vec4 Node::GetMargin() const return pp::panopainter::legacy_ui_node_get_margin(*this); } -void Node::SetPosition(const glm::vec2 pos) -{ - SetPosition(pos.x, pos.y); - m_pos = pos; - app_redraw(); -} - void Node::SetPosition(float l, float t) { pp::panopainter::legacy_ui_node_set_position(*this, l, t); diff --git a/src/node_canvas.cpp b/src/node_canvas.cpp index 5009a3f1..e4a4469f 100644 --- a/src/node_canvas.cpp +++ b/src/node_canvas.cpp @@ -6,172 +6,13 @@ #include #include -#include "app_core/canvas_hotkey.h" -#include "app_core/canvas_tool_ui.h" #include "app_core/document_animation.h" #include "app.h" #include "legacy_node_canvas_draw_services.h" #include "legacy_node_canvas_state_services.h" -#include "legacy_ui_overlay_services.h" #include "legacy_canvas_tool_services.h" -#include "legacy_history_services.h" -#include "log.h" #include "node_canvas.h" -namespace { - -pp::app::CanvasHotkeyKey canvas_hotkey_key(kKey key) noexcept -{ - switch (key) { - case kKey::AndroidBack: - return pp::app::CanvasHotkeyKey::android_back; - case kKey::KeyAlt: - return pp::app::CanvasHotkeyKey::alt; - case kKey::KeyE: - return pp::app::CanvasHotkeyKey::e; - case kKey::KeyS: - return pp::app::CanvasHotkeyKey::s; - case kKey::KeyTab: - return pp::app::CanvasHotkeyKey::tab; - case kKey::KeyZ: - return pp::app::CanvasHotkeyKey::z; - case kKey::KeyBracketLeft: - return pp::app::CanvasHotkeyKey::bracket_left; - case kKey::KeyBracketRight: - return pp::app::CanvasHotkeyKey::bracket_right; - default: - return pp::app::CanvasHotkeyKey::other; - } -} - -pp::app::CanvasHotkeyState canvas_hotkey_state(bool mouse_focused, int touch_finger_count = 0) noexcept -{ - pp::app::CanvasHotkeyState state; - state.ctrl_down = App::I && App::I->keys[(int)kKey::KeyCtrl]; - state.shift_down = App::I && App::I->keys[(int)kKey::KeyShift]; - state.mouse_focused = mouse_focused; - const auto history = pp::panopainter::legacy_history_snapshot(); - state.undo_count = history.undo_count; - state.redo_count = history.redo_count; - state.touch_finger_count = touch_finger_count; - return state; -} - -void execute_canvas_hotkey_plan(const pp::app::CanvasHotkeyPlan& plan) -{ - const auto status = pp::panopainter::execute_legacy_canvas_hotkey_plan(plan); - if (!status.ok()) - LOG("Canvas hotkey action failed: %s", status.message); -} - -void run_canvas_hotkey( - pp::app::CanvasHotkeyEvent event, - kKey key, - bool mouse_focused, - int touch_finger_count = 0) -{ - const auto plan = pp::app::plan_canvas_hotkey( - event, - canvas_hotkey_key(key), - canvas_hotkey_state(mouse_focused, touch_finger_count)); - if (plan) - execute_canvas_hotkey_plan(plan.value()); - else - LOG("Canvas hotkey planning failed: %s", plan.status().message); -} - -void run_canvas_tool_mode(pp::app::CanvasToolMode mode) -{ - const auto plan = pp::app::plan_canvas_tool_select(mode); - const auto status = pp::panopainter::execute_legacy_canvas_input_tool_plan(plan); - if (!status.ok()) - LOG("Canvas input tool action failed: %s", status.message); -} - -[[nodiscard]] kEventResult execute_node_canvas_handle_event(NodeCanvas& node_canvas, Event* e) -{ - static bool stylus_eraser = false; - MouseEvent* me = static_cast(e); - KeyEvent* ke = static_cast(e); - GestureEvent* ge = static_cast(e); - TouchEvent* te = static_cast(e); - auto loc = (me->m_pos - node_canvas.m_pos) * node_canvas.root()->m_zoom; - - switch (e->m_type) - { - case kEventType::MouseMove: - if (stylus_eraser != me->m_eraser) - { - run_canvas_tool_mode(me->m_eraser ? - pp::app::CanvasToolMode::erase : - pp::app::CanvasToolMode::draw); - stylus_eraser = me->m_eraser; - } - case kEventType::MouseScroll: - case kEventType::MouseDownL: - case kEventType::MouseUpL: - case kEventType::MouseDownR: - case kEventType::MouseUpR: - case kEventType::MouseCancel: - node_canvas.m_canvas->m_cur_pos = loc; - node_canvas.update_cursor(); - for (auto& mode : *node_canvas.m_canvas->m_mode) - mode->on_MouseEvent(me, loc); - break; - case kEventType::MouseUnfocus: - (*node_canvas.m_canvas->m_mode)[0]->m_draw_tip = false; - App::I->show_cursor(); - break; - case kEventType::MouseFocus: - node_canvas.update_cursor(); - break; - case kEventType::KeyDown: - run_canvas_hotkey( - pp::app::CanvasHotkeyEvent::key_down, - ke->m_key, - node_canvas.m_mouse_focus); - for (auto& mode : *node_canvas.m_canvas->m_mode) - mode->on_KeyEvent(ke); - break; - case kEventType::KeyUp: - node_canvas.update_cursor(); - run_canvas_hotkey( - pp::app::CanvasHotkeyEvent::key_up, - ke->m_key, - node_canvas.m_mouse_focus); - for (auto& mode : *node_canvas.m_canvas->m_mode) - mode->on_KeyEvent(ke); - break; - case kEventType::GestureStart: - node_canvas.mouse_capture(); - for (auto& mode : *node_canvas.m_canvas->m_mode) - mode->on_GestureEvent(ge); - break; - case kEventType::GestureMove: - for (auto& mode : *node_canvas.m_canvas->m_mode) - mode->on_GestureEvent(ge); - break; - case kEventType::GestureEnd: - pp::panopainter::release_legacy_mouse_capture(node_canvas); - for (auto& mode : *node_canvas.m_canvas->m_mode) - mode->on_GestureEvent(ge); - break; - case kEventType::TouchTap: - run_canvas_hotkey( - pp::app::CanvasHotkeyEvent::touch_tap, - kKey::Unknown, - node_canvas.m_mouse_focus, - te->m_finger_count); - break; - default: - return kEventResult::Available; - break; - } - return kEventResult::Consumed; -} - -} - Node* NodeCanvas::clone_instantiate() const { return new NodeCanvas(); @@ -205,7 +46,7 @@ void NodeCanvas::handle_resize(glm::vec2 old_size, glm::vec2 new_size, float zoo kEventResult NodeCanvas::handle_event(Event* e) { Node::handle_event(e); - return execute_node_canvas_handle_event(*this, e); + return pp::panopainter::handle_legacy_node_canvas_event(*this, e); } void NodeCanvas::reset_camera() diff --git a/src/node_stroke_preview.cpp b/src/node_stroke_preview.cpp index 2baa08c2..8dee5313 100644 --- a/src/node_stroke_preview.cpp +++ b/src/node_stroke_preview.cpp @@ -2,118 +2,14 @@ #include "log.h" #include "node_stroke_preview.h" #include "texture.h" -#include "shader.h" #include "canvas.h" #include "app.h" #include "legacy_canvas_stroke_shader_services.h" #include "legacy_node_stroke_preview_execution_services.h" #include "legacy_node_stroke_preview_runtime_services.h" #include "legacy_node_stroke_preview_sample_services.h" -#include "legacy_ui_gl_dispatch.h" -#include "renderer_gl/opengl_capabilities.h" #include "util.h" #include -#include - -namespace { - -pp::renderer::RenderDeviceFeatures stroke_preview_render_device_features() noexcept -{ - return ShaderManager::render_device_features(); -} - -void set_active_texture_unit(std::uint32_t unit_index) -{ - pp::legacy::ui_gl::activate_texture_unit(unit_index, "NodeStrokePreview"); -} - -void unbind_texture_2d() -{ - pp::legacy::ui_gl::unbind_texture_2d("NodeStrokePreview"); -} - -void apply_stroke_preview_viewport(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height) -{ - pp::legacy::ui_gl::apply_viewport(x, y, width, height, "NodeStrokePreview"); -} - -pp::renderer::gl::OpenGlViewportRect query_stroke_preview_viewport() -{ - return pp::legacy::ui_gl::query_viewport_rect("NodeStrokePreview"); -} - -std::array query_stroke_preview_clear_color() -{ - return pp::legacy::ui_gl::query_clear_color("NodeStrokePreview"); -} - -void apply_stroke_preview_clear_color(std::array color) -{ - pp::legacy::ui_gl::set_clear_color(color, "NodeStrokePreview"); -} - -void apply_stroke_preview_scissor(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height) -{ - pp::legacy::ui_gl::apply_scissor_rect(x, y, width, height, "NodeStrokePreview"); -} - -void apply_stroke_preview_capability(std::uint32_t state, bool enabled) -{ - pp::legacy::ui_gl::set_capability(state, enabled, "NodeStrokePreview"); -} - -namespace stroke_preview_live_slots { -constexpr std::uint32_t kTip = 0U; -constexpr std::uint32_t kDestination = 1U; -constexpr std::uint32_t kPattern = 2U; -constexpr std::uint32_t kMixer = 3U; -constexpr std::uint32_t kReservedLinear = 4U; -} - -void bind_stroke_preview_live_samplers( - Sampler& mipmap_sampler, - Sampler& linear_sampler, - Sampler& repeat_sampler) -{ - mipmap_sampler.bind(stroke_preview_live_slots::kTip); - linear_sampler.bind(stroke_preview_live_slots::kDestination); - repeat_sampler.bind(stroke_preview_live_slots::kPattern); - linear_sampler.bind(stroke_preview_live_slots::kMixer); - linear_sampler.bind(stroke_preview_live_slots::kReservedLinear); -} - -void bind_stroke_preview_dual_pass_textures(const Brush& dual_brush) -{ - set_active_texture_unit(stroke_preview_live_slots::kTip); - dual_brush.m_tip_texture ? - dual_brush.m_tip_texture->bind() : - unbind_texture_2d(); -} - -void bind_stroke_preview_destination_texture(Texture2D& texture) -{ - set_active_texture_unit(stroke_preview_live_slots::kDestination); - texture.bind(); -} - -void unbind_stroke_preview_destination_texture(Texture2D& texture) -{ - set_active_texture_unit(stroke_preview_live_slots::kDestination); - texture.unbind(); -} - -void copy_stroke_preview_destination_texture_region( - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height) -{ - copy_framebuffer_to_texture_2d(src_x, src_y, dst_x, dst_y, width, height); -} - -} Node* NodeStrokePreview::clone_instantiate() const { @@ -176,7 +72,7 @@ glm::vec4 NodeStrokePreview::stroke_draw_samples( .brush_shape = m_brush_shape, .copy_stroke_destination = copy_stroke_destination, .bind_destination_texture = [&] { - bind_stroke_preview_destination_texture(blend_tex); + pp::panopainter::bind_legacy_node_stroke_preview_destination_texture(blend_tex); }, .copy_framebuffer_to_destination_texture = []( int src_x, @@ -185,7 +81,7 @@ glm::vec4 NodeStrokePreview::stroke_draw_samples( int dst_y, int width, int height) { - copy_stroke_preview_destination_texture_region( + pp::panopainter::copy_legacy_node_stroke_preview_destination_texture_region( src_x, src_y, dst_x, @@ -194,7 +90,7 @@ glm::vec4 NodeStrokePreview::stroke_draw_samples( height); }, .unbind_destination_texture = [&] { - unbind_stroke_preview_destination_texture(blend_tex); + pp::panopainter::unbind_legacy_node_stroke_preview_destination_texture(blend_tex); }, }); } @@ -227,8 +123,8 @@ void NodeStrokePreview::draw_stroke_immediate() return; } - const auto vp = query_stroke_preview_viewport(); - const auto cc = query_stroke_preview_clear_color(); + const auto vp = pp::panopainter::query_legacy_node_stroke_preview_viewport(); + const auto cc = pp::panopainter::query_legacy_node_stroke_preview_clear_color(); const glm::vec2 size = { m_rtt.getWidth(), m_rtt.getHeight() }; const float zoom = root()->m_zoom; const bool sequence_ok = pp::panopainter::execute_legacy_node_stroke_preview_immediate_runtime( @@ -241,7 +137,7 @@ void NodeStrokePreview::draw_stroke_immediate() .pad_override = m_pad_override, .camera_fov = Canvas::I->m_cam_fov, .camera_rot = Canvas::I->m_cam_rot, - .render_device_features = stroke_preview_render_device_features(), + .render_device_features = pp::panopainter::stroke_preview_render_device_features(), .preview_rtt = m_rtt, .preview_rtt_mixer = m_rtt_mixer, .preview_stroke_texture = m_tex, @@ -251,10 +147,10 @@ void NodeStrokePreview::draw_stroke_immediate() .linear_sampler = m_sampler_linear, .repeat_sampler = m_sampler_linear_repeat, .prepare_render_target = [&] { - apply_stroke_preview_viewport(0, 0, m_rtt.getWidth(), m_rtt.getHeight()); + pp::panopainter::apply_legacy_node_stroke_preview_viewport(0, 0, m_rtt.getWidth(), m_rtt.getHeight()); m_rtt.bindFramebuffer(); m_rtt.clear(); - bind_stroke_preview_live_samplers( + pp::panopainter::bind_legacy_node_stroke_preview_live_samplers( m_sampler_mipmap, m_sampler_linear, m_sampler_linear_repeat); @@ -263,13 +159,13 @@ void NodeStrokePreview::draw_stroke_immediate() m_rtt.unbindFramebuffer(); }, .set_blend_enabled = [&](bool enabled) { - apply_stroke_preview_capability(pp::renderer::gl::blend_state(), enabled); + pp::panopainter::apply_legacy_node_stroke_preview_capability(pp::renderer::gl::blend_state(), enabled); }, .setup_stroke_shader = [](const pp::panopainter::LegacyStrokeShaderSetupUniforms& uniforms) { pp::panopainter::setup_legacy_stroke_shader(uniforms); }, .bind_dual_pass_textures = [](const Brush& dual_brush) { - bind_stroke_preview_dual_pass_textures(dual_brush); + pp::panopainter::bind_legacy_node_stroke_preview_dual_pass_textures(dual_brush); }, .capture_background = [&](bool colorize) { pp::panopainter::execute_legacy_node_stroke_preview_background_capture_pass( @@ -292,11 +188,10 @@ void NodeStrokePreview::draw_stroke_immediate() stroke_draw_mix(bb_min, bb_sz); }, .unbind_mixer_texture = [&] { - set_active_texture_unit(3U); - m_rtt_mixer.unbindTexture(); + pp::panopainter::unbind_legacy_node_stroke_preview_mixer_texture(m_rtt_mixer); }, .bind_pattern_texture = [&] { - m_brush->m_pattern_texture ? m_brush->m_pattern_texture->bind() : unbind_texture_2d(); + pp::panopainter::bind_legacy_node_stroke_preview_pattern_texture(*m_brush); }, .draw_composite = [&] { m_plane.draw_fill(); @@ -304,6 +199,6 @@ void NodeStrokePreview::draw_stroke_immediate() }); assert(sequence_ok); - apply_stroke_preview_viewport(vp.x, vp.y, vp.width, vp.height); - apply_stroke_preview_clear_color(cc); + pp::panopainter::apply_legacy_node_stroke_preview_viewport(vp.x, vp.y, vp.width, vp.height); + pp::panopainter::apply_legacy_node_stroke_preview_clear_color(cc); }