#include "pch.h" #include "app.h" #include "app_core/app_frame.h" #include "app_core/canvas_tool_ui.h" #include "legacy_ui_gl_dispatch.h" #include "renderer_gl/opengl_capabilities.h" namespace { pp::app::CanvasToolMode canvas_tool_mode_from_canvas_mode(kCanvasMode mode) noexcept { switch (mode) { case kCanvasMode::Draw: return pp::app::CanvasToolMode::draw; case kCanvasMode::Erase: return pp::app::CanvasToolMode::erase; case kCanvasMode::Line: return pp::app::CanvasToolMode::line; case kCanvasMode::Camera: return pp::app::CanvasToolMode::camera; case kCanvasMode::Grid: return pp::app::CanvasToolMode::grid; case kCanvasMode::Copy: return pp::app::CanvasToolMode::copy; case kCanvasMode::Cut: return pp::app::CanvasToolMode::cut; case kCanvasMode::Fill: return pp::app::CanvasToolMode::fill; case kCanvasMode::MaskFree: return pp::app::CanvasToolMode::mask_free; case kCanvasMode::MaskLine: return pp::app::CanvasToolMode::mask_line; case kCanvasMode::FloodFill: return pp::app::CanvasToolMode::flood_fill; default: return pp::app::CanvasToolMode::draw; } } void apply_legacy_app_scissor(pp::renderer::gl::OpenGlScissorRect scissor) { const auto status = pp::renderer::gl::apply_opengl_scissor_rect( scissor, pp::renderer::gl::OpenGlScissorDispatch { .enable = pp::legacy::ui_gl::enable_opengl_state, .disable = pp::legacy::ui_gl::disable_opengl_state, .scissor = pp::legacy::ui_gl::set_opengl_scissor, }); if (!status.ok()) LOG("OpenGL scissor failed: %s", status.message); } void watch_layout_children(LayoutManager* layout, uint16_t main_id, int start_index, const std::function& observer) { if (!layout) return; if (auto* root = layout->get(main_id)) { for (int i = start_index; i < static_cast(root->m_children.size()); ++i) root->m_children[i]->watch(observer); } } } namespace pp::panopainter { bool update_legacy_app_ui_observer(App& app, Node* n) { std::vector parent_clips; if (n) { for (Node* p = n->m_parent; p; p = p->m_parent) { parent_clips.push_back(pp::app::AppUiObserverParentClip { .clip = pp::app::AppUiObserverRect { .x = p->m_clip_uncut.x, .y = p->m_clip_uncut.y, .width = p->m_clip_uncut.z, .height = p->m_clip_uncut.w, }, .padding_top = YGNodeLayoutGetPadding(p->y_node, YGEdgeTop), .padding_right = YGNodeLayoutGetPadding(p->y_node, YGEdgeRight), .padding_bottom = YGNodeLayoutGetPadding(p->y_node, YGEdgeBottom), .padding_left = YGNodeLayoutGetPadding(p->y_node, YGEdgeLeft), }); } } const auto plan = pp::app::plan_app_ui_observer( n != nullptr, n && n->m_display, n && n->m_on_screen, n ? pp::app::AppUiObserverRect { .x = n->m_clip_uncut.x, .y = n->m_clip_uncut.y, .width = n->m_clip_uncut.z, .height = n->m_clip_uncut.w, } : pp::app::AppUiObserverRect {}, parent_clips, app.height, app.zoom, app.off_x, app.off_y); if (!plan) { LOG("UI observer plan failed: %s", plan.status().message); return false; } if (!n) return false; if (plan.value().notify_leave_screen) n->handle_on_screen(true, false); if (plan.value().notify_enter_screen) n->handle_on_screen(false, true); n->m_on_screen = plan.value().next_on_screen; if (!plan.value().draw_node) return false; apply_legacy_app_scissor(pp::renderer::gl::OpenGlScissorRect { .enabled = 1U, .x = plan.value().scissor_x, .y = plan.value().scissor_y, .width = plan.value().scissor_width, .height = plan.value().scissor_height, }); n->draw(); return true; } void watch_legacy_app_ui_children(App& app, const std::function& observer, bool skip_first_main_child) { watch_layout_children(&app.layout, app.main_id, skip_first_main_child ? 1 : 0, observer); watch_layout_children(&app.layout_designer, app.main_id, 0, observer); } void update_legacy_canvas_toolbar(App& app) { const auto mode = Canvas::I->m_current_mode; auto* pm = app.canvas->m_canvas->get_mode(); const auto toolbar = pp::app::plan_canvas_tool_button_state( canvas_tool_mode_from_canvas_mode(mode), pm && pm->m_picking, app.canvas->m_canvas->m_touch_lock); app.layout[app.main_id]->find("btn-pick")->set_active(toolbar.pick_active); app.layout[app.main_id]->find("btn-touchlock")->set_active(toolbar.touch_lock_active); app.layout[app.main_id]->find("btn-pen")->set_active(toolbar.pen_active); app.layout[app.main_id]->find("btn-erase")->set_active(toolbar.erase_active); app.layout[app.main_id]->find("btn-cam")->set_active(toolbar.camera_active); app.layout[app.main_id]->find("btn-line")->set_active(toolbar.line_active); app.layout[app.main_id]->find("btn-grid")->set_active(toolbar.grid_active); app.layout[app.main_id]->find("btn-copy")->set_active(toolbar.copy_active); app.layout[app.main_id]->find("btn-cut")->set_active(toolbar.cut_active); app.layout[app.main_id]->find("btn-mask-free")->set_active(toolbar.mask_free_active); app.layout[app.main_id]->find("btn-mask-line")->set_active(toolbar.mask_line_active); app.layout[app.main_id]->find("btn-bucket")->set_active(toolbar.flood_fill_active); } }