Extract canvas object draw and brush panel services
This commit is contained in:
@@ -23,6 +23,8 @@ set(PP_LEGACY_PAINT_DOCUMENT_SOURCES
|
|||||||
src/canvas_actions.cpp
|
src/canvas_actions.cpp
|
||||||
src/canvas_layer.cpp
|
src/canvas_layer.cpp
|
||||||
src/legacy_canvas_document_io_services.cpp
|
src/legacy_canvas_document_io_services.cpp
|
||||||
|
src/legacy_canvas_object_draw_services.cpp
|
||||||
|
src/legacy_canvas_object_draw_services.h
|
||||||
src/legacy_canvas_projection_services.cpp
|
src/legacy_canvas_projection_services.cpp
|
||||||
src/legacy_canvas_projection_services.h
|
src/legacy_canvas_projection_services.h
|
||||||
src/legacy_canvas_state_services.cpp
|
src/legacy_canvas_state_services.cpp
|
||||||
@@ -143,6 +145,8 @@ set(PP_PANOPAINTER_APP_SOURCES
|
|||||||
set(PP_PANOPAINTER_UI_SOURCES
|
set(PP_PANOPAINTER_UI_SOURCES
|
||||||
src/legacy_brush_ui_services.cpp
|
src/legacy_brush_ui_services.cpp
|
||||||
src/legacy_brush_ui_services.h
|
src/legacy_brush_ui_services.h
|
||||||
|
src/legacy_brush_panel_services.cpp
|
||||||
|
src/legacy_brush_panel_services.h
|
||||||
src/legacy_document_animation_services.cpp
|
src/legacy_document_animation_services.cpp
|
||||||
src/legacy_document_animation_services.h
|
src/legacy_document_animation_services.h
|
||||||
src/legacy_grid_ui_services.cpp
|
src/legacy_grid_ui_services.cpp
|
||||||
|
|||||||
@@ -79,14 +79,14 @@ What is still carrying too much live ownership:
|
|||||||
|
|
||||||
Current hotspot files:
|
Current hotspot files:
|
||||||
|
|
||||||
- `src/canvas.cpp`: 2728 lines
|
- `src/canvas.cpp`: 2592 lines
|
||||||
- `src/app_layout.cpp`: 125 lines
|
- `src/app_layout.cpp`: 125 lines
|
||||||
- `src/canvas_modes.cpp`: 1710 lines
|
- `src/canvas_modes.cpp`: 1626 lines
|
||||||
- `src/node.cpp`: 1368 lines
|
- `src/node.cpp`: 1368 lines
|
||||||
- `src/main.cpp`: 271 lines
|
- `src/main.cpp`: 271 lines
|
||||||
- `src/node_panel_brush.cpp`: 1207 lines
|
- `src/node_panel_brush.cpp`: 1094 lines
|
||||||
- `src/node_stroke_preview.cpp`: 910 lines
|
- `src/node_stroke_preview.cpp`: 910 lines
|
||||||
- `src/node_canvas.cpp`: 864 lines
|
- `src/node_canvas.cpp`: 872 lines
|
||||||
- `src/app.cpp`: 575 lines
|
- `src/app.cpp`: 575 lines
|
||||||
- `src/app_dialogs.cpp`: 168 lines
|
- `src/app_dialogs.cpp`: 168 lines
|
||||||
|
|
||||||
@@ -244,6 +244,18 @@ Current architecture mismatches that must be treated as real blockers:
|
|||||||
callback-assembly setup now also route through
|
callback-assembly setup now also route through
|
||||||
`execute_node_canvas_draw_unmerged_pass(...)`, which trims another coherent
|
`execute_node_canvas_draw_unmerged_pass(...)`, which trims another coherent
|
||||||
unmerged draw shell from the live node even though the file itself remains
|
unmerged draw shell from the live node even though the file itself remains
|
||||||
|
large, while `NodeCanvas::draw()` merged-pass callback wiring and pass setup
|
||||||
|
now also route through `execute_node_canvas_draw_merged_pass(...)`, which
|
||||||
|
trims another coherent merged draw shell from the live node even though the
|
||||||
|
broader draw loop still remains inline,
|
||||||
|
while `Canvas::draw_objects_direct(...)` and `Canvas::draw_objects(...)` now
|
||||||
|
route through `src/legacy_canvas_object_draw_services.*` instead of staying
|
||||||
|
inline in `src/canvas.cpp`, which trims another coherent object-draw and
|
||||||
|
viewport-state execution family from the live canvas shell,
|
||||||
|
while `NodePanelBrush` save/restore/scan/reload/find/get-path ownership now
|
||||||
|
routes through `src/legacy_brush_panel_services.*` instead of staying inline
|
||||||
|
in `src/node_panel_brush.cpp`, which trims another retained brush-workflow
|
||||||
|
pocket from the live UI node even though the broader panel still remains
|
||||||
large, while shared canvas-mode GL wrappers plus the
|
large, while shared canvas-mode GL wrappers plus the
|
||||||
`CanvasModeBasicCamera` and `CanvasModeCamera` input handlers now also route
|
`CanvasModeBasicCamera` and `CanvasModeCamera` input handlers now also route
|
||||||
through `src/legacy_canvas_mode_helpers.*` instead of staying inline in
|
through `src/legacy_canvas_mode_helpers.*` instead of staying inline in
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ Status: In Progress
|
|||||||
|
|
||||||
Why now:
|
Why now:
|
||||||
`src/canvas.cpp` is still the biggest single architectural blocker at about
|
`src/canvas.cpp` is still the biggest single architectural blocker at about
|
||||||
2728 lines.
|
2592 lines.
|
||||||
|
|
||||||
Current slice:
|
Current slice:
|
||||||
- Canvas state-management helpers for picking, clear/clear-all, layer
|
- Canvas state-management helpers for picking, clear/clear-all, layer
|
||||||
@@ -108,6 +108,10 @@ Current slice:
|
|||||||
`src/legacy_canvas_projection_services.*` instead of staying inline in
|
`src/legacy_canvas_projection_services.*` instead of staying inline in
|
||||||
`src/canvas.cpp`, which trims another coherent non-UI state/query pocket
|
`src/canvas.cpp`, which trims another coherent non-UI state/query pocket
|
||||||
from the live canvas shell.
|
from the live canvas shell.
|
||||||
|
- `Canvas::draw_objects_direct(...)` and `Canvas::draw_objects(...)` now also
|
||||||
|
live in `src/legacy_canvas_object_draw_services.*` instead of staying inline
|
||||||
|
in `src/canvas.cpp`, which trims another coherent object-draw and
|
||||||
|
viewport-state execution pocket from the live canvas shell.
|
||||||
- Shared canvas-mode GL wrappers plus the `CanvasModeBasicCamera` and
|
- Shared canvas-mode GL wrappers plus the `CanvasModeBasicCamera` and
|
||||||
`CanvasModeCamera` input handlers now also live in
|
`CanvasModeCamera` input handlers now also live in
|
||||||
`src/legacy_canvas_mode_helpers.*` instead of staying inline in
|
`src/legacy_canvas_mode_helpers.*` instead of staying inline in
|
||||||
@@ -263,6 +267,10 @@ Current slice:
|
|||||||
through `execute_node_canvas_draw_unmerged_pass(...)`, which trims another
|
through `execute_node_canvas_draw_unmerged_pass(...)`, which trims another
|
||||||
coherent unmerged draw-orchestration block from the live node even though
|
coherent unmerged draw-orchestration block from the live node even though
|
||||||
the file size remains roughly flat.
|
the file size remains roughly flat.
|
||||||
|
- `NodeCanvas::draw()` merged-pass callback wiring and pass setup now also
|
||||||
|
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.
|
||||||
|
|
||||||
Write scope:
|
Write scope:
|
||||||
- `src/node_stroke_preview.cpp`
|
- `src/node_stroke_preview.cpp`
|
||||||
@@ -970,6 +978,13 @@ Why now:
|
|||||||
Cloud browse/download/upload and brush package import/export still close over
|
Cloud browse/download/upload and brush package import/export still close over
|
||||||
retained nodes, worker threads, and direct UI ownership.
|
retained nodes, worker threads, and direct UI ownership.
|
||||||
|
|
||||||
|
Current slice:
|
||||||
|
- `NodePanelBrush` save/restore/scan/reload/find/get-path ownership now routes
|
||||||
|
through `src/legacy_brush_panel_services.*` instead of staying inline in
|
||||||
|
`src/node_panel_brush.cpp`, which trims a coherent retained brush-workflow
|
||||||
|
pocket from the live UI node even though cloud and package-worker ownership
|
||||||
|
still remain separate follow-up work.
|
||||||
|
|
||||||
Write scope:
|
Write scope:
|
||||||
- `src/legacy_cloud_services.*`
|
- `src/legacy_cloud_services.*`
|
||||||
- `src/node_dialog_cloud.*`
|
- `src/node_dialog_cloud.*`
|
||||||
|
|||||||
142
src/canvas.cpp
142
src/canvas.cpp
@@ -10,6 +10,7 @@
|
|||||||
#include "legacy_canvas_stroke_edge_services.h"
|
#include "legacy_canvas_stroke_edge_services.h"
|
||||||
#include "legacy_canvas_stroke_execution_services.h"
|
#include "legacy_canvas_stroke_execution_services.h"
|
||||||
#include "legacy_canvas_stroke_shader_services.h"
|
#include "legacy_canvas_stroke_shader_services.h"
|
||||||
|
#include "legacy_canvas_object_draw_services.h"
|
||||||
#include "legacy_canvas_projection_services.h"
|
#include "legacy_canvas_projection_services.h"
|
||||||
#include "legacy_canvas_stroke_services.h"
|
#include "legacy_canvas_stroke_services.h"
|
||||||
#include "legacy_ui_gl_dispatch.h"
|
#include "legacy_ui_gl_dispatch.h"
|
||||||
@@ -2531,149 +2532,12 @@ void Canvas::clear_context()
|
|||||||
|
|
||||||
void Canvas::draw_objects_direct(std::function<void(const glm::mat4& camera, const glm::mat4& proj, int i)> observer, Layer& layer, int frame)
|
void Canvas::draw_objects_direct(std::function<void(const glm::mat4& camera, const glm::mat4& proj, int i)> observer, Layer& layer, int frame)
|
||||||
{
|
{
|
||||||
App::I->render_task([&]
|
pp::panopainter::legacy_canvas_draw_objects_direct(*this, std::move(observer), layer, frame);
|
||||||
{
|
|
||||||
// save viewport and clear color states
|
|
||||||
const auto vp = query_canvas_viewport();
|
|
||||||
const auto cc = query_canvas_clear_color();
|
|
||||||
auto blend = query_canvas_capability(blend_state());
|
|
||||||
|
|
||||||
// prepare common states
|
|
||||||
apply_canvas_viewport(0, 0, layer.w, layer.h);
|
|
||||||
apply_canvas_capability(blend_state(), false);
|
|
||||||
|
|
||||||
GLuint rboID = allocate_canvas_depth_renderbuffer(layer.w, layer.h);
|
|
||||||
|
|
||||||
glm::mat4 proj = glm::perspective(glm::radians(90.f), 1.f, .01f, 1000.f);
|
|
||||||
for (int i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
glm::mat4 plane_camera = glm::lookAt(glm::vec3(0), m_plane_origin[i], m_plane_tangent[i]);
|
|
||||||
layer.rtt(i, frame).bindFramebuffer();
|
|
||||||
attach_canvas_depth_renderbuffer(rboID);
|
|
||||||
|
|
||||||
observer(plane_camera, proj, i);
|
|
||||||
|
|
||||||
attach_canvas_depth_renderbuffer(0);
|
|
||||||
layer.rtt(i, frame).unbindFramebuffer();
|
|
||||||
|
|
||||||
layer.face(i, frame) = true;
|
|
||||||
layer.box(i, frame) = { 0, 0, layer.w, layer.h };
|
|
||||||
}
|
|
||||||
|
|
||||||
delete_canvas_renderbuffer(rboID);
|
|
||||||
|
|
||||||
// restore viewport and clear color states
|
|
||||||
blend ? apply_canvas_capability(blend_state(), true) : apply_canvas_capability(blend_state(), false);
|
|
||||||
apply_canvas_viewport(vp.x, vp.y, vp.width, vp.height);
|
|
||||||
apply_canvas_clear_color(cc);
|
|
||||||
set_active_texture_unit(0);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::draw_objects(std::function<void(const glm::mat4& camera, const glm::mat4& proj, int i)> observer, Layer& layer, int frame, bool save_history)
|
void Canvas::draw_objects(std::function<void(const glm::mat4& camera, const glm::mat4& proj, int i)> observer, Layer& layer, int frame, bool save_history)
|
||||||
{
|
{
|
||||||
App::I->render_task([&]
|
pp::panopainter::legacy_canvas_draw_objects(*this, std::move(observer), layer, frame, save_history);
|
||||||
{
|
|
||||||
// save viewport and clear color states
|
|
||||||
const auto vp = query_canvas_viewport();
|
|
||||||
const auto cc = query_canvas_clear_color();
|
|
||||||
auto blend = query_canvas_capability(blend_state());
|
|
||||||
|
|
||||||
// prepare common states
|
|
||||||
apply_canvas_viewport(0, 0, layer.w, layer.h);
|
|
||||||
apply_canvas_capability(blend_state(), false);
|
|
||||||
|
|
||||||
GLuint rboID = allocate_canvas_depth_renderbuffer(layer.w, layer.h);
|
|
||||||
|
|
||||||
RTT rtt;
|
|
||||||
rtt.create(layer.w, layer.h);
|
|
||||||
rtt.bindFramebuffer();
|
|
||||||
attach_canvas_depth_renderbuffer(rboID);
|
|
||||||
rtt.unbindFramebuffer();
|
|
||||||
|
|
||||||
// allocate action to add to history
|
|
||||||
ActionStroke* action;
|
|
||||||
|
|
||||||
if (save_history)
|
|
||||||
{
|
|
||||||
action = new ActionStroke;
|
|
||||||
action->was_saved = !m_unsaved;
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::mat4 proj = glm::perspective(glm::radians(90.f), 1.f, .01f, 1000.f);
|
|
||||||
for (int i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
glm::mat4 plane_camera = glm::lookAt(glm::vec3(0), m_plane_origin[i], m_plane_tangent[i]);
|
|
||||||
rtt.bindFramebuffer();
|
|
||||||
rtt.clear({ 1, 1, 1, 0 });
|
|
||||||
observer(plane_camera, proj, i);
|
|
||||||
rtt.unbindFramebuffer();
|
|
||||||
|
|
||||||
glm::vec4 bounds = rtt.calc_bounds();
|
|
||||||
|
|
||||||
layer.rtt(i, frame).bindFramebuffer();
|
|
||||||
|
|
||||||
glm::vec2 box_sz = zw(bounds) - xy(bounds);
|
|
||||||
bool has_data = box_sz.x > 0 && box_sz.y > 0;
|
|
||||||
|
|
||||||
if (save_history)
|
|
||||||
{
|
|
||||||
// save image before commit
|
|
||||||
if (has_data)
|
|
||||||
{
|
|
||||||
action->m_image[i] = std::make_unique<uint8_t[]>(box_sz.x * box_sz.y * 4);
|
|
||||||
layer.rtt(i, frame).readPixelsRgba8(
|
|
||||||
static_cast<int>(bounds.x),
|
|
||||||
static_cast<int>(bounds.y),
|
|
||||||
static_cast<int>(box_sz.x),
|
|
||||||
static_cast<int>(box_sz.y),
|
|
||||||
action->m_image[i].get());
|
|
||||||
action->m_box[i] = bounds;
|
|
||||||
}
|
|
||||||
action->m_old_box[i] = layer.box(i, frame);
|
|
||||||
action->m_old_dirty[i] = layer.face(i, frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw the tmp layer into the actual layer
|
|
||||||
if (has_data)
|
|
||||||
{
|
|
||||||
pp::panopainter::setup_legacy_canvas_draw_merge_texture_shader(
|
|
||||||
pp::panopainter::LegacyCanvasDrawMergeTextureUniforms {
|
|
||||||
.mvp = glm::ortho(-0.5f, 0.5f, -0.5f, 0.5f),
|
|
||||||
.texture_slot = 0,
|
|
||||||
});
|
|
||||||
set_active_texture_unit(0);
|
|
||||||
m_sampler_nearest.bind(0);
|
|
||||||
rtt.bindTexture();
|
|
||||||
m_plane.draw_fill();
|
|
||||||
rtt.unbindTexture();
|
|
||||||
|
|
||||||
layer.face(i, frame) = true;
|
|
||||||
layer.box(i, frame) = { glm::min(xy(layer.box(i, frame)), xy(bounds)), glm::max(zw(layer.box(i, frame)), zw(bounds)) };
|
|
||||||
}
|
|
||||||
|
|
||||||
layer.rtt(i, frame).unbindFramebuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (save_history)
|
|
||||||
{
|
|
||||||
// save history
|
|
||||||
action->m_layer_idx = m_current_layer_idx;
|
|
||||||
action->m_frame_idx = frame;
|
|
||||||
action->m_canvas = this;
|
|
||||||
//action->m_stroke = std::move(m_current_stroke);
|
|
||||||
ActionManager::add(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete_canvas_renderbuffer(rboID);
|
|
||||||
rtt.destroy();
|
|
||||||
|
|
||||||
// restore viewport and clear color states
|
|
||||||
blend ? apply_canvas_capability(blend_state(), true) : apply_canvas_capability(blend_state(), false);
|
|
||||||
apply_canvas_viewport(vp.x, vp.y, vp.width, vp.height);
|
|
||||||
apply_canvas_clear_color(cc);
|
|
||||||
set_active_texture_unit(0);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::draw_objects(std::function<void(const glm::mat4& camera, const glm::mat4& proj, int i)> observer, int frame, bool save_history)
|
void Canvas::draw_objects(std::function<void(const glm::mat4& camera, const glm::mat4& proj, int i)> observer, int frame, bool save_history)
|
||||||
|
|||||||
166
src/legacy_brush_panel_services.cpp
Normal file
166
src/legacy_brush_panel_services.cpp
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
|
||||||
|
#include "legacy_brush_panel_services.h"
|
||||||
|
|
||||||
|
#include "app.h"
|
||||||
|
#include "asset.h"
|
||||||
|
#include "node_panel_brush.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace pp::panopainter {
|
||||||
|
|
||||||
|
LegacyBrushPanelServices::LegacyBrushPanelServices(NodePanelBrush& panel) noexcept
|
||||||
|
: panel_(panel)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int LegacyBrushPanelServices::find_brush(const std::string& name) const
|
||||||
|
{
|
||||||
|
for (int i = 0; i < panel_.m_container->m_children.size(); i++) {
|
||||||
|
auto* b = static_cast<NodeButtonBrush*>(panel_.m_container->m_children[i].get());
|
||||||
|
if (b->brush_name.find(name) != std::string::npos) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string LegacyBrushPanelServices::get_texture_path(int index) const
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= panel_.m_container->m_children.size()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return static_cast<NodeButtonBrush*>(panel_.m_container->m_children[index].get())->high_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string LegacyBrushPanelServices::get_thumb_path(int index) const
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= panel_.m_container->m_children.size()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return static_cast<NodeButtonBrush*>(panel_.m_container->m_children[index].get())->thumb_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LegacyBrushPanelServices::save()
|
||||||
|
{
|
||||||
|
std::ofstream f(App::I->data_path + "/settings/" + panel_.m_dir_name + ".bin", std::ios::binary);
|
||||||
|
if (f.good()) {
|
||||||
|
BinaryStreamWriter sw;
|
||||||
|
sw.init();
|
||||||
|
sw.wstring_raw("PPVR"); // magic code
|
||||||
|
sw.wu16(0); // version major
|
||||||
|
sw.wu16(1); // minor
|
||||||
|
sw.wu32((int)panel_.m_container->m_children.size()); // number of items
|
||||||
|
for (const auto& child : panel_.m_container->m_children) {
|
||||||
|
auto b = std::static_pointer_cast<NodeButtonBrush>(child);
|
||||||
|
sw << *b;
|
||||||
|
}
|
||||||
|
f.write((char*)sw.m_data.data(), sw.m_data.size());
|
||||||
|
f.close();
|
||||||
|
App::I->flush_platform_storage();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LegacyBrushPanelServices::restore()
|
||||||
|
{
|
||||||
|
Asset f;
|
||||||
|
auto path = App::I->data_path + "/settings/" + panel_.m_dir_name + ".bin";
|
||||||
|
if (f.open(path.c_str())) {
|
||||||
|
f.read_all();
|
||||||
|
|
||||||
|
if (f.m_len == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryStreamReader sr;
|
||||||
|
sr.init(f.m_data, f.m_len);
|
||||||
|
|
||||||
|
if (sr.rstring(4) != "PPVR") {
|
||||||
|
LOG("PPVR tag not found")
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto vmaj = sr.ru16();
|
||||||
|
auto vmin = sr.ru16();
|
||||||
|
if (vmaj != 0 && vmin != 1) {
|
||||||
|
LOG("unrecognised version %d.%d", vmaj, vmin);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto count = sr.ru32();
|
||||||
|
|
||||||
|
for (int k = 0; k < count; k++) {
|
||||||
|
auto b = std::make_shared<NodeButtonBrush>();
|
||||||
|
if (!b->read(sr)) {
|
||||||
|
LOG("error deserializing the button brush");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Asset::exist(b->high_path)) {
|
||||||
|
panel_.m_container->add_child(b);
|
||||||
|
b->init();
|
||||||
|
b->create();
|
||||||
|
b->loaded();
|
||||||
|
b->set_icon(b->thumb_path.c_str());
|
||||||
|
b->on_click = std::bind(&NodePanelBrush::handle_click, &panel_, std::placeholders::_1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LegacyBrushPanelServices::clear()
|
||||||
|
{
|
||||||
|
panel_.m_container->remove_all_children();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LegacyBrushPanelServices::scan()
|
||||||
|
{
|
||||||
|
auto icons = Asset::list_files("data/" + panel_.m_dir_name, ".*\\.png$");
|
||||||
|
for (auto& i : icons) {
|
||||||
|
std::string path = "data/" + panel_.m_dir_name + "/thumbs/" + i;
|
||||||
|
std::string path_hi = "data/" + panel_.m_dir_name + "/" + i;
|
||||||
|
NodeButtonBrush* brush = new NodeButtonBrush;
|
||||||
|
panel_.m_container->add_child(brush);
|
||||||
|
brush->init();
|
||||||
|
brush->create();
|
||||||
|
brush->loaded();
|
||||||
|
brush->set_icon(path.c_str());
|
||||||
|
brush->thumb_path = path;
|
||||||
|
brush->high_path = path_hi;
|
||||||
|
brush->brush_name = i;
|
||||||
|
brush->m_user_brush = false; // system brush, cannot be deleted from file
|
||||||
|
brush->on_click = std::bind(&NodePanelBrush::handle_click, &panel_, std::placeholders::_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto custom_icons = Asset::list_files(App::I->data_path + "/" + panel_.m_dir_name, ".*\\.png$");
|
||||||
|
for (auto& i : custom_icons) {
|
||||||
|
std::string path_thumb = App::I->data_path + "/" + panel_.m_dir_name + "/thumbs/" + i;
|
||||||
|
std::string path_high = App::I->data_path + "/" + panel_.m_dir_name + "/" + i;
|
||||||
|
NodeButtonBrush* brush = new NodeButtonBrush;
|
||||||
|
panel_.m_container->add_child(brush);
|
||||||
|
brush->init();
|
||||||
|
brush->create();
|
||||||
|
brush->loaded();
|
||||||
|
brush->set_icon(path_thumb.c_str());
|
||||||
|
brush->thumb_path = path_thumb;
|
||||||
|
brush->high_path = path_high;
|
||||||
|
brush->brush_name = i;
|
||||||
|
brush->m_user_brush = true;
|
||||||
|
brush->on_click = std::bind(&NodePanelBrush::handle_click, &panel_, std::placeholders::_1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LegacyBrushPanelServices::reload()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
scan();
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace pp::panopainter
|
||||||
26
src/legacy_brush_panel_services.h
Normal file
26
src/legacy_brush_panel_services.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class NodePanelBrush;
|
||||||
|
|
||||||
|
namespace pp::panopainter {
|
||||||
|
|
||||||
|
class LegacyBrushPanelServices final {
|
||||||
|
public:
|
||||||
|
explicit LegacyBrushPanelServices(NodePanelBrush& panel) noexcept;
|
||||||
|
|
||||||
|
int find_brush(const std::string& name) const;
|
||||||
|
std::string get_texture_path(int index) const;
|
||||||
|
std::string get_thumb_path(int index) const;
|
||||||
|
bool save();
|
||||||
|
bool restore();
|
||||||
|
void clear();
|
||||||
|
void scan();
|
||||||
|
void reload();
|
||||||
|
|
||||||
|
private:
|
||||||
|
NodePanelBrush& panel_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace pp::panopainter
|
||||||
221
src/legacy_canvas_object_draw_services.cpp
Normal file
221
src/legacy_canvas_object_draw_services.cpp
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
|
||||||
|
#include "legacy_canvas_object_draw_services.h"
|
||||||
|
|
||||||
|
#include "app.h"
|
||||||
|
#include "canvas.h"
|
||||||
|
#include "legacy_canvas_draw_merge_services.h"
|
||||||
|
#include "legacy_gl_renderbuffer_dispatch.h"
|
||||||
|
#include "legacy_ui_gl_dispatch.h"
|
||||||
|
#include "renderer_gl/opengl_capabilities.h"
|
||||||
|
|
||||||
|
namespace pp::panopainter {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
GLenum blend_state()
|
||||||
|
{
|
||||||
|
return static_cast<GLenum>(pp::renderer::gl::blend_state());
|
||||||
|
}
|
||||||
|
|
||||||
|
void apply_canvas_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, "Canvas");
|
||||||
|
}
|
||||||
|
|
||||||
|
pp::renderer::gl::OpenGlViewportRect query_canvas_viewport()
|
||||||
|
{
|
||||||
|
return pp::legacy::ui_gl::query_viewport_rect("Canvas");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<float, 4> query_canvas_clear_color()
|
||||||
|
{
|
||||||
|
return pp::legacy::ui_gl::query_clear_color("Canvas");
|
||||||
|
}
|
||||||
|
|
||||||
|
void apply_canvas_clear_color(std::array<float, 4> color)
|
||||||
|
{
|
||||||
|
pp::legacy::ui_gl::set_clear_color(color, "Canvas");
|
||||||
|
}
|
||||||
|
|
||||||
|
void apply_canvas_capability(std::uint32_t state, bool enabled)
|
||||||
|
{
|
||||||
|
pp::legacy::ui_gl::set_capability(state, enabled, "Canvas");
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_active_texture_unit(std::uint32_t unit_index)
|
||||||
|
{
|
||||||
|
pp::legacy::ui_gl::activate_texture_unit(unit_index, "Canvas");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LegacyCanvasObjectDrawState {
|
||||||
|
pp::renderer::gl::OpenGlViewportRect viewport;
|
||||||
|
std::array<float, 4> clear_color;
|
||||||
|
bool blend = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
LegacyCanvasObjectDrawState capture_legacy_canvas_object_draw_state()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
.viewport = query_canvas_viewport(),
|
||||||
|
.clear_color = query_canvas_clear_color(),
|
||||||
|
.blend = pp::legacy::ui_gl::query_capability(blend_state(), "Canvas"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void restore_legacy_canvas_object_draw_state(const LegacyCanvasObjectDrawState& state)
|
||||||
|
{
|
||||||
|
state.blend ? apply_canvas_capability(blend_state(), true) : apply_canvas_capability(blend_state(), false);
|
||||||
|
apply_canvas_viewport(state.viewport.x, state.viewport.y, state.viewport.width, state.viewport.height);
|
||||||
|
apply_canvas_clear_color(state.clear_color);
|
||||||
|
set_active_texture_unit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Execute>
|
||||||
|
void execute_legacy_canvas_object_draw_task(Layer& layer, Execute&& execute)
|
||||||
|
{
|
||||||
|
const auto state = capture_legacy_canvas_object_draw_state();
|
||||||
|
|
||||||
|
apply_canvas_viewport(0, 0, layer.w, layer.h);
|
||||||
|
apply_canvas_capability(blend_state(), false);
|
||||||
|
|
||||||
|
GLuint rboID = pp::legacy::gl_renderbuffer::allocate_depth_renderbuffer(layer.w, layer.h, "Canvas");
|
||||||
|
execute(rboID);
|
||||||
|
pp::legacy::gl_renderbuffer::delete_renderbuffer(rboID, "Canvas");
|
||||||
|
|
||||||
|
restore_legacy_canvas_object_draw_state(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void execute_legacy_canvas_object_draw_face(
|
||||||
|
Canvas& canvas,
|
||||||
|
Layer& layer,
|
||||||
|
int frame,
|
||||||
|
int face_index,
|
||||||
|
RTT& rtt,
|
||||||
|
ActionStroke* action,
|
||||||
|
bool save_history,
|
||||||
|
const std::function<void(const glm::mat4& camera, const glm::mat4& proj, int i)>& observer)
|
||||||
|
{
|
||||||
|
rtt.bindFramebuffer();
|
||||||
|
rtt.clear({ 1, 1, 1, 0 });
|
||||||
|
glm::mat4 proj = glm::perspective(glm::radians(90.f), 1.f, .01f, 1000.f);
|
||||||
|
glm::mat4 plane_camera = glm::lookAt(glm::vec3(0), canvas.m_plane_origin[face_index], canvas.m_plane_tangent[face_index]);
|
||||||
|
observer(plane_camera, proj, face_index);
|
||||||
|
rtt.unbindFramebuffer();
|
||||||
|
|
||||||
|
glm::vec4 bounds = rtt.calc_bounds();
|
||||||
|
|
||||||
|
layer.rtt(face_index, frame).bindFramebuffer();
|
||||||
|
|
||||||
|
glm::vec2 box_sz = zw(bounds) - xy(bounds);
|
||||||
|
bool has_data = box_sz.x > 0 && box_sz.y > 0;
|
||||||
|
|
||||||
|
if (save_history)
|
||||||
|
{
|
||||||
|
if (has_data)
|
||||||
|
{
|
||||||
|
action->m_image[face_index] = std::make_unique<uint8_t[]>(box_sz.x * box_sz.y * 4);
|
||||||
|
layer.rtt(face_index, frame).readPixelsRgba8(
|
||||||
|
static_cast<int>(bounds.x),
|
||||||
|
static_cast<int>(bounds.y),
|
||||||
|
static_cast<int>(box_sz.x),
|
||||||
|
static_cast<int>(box_sz.y),
|
||||||
|
action->m_image[face_index].get());
|
||||||
|
action->m_box[face_index] = bounds;
|
||||||
|
}
|
||||||
|
action->m_old_box[face_index] = layer.box(face_index, frame);
|
||||||
|
action->m_old_dirty[face_index] = layer.face(face_index, frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_data)
|
||||||
|
{
|
||||||
|
pp::panopainter::setup_legacy_canvas_draw_merge_texture_shader(
|
||||||
|
pp::panopainter::LegacyCanvasDrawMergeTextureUniforms {
|
||||||
|
.mvp = glm::ortho(-0.5f, 0.5f, -0.5f, 0.5f),
|
||||||
|
.texture_slot = 0,
|
||||||
|
});
|
||||||
|
set_active_texture_unit(0);
|
||||||
|
canvas.m_sampler_nearest.bind(0);
|
||||||
|
rtt.bindTexture();
|
||||||
|
canvas.m_plane.draw_fill();
|
||||||
|
rtt.unbindTexture();
|
||||||
|
|
||||||
|
layer.face(face_index, frame) = true;
|
||||||
|
layer.box(face_index, frame) = { glm::min(xy(layer.box(face_index, frame)), xy(bounds)), glm::max(zw(layer.box(face_index, frame)), zw(bounds)) };
|
||||||
|
}
|
||||||
|
|
||||||
|
layer.rtt(face_index, frame).unbindFramebuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void legacy_canvas_draw_objects_direct(
|
||||||
|
Canvas& canvas,
|
||||||
|
std::function<void(const glm::mat4& camera, const glm::mat4& proj, int i)> observer,
|
||||||
|
Layer& layer,
|
||||||
|
int frame)
|
||||||
|
{
|
||||||
|
App::I->render_task([&]
|
||||||
|
{
|
||||||
|
execute_legacy_canvas_object_draw_task(layer, [&](GLuint rboID)
|
||||||
|
{
|
||||||
|
glm::mat4 proj = glm::perspective(glm::radians(90.f), 1.f, .01f, 1000.f);
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
glm::mat4 plane_camera = glm::lookAt(glm::vec3(0), canvas.m_plane_origin[i], canvas.m_plane_tangent[i]);
|
||||||
|
layer.rtt(i, frame).bindFramebuffer();
|
||||||
|
pp::legacy::gl_renderbuffer::attach_depth_renderbuffer(rboID, "Canvas");
|
||||||
|
|
||||||
|
observer(plane_camera, proj, i);
|
||||||
|
|
||||||
|
pp::legacy::gl_renderbuffer::attach_depth_renderbuffer(0, "Canvas");
|
||||||
|
layer.rtt(i, frame).unbindFramebuffer();
|
||||||
|
|
||||||
|
layer.face(i, frame) = true;
|
||||||
|
layer.box(i, frame) = { 0, 0, layer.w, layer.h };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void legacy_canvas_draw_objects(
|
||||||
|
Canvas& canvas,
|
||||||
|
std::function<void(const glm::mat4& camera, const glm::mat4& proj, int i)> observer,
|
||||||
|
Layer& layer,
|
||||||
|
int frame,
|
||||||
|
bool save_history)
|
||||||
|
{
|
||||||
|
App::I->render_task([&]
|
||||||
|
{
|
||||||
|
execute_legacy_canvas_object_draw_task(layer, [&](GLuint rboID)
|
||||||
|
{
|
||||||
|
RTT rtt;
|
||||||
|
rtt.create(layer.w, layer.h);
|
||||||
|
rtt.bindFramebuffer();
|
||||||
|
pp::legacy::gl_renderbuffer::attach_depth_renderbuffer(rboID, "Canvas");
|
||||||
|
rtt.unbindFramebuffer();
|
||||||
|
|
||||||
|
ActionStroke* action = nullptr;
|
||||||
|
if (save_history)
|
||||||
|
{
|
||||||
|
action = new ActionStroke;
|
||||||
|
action->was_saved = !canvas.m_unsaved;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
execute_legacy_canvas_object_draw_face(canvas, layer, frame, i, rtt, action, save_history, observer);
|
||||||
|
|
||||||
|
if (save_history)
|
||||||
|
{
|
||||||
|
action->m_layer_idx = canvas.m_current_layer_idx;
|
||||||
|
action->m_frame_idx = frame;
|
||||||
|
action->m_canvas = &canvas;
|
||||||
|
ActionManager::add(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
rtt.destroy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace pp::panopainter
|
||||||
22
src/legacy_canvas_object_draw_services.h
Normal file
22
src/legacy_canvas_object_draw_services.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "canvas.h"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace pp::panopainter {
|
||||||
|
|
||||||
|
void legacy_canvas_draw_objects_direct(
|
||||||
|
Canvas& canvas,
|
||||||
|
std::function<void(const glm::mat4& camera, const glm::mat4& proj, int i)> observer,
|
||||||
|
Layer& layer,
|
||||||
|
int frame);
|
||||||
|
|
||||||
|
void legacy_canvas_draw_objects(
|
||||||
|
Canvas& canvas,
|
||||||
|
std::function<void(const glm::mat4& camera, const glm::mat4& proj, int i)> observer,
|
||||||
|
Layer& layer,
|
||||||
|
int frame,
|
||||||
|
bool save_history);
|
||||||
|
|
||||||
|
} // namespace pp::panopainter
|
||||||
@@ -446,6 +446,26 @@ void execute_node_canvas_draw_unmerged_pass(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void execute_node_canvas_draw_merged_pass(
|
||||||
|
NodeCanvas& node_canvas,
|
||||||
|
const glm::mat4& proj,
|
||||||
|
const glm::mat4& camera)
|
||||||
|
{
|
||||||
|
pp::panopainter::execute_legacy_canvas_draw_merged_pass(
|
||||||
|
node_canvas,
|
||||||
|
proj,
|
||||||
|
camera,
|
||||||
|
[&](auto state, bool enabled) {
|
||||||
|
apply_node_canvas_capability(state, enabled);
|
||||||
|
},
|
||||||
|
[](int unit) {
|
||||||
|
set_active_texture_unit(unit);
|
||||||
|
},
|
||||||
|
[&] {
|
||||||
|
node_canvas.m_face_plane.draw_fill();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void execute_node_canvas_draw_merge_tail(
|
void execute_node_canvas_draw_merge_tail(
|
||||||
NodeCanvas& node_canvas,
|
NodeCanvas& node_canvas,
|
||||||
const glm::mat4& ortho_proj,
|
const glm::mat4& ortho_proj,
|
||||||
@@ -662,19 +682,7 @@ void NodeCanvas::draw()
|
|||||||
apply_node_canvas_viewport(c.x + App::I->off_x, c.y + App::I->off_y, c.z, c.w);
|
apply_node_canvas_viewport(c.x + App::I->off_x, c.y + App::I->off_y, c.z, c.w);
|
||||||
},
|
},
|
||||||
[&] {
|
[&] {
|
||||||
pp::panopainter::execute_legacy_canvas_draw_merged_pass(
|
execute_node_canvas_draw_merged_pass(*this, proj, camera);
|
||||||
*this,
|
|
||||||
proj,
|
|
||||||
camera,
|
|
||||||
[&](auto state, bool enabled) {
|
|
||||||
apply_node_canvas_capability(state, enabled);
|
|
||||||
},
|
|
||||||
[](int unit) {
|
|
||||||
set_active_texture_unit(unit);
|
|
||||||
},
|
|
||||||
[&] {
|
|
||||||
m_face_plane.draw_fill();
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
[&] {
|
[&] {
|
||||||
execute_node_canvas_draw_unmerged_pass(*this, proj, camera, c, yaw, pitch, roll);
|
execute_node_canvas_draw_unmerged_pass(*this, proj, camera, c, yaw, pitch, roll);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "node_panel_brush.h"
|
#include "node_panel_brush.h"
|
||||||
|
#include "legacy_brush_panel_services.h"
|
||||||
#include "assets/brush_package.h"
|
#include "assets/brush_package.h"
|
||||||
#include "app_core/brush_ui.h"
|
#include "app_core/brush_ui.h"
|
||||||
#include "legacy_brush_ui_services.h"
|
#include "legacy_brush_ui_services.h"
|
||||||
@@ -208,156 +209,42 @@ void NodePanelBrush::handle_click(Node* target)
|
|||||||
|
|
||||||
int NodePanelBrush::find_brush(const std::string & name) const
|
int NodePanelBrush::find_brush(const std::string & name) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < m_container->m_children.size(); i++)
|
return pp::panopainter::LegacyBrushPanelServices(const_cast<NodePanelBrush&>(*this)).find_brush(name);
|
||||||
{
|
|
||||||
NodeButtonBrush* b = (NodeButtonBrush*)m_container->m_children[i].get();
|
|
||||||
if (b->brush_name.find(name) != std::string::npos)
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string NodePanelBrush::get_texture_path(int index) const
|
std::string NodePanelBrush::get_texture_path(int index) const
|
||||||
{
|
{
|
||||||
if (index < 0 || index >= m_container->m_children.size())
|
return pp::panopainter::LegacyBrushPanelServices(const_cast<NodePanelBrush&>(*this)).get_texture_path(index);
|
||||||
return "";
|
|
||||||
return ((NodeButtonBrush*)m_container->m_children[index].get())->high_path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string NodePanelBrush::get_thumb_path(int index) const
|
std::string NodePanelBrush::get_thumb_path(int index) const
|
||||||
{
|
{
|
||||||
if (index < 0 || index >= m_container->m_children.size())
|
return pp::panopainter::LegacyBrushPanelServices(const_cast<NodePanelBrush&>(*this)).get_thumb_path(index);
|
||||||
return "";
|
|
||||||
return ((NodeButtonBrush*)m_container->m_children[index].get())->thumb_path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NodePanelBrush::save()
|
bool NodePanelBrush::save()
|
||||||
{
|
{
|
||||||
std::ofstream f(App::I->data_path + "/settings/" + m_dir_name + ".bin", std::ios::binary);
|
return pp::panopainter::LegacyBrushPanelServices(*this).save();
|
||||||
if (f.good())
|
|
||||||
{
|
|
||||||
BinaryStreamWriter sw;
|
|
||||||
sw.init();
|
|
||||||
sw.wstring_raw("PPVR"); // magic code
|
|
||||||
sw.wu16(0); // version major
|
|
||||||
sw.wu16(1); // minor
|
|
||||||
sw.wu32((int)m_container->m_children.size()); // number of items
|
|
||||||
for (const auto& child : m_container->m_children)
|
|
||||||
{
|
|
||||||
auto b = std::static_pointer_cast<NodeButtonBrush>(child);
|
|
||||||
sw << *b;
|
|
||||||
}
|
|
||||||
f.write((char*)sw.m_data.data(), sw.m_data.size());
|
|
||||||
f.close();
|
|
||||||
App::I->flush_platform_storage();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NodePanelBrush::restore()
|
bool NodePanelBrush::restore()
|
||||||
{
|
{
|
||||||
Asset f;
|
return pp::panopainter::LegacyBrushPanelServices(*this).restore();
|
||||||
auto path = App::I->data_path + "/settings/" + m_dir_name + ".bin";
|
|
||||||
if (f.open(path.c_str()))
|
|
||||||
{
|
|
||||||
f.read_all();
|
|
||||||
|
|
||||||
if (f.m_len == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
BinaryStreamReader sr;
|
|
||||||
sr.init(f.m_data, f.m_len);
|
|
||||||
|
|
||||||
// sanity checks
|
|
||||||
if (sr.rstring(4) != "PPVR")
|
|
||||||
{
|
|
||||||
LOG("PPVR tag not found")
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
auto vmaj = sr.ru16();
|
|
||||||
auto vmin = sr.ru16();
|
|
||||||
if (vmaj != 0 && vmin != 1)
|
|
||||||
{
|
|
||||||
LOG("unrecognised version %d.%d", vmaj, vmin);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto count = sr.ru32();
|
|
||||||
|
|
||||||
for (int k = 0; k < count; k++)
|
|
||||||
{
|
|
||||||
auto b = std::make_shared<NodeButtonBrush>();
|
|
||||||
if (!b->read(sr))
|
|
||||||
{
|
|
||||||
LOG("error deserializing the button brush");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Asset::exist(b->high_path))
|
|
||||||
{
|
|
||||||
m_container->add_child(b);
|
|
||||||
b->init();
|
|
||||||
b->create();
|
|
||||||
b->loaded();
|
|
||||||
b->set_icon(b->thumb_path.c_str());
|
|
||||||
b->on_click = std::bind(&NodePanelBrush::handle_click, this, std::placeholders::_1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodePanelBrush::clear()
|
void NodePanelBrush::clear()
|
||||||
{
|
{
|
||||||
m_container->remove_all_children();
|
pp::panopainter::LegacyBrushPanelServices(*this).clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodePanelBrush::scan()
|
void NodePanelBrush::scan()
|
||||||
{
|
{
|
||||||
auto icons = Asset::list_files("data/" + m_dir_name, ".*\\.png$");
|
pp::panopainter::LegacyBrushPanelServices(*this).scan();
|
||||||
for (auto& i : icons)
|
|
||||||
{
|
|
||||||
std::string path = "data/" + m_dir_name + "/thumbs/" + i;
|
|
||||||
std::string path_hi = "data/" + m_dir_name + "/" + i;
|
|
||||||
NodeButtonBrush* brush = new NodeButtonBrush;
|
|
||||||
m_container->add_child(brush);
|
|
||||||
brush->init();
|
|
||||||
brush->create();
|
|
||||||
brush->loaded();
|
|
||||||
brush->set_icon(path.c_str());
|
|
||||||
brush->thumb_path = path;
|
|
||||||
brush->high_path = path_hi;
|
|
||||||
brush->brush_name = i;
|
|
||||||
brush->m_user_brush = false; // system brush, cannot be deleted from file
|
|
||||||
brush->on_click = std::bind(&NodePanelBrush::handle_click, this, std::placeholders::_1);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto custom_icons = Asset::list_files(App::I->data_path + "/" + m_dir_name, ".*\\.png$");
|
|
||||||
for (auto& i : custom_icons)
|
|
||||||
{
|
|
||||||
std::string path_thumb = App::I->data_path + "/" + m_dir_name + "/thumbs/" + i;
|
|
||||||
std::string path_high = App::I->data_path + "/" + m_dir_name + "/" + i;
|
|
||||||
NodeButtonBrush* brush = new NodeButtonBrush;
|
|
||||||
m_container->add_child(brush);
|
|
||||||
brush->init();
|
|
||||||
brush->create();
|
|
||||||
brush->loaded();
|
|
||||||
brush->set_icon(path_thumb.c_str());
|
|
||||||
brush->thumb_path = path_thumb;
|
|
||||||
brush->high_path = path_high;
|
|
||||||
brush->brush_name = i;
|
|
||||||
brush->m_user_brush = true;
|
|
||||||
brush->on_click = std::bind(&NodePanelBrush::handle_click, this, std::placeholders::_1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodePanelBrush::reload()
|
void NodePanelBrush::reload()
|
||||||
{
|
{
|
||||||
clear();
|
pp::panopainter::LegacyBrushPanelServices(*this).reload();
|
||||||
scan();
|
|
||||||
save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodePanelBrush::added(Node* parent)
|
void NodePanelBrush::added(Node* parent)
|
||||||
|
|||||||
Reference in New Issue
Block a user