diff --git a/cmake/PanoPainterSources.cmake b/cmake/PanoPainterSources.cmake index 143a1363..db95ddb6 100644 --- a/cmake/PanoPainterSources.cmake +++ b/cmake/PanoPainterSources.cmake @@ -53,6 +53,8 @@ set(PP_LEGACY_UI_CORE_SOURCES src/legacy_ui_node_loader.h src/legacy_ui_node_event.cpp src/legacy_ui_node_event.h + src/legacy_ui_node_style.cpp + src/legacy_ui_node_style.h src/legacy_ui_node_execution.cpp src/legacy_ui_node_tree_services.cpp src/layout.cpp @@ -82,6 +84,7 @@ set(PP_LEGACY_APP_SOURCES src/legacy_canvas_mode_pen_line.cpp src/legacy_canvas_mode_helpers.cpp src/legacy_canvas_mode_helpers.h + src/legacy_canvas_mode_mask.cpp src/legacy_canvas_mode_transform.cpp src/legacy_app_shell_services.cpp src/legacy_app_shell_services.h @@ -198,6 +201,8 @@ set(PP_PANOPAINTER_UI_SOURCES src/node_panel_layer.cpp src/node_panel_quick.cpp src/node_panel_stroke.cpp + src/legacy_node_stroke_preview_draw_services.cpp + src/legacy_node_stroke_preview_draw_services.h src/legacy_node_stroke_preview_runtime_services.cpp src/node_stroke_preview.cpp src/node_tool_bucket.cpp diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index b5ad0461..c4cf6cc7 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -81,11 +81,11 @@ Current hotspot files: - `src/canvas.cpp`: 429 lines - `src/app_layout.cpp`: 125 lines -- `src/canvas_modes.cpp`: 720 lines -- `src/node.cpp`: 465 lines +- `src/canvas_modes.cpp`: 402 lines +- `src/node.cpp`: 389 lines - `src/main.cpp`: 271 lines - `src/node_panel_brush.cpp`: 435 lines -- `src/node_stroke_preview.cpp`: 607 lines +- `src/node_stroke_preview.cpp`: 562 lines - `src/node_canvas.cpp`: 219 lines - `src/app.cpp`: 292 lines - `src/app_dialogs.cpp`: 168 lines @@ -347,7 +347,16 @@ Current architecture mismatches that must be treated as real blockers: `added_to_root()`, `handle_on_screen(...)`, template loading helpers, child add/remove/move helpers, and child query helpers now also route through `src/legacy_ui_node_tree_services.cpp` instead of staying inline in - `src/node.cpp`. + `src/node.cpp`, while the `CanvasModeMaskFree` and `CanvasModeMaskLine` + interaction families now also route through + `src/legacy_canvas_mode_mask.cpp` instead of staying inline in + `src/canvas_modes.cpp`, while the remaining live render/pass orchestration in + `NodeStrokePreview::draw_stroke_immediate()` now also routes through + `src/legacy_node_stroke_preview_draw_services.*` instead of staying inline in + `src/node_stroke_preview.cpp`, and while the generic Yoga + style/visibility pocket from `Node::SetWidth(...)` through `Node::GetRTL()` + now also routes through `src/legacy_ui_node_style.*` instead of staying + inline in `src/node.cpp`. - Modern C++23 usage exists in extracted components, especially `std::span`, explicit result/status objects, and a few concepts, but the live app still does not consistently express ownership, thread affinity, or renderer diff --git a/docs/modernization/tasks.md b/docs/modernization/tasks.md index df4a175e..8822cbe1 100644 --- a/docs/modernization/tasks.md +++ b/docs/modernization/tasks.md @@ -152,6 +152,10 @@ Current slice: in `src/legacy_canvas_mode_pen_line.cpp` instead of staying inline in `src/canvas_modes.cpp`, which materially thins another retained pen/line interaction pocket from the broader canvas/render hotspot family. +- The `CanvasModeMaskFree` and `CanvasModeMaskLine` interaction families now + also live in `src/legacy_canvas_mode_mask.cpp` instead of staying inline in + `src/canvas_modes.cpp`, which materially thins another retained mask-tool + interaction pocket from the broader canvas/render hotspot family. Write scope: - `src/canvas.cpp` @@ -326,6 +330,11 @@ 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 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 + `src/node_stroke_preview.cpp`, which trims another coherent preview + draw-pass pocket while preserving the current runtime-facing shell. - `NodeCanvas::init()` plus the remaining `NodeCanvas::draw()` outer shell now 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 @@ -778,6 +787,10 @@ Current slice: `src/legacy_ui_node_tree_services.cpp` instead of staying inline in `src/node.cpp`, which materially thins the remaining generic scene-graph lifecycle/tree shell without changing the public surface. +- The generic Yoga style/visibility pocket from `Node::SetWidth(...)` through + `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. Write scope: - `src/node.cpp` diff --git a/src/canvas_modes.cpp b/src/canvas_modes.cpp index c84e232c..6adb491f 100644 --- a/src/canvas_modes.cpp +++ b/src/canvas_modes.cpp @@ -2,26 +2,19 @@ #include -#include "log.h" #include "canvas_modes.h" #include "layout.h" #include "canvas.h" -#include "shader.h" #include "node_canvas.h" #include "legacy_canvas_draw_merge_services.h" -#include "legacy_canvas_stroke_composite_services.h" #include "legacy_canvas_mode_helpers.h" #include "legacy_ui_overlay_services.h" -#include "legacy_ui_gl_dispatch.h" #include "app.h" #include "util.h" -#include "renderer_gl/opengl_capabilities.h" NodeCanvas* CanvasMode::node; -using pp::legacy_canvas_mode::apply_canvas_mode_capability; using pp::legacy_canvas_mode::apply_canvas_mode_viewport; -using pp::legacy_canvas_mode::query_canvas_mode_capability; using pp::legacy_canvas_mode::query_canvas_mode_read_framebuffer; //////////////////////////////////////////////////////////////////// @@ -199,332 +192,6 @@ void ActionModeGrid::undo() //////////////////////////////////////////////////////////////////// -void CanvasModeMaskFree::init() -{ - m_shape.create(); -} - -void CanvasModeMaskFree::leave(kCanvasMode next) -{ -// Canvas::I->draw_objects(std::bind(&CanvasModeFill::on_Draw, this, glm::mat4(1), std::placeholders::_1, std::placeholders::_2)); - if (next != kCanvasMode::Draw && next != kCanvasMode::Erase && next != kCanvasMode::Line) - { - m_points.clear(); - Canvas::I->m_smask_active = false; - } -} - -void CanvasModeMaskFree::clear() -{ - m_points.clear(); - m_points2d.clear(); - m_shape.clear(); -} - -void CanvasModeMaskFree::on_MouseEvent(MouseEvent* me, glm::vec2& loc) -{ - static glm::vec2 oldpos; - static glm::vec2 oldvec; - static float acc = 0.f; - if (Canvas::I->m_touch_lock && me->m_source == kEventSource::Touch) - return; - switch (me->m_type) - { - case kEventType::MouseDownL: - { - node->mouse_capture(); - m_dragging = true; - m_points2d.clear(); - m_points.clear(); - oldpos = loc; - oldvec = {1.f, 0.f}; - acc = 0; - vertex_t vert; - vert.pos = glm::vec4(loc, 0, 1); - m_points2d.push_back(loc); - m_points2d.push_back(loc); - m_points.push_back(vert); - m_points.push_back(vert); - if (!(App::I->keys[(int)kKey::KeyShift] || App::I->keys[(int)kKey::KeyCtrl])) - Canvas::I->m_smask.clear({0, 0, 0, 0}); - Canvas::I->m_smask_active = true; - Canvas::I->m_smask_mode = 1; - break; - } - case kEventType::MouseUpL: - pp::panopainter::release_legacy_mouse_capture(*node); - m_dragging = false; - if (m_points2d.size() > 3) - { - if (!m_points.empty()) - { - m_selection_cam = Canvas::I->get_camera(); - //m_points2d = poly_intersect(poly_remove_duplicate(m_points2d), Canvas::I->face_to_shape2D(0)); - auto drawer = [this](const glm::mat4& camera, const glm::mat4& proj) { - // blending state intentionally left unchanged here. - apply_canvas_mode_capability(pp::renderer::gl::depth_test_state(), false); - pp::panopainter::setup_legacy_vr_color_shader({ - .color = App::I->keys[(int)kKey::KeyCtrl] ? glm::vec4(0, 0, 0, 1) : glm::vec4(1, 1, 1, 1), - .mvp = proj * camera, - }); - m_shape.draw_fill(); - }; - // use m_shape to render the mask polygon - auto v = triangulate(poly_remove_duplicate(m_points2d)); - Canvas::I->project2Dpoints(v); - m_shape.update_vertices(v.data(), (int)v.size()); - Canvas::I->draw_objects_direct(std::bind(drawer, std::placeholders::_1, std::placeholders::_2), Canvas::I->m_smask, 0); - - // close the path and reset m_shape to contour rendering - m_points.push_back(m_points.back()); - m_points.push_back(m_points.front()); - Canvas::I->project2Dpoints(m_points); - m_shape.update_vertices(m_points.data(), (int)m_points.size()); - } - } - else - { - Canvas::I->m_smask_active = false; - } - break; - case kEventType::MouseMove: - { - if (m_dragging) - { - auto v = loc - oldpos; - float len = glm::length(v); - if (len > 5) - { - m_points.back().pos = glm::vec4(loc, 0, 1); - m_points2d.back() = loc; - - v = glm::normalize(v); - float d = 1.f - glm::dot(v, oldvec); - acc += d; - oldpos = loc; - oldvec = v; - if (acc > 0.001) // angle change tolerance - { - //LOG("d=%f acc=%f", d, acc); - acc = 0; - - m_points2d.push_back(loc); - vertex_t vert; - vert.pos = glm::vec4(loc, 0, 1); - m_points.push_back(vert); - m_points.push_back(vert); - } - m_shape.update_vertices(m_points.data(), (int)m_points.size()); - } - } - break; - } - case kEventType::MouseCancel: - if (m_dragging) - { - m_points.pop_back(); - m_shape.update_vertices(m_points.data(), (int)m_points.size()); - } - m_dragging = false; - pp::panopainter::release_legacy_mouse_capture(*node); - if (m_points.size() < 4) - { - m_points.clear(); - m_shape.update_vertices(m_points.data(), (int)m_points.size()); - } - break; - default: - break; - } -} - -void CanvasModeMaskFree::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) -{ - const bool depth = query_canvas_mode_capability(pp::renderer::gl::depth_test_state()); - apply_canvas_mode_capability(pp::renderer::gl::depth_test_state(), false); - if (m_points.size() > 3) - { - if (m_dragging) - { - pp::panopainter::setup_legacy_vr_color_shader({ - .color = { 0, 0, 0, 1 }, - .mvp = glm::scale(glm::vec3(1, -1, 1)) * ortho, - }); - //m_dragging ? m_shape.draw_stroke() : m_shape.draw_fill(); - m_shape.draw_stroke(); - } - //else - //{ - // ShaderManager::use(kShader::Color); - // ShaderManager::u_mat4(kShaderUniform::MVP, proj * camera); - // ShaderManager::u_vec4(kShaderUniform::Col, { 0, 0, 0, 1 }); - // m_shape.draw_stroke(); - //} - } - if (depth) apply_canvas_mode_capability(pp::renderer::gl::depth_test_state(), true); -} - - -//////////////////////////////////////////////////////////////////// - -void CanvasModeMaskLine::init() -{ - m_shape.create(); -} - -void CanvasModeMaskLine::leave(kCanvasMode next) -{ - if (next != kCanvasMode::Draw && next != kCanvasMode::Erase && next != kCanvasMode::Line) - { - m_points.clear(); - m_active_tool = false; - Canvas::I->m_smask_active = false; - } - - if (!m_active_tool) - return; - - if (m_points2d.size() > 3) - { - std::vector points; - for (int i = 0; i < (int)m_points2d.size(); i++) - points.emplace_back(m_points2d[i]); - auto v = triangulate(poly_remove_duplicate(points)); - Canvas::I->project2Dpoints(v); - LOG("%d points", (int)v.size()); - - m_shape.update_vertices(v.data(), (int)v.size()); - - if (!m_points.empty()) - { - auto drawer = [this](const glm::mat4& camera, const glm::mat4& proj) { - // blending state intentionally left unchanged here. - pp::panopainter::setup_legacy_vr_color_shader({ - .color = { 1, 1, 1, 1 }, - .mvp = proj * camera, - }); - m_shape.draw_fill(); - }; - Canvas::I->draw_objects_direct(std::bind(drawer, std::placeholders::_1, std::placeholders::_2), Canvas::I->m_smask, 0); - - //m_points.clear(); - // close the path - m_points.push_back(m_points.back()); - m_points.push_back(m_points.back()); - m_points.push_back(m_points.front()); - Canvas::I->project2Dpoints(m_points); - // reset m_shape to contour rendering - m_shape.update_vertices(m_points.data(), (int)m_points.size()); - } - } - else - { - Canvas::I->m_smask_active = false; - } - m_active_tool = false; -} - -void CanvasModeMaskLine::enter(kCanvasMode prev) -{ - //m_points2d.clear(); - //m_points.clear(); - //Canvas::I->m_smask.clear({0, 0, 0, 0}); - //m_active_tool = true; -} - -void CanvasModeMaskLine::on_MouseEvent(MouseEvent* me, glm::vec2& loc) -{ - if (Canvas::I->m_touch_lock && me->m_source == kEventSource::Touch) - return; - switch (me->m_type) - { - case kEventType::MouseDownL: - { - if (m_active_tool == false) - { - m_active_tool = true; - m_points2d.clear(); - m_points.clear(); - Canvas::I->m_smask.clear({ 0, 0, 0, 0 }); - Canvas::I->m_smask_active = true; - Canvas::I->m_smask_mode = 2; - } - node->mouse_capture(); - m_dragging = true; - m_points2d.push_back(loc); - vertex_t vert; - vert.pos = glm::vec4(loc, 0, 1); - m_points.push_back(vert); - m_shape.update_vertices(m_points.data(), (int)m_points.size()); - break; - } - case kEventType::MouseUpL: - pp::panopainter::release_legacy_mouse_capture(*node); - m_dragging = false; - if (m_points.size() > 1) - { - m_selection_cam = Canvas::I->get_camera(); - m_points.push_back(m_points.back()); - m_shape.update_vertices(m_points.data(), (int)m_points.size()); - } - break; - case kEventType::MouseMove: - { - if (m_dragging) - { - if (glm::distance(m_points2d.front(), loc) < 10) - loc = m_points2d.front(); - m_points.back().pos = glm::vec4(loc, 0, 1); - m_points2d.back() = loc; - m_shape.update_vertices(m_points.data(), (int)m_points.size()); - } - break; - } - case kEventType::MouseCancel: - if (m_dragging) - { - m_points.pop_back(); - m_shape.update_vertices(m_points.data(), (int)m_points.size()); - } - m_dragging = false; - pp::panopainter::release_legacy_mouse_capture(*node); - if (m_points.size() < 4) - { - m_points.clear(); - m_shape.update_vertices(m_points.data(), (int)m_points.size()); - } - break; - default: - break; - } -} - -void CanvasModeMaskLine::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) -{ - if (m_points.size() > 1) - { - if (m_active_tool) - { - pp::panopainter::setup_legacy_vr_color_shader({ - .color = { 0, 0, 0, 1 }, - .mvp = glm::scale(glm::vec3(1, -1, 1)) * ortho, - }); - //m_dragging ? m_shape.draw_stroke() : m_shape.draw_fill(); - m_shape.draw_stroke(); - } - else - { - pp::panopainter::setup_legacy_vr_color_shader({ - .color = { 0, 0, 0, 1 }, - .mvp = proj * camera, - }); - m_shape.draw_stroke(); - } - } -} - -//////////////////////////////////////////////////////////////////// - void CanvasModeFill::init() { m_shape.create(); diff --git a/src/legacy_canvas_mode_mask.cpp b/src/legacy_canvas_mode_mask.cpp new file mode 100644 index 00000000..82982735 --- /dev/null +++ b/src/legacy_canvas_mode_mask.cpp @@ -0,0 +1,327 @@ +#include "pch.h" + +#include "canvas_modes.h" + +#include "app.h" +#include "canvas.h" +#include "legacy_canvas_mode_helpers.h" +#include "legacy_ui_overlay_services.h" +#include "log.h" +#include "renderer_gl/opengl_capabilities.h" + +using pp::legacy_canvas_mode::apply_canvas_mode_capability; +using pp::legacy_canvas_mode::query_canvas_mode_capability; + +void CanvasModeMaskFree::init() +{ + m_shape.create(); +} + +void CanvasModeMaskFree::leave(kCanvasMode next) +{ +// Canvas::I->draw_objects(std::bind(&CanvasModeFill::on_Draw, this, glm::mat4(1), std::placeholders::_1, std::placeholders::_2)); + if (next != kCanvasMode::Draw && next != kCanvasMode::Erase && next != kCanvasMode::Line) + { + m_points.clear(); + Canvas::I->m_smask_active = false; + } +} + +void CanvasModeMaskFree::clear() +{ + m_points.clear(); + m_points2d.clear(); + m_shape.clear(); +} + +void CanvasModeMaskFree::on_MouseEvent(MouseEvent* me, glm::vec2& loc) +{ + static glm::vec2 oldpos; + static glm::vec2 oldvec; + static float acc = 0.f; + if (Canvas::I->m_touch_lock && me->m_source == kEventSource::Touch) + return; + switch (me->m_type) + { + case kEventType::MouseDownL: + { + node->mouse_capture(); + m_dragging = true; + m_points2d.clear(); + m_points.clear(); + oldpos = loc; + oldvec = {1.f, 0.f}; + acc = 0; + vertex_t vert; + vert.pos = glm::vec4(loc, 0, 1); + m_points2d.push_back(loc); + m_points2d.push_back(loc); + m_points.push_back(vert); + m_points.push_back(vert); + if (!(App::I->keys[(int)kKey::KeyShift] || App::I->keys[(int)kKey::KeyCtrl])) + Canvas::I->m_smask.clear({0, 0, 0, 0}); + Canvas::I->m_smask_active = true; + Canvas::I->m_smask_mode = 1; + break; + } + case kEventType::MouseUpL: + pp::panopainter::release_legacy_mouse_capture(*node); + m_dragging = false; + if (m_points2d.size() > 3) + { + if (!m_points.empty()) + { + m_selection_cam = Canvas::I->get_camera(); + //m_points2d = poly_intersect(poly_remove_duplicate(m_points2d), Canvas::I->face_to_shape2D(0)); + auto drawer = [this](const glm::mat4& camera, const glm::mat4& proj) { + // blending state intentionally left unchanged here. + apply_canvas_mode_capability(pp::renderer::gl::depth_test_state(), false); + pp::panopainter::setup_legacy_vr_color_shader({ + .color = App::I->keys[(int)kKey::KeyCtrl] ? glm::vec4(0, 0, 0, 1) : glm::vec4(1, 1, 1, 1), + .mvp = proj * camera, + }); + m_shape.draw_fill(); + }; + // use m_shape to render the mask polygon + auto v = triangulate(poly_remove_duplicate(m_points2d)); + Canvas::I->project2Dpoints(v); + m_shape.update_vertices(v.data(), (int)v.size()); + Canvas::I->draw_objects_direct(std::bind(drawer, std::placeholders::_1, std::placeholders::_2), Canvas::I->m_smask, 0); + + // close the path and reset m_shape to contour rendering + m_points.push_back(m_points.back()); + m_points.push_back(m_points.front()); + Canvas::I->project2Dpoints(m_points); + m_shape.update_vertices(m_points.data(), (int)m_points.size()); + } + } + else + { + Canvas::I->m_smask_active = false; + } + break; + case kEventType::MouseMove: + { + if (m_dragging) + { + auto v = loc - oldpos; + float len = glm::length(v); + if (len > 5) + { + m_points.back().pos = glm::vec4(loc, 0, 1); + m_points2d.back() = loc; + + v = glm::normalize(v); + float d = 1.f - glm::dot(v, oldvec); + acc += d; + oldpos = loc; + oldvec = v; + if (acc > 0.001) // angle change tolerance + { + //LOG("d=%f acc=%f", d, acc); + acc = 0; + + m_points2d.push_back(loc); + vertex_t vert; + vert.pos = glm::vec4(loc, 0, 1); + m_points.push_back(vert); + m_points.push_back(vert); + } + m_shape.update_vertices(m_points.data(), (int)m_points.size()); + } + } + break; + } + case kEventType::MouseCancel: + if (m_dragging) + { + m_points.pop_back(); + m_shape.update_vertices(m_points.data(), (int)m_points.size()); + } + m_dragging = false; + pp::panopainter::release_legacy_mouse_capture(*node); + if (m_points.size() < 4) + { + m_points.clear(); + m_shape.update_vertices(m_points.data(), (int)m_points.size()); + } + break; + default: + break; + } +} + +void CanvasModeMaskFree::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) +{ + const bool depth = query_canvas_mode_capability(pp::renderer::gl::depth_test_state()); + apply_canvas_mode_capability(pp::renderer::gl::depth_test_state(), false); + if (m_points.size() > 3) + { + if (m_dragging) + { + pp::panopainter::setup_legacy_vr_color_shader({ + .color = { 0, 0, 0, 1 }, + .mvp = glm::scale(glm::vec3(1, -1, 1)) * ortho, + }); + //m_dragging ? m_shape.draw_stroke() : m_shape.draw_fill(); + m_shape.draw_stroke(); + } + } + if (depth) apply_canvas_mode_capability(pp::renderer::gl::depth_test_state(), true); +} + +void CanvasModeMaskLine::init() +{ + m_shape.create(); +} + +void CanvasModeMaskLine::leave(kCanvasMode next) +{ + if (next != kCanvasMode::Draw && next != kCanvasMode::Erase && next != kCanvasMode::Line) + { + m_points.clear(); + m_active_tool = false; + Canvas::I->m_smask_active = false; + } + + if (!m_active_tool) + return; + + if (m_points2d.size() > 3) + { + std::vector points; + for (int i = 0; i < (int)m_points2d.size(); i++) + points.emplace_back(m_points2d[i]); + auto v = triangulate(poly_remove_duplicate(points)); + Canvas::I->project2Dpoints(v); + LOG("%d points", (int)v.size()); + + m_shape.update_vertices(v.data(), (int)v.size()); + + if (!m_points.empty()) + { + auto drawer = [this](const glm::mat4& camera, const glm::mat4& proj) { + // blending state intentionally left unchanged here. + pp::panopainter::setup_legacy_vr_color_shader({ + .color = { 1, 1, 1, 1 }, + .mvp = proj * camera, + }); + m_shape.draw_fill(); + }; + Canvas::I->draw_objects_direct(std::bind(drawer, std::placeholders::_1, std::placeholders::_2), Canvas::I->m_smask, 0); + + //m_points.clear(); + // close the path + m_points.push_back(m_points.back()); + m_points.push_back(m_points.back()); + m_points.push_back(m_points.front()); + Canvas::I->project2Dpoints(m_points); + // reset m_shape to contour rendering + m_shape.update_vertices(m_points.data(), (int)m_points.size()); + } + } + else + { + Canvas::I->m_smask_active = false; + } + m_active_tool = false; +} + +void CanvasModeMaskLine::enter(kCanvasMode prev) +{ + //m_points2d.clear(); + //m_points.clear(); + //Canvas::I->m_smask.clear({0, 0, 0, 0}); + //m_active_tool = true; +} + +void CanvasModeMaskLine::on_MouseEvent(MouseEvent* me, glm::vec2& loc) +{ + if (Canvas::I->m_touch_lock && me->m_source == kEventSource::Touch) + return; + switch (me->m_type) + { + case kEventType::MouseDownL: + { + if (m_active_tool == false) + { + m_active_tool = true; + m_points2d.clear(); + m_points.clear(); + Canvas::I->m_smask.clear({ 0, 0, 0, 0 }); + Canvas::I->m_smask_active = true; + Canvas::I->m_smask_mode = 2; + } + node->mouse_capture(); + m_dragging = true; + m_points2d.push_back(loc); + vertex_t vert; + vert.pos = glm::vec4(loc, 0, 1); + m_points.push_back(vert); + m_shape.update_vertices(m_points.data(), (int)m_points.size()); + break; + } + case kEventType::MouseUpL: + pp::panopainter::release_legacy_mouse_capture(*node); + m_dragging = false; + if (m_points.size() > 1) + { + m_selection_cam = Canvas::I->get_camera(); + m_points.push_back(m_points.back()); + m_shape.update_vertices(m_points.data(), (int)m_points.size()); + } + break; + case kEventType::MouseMove: + { + if (m_dragging) + { + if (glm::distance(m_points2d.front(), loc) < 10) + loc = m_points2d.front(); + m_points.back().pos = glm::vec4(loc, 0, 1); + m_points2d.back() = loc; + m_shape.update_vertices(m_points.data(), (int)m_points.size()); + } + break; + } + case kEventType::MouseCancel: + if (m_dragging) + { + m_points.pop_back(); + m_shape.update_vertices(m_points.data(), (int)m_points.size()); + } + m_dragging = false; + pp::panopainter::release_legacy_mouse_capture(*node); + if (m_points.size() < 4) + { + m_points.clear(); + m_shape.update_vertices(m_points.data(), (int)m_points.size()); + } + break; + default: + break; + } +} + +void CanvasModeMaskLine::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) +{ + if (m_points.size() > 1) + { + if (m_active_tool) + { + pp::panopainter::setup_legacy_vr_color_shader({ + .color = { 0, 0, 0, 1 }, + .mvp = glm::scale(glm::vec3(1, -1, 1)) * ortho, + }); + //m_dragging ? m_shape.draw_stroke() : m_shape.draw_fill(); + m_shape.draw_stroke(); + } + else + { + pp::panopainter::setup_legacy_vr_color_shader({ + .color = { 0, 0, 0, 1 }, + .mvp = proj * camera, + }); + m_shape.draw_stroke(); + } + } +} diff --git a/src/legacy_node_stroke_preview_draw_services.cpp b/src/legacy_node_stroke_preview_draw_services.cpp new file mode 100644 index 00000000..2d472ae1 --- /dev/null +++ b/src/legacy_node_stroke_preview_draw_services.cpp @@ -0,0 +1,123 @@ +#include "pch.h" + +#include "legacy_node_stroke_preview_draw_services.h" + +namespace pp::panopainter { + +namespace { + +bool has_valid_live_render_callbacks(const LegacyNodeStrokePreviewLiveRenderRequest& request) +{ + return request.bind_dual_pass_textures && + request.capture_background && + request.compute_frames && + request.draw_samples && + request.draw_mix && + request.unbind_mixer_texture && + request.bind_pattern_texture && + request.draw_composite; +} + +} // namespace + +bool execute_legacy_node_stroke_preview_live_render_passes( + const LegacyNodeStrokePreviewLiveRenderRequest& request) +{ + if (!has_valid_live_render_callbacks(request)) { + return false; + } + + return execute_legacy_node_stroke_preview_draw_immediate_shell( + request.brush, + request.pass_orchestration, + request.stroke_texture, + request.mixer_rtt, + request.render_target, + request.background_texture, + request.dual_texture, + request.preview_texture, + request.linear_sampler, + request.repeat_sampler, + request.copy_stroke_destination, + request.size, + kLegacyNodeStrokePreviewStrokeTextureSlot, + [&] { + if (!request.pass_orchestration.material.dual_pass.enabled) { + return; + } + + setup_legacy_stroke_dual_shader(request.pass_orchestration.material.dual_pass.uses_pattern); + request.bind_dual_pass_textures(*request.prepared_strokes.dual_brush); + execute_legacy_stroke_preview_live_pass( + [&] { + request.render_target.clear(); + }, + [&] { + return request.compute_frames( + const_cast(request.prepared_strokes.dual_stroke), + request.zoom); + }, + [](auto& frame) { + frame.col = { 0, 0, 0, 1 }; + }, + [&](auto& frame) { + use_legacy_stroke_shader(); + apply_legacy_stroke_sample_uniforms( + LegacyStrokeSampleUniforms { + .color = frame.col, + .alpha = frame.flow, + .opacity = frame.opacity, + }); + }, + [&](auto& frame) { + request.draw_samples(frame.shapes, request.dual_texture, request.copy_stroke_destination); + }, + [&] { + copy_legacy_node_stroke_preview_framebuffer_to_texture( + request.dual_texture, + request.size, + kLegacyNodeStrokePreviewStrokeTextureSlot); + }); + }, + [&] { + request.capture_background(request.pass_orchestration.background_colorize); + }, + [&] { + return request.compute_frames( + const_cast(request.prepared_strokes.stroke), + request.zoom); + }, + [&](auto& frame) { + if (request.brush.m_tip_mix > 0.0f) { + request.draw_mix(xy(frame.mixer_rect), zw(frame.mixer_rect)); + } + + frame.col = request.brush.m_blend_mode != 0 || request.brush.m_tip_mix > 0.0f ? + glm::vec4 { .7f, .4f, .1f, 1.0f } : + glm::vec4 { 0.0f, 0.0f, 0.0f, 1.0f }; + frame.flow = glm::max(frame.flow, request.min_flow); + }, + [&](auto& frame) { + use_legacy_stroke_shader(); + apply_legacy_stroke_sample_uniforms( + LegacyStrokeSampleUniforms { + .color = frame.col, + .alpha = frame.flow, + .opacity = frame.opacity, + }); + }, + [&](auto& frame) { + request.draw_samples(frame.shapes, request.stroke_texture, request.copy_stroke_destination); + }, + [&] { + request.unbind_mixer_texture(); + }, + [&] { + request.bind_pattern_texture(); + }, + [&] { + request.draw_composite(); + }); +} + +} // namespace pp::panopainter diff --git a/src/legacy_node_stroke_preview_draw_services.h b/src/legacy_node_stroke_preview_draw_services.h new file mode 100644 index 00000000..1c49eeaa --- /dev/null +++ b/src/legacy_node_stroke_preview_draw_services.h @@ -0,0 +1,51 @@ +#pragma once + +#include "brush.h" +#include "legacy_node_stroke_preview_execution_services.h" +#include "rtt.h" +#include "texture.h" + +#include +#include +#include + +namespace pp::panopainter { + +struct LegacyNodeStrokePreviewFrame { + glm::vec4 col {}; + float flow = 0.0f; + float opacity = 0.0f; + std::array shapes {}; + glm::vec4 mixer_rect {}; +}; + +struct LegacyNodeStrokePreviewLiveRenderRequest { + const Brush& brush; + const LegacyNodeStrokePreviewPassOrchestrationPlan& pass_orchestration; + const LegacyNodeStrokePreviewPreparedStrokes& prepared_strokes; + Texture2D& stroke_texture; + RTT& mixer_rtt; + RTT& render_target; + Texture2D& background_texture; + Texture2D& dual_texture; + Texture2D& preview_texture; + Sampler& linear_sampler; + Sampler& repeat_sampler; + float zoom = 1.0f; + float min_flow = 0.0f; + bool copy_stroke_destination = false; + glm::vec2 size {}; + std::function bind_dual_pass_textures; + std::function capture_background; + std::function(const Stroke&, float)> compute_frames; + std::function&, Texture2D&, bool)> draw_samples; + std::function draw_mix; + std::function unbind_mixer_texture; + std::function bind_pattern_texture; + std::function draw_composite; +}; + +[[nodiscard]] bool execute_legacy_node_stroke_preview_live_render_passes( + const LegacyNodeStrokePreviewLiveRenderRequest& request); + +} // namespace pp::panopainter diff --git a/src/legacy_ui_node_style.cpp b/src/legacy_ui_node_style.cpp new file mode 100644 index 00000000..4eb1fa23 --- /dev/null +++ b/src/legacy_ui_node_style.cpp @@ -0,0 +1,250 @@ +#include "pch.h" +#include "legacy_ui_node_style.h" + +#include "app.h" +#include "node.h" + +namespace pp::panopainter { + +void legacy_ui_node_set_width(Node& node, float value) +{ + YGNodeStyleSetWidth(node.y_node, value); + node.m_size.x = value; + node.auto_width = value == YGUndefined; + node.app_redraw(); +} + +void legacy_ui_node_set_width_percent(Node& node, float value) +{ + YGNodeStyleSetWidthPercent(node.y_node, value); + node.auto_width = value == YGUndefined; + node.app_redraw(); +} + +void legacy_ui_node_set_height(Node& node, float value) +{ + YGNodeStyleSetHeight(node.y_node, value); + node.m_size.y = value; + node.auto_height = value == YGUndefined; + node.app_redraw(); +} + +void legacy_ui_node_set_height_percent(Node& node, float value) +{ + YGNodeStyleSetHeightPercent(node.y_node, value); + node.auto_height = value == YGUndefined; + node.app_redraw(); +} + +void legacy_ui_node_set_max_width(Node& node, float value) +{ + YGNodeStyleSetMaxWidth(node.y_node, value); + node.app_redraw(); +} + +void legacy_ui_node_set_max_width_percent(Node& node, float value) +{ + YGNodeStyleSetMaxWidthPercent(node.y_node, value); + node.app_redraw(); +} + +void legacy_ui_node_set_max_height(Node& node, float value) +{ + YGNodeStyleSetMaxHeight(node.y_node, value); + node.app_redraw(); +} + +void legacy_ui_node_set_max_height_percent(Node& node, float value) +{ + YGNodeStyleSetMaxHeightPercent(node.y_node, value); + node.app_redraw(); +} + +void legacy_ui_node_set_min_width(Node& node, float value) +{ + YGNodeStyleSetMinWidth(node.y_node, value); + node.app_redraw(); +} + +void legacy_ui_node_set_min_width_percent(Node& node, float value) +{ + YGNodeStyleSetMinWidthPercent(node.y_node, value); + node.app_redraw(); +} + +void legacy_ui_node_set_min_height(Node& node, float value) +{ + YGNodeStyleSetMinHeight(node.y_node, value); + node.app_redraw(); +} + +void legacy_ui_node_set_min_height_percent(Node& node, float value) +{ + YGNodeStyleSetMinHeightPercent(node.y_node, value); + node.app_redraw(); +} + +void legacy_ui_node_set_padding(Node& node, float t, float r, float b, float l) +{ + YGNodeStyleSetPadding(node.y_node, YGEdgeTop, t); + YGNodeStyleSetPadding(node.y_node, YGEdgeRight, r); + YGNodeStyleSetPadding(node.y_node, YGEdgeBottom, b); + YGNodeStyleSetPadding(node.y_node, YGEdgeLeft, l); + node.app_redraw(); +} + +glm::vec4 legacy_ui_node_get_padding(const Node& node) +{ + float t = YGNodeLayoutGetPadding(node.y_node, YGEdgeTop); + float r = YGNodeLayoutGetPadding(node.y_node, YGEdgeRight); + float b = YGNodeLayoutGetPadding(node.y_node, YGEdgeBottom); + float l = YGNodeLayoutGetPadding(node.y_node, YGEdgeLeft); + return { t, r, b, l }; +} + +void legacy_ui_node_set_margin(Node& node, float t, float r, float b, float l) +{ + YGNodeStyleSetMargin(node.y_node, YGEdgeTop, t); + YGNodeStyleSetMargin(node.y_node, YGEdgeRight, r); + YGNodeStyleSetMargin(node.y_node, YGEdgeBottom, b); + YGNodeStyleSetMargin(node.y_node, YGEdgeLeft, l); + node.app_redraw(); +} + +glm::vec4 legacy_ui_node_get_margin(const Node& node) +{ + float t = YGNodeLayoutGetMargin(node.y_node, YGEdgeTop); + float r = YGNodeLayoutGetMargin(node.y_node, YGEdgeRight); + float b = YGNodeLayoutGetMargin(node.y_node, YGEdgeBottom); + float l = YGNodeLayoutGetMargin(node.y_node, YGEdgeLeft); + return { t, r, b, l }; +} + +void legacy_ui_node_set_position(Node& node, float l, float t) +{ + YGNodeStyleSetPosition(node.y_node, YGEdgeTop, t); + YGNodeStyleSetPosition(node.y_node, YGEdgeLeft, l); + node.m_pos = { l, t }; + node.app_redraw(); +} + +void legacy_ui_node_set_position(Node& node, float l, float t, float r, float b) +{ + YGNodeStyleSetPosition(node.y_node, YGEdgeTop, t); + YGNodeStyleSetPosition(node.y_node, YGEdgeRight, r); + YGNodeStyleSetPosition(node.y_node, YGEdgeBottom, b); + YGNodeStyleSetPosition(node.y_node, YGEdgeLeft, l); + node.app_redraw(); +} + +void legacy_ui_node_set_flex_grow(Node& node, float value) +{ + YGNodeStyleSetFlexGrow(node.y_node, value); + node.app_redraw(); +} + +void legacy_ui_node_set_flex_shrink(Node& node, float value) +{ + YGNodeStyleSetFlexShrink(node.y_node, value); + node.app_redraw(); +} + +void legacy_ui_node_set_flex_dir(Node& node, YGFlexDirection value) +{ + YGNodeStyleSetFlexDirection(node.y_node, value); + node.app_redraw(); +} + +void legacy_ui_node_set_flex_wrap(Node& node, YGWrap value) +{ + YGNodeStyleSetFlexWrap(node.y_node, value); + node.app_redraw(); +} + +void legacy_ui_node_set_justify(Node& node, YGJustify value) +{ + YGNodeStyleSetJustifyContent(node.y_node, value); + node.app_redraw(); +} + +void legacy_ui_node_set_align(Node& node, YGAlign value) +{ + YGNodeStyleSetAlignItems(node.y_node, value); + node.app_redraw(); +} + +void legacy_ui_node_set_positioning(Node& node, YGPositionType value) +{ + YGNodeStyleSetPositionType(node.y_node, value); + node.app_redraw(); +} + +void legacy_ui_node_set_aspect_ratio(Node& node, float ar) +{ + YGNodeStyleSetAspectRatio(node.y_node, ar); + node.app_redraw(); +} + +void legacy_ui_node_set_rtl(Node& node, YGDirection dir) +{ + YGNodeStyleSetDirection(node.y_node, dir); + node.app_redraw(); +} + +bool legacy_ui_node_get_visibility(const Node& node) +{ + return node.m_display; +} + +void legacy_ui_node_set_visibility(Node& node, bool visible) +{ + App::I->ui_task([&node, visible] + { + if (node.m_display && !visible) + { + int idx = node.m_parent->get_child_index(&node); + YGNodeRemoveChild(node.m_parent->y_node, node.y_node); + node.y_placeholder = YGNodeNew(); + YGNodeInsertChild(node.m_parent->y_node, node.y_placeholder, idx); + } + else if (!node.m_display && visible) + { + int count = YGNodeGetChildCount(node.m_parent->y_node); + for (int i = 0; i < count; i++) + { + if (YGNodeGetChild(node.m_parent->y_node, i) == node.y_placeholder) + { + YGNodeRemoveChild(node.m_parent->y_node, node.y_placeholder); + YGNodeInsertChild(node.m_parent->y_node, node.y_node, i); + YGNodeFree(node.y_placeholder); + node.y_placeholder = nullptr; + break; + } + } + } + }); + node.m_display = visible; + node.app_redraw(); +} + +glm::vec2 legacy_ui_node_get_position(const Node& node) +{ + return { YGNodeLayoutGetLeft(node.y_node), YGNodeLayoutGetTop(node.y_node) }; +} + +float legacy_ui_node_get_width(const Node& node) +{ + return YGNodeLayoutGetWidth(node.y_node); +} + +float legacy_ui_node_get_height(const Node& node) +{ + return YGNodeLayoutGetHeight(node.y_node); +} + +YGDirection legacy_ui_node_get_rtl(const Node& node) +{ + return YGNodeStyleGetDirection(node.y_node); +} + +} // namespace pp::panopainter diff --git a/src/legacy_ui_node_style.h b/src/legacy_ui_node_style.h new file mode 100644 index 00000000..8562d5d0 --- /dev/null +++ b/src/legacy_ui_node_style.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include +#include + +class Node; + +namespace pp::panopainter { + +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_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); +void legacy_ui_node_set_max_height_percent(Node& node, float value); +void legacy_ui_node_set_min_width(Node& node, float value); +void legacy_ui_node_set_min_width_percent(Node& node, float value); +void legacy_ui_node_set_min_height(Node& node, float value); +void legacy_ui_node_set_min_height_percent(Node& node, float value); +void legacy_ui_node_set_padding(Node& node, float t, float r, float b, float l); +glm::vec4 legacy_ui_node_get_padding(const Node& node); +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_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); +void legacy_ui_node_set_flex_wrap(Node& node, YGWrap value); +void legacy_ui_node_set_justify(Node& node, YGJustify value); +void legacy_ui_node_set_align(Node& node, YGAlign value); +void legacy_ui_node_set_positioning(Node& node, YGPositionType value); +void legacy_ui_node_set_aspect_ratio(Node& node, float ar); +void legacy_ui_node_set_rtl(Node& node, YGDirection dir); +bool legacy_ui_node_get_visibility(const Node& node); +void legacy_ui_node_set_visibility(Node& node, bool visible); +glm::vec2 legacy_ui_node_get_position(const Node& node); +float legacy_ui_node_get_width(const Node& node); +float legacy_ui_node_get_height(const Node& node); +YGDirection legacy_ui_node_get_rtl(const Node& node); + +} // namespace pp::panopainter diff --git a/src/node.cpp b/src/node.cpp index a4fde796..ea475127 100644 --- a/src/node.cpp +++ b/src/node.cpp @@ -4,6 +4,7 @@ #include "legacy_ui_node_attributes.h" #include "legacy_ui_node_event.h" #include "legacy_ui_node_loader.h" +#include "legacy_ui_node_style.h" #include "node.h" #include "layout.h" #include "util.h" @@ -163,32 +164,22 @@ Node::~Node() void Node::SetWidth(float value) { - YGNodeStyleSetWidth(y_node, value); - m_size.x = value; - auto_width = value == YGUndefined; - app_redraw(); + pp::panopainter::legacy_ui_node_set_width(*this, value); } void Node::SetWidthP(float value) { - YGNodeStyleSetWidthPercent(y_node, value); - auto_width = value == YGUndefined; - app_redraw(); + pp::panopainter::legacy_ui_node_set_width_percent(*this, value); } void Node::SetHeight(float value) { - YGNodeStyleSetHeight(y_node, value); - m_size.y = value; - auto_height = value == YGUndefined; - app_redraw(); + pp::panopainter::legacy_ui_node_set_height(*this, value); } void Node::SetHeightP(float value) { - YGNodeStyleSetHeightPercent(y_node, value); - auto_height = value == YGUndefined; - app_redraw(); + pp::panopainter::legacy_ui_node_set_height_percent(*this, value); } void Node::SetSize(float w, float h) @@ -231,86 +222,62 @@ void Node::SetMaxSize(glm::vec2 value) void Node::SetMaxWidth(float value) { - YGNodeStyleSetMaxWidth(y_node, value); - app_redraw(); + pp::panopainter::legacy_ui_node_set_max_width(*this, value); } void Node::SetMaxWidthP(float value) { - YGNodeStyleSetMaxWidthPercent(y_node, value); - app_redraw(); + pp::panopainter::legacy_ui_node_set_max_width_percent(*this, value); } void Node::SetMaxHeight(float value) { - YGNodeStyleSetMaxHeight(y_node, value); - app_redraw(); + pp::panopainter::legacy_ui_node_set_max_height(*this, value); } void Node::SetMaxHeightP(float value) { - YGNodeStyleSetMaxHeightPercent(y_node, value); - app_redraw(); + pp::panopainter::legacy_ui_node_set_max_height_percent(*this, value); } void Node::SetMinWidth(float value) { - YGNodeStyleSetMinWidth(y_node, value); - app_redraw(); + pp::panopainter::legacy_ui_node_set_min_width(*this, value); } void Node::SetMinWidthP(float value) { - YGNodeStyleSetMinWidthPercent(y_node, value); - app_redraw(); + pp::panopainter::legacy_ui_node_set_min_width_percent(*this, value); } void Node::SetMinHeight(float value) { - YGNodeStyleSetMinHeight(y_node, value); - app_redraw(); + pp::panopainter::legacy_ui_node_set_min_height(*this, value); } void Node::SetMinHeightP(float value) { - YGNodeStyleSetMinHeightPercent(y_node, value); - app_redraw(); + pp::panopainter::legacy_ui_node_set_min_height_percent(*this, value); } void Node::SetPadding(float t, float r, float b, float l) { - YGNodeStyleSetPadding(y_node, YGEdgeTop, t); - YGNodeStyleSetPadding(y_node, YGEdgeRight, r); - YGNodeStyleSetPadding(y_node, YGEdgeBottom, b); - YGNodeStyleSetPadding(y_node, YGEdgeLeft, l); - app_redraw(); + pp::panopainter::legacy_ui_node_set_padding(*this, t, r, b, l); } glm::vec4 Node::GetPadding() const { - float t = YGNodeLayoutGetPadding(y_node, YGEdgeTop); - float r = YGNodeLayoutGetPadding(y_node, YGEdgeRight); - float b = YGNodeLayoutGetPadding(y_node, YGEdgeBottom); - float l = YGNodeLayoutGetPadding(y_node, YGEdgeLeft); - return{ t, r, b, l }; + return pp::panopainter::legacy_ui_node_get_padding(*this); } void Node::SetMargin(float t, float r, float b, float l) { - YGNodeStyleSetMargin(y_node, YGEdgeTop, t); - YGNodeStyleSetMargin(y_node, YGEdgeRight, r); - YGNodeStyleSetMargin(y_node, YGEdgeBottom, b); - YGNodeStyleSetMargin(y_node, YGEdgeLeft, l); - app_redraw(); + pp::panopainter::legacy_ui_node_set_margin(*this, t, r, b, l); } glm::vec4 Node::GetMargin() const { - float t = YGNodeLayoutGetMargin(y_node, YGEdgeTop); - float r = YGNodeLayoutGetMargin(y_node, YGEdgeRight); - float b = YGNodeLayoutGetMargin(y_node, YGEdgeBottom); - float l = YGNodeLayoutGetMargin(y_node, YGEdgeLeft); - return{ t, r, b, l }; + return pp::panopainter::legacy_ui_node_get_margin(*this); } void Node::SetPosition(const glm::vec2 pos) @@ -322,110 +289,67 @@ void Node::SetPosition(const glm::vec2 pos) void Node::SetPosition(float l, float t) { - YGNodeStyleSetPosition(y_node, YGEdgeTop, t); - YGNodeStyleSetPosition(y_node, YGEdgeLeft, l); - m_pos = {l, t}; - app_redraw(); + pp::panopainter::legacy_ui_node_set_position(*this, l, t); } void Node::SetPosition(float l, float t, float r, float b) { - YGNodeStyleSetPosition(y_node, YGEdgeTop, t); - YGNodeStyleSetPosition(y_node, YGEdgeRight, r); - YGNodeStyleSetPosition(y_node, YGEdgeBottom, b); - YGNodeStyleSetPosition(y_node, YGEdgeLeft, l); - app_redraw(); + pp::panopainter::legacy_ui_node_set_position(*this, l, t, r, b); } void Node::SetFlexGrow(float value) { - YGNodeStyleSetFlexGrow(y_node, value); - app_redraw(); + pp::panopainter::legacy_ui_node_set_flex_grow(*this, value); } void Node::SetFlexShrink(float value) { - YGNodeStyleSetFlexShrink(y_node, value); - app_redraw(); + pp::panopainter::legacy_ui_node_set_flex_shrink(*this, value); } void Node::SetFlexDir(YGFlexDirection value) { - YGNodeStyleSetFlexDirection(y_node, value); - app_redraw(); + pp::panopainter::legacy_ui_node_set_flex_dir(*this, value); } void Node::SetFlexWrap(YGWrap value) { - YGNodeStyleSetFlexWrap(y_node, value); - app_redraw(); + pp::panopainter::legacy_ui_node_set_flex_wrap(*this, value); } void Node::SetJustify(YGJustify value) { - YGNodeStyleSetJustifyContent(y_node, value); - app_redraw(); + pp::panopainter::legacy_ui_node_set_justify(*this, value); } void Node::SetAlign(YGAlign value) { - YGNodeStyleSetAlignItems(y_node, value); - app_redraw(); + pp::panopainter::legacy_ui_node_set_align(*this, value); } void Node::SetPositioning(YGPositionType value) { - YGNodeStyleSetPositionType(y_node, value); - app_redraw(); + pp::panopainter::legacy_ui_node_set_positioning(*this, value); } void Node::SetAspectRatio(float ar) { - YGNodeStyleSetAspectRatio(y_node, ar); - app_redraw(); + pp::panopainter::legacy_ui_node_set_aspect_ratio(*this, ar); } void Node::SetRTL(YGDirection dir) { - YGNodeStyleSetDirection(y_node, dir); - app_redraw(); + pp::panopainter::legacy_ui_node_set_rtl(*this, dir); } bool Node::GetVisibility() { - return m_display; + return pp::panopainter::legacy_ui_node_get_visibility(*this); } void Node::SetVisibility(bool visible) { - App::I->ui_task([&] - { - if (m_display && !visible) - { - // hide - int idx = m_parent->get_child_index(this); - YGNodeRemoveChild(m_parent->y_node, y_node); - y_placeholder = YGNodeNew(); - YGNodeInsertChild(m_parent->y_node, y_placeholder, idx); - } - else if (!m_display && visible) - { - int count = YGNodeGetChildCount(m_parent->y_node); - for (int i = 0; i < count; i++) - { - if (YGNodeGetChild(m_parent->y_node, i) == y_placeholder) - { - YGNodeRemoveChild(m_parent->y_node, y_placeholder); - YGNodeInsertChild(m_parent->y_node, y_node, i); - YGNodeFree(y_placeholder); - y_placeholder = nullptr; - break; - } - } - } - }); - m_display = visible; - app_redraw(); + pp::panopainter::legacy_ui_node_set_visibility(*this, visible); } void Node::ToggleVisibility() @@ -435,17 +359,17 @@ void Node::ToggleVisibility() glm::vec2 Node::GetPosition() { - return { YGNodeLayoutGetLeft(y_node), YGNodeLayoutGetTop(y_node) }; + return pp::panopainter::legacy_ui_node_get_position(*this); } float Node::GetWidth() { - return YGNodeLayoutGetWidth(y_node); + return pp::panopainter::legacy_ui_node_get_width(*this); } float Node::GetHeight() { - return YGNodeLayoutGetHeight(y_node); + return pp::panopainter::legacy_ui_node_get_height(*this); } glm::vec2 Node::GetSize() @@ -455,7 +379,7 @@ glm::vec2 Node::GetSize() YGDirection Node::GetRTL() { - return YGNodeStyleGetDirection(y_node); + return pp::panopainter::legacy_ui_node_get_rtl(*this); } void Node::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) diff --git a/src/node_stroke_preview.cpp b/src/node_stroke_preview.cpp index 7fab11f4..41bfe76e 100644 --- a/src/node_stroke_preview.cpp +++ b/src/node_stroke_preview.cpp @@ -448,9 +448,9 @@ glm::vec4 NodeStrokePreview::stroke_draw_samples( copy_stroke_destination); } -std::vector NodeStrokePreview::stroke_draw_compute(Stroke& stroke, float zoom) const +std::vector NodeStrokePreview::stroke_draw_compute(const Stroke& stroke, float zoom) const { - auto samples = stroke.compute_samples(); + auto samples = const_cast(stroke).compute_samples(); StrokeSample previous_sample = stroke.m_prev_sample; previous_sample.size *= zoom; for (auto& sample : samples) { @@ -475,13 +475,13 @@ std::vector NodeStrokePreview::stroke_draw_compu glm::vec4 color, float flow, float opacity, - std::array&& shapes) { + std::array&& shapes) -> StrokeFrame { return StrokeFrame { .col = color, .flow = flow, .opacity = opacity, .shapes = std::move(shapes), - .m_mixer_rect = mixer_rect, + .mixer_rect = mixer_rect, }; }); } @@ -548,102 +548,55 @@ void NodeStrokePreview::draw_stroke_immediate() size, *b, ortho_proj)); - const bool copy_stroke_destination = pass_orchestration.copy_stroke_destination; pp::panopainter::setup_legacy_stroke_shader(pass_orchestration.stroke_shader); - const bool sequence_ok = pp::panopainter::execute_legacy_node_stroke_preview_draw_immediate_shell( - *b, - pass_orchestration, - m_tex, - m_rtt_mixer, - m_rtt, - m_tex_background, - m_tex_dual, - m_tex_preview, - m_sampler_linear, - m_sampler_linear_repeat, - copy_stroke_destination, - size, - pp::panopainter::kLegacyNodeStrokePreviewStrokeTextureSlot, - [&] { - if (!pass_orchestration.material.dual_pass.enabled) { - return; - } - - pp::panopainter::setup_legacy_stroke_dual_shader(pass_orchestration.material.dual_pass.uses_pattern); - bind_stroke_preview_dual_pass_textures(*prepared_strokes.dual_brush); - pp::panopainter::execute_legacy_stroke_preview_live_pass( - [&] { - m_rtt.clear(); - }, - [&] { - return stroke_draw_compute(prepared_strokes.dual_stroke, zoom); - }, - [](auto& frame) { - frame.col = { 0, 0, 0, 1 }; - }, - [&](auto& frame) { - pp::panopainter::use_legacy_stroke_shader(); - pp::panopainter::apply_legacy_stroke_sample_uniforms( - pp::panopainter::LegacyStrokeSampleUniforms { - .color = frame.col, - .alpha = frame.flow, - .opacity = frame.opacity, - }); - }, - [&](auto& frame) { - /*auto rect =*/ stroke_draw_samples(frame.shapes, m_tex_dual, copy_stroke_destination); - }, - [&] { - pp::panopainter::copy_legacy_node_stroke_preview_framebuffer_to_texture( - m_tex_dual, - size, - pp::panopainter::kLegacyNodeStrokePreviewStrokeTextureSlot); - }); - }, - [&] { - execute_stroke_preview_background_capture_pass( - size, - pass_orchestration.background_colorize, - m_tex_background, - [&] { - m_plane.draw_fill(); - }); - }, - [&] { - return stroke_draw_compute(prepared_strokes.stroke, zoom); - }, - [&](auto& frame) { - if (b->m_tip_mix > 0.f) - { - stroke_draw_mix(xy(frame.m_mixer_rect), zw(frame.m_mixer_rect)); - } - - frame.col = b->m_blend_mode != 0 || b->m_tip_mix > 0.f ? - glm::vec4 { .7, .4, .1, 1 } : - glm::vec4 { 0, 0, 0, 1 }; - frame.flow = glm::max(frame.flow, m_min_flow); - }, - [&](auto& frame) { - pp::panopainter::use_legacy_stroke_shader(); - pp::panopainter::apply_legacy_stroke_sample_uniforms( - pp::panopainter::LegacyStrokeSampleUniforms { - .color = frame.col, - .alpha = frame.flow, - .opacity = frame.opacity, - }); - }, - [&](auto& frame) { - /*auto rect =*/ stroke_draw_samples(frame.shapes, m_tex, copy_stroke_destination); - }, - [&] { - set_active_texture_unit(3U); - m_rtt_mixer.unbindTexture(); - }, - [&] { - b->m_pattern_texture ? b->m_pattern_texture->bind() : unbind_texture_2d(); - }, - [&] { - m_plane.draw_fill(); + const bool sequence_ok = pp::panopainter::execute_legacy_node_stroke_preview_live_render_passes( + pp::panopainter::LegacyNodeStrokePreviewLiveRenderRequest { + .brush = *b, + .pass_orchestration = pass_orchestration, + .prepared_strokes = prepared_strokes, + .stroke_texture = m_tex, + .mixer_rtt = m_rtt_mixer, + .render_target = m_rtt, + .background_texture = m_tex_background, + .dual_texture = m_tex_dual, + .preview_texture = m_tex_preview, + .linear_sampler = m_sampler_linear, + .repeat_sampler = m_sampler_linear_repeat, + .zoom = zoom, + .min_flow = m_min_flow, + .copy_stroke_destination = pass_orchestration.copy_stroke_destination, + .size = size, + .bind_dual_pass_textures = [](const Brush& dual_brush) { + bind_stroke_preview_dual_pass_textures(dual_brush); + }, + .capture_background = [&](bool colorize) { + execute_stroke_preview_background_capture_pass( + size, + colorize, + m_tex_background, + [&] { + m_plane.draw_fill(); + }); + }, + .compute_frames = [&](const Stroke& stroke, float frame_zoom) { + return stroke_draw_compute(stroke, frame_zoom); + }, + .draw_samples = [&](std::array& shapes, Texture2D& texture, bool copy_stroke_destination) { + return stroke_draw_samples(shapes, texture, copy_stroke_destination); + }, + .draw_mix = [&](const glm::vec2& bb_min, const glm::vec2& bb_sz) { + stroke_draw_mix(bb_min, bb_sz); + }, + .unbind_mixer_texture = [&] { + set_active_texture_unit(3U); + m_rtt_mixer.unbindTexture(); + }, + .bind_pattern_texture = [&] { + b->m_pattern_texture ? b->m_pattern_texture->bind() : unbind_texture_2d(); + }, + .draw_composite = [&] { + m_plane.draw_fill(); + }, }); assert(sequence_ok); diff --git a/src/node_stroke_preview.h b/src/node_stroke_preview.h index d7eb46b2..ba90f429 100644 --- a/src/node_stroke_preview.h +++ b/src/node_stroke_preview.h @@ -5,20 +5,12 @@ #include "rtt.h" #include "brush.h" #include "texture.h" +#include "legacy_node_stroke_preview_draw_services.h" #include "legacy_node_stroke_preview_execution_services.h" class NodeStrokePreview : public NodeBorder { - struct StrokeFrame - { - glm::vec4 col; - float flow; - float opacity; - std::array shapes; - glm::vec4 m_mixer_rect; - }; - - using StrokeMainLivePassRequest = pp::panopainter::LegacyNodeStrokePreviewMainLivePassRequestT; + using StrokeFrame = pp::panopainter::LegacyNodeStrokePreviewFrame; static RTT m_rtt; static RTT m_rtt_mixer; @@ -55,7 +47,7 @@ public: void stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz); // return rect {origin, size} glm::vec4 stroke_draw_samples(std::array& P, Texture2D& blend_tex, bool copy_stroke_destination); - std::vector stroke_draw_compute(Stroke& stroke, float zoom) const; + std::vector stroke_draw_compute(const Stroke& stroke, float zoom) const; void draw_stroke(); void draw_stroke_immediate(); Image render_to_image();