165 lines
5.9 KiB
C++
165 lines
5.9 KiB
C++
#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<bool(Node*)>& observer)
|
|
{
|
|
if (!layout)
|
|
return;
|
|
|
|
if (auto* root = layout->get(main_id)) {
|
|
for (int i = start_index; i < static_cast<int>(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<pp::app::AppUiObserverParentClip> 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<bool(Node*)>& 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<CanvasModePen>();
|
|
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<NodeButtonCustom>("btn-pick")->set_active(toolbar.pick_active);
|
|
app.layout[app.main_id]->find<NodeButtonCustom>("btn-touchlock")->set_active(toolbar.touch_lock_active);
|
|
|
|
app.layout[app.main_id]->find<NodeButtonCustom>("btn-pen")->set_active(toolbar.pen_active);
|
|
app.layout[app.main_id]->find<NodeButtonCustom>("btn-erase")->set_active(toolbar.erase_active);
|
|
app.layout[app.main_id]->find<NodeButton>("btn-cam")->set_active(toolbar.camera_active);
|
|
app.layout[app.main_id]->find<NodeButtonCustom>("btn-line")->set_active(toolbar.line_active);
|
|
app.layout[app.main_id]->find<NodeButton>("btn-grid")->set_active(toolbar.grid_active);
|
|
app.layout[app.main_id]->find<NodeButton>("btn-copy")->set_active(toolbar.copy_active);
|
|
app.layout[app.main_id]->find<NodeButton>("btn-cut")->set_active(toolbar.cut_active);
|
|
app.layout[app.main_id]->find<NodeButtonCustom>("btn-mask-free")->set_active(toolbar.mask_free_active);
|
|
app.layout[app.main_id]->find<NodeButtonCustom>("btn-mask-line")->set_active(toolbar.mask_line_active);
|
|
app.layout[app.main_id]->find<NodeButtonCustom>("btn-bucket")->set_active(toolbar.flood_fill_active);
|
|
}
|
|
|
|
}
|