diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index fa9522f1..404c51cf 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -81,9 +81,9 @@ Current hotspot files: - `src/canvas.cpp`: 17 lines - `src/app_layout.cpp`: 125 lines -- `src/canvas_modes.cpp`: 191 lines -- `src/node.cpp`: 257 lines -- `src/main.cpp`: 156 lines +- `src/canvas_modes.cpp`: 1 line +- `src/node.cpp`: 231 lines +- `src/main.cpp`: 87 lines - `src/node_panel_brush.cpp`: 2 lines - `src/node_stroke_preview.cpp`: 160 lines - `src/node_canvas.cpp`: 85 lines @@ -131,6 +131,16 @@ Latest slice: `src/legacy_brush_preset_list_services.*`, and `src/legacy_brush_preset_services.*`), leaving `src/node_panel_brush.cpp` as a thin translation unit. +- `Node::load_internal(...)` now routes through + `load_legacy_ui_node(...)` in `src/legacy_ui_node_loader.*`, which moves the + init/attribute-parse/create/child-load/loaded shell out of `src/node.cpp`. +- The remaining Win32 shell wrappers for close, async lock/swap, stylus/FPS + updates, VR start/stop, window-state save, and the window-handle accessor now + live in `src/platform_windows/windows_platform_services.cpp` instead of + `src/main.cpp`, leaving `main.cpp` as a thinner entry/runtime dispatcher. +- The entire `CanvasModeGrid` implementation plus `ActionModeGrid` undo/redo + glue now live in `src/legacy_canvas_mode_helpers.cpp` instead of + `src/canvas_modes.cpp`, leaving `src/canvas_modes.cpp` as a minimal shell. Current architecture mismatches that must be treated as real blockers: diff --git a/docs/modernization/tasks.md b/docs/modernization/tasks.md index bf9d31d9..4597f22e 100644 --- a/docs/modernization/tasks.md +++ b/docs/modernization/tasks.md @@ -391,6 +391,10 @@ Current slice: render-target validation, viewport/clear-color save-restore, and immediate runtime request assembly out of the live node file and leaves `src/node_stroke_preview.cpp` at 160 lines. +- `CanvasModeGrid` plus `ActionModeGrid` undo/redo now also live in + `src/legacy_canvas_mode_helpers.cpp` instead of staying inline in + `src/canvas_modes.cpp`, which leaves the live canvas-modes file as a + minimal 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 @@ -908,6 +912,10 @@ Current slice: base clone plumbing now also lives in `src/legacy_ui_node_lifecycle.*` instead of staying inline in `src/node.cpp`, which materially thins another coherent generic scene-graph shell without changing the public surface. +- `Node::load_internal(...)` now also routes through + `load_legacy_ui_node(...)` in `src/legacy_ui_node_loader.*`, which moves the + init/attribute-parse/create/child-load/loaded shell out of `src/node.cpp` + and leaves the remaining live node file thinner. Write scope: - `src/node.cpp` @@ -1090,6 +1098,12 @@ Current slice: directly in those method bodies - retained Apple callback injection and broader `platform_legacy` singleton reach are still open +- The remaining Win32 shell wrappers for close, async lock/swap, + stylus/FPS updates, VR start/stop, window-state save, and the + window-handle accessor now live in + `src/platform_windows/windows_platform_services.cpp` instead of + `src/main.cpp`, which leaves the live entry file as a thinner + startup/runtime dispatcher. Write scope: - `src/platform_apple/*` diff --git a/src/canvas_modes.cpp b/src/canvas_modes.cpp index 40bba885..1d9f38c5 100644 --- a/src/canvas_modes.cpp +++ b/src/canvas_modes.cpp @@ -1,191 +1 @@ #include "pch.h" - -#include - -#include "canvas_modes.h" -#include "layout.h" -#include "canvas.h" -#include "node_canvas.h" -#include "legacy_canvas_draw_merge_services.h" -#include "legacy_canvas_mode_helpers.h" -#include "legacy_ui_overlay_services.h" -#include "app.h" -#include "util.h" - -NodeCanvas* CanvasMode::node; - -using pp::legacy_canvas_mode::apply_canvas_mode_viewport; -using pp::legacy_canvas_mode::query_canvas_mode_read_framebuffer; - -//////////////////////////////////////////////////////////////////// - - -void CanvasModeGrid::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: - { - node->mouse_capture(); - glm::vec3 ro, rd, hit_o, hit_d; - glm::vec2 fb_pos; - if (Canvas::I->point_trace(loc, ro, rd, hit_o, fb_pos, hit_d, m_plane_id)) - { - m_action = std::make_unique(); - m_action->m_mode = this; - m_action->m_highlight = m_highlight; - m_action->m_selected_index = m_selected_index; - m_action->m_lines = m_lines; - - int select = -1; - for (int i = 0; i < m_lines.size(); i++) - { - auto const& l = m_lines[i]; - float d = lines_distance(ro, ro+rd*10.f, l.o-l.d*10.f, l.o+l.d*10.f); - if (d < 0.03f) - select = i; - } - if (select == -1) - { - m_lines.push_back({ hit_o, hit_d }); - m_selected_index = (int)m_lines.size() - 1; - m_highlight = false; - m_added = true; - } - else - { - m_selected_index = select; - m_highlight = true; - m_added = false; - } - origin = hit_o; - dir = hit_d; - m_dragging = true; - } - break; - } - case kEventType::MouseUpL: - pp::panopainter::release_legacy_mouse_capture(*node); - m_dragging = false; - ActionManager::add(m_action.release()); - //commit(); - break; - case kEventType::MouseMove: - { - glm::vec3 ro, rd, hit_o, hit_d; - glm::vec2 hit_fb; - if (m_dragging && Canvas::I->point_trace_plane(loc, ro, rd, hit_o, hit_d, hit_fb, m_plane_id)) - { - m_lines[m_selected_index] = { hit_o, hit_d }; - origin = hit_o; - dir = hit_d; - m_dragging = true; - } - break; - } - case kEventType::MouseCancel: - if (m_dragging && m_selected_index == m_lines.size() - 1) - m_lines.pop_back(); - m_dragging = false; - pp::panopainter::release_legacy_mouse_capture(*node); - break; - default: - break; - } -} - -void CanvasModeGrid::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) -{ - const glm::vec4 blue(0, 0, 1, 1); - const glm::vec4 red(1, 0, 0, 1); - for (int i = 0; i < m_lines.size(); i++) - { - auto const& l = m_lines[i]; - auto origin = l.o; - auto dir = l.d; - pp::panopainter::setup_legacy_vr_color_shader({ - .color = m_highlight && i == m_selected_index ? blue : red, - .mvp = proj * camera, - }); - static glm::vec4 AB[2]; - AB[0] = {origin - dir * 10.f, 1}; - AB[1] = {origin + dir * 10.f, 1 }; - m_line.update_vertices(AB); - m_line.draw_stroke(); - } -} - -void CanvasModeGrid::init() -{ - m_line.create(); -} - -void CanvasModeGrid::commit() -{ - auto drawer = [this](const glm::mat4& camera, const glm::mat4& proj){ - pp::panopainter::setup_legacy_vr_color_shader({ - .color = { 1, 0, 0, 1 }, - .mvp = proj * camera, - }); - static glm::vec4 AB[2]; - AB[0] = {origin - dir * 10.f, 1}; - AB[1] = {origin + dir * 10.f, 1 }; - m_line.update_vertices(AB); - m_line.draw_stroke(); - }; - Canvas::I->draw_objects(std::bind(drawer, std::placeholders::_1, std::placeholders::_2), Canvas::I->layer().m_frame_index, true); -} - -void CanvasModeGrid::clear() -{ - auto a = new ActionModeGrid; - a->m_mode = this; - a->m_highlight = m_highlight; - a->m_selected_index = m_selected_index; - a->m_lines = m_lines; - ActionManager::add(a); - - m_lines.clear(); -} - -void CanvasModeGrid::leave(kCanvasMode next) -{ - m_selected_index = -1; -} - -void CanvasModeGrid::on_KeyEvent(KeyEvent* ke) -{ - if ((ke->m_key == kKey::KeyBackspace || ke->m_key == kKey::KeyDel) - && ke->m_type == kEventType::KeyUp) - { - if (m_highlight) - { - auto a = new ActionModeGrid; - a->m_mode = this; - a->m_highlight = m_highlight; - a->m_selected_index = m_selected_index; - a->m_lines = m_lines; - ActionManager::add(a); - m_lines.erase(m_lines.begin() + m_selected_index); - m_highlight = false; - } - } -} - -Action* ActionModeGrid::get_redo() -{ - auto a = new ActionModeGrid; - a->m_mode = m_mode; - a->m_highlight = m_mode->m_highlight; - a->m_selected_index = m_mode->m_selected_index; - a->m_lines = m_mode->m_lines; - return a; -} -void ActionModeGrid::undo() -{ - m_mode->m_highlight = m_highlight; - m_mode->m_selected_index = m_selected_index; - m_mode->m_lines = m_lines; -} diff --git a/src/legacy_canvas_mode_helpers.cpp b/src/legacy_canvas_mode_helpers.cpp index 97b882fa..3a6ed961 100644 --- a/src/legacy_canvas_mode_helpers.cpp +++ b/src/legacy_canvas_mode_helpers.cpp @@ -9,6 +9,8 @@ #include "legacy_ui_gl_dispatch.h" #include "renderer_gl/opengl_capabilities.h" +NodeCanvas* CanvasMode::node; + namespace pp::legacy_canvas_mode { void set_canvas_mode_active_texture_unit(std::uint32_t unit_index) @@ -188,3 +190,174 @@ void CanvasModeCamera::on_MouseEvent(MouseEvent* me, glm::vec2& loc) break; } } + +void CanvasModeGrid::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: + { + node->mouse_capture(); + glm::vec3 ro, rd, hit_o, hit_d; + glm::vec2 fb_pos; + if (Canvas::I->point_trace(loc, ro, rd, hit_o, fb_pos, hit_d, m_plane_id)) + { + m_action = std::make_unique(); + m_action->m_mode = this; + m_action->m_highlight = m_highlight; + m_action->m_selected_index = m_selected_index; + m_action->m_lines = m_lines; + + int select = -1; + for (int i = 0; i < m_lines.size(); i++) + { + auto const& l = m_lines[i]; + float d = lines_distance(ro, ro + rd * 10.f, l.o - l.d * 10.f, l.o + l.d * 10.f); + if (d < 0.03f) + select = i; + } + if (select == -1) + { + m_lines.push_back({ hit_o, hit_d }); + m_selected_index = (int)m_lines.size() - 1; + m_highlight = false; + m_added = true; + } + else + { + m_selected_index = select; + m_highlight = true; + m_added = false; + } + origin = hit_o; + dir = hit_d; + m_dragging = true; + } + break; + } + case kEventType::MouseUpL: + pp::panopainter::release_legacy_mouse_capture(*node); + m_dragging = false; + ActionManager::add(m_action.release()); + //commit(); + break; + case kEventType::MouseMove: + { + glm::vec3 ro, rd, hit_o, hit_d; + glm::vec2 hit_fb; + if (m_dragging && Canvas::I->point_trace_plane(loc, ro, rd, hit_o, hit_d, hit_fb, m_plane_id)) + { + m_lines[m_selected_index] = { hit_o, hit_d }; + origin = hit_o; + dir = hit_d; + m_dragging = true; + } + break; + } + case kEventType::MouseCancel: + if (m_dragging && m_selected_index == m_lines.size() - 1) + m_lines.pop_back(); + m_dragging = false; + pp::panopainter::release_legacy_mouse_capture(*node); + break; + default: + break; + } +} + +void CanvasModeGrid::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) +{ + const glm::vec4 blue(0, 0, 1, 1); + const glm::vec4 red(1, 0, 0, 1); + for (int i = 0; i < m_lines.size(); i++) + { + auto const& l = m_lines[i]; + auto origin = l.o; + auto dir = l.d; + pp::panopainter::setup_legacy_vr_color_shader({ + .color = m_highlight && i == m_selected_index ? blue : red, + .mvp = proj * camera, + }); + static glm::vec4 AB[2]; + AB[0] = { origin - dir * 10.f, 1 }; + AB[1] = { origin + dir * 10.f, 1 }; + m_line.update_vertices(AB); + m_line.draw_stroke(); + } +} + +void CanvasModeGrid::init() +{ + m_line.create(); +} + +void CanvasModeGrid::commit() +{ + auto drawer = [this](const glm::mat4& camera, const glm::mat4& proj) { + pp::panopainter::setup_legacy_vr_color_shader({ + .color = { 1, 0, 0, 1 }, + .mvp = proj * camera, + }); + static glm::vec4 AB[2]; + AB[0] = { origin - dir * 10.f, 1 }; + AB[1] = { origin + dir * 10.f, 1 }; + m_line.update_vertices(AB); + m_line.draw_stroke(); + }; + Canvas::I->draw_objects(std::bind(drawer, std::placeholders::_1, std::placeholders::_2), Canvas::I->layer().m_frame_index, true); +} + +void CanvasModeGrid::clear() +{ + auto a = new ActionModeGrid; + a->m_mode = this; + a->m_highlight = m_highlight; + a->m_selected_index = m_selected_index; + a->m_lines = m_lines; + ActionManager::add(a); + + m_lines.clear(); +} + +void CanvasModeGrid::leave(kCanvasMode next) +{ + m_selected_index = -1; +} + +void CanvasModeGrid::on_KeyEvent(KeyEvent* ke) +{ + if ((ke->m_key == kKey::KeyBackspace || ke->m_key == kKey::KeyDel) + && ke->m_type == kEventType::KeyUp) + { + if (m_highlight) + { + auto a = new ActionModeGrid; + a->m_mode = this; + a->m_highlight = m_highlight; + a->m_selected_index = m_selected_index; + a->m_lines = m_lines; + ActionManager::add(a); + m_lines.erase(m_lines.begin() + m_selected_index); + m_highlight = false; + } + } +} + +Action* ActionModeGrid::get_redo() +{ + auto a = new ActionModeGrid; + a->m_mode = m_mode; + a->m_highlight = m_mode->m_highlight; + a->m_selected_index = m_mode->m_selected_index; + a->m_lines = m_mode->m_lines; + return a; +} + +void ActionModeGrid::undo() +{ + m_mode->m_highlight = m_highlight; + m_mode->m_selected_index = m_selected_index; + m_mode->m_lines = m_lines; +} diff --git a/src/legacy_ui_node_loader.cpp b/src/legacy_ui_node_loader.cpp index 38f87ad3..d5836281 100644 --- a/src/legacy_ui_node_loader.cpp +++ b/src/legacy_ui_node_loader.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include "legacy_ui_node_loader.h" +#include "legacy_ui_node_attributes.h" #include "log.h" #include "node.h" #include "layout.h" @@ -154,6 +155,32 @@ void load_typed_child(Node& parent, const tinyxml2::XMLElement& x_child, std::st } // namespace +void load_legacy_ui_node(Node& node, const tinyxml2::XMLElement& x_node, bool skip_children) +{ + node.m_name = x_node.Name(); + //LOG("load_internal node %s", node.m_name.c_str()); + + node.init(); + + auto attr = x_node.FirstAttribute(); + while (attr) + { + parse_legacy_ui_node_attribute(node, (kAttribute)const_hash(attr->Name()), attr); + attr = attr->Next(); + } + + node.create(); + + if (skip_children) + { + node.loaded(); + return; + } + + load_legacy_ui_children(node, x_node); + node.loaded(); +} + void load_legacy_ui_children(Node& parent, const tinyxml2::XMLElement& x_node) { auto x_child = x_node.FirstChildElement(); diff --git a/src/legacy_ui_node_loader.h b/src/legacy_ui_node_loader.h index 022b6cc9..5c622605 100644 --- a/src/legacy_ui_node_loader.h +++ b/src/legacy_ui_node_loader.h @@ -8,6 +8,7 @@ class Node; namespace pp::panopainter { +void load_legacy_ui_node(Node& node, const tinyxml2::XMLElement& x_node, bool skip_children = false); void load_legacy_ui_children(Node& parent, const tinyxml2::XMLElement& x_node); } // namespace pp::panopainter diff --git a/src/main.cpp b/src/main.cpp index 80a13d1b..95180537 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -19,76 +19,7 @@ #include "wacom.h" #include "abr.h" -namespace pp::platform::windows { - void set_async_render_context(HDC hdc, HGLRC hrc); - void lock_async_render_context(); - bool try_lock_async_render_context(); - void unlock_async_render_context(); - void swap_async_render_context(); - RetainedState& retained_state(); -} using pp::platform::windows::retained_state; - -HWND pp_windows_main_window_handle() -{ - return retained_state().hWnd; -} - -void destroy_window() -{ - pp::platform::windows::enqueue_main_thread_task(std::packaged_task([hWnd = retained_state().hWnd] { - pp::platform::windows::request_window_close(hWnd); - })); -} - -void async_lock() -{ - pp::platform::windows::lock_async_render_context(); -} - -bool async_lock_try() -{ - return pp::platform::windows::try_lock_async_render_context(); -} - -void win32_async_swap() -{ - pp::platform::windows::swap_async_render_context(); -} - -void async_unlock() -{ - pp::platform::windows::unlock_async_render_context(); -} - -void win32_update_stylus(float dt) -{ - pp::platform::windows::update_stylus_frame(dt); -} - -void win32_update_fps(int frames) -{ - auto& state = retained_state(); - pp::platform::windows::enqueue_main_thread_task(std::packaged_task([hWnd = state.hWnd, window_title = state.window_title, &vr = state.vr, frames] { - pp::platform::windows::update_window_fps(hWnd, window_title, vr, frames); - })); -} - -bool win32_vr_start() -{ - auto& state = retained_state(); - return pp::platform::windows::start_window_vr(state.vr, state.sandboxed); -} - -void win32_vr_stop() -{ - pp::platform::windows::stop_window_vr(retained_state().vr); -} - -void win32_save_window_state() -{ - pp::platform::windows::save_window_preferences(retained_state().hWnd); -} int main(int argc, char** argv) { auto& state = retained_state(); diff --git a/src/node.cpp b/src/node.cpp index 66eeccd3..d5e46340 100644 --- a/src/node.cpp +++ b/src/node.cpp @@ -1,14 +1,9 @@ #include "pch.h" -#include "app.h" -#include "log.h" #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" -#include "asset.h" kEventResult Node::on_event(Event* e) { @@ -232,26 +227,5 @@ void Node::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) void Node::load_internal(const tinyxml2::XMLElement* x_node, bool skip_children /*= false*/) { - m_name = x_node->Name(); - //LOG("load_internal node %s", m_name.c_str()); - - init(); - - auto attr = x_node->FirstAttribute(); - while (attr) - { - parse_attributes((kAttribute)const_hash(attr->Name()), attr); - attr = attr->Next(); - } - - create(); - - if (skip_children) - { - loaded(); - return; - } - - pp::panopainter::load_legacy_ui_children(*this, *x_node); - loaded(); + pp::panopainter::load_legacy_ui_node(*this, *x_node, skip_children); } diff --git a/src/platform_windows/windows_platform_services.cpp b/src/platform_windows/windows_platform_services.cpp index 6f98bccd..dc498f31 100644 --- a/src/platform_windows/windows_platform_services.cpp +++ b/src/platform_windows/windows_platform_services.cpp @@ -1,6 +1,9 @@ #include "pch.h" #include "platform_windows/windows_bootstrap_helpers.h" +#include "platform_windows/windows_lifecycle_shell.h" #include "platform_windows/windows_platform_services.h" +#include "platform_windows/windows_stylus_input.h" +#include "platform_windows/windows_window_shell.h" #include "log.h" #include "legacy_gl_runtime_dispatch.h" @@ -12,6 +15,15 @@ #include #include +namespace pp::platform::windows { +void set_async_render_context(HDC hdc, HGLRC hrc); +void lock_async_render_context(); +bool try_lock_async_render_context(); +void unlock_async_render_context(); +void swap_async_render_context(); +RetainedState& retained_state(); +} + void destroy_window(); void async_lock(); void async_unlock(); @@ -23,6 +35,67 @@ bool win32_vr_start(); void win32_vr_stop(); HWND pp_windows_main_window_handle(); +HWND pp_windows_main_window_handle() +{ + return pp::platform::windows::retained_state().hWnd; +} + +void destroy_window() +{ + pp::platform::windows::enqueue_main_thread_task(std::packaged_task([hWnd = pp::platform::windows::retained_state().hWnd] { + pp::platform::windows::request_window_close(hWnd); + })); +} + +void async_lock() +{ + pp::platform::windows::lock_async_render_context(); +} + +bool async_lock_try() +{ + return pp::platform::windows::try_lock_async_render_context(); +} + +void win32_async_swap() +{ + pp::platform::windows::swap_async_render_context(); +} + +void async_unlock() +{ + pp::platform::windows::unlock_async_render_context(); +} + +void win32_update_stylus(float dt) +{ + pp::platform::windows::update_stylus_frame(dt); +} + +void win32_update_fps(int frames) +{ + auto& state = pp::platform::windows::retained_state(); + pp::platform::windows::enqueue_main_thread_task(std::packaged_task([hWnd = state.hWnd, window_title = state.window_title, &vr = state.vr, frames] { + pp::platform::windows::update_window_fps(hWnd, window_title, vr, frames); + })); +} + +bool win32_vr_start() +{ + auto& state = pp::platform::windows::retained_state(); + return pp::platform::windows::start_window_vr(state.vr, state.sandboxed); +} + +void win32_vr_stop() +{ + pp::platform::windows::stop_window_vr(pp::platform::windows::retained_state().vr); +} + +void win32_save_window_state() +{ + pp::platform::windows::save_window_preferences(pp::platform::windows::retained_state().hWnd); +} + namespace pp::platform::windows { namespace {