Extract fill modes, preview runtime pockets, and brush item UI
This commit is contained in:
@@ -85,6 +85,7 @@ set(PP_LEGACY_UI_CORE_SOURCES
|
|||||||
|
|
||||||
set(PP_LEGACY_APP_SOURCES
|
set(PP_LEGACY_APP_SOURCES
|
||||||
src/canvas_modes.cpp
|
src/canvas_modes.cpp
|
||||||
|
src/legacy_canvas_mode_fill.cpp
|
||||||
src/legacy_canvas_mode_pen_line.cpp
|
src/legacy_canvas_mode_pen_line.cpp
|
||||||
src/legacy_canvas_mode_helpers.cpp
|
src/legacy_canvas_mode_helpers.cpp
|
||||||
src/legacy_canvas_mode_helpers.h
|
src/legacy_canvas_mode_helpers.h
|
||||||
@@ -151,6 +152,8 @@ set(PP_PANOPAINTER_APP_SOURCES
|
|||||||
src/legacy_brush_package_import_services.h
|
src/legacy_brush_package_import_services.h
|
||||||
src/legacy_brush_package_export_services.cpp
|
src/legacy_brush_package_export_services.cpp
|
||||||
src/legacy_brush_package_export_services.h
|
src/legacy_brush_package_export_services.h
|
||||||
|
src/legacy_brush_panel_item_ui.cpp
|
||||||
|
src/legacy_brush_panel_item_ui.h
|
||||||
src/legacy_brush_preset_services.cpp
|
src/legacy_brush_preset_services.cpp
|
||||||
src/legacy_brush_preset_services.h
|
src/legacy_brush_preset_services.h
|
||||||
src/legacy_cloud_services.cpp
|
src/legacy_cloud_services.cpp
|
||||||
|
|||||||
@@ -81,11 +81,11 @@ Current hotspot files:
|
|||||||
|
|
||||||
- `src/canvas.cpp`: 17 lines
|
- `src/canvas.cpp`: 17 lines
|
||||||
- `src/app_layout.cpp`: 125 lines
|
- `src/app_layout.cpp`: 125 lines
|
||||||
- `src/canvas_modes.cpp`: 402 lines
|
- `src/canvas_modes.cpp`: 176 lines
|
||||||
- `src/node.cpp`: 260 lines
|
- `src/node.cpp`: 260 lines
|
||||||
- `src/main.cpp`: 130 lines
|
- `src/main.cpp`: 130 lines
|
||||||
- `src/node_panel_brush.cpp`: 231 lines
|
- `src/node_panel_brush.cpp`: 189 lines
|
||||||
- `src/node_stroke_preview.cpp`: 343 lines
|
- `src/node_stroke_preview.cpp`: 280 lines
|
||||||
- `src/node_canvas.cpp`: 219 lines
|
- `src/node_canvas.cpp`: 219 lines
|
||||||
- `src/app.cpp`: 113 lines
|
- `src/app.cpp`: 113 lines
|
||||||
- `src/app_dialogs.cpp`: 168 lines
|
- `src/app_dialogs.cpp`: 168 lines
|
||||||
@@ -309,6 +309,10 @@ Current architecture mismatches that must be treated as real blockers:
|
|||||||
`CanvasModeLine` interaction families now also route through
|
`CanvasModeLine` interaction families now also route through
|
||||||
`src/legacy_canvas_mode_pen_line.cpp` instead of staying inline in
|
`src/legacy_canvas_mode_pen_line.cpp` instead of staying inline in
|
||||||
`src/canvas_modes.cpp`,
|
`src/canvas_modes.cpp`,
|
||||||
|
while the `CanvasModeFill` and `CanvasModeFloodFill` interaction families now
|
||||||
|
also route through `src/legacy_canvas_mode_fill.cpp` instead of staying
|
||||||
|
inline in `src/canvas_modes.cpp`, which materially thins another retained
|
||||||
|
fill-mode execution pocket from the broader canvas/render hotspot family,
|
||||||
while `NodePanelBrush` save/restore/scan/reload/find/get-path ownership now
|
while `NodePanelBrush` save/restore/scan/reload/find/get-path ownership now
|
||||||
routes through `src/legacy_brush_panel_services.*` instead of staying inline
|
routes through `src/legacy_brush_panel_services.*` instead of staying inline
|
||||||
in `src/node_panel_brush.cpp`, which trims another retained brush-workflow
|
in `src/node_panel_brush.cpp`, which trims another retained brush-workflow
|
||||||
@@ -324,7 +328,13 @@ Current architecture mismatches that must be treated as real blockers:
|
|||||||
panel UI pocket, while the retained `LegacyBrushPresetListServices` block
|
panel UI pocket, while the retained `LegacyBrushPresetListServices` block
|
||||||
now also lives in `src/legacy_brush_preset_list_services.*` instead of
|
now also lives in `src/legacy_brush_preset_list_services.*` instead of
|
||||||
staying inline in `src/node_panel_brush.cpp`, which trims another retained
|
staying inline in `src/node_panel_brush.cpp`, which trims another retained
|
||||||
preset popup tail now also lives in `src/legacy_brush_preset_panel_ui.*`
|
preset-list pocket, while `NodeButtonBrush` clone/init/icon/read/write/draw
|
||||||
|
behavior and `NodeBrushPresetItem` clone/init/draw behavior now also live in
|
||||||
|
`src/legacy_brush_panel_item_ui.*` instead of staying inline in
|
||||||
|
`src/node_panel_brush.cpp`, which trims the remaining brush-item UI pocket
|
||||||
|
from the live brush panel file, while `NodePanelBrushPreset` popup-close
|
||||||
|
event handling now also lives in
|
||||||
|
`src/legacy_brush_preset_panel_ui.*`
|
||||||
instead of staying inline in `src/node_panel_brush.cpp`, which removes the
|
instead of staying inline in `src/node_panel_brush.cpp`, which removes the
|
||||||
last inline brush-panel popup close handler from the live node. The
|
last inline brush-panel popup close handler from the live node. The
|
||||||
broader preset workflow pocket still remains, while `NodeCanvas::handle_event()`
|
broader preset workflow pocket still remains, while `NodeCanvas::handle_event()`
|
||||||
|
|||||||
@@ -132,6 +132,10 @@ Current slice:
|
|||||||
`src/legacy_canvas_mode_transform.cpp` instead of staying inline in
|
`src/legacy_canvas_mode_transform.cpp` instead of staying inline in
|
||||||
`src/canvas_modes.cpp`, which materially thins another retained
|
`src/canvas_modes.cpp`, which materially thins another retained
|
||||||
transform-mode pocket from the broader canvas/render hotspot family.
|
transform-mode pocket from the broader canvas/render hotspot family.
|
||||||
|
- The `CanvasModeFill` and `CanvasModeFloodFill` interaction families now
|
||||||
|
also live in `src/legacy_canvas_mode_fill.cpp` instead of staying inline in
|
||||||
|
`src/canvas_modes.cpp`, which materially thins another retained fill-mode
|
||||||
|
pocket from the live canvas-mode shell.
|
||||||
- The live `Canvas::stroke_draw()` orchestration now also lives in
|
- The live `Canvas::stroke_draw()` orchestration now also lives in
|
||||||
`src/legacy_canvas_stroke_live_services.cpp` instead of staying inline in
|
`src/legacy_canvas_stroke_live_services.cpp` instead of staying inline in
|
||||||
`src/canvas.cpp`, which materially thins another large retained live
|
`src/canvas.cpp`, which materially thins another large retained live
|
||||||
@@ -231,6 +235,9 @@ Current slice:
|
|||||||
which trims another coherent setup pocket from
|
which trims another coherent setup pocket from
|
||||||
`src/node_stroke_preview.cpp` even though worker/readback ownership and
|
`src/node_stroke_preview.cpp` even though worker/readback ownership and
|
||||||
broader preview flow still remain inline.
|
broader preview flow still remain inline.
|
||||||
|
- `src/node_stroke_preview.cpp` is now 280 lines after moving the preview
|
||||||
|
background-capture and stroke-frame planning pocket into
|
||||||
|
`legacy_node_stroke_preview_runtime_services.*`.
|
||||||
- The remaining immediate preview pass shell in
|
- The remaining immediate preview pass shell in
|
||||||
`NodeStrokePreview::draw_stroke_immediate()` now also routes through
|
`NodeStrokePreview::draw_stroke_immediate()` now also routes through
|
||||||
`execute_legacy_node_stroke_preview_draw_immediate_shell(...)`, which
|
`execute_legacy_node_stroke_preview_draw_immediate_shell(...)`, which
|
||||||
@@ -1133,6 +1140,11 @@ Current slice:
|
|||||||
`src/node_panel_brush.cpp`, which trims a coherent retained brush-workflow
|
`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
|
pocket from the live UI node even though cloud and package-worker ownership
|
||||||
still remain separate follow-up work.
|
still remain separate follow-up work.
|
||||||
|
- `NodeButtonBrush` clone/init/icon/read/write/draw behavior and
|
||||||
|
`NodeBrushPresetItem` clone/init/draw behavior now also live in
|
||||||
|
`src/legacy_brush_panel_item_ui.*` instead of staying inline in
|
||||||
|
`src/node_panel_brush.cpp`, which trims the remaining brush-item UI pocket
|
||||||
|
from the live brush panel file.
|
||||||
- `NodePanelBrushPreset` save/restore plus PPBR/ABR import/export routing now
|
- `NodePanelBrushPreset` save/restore plus PPBR/ABR import/export routing now
|
||||||
also lives in `src/legacy_brush_preset_services.*` instead of staying inline
|
also lives in `src/legacy_brush_preset_services.*` instead of staying inline
|
||||||
in `src/node_panel_brush.cpp`, which trims another large preset-workflow
|
in `src/node_panel_brush.cpp`, which trims another large preset-workflow
|
||||||
|
|||||||
@@ -189,245 +189,3 @@ void ActionModeGrid::undo()
|
|||||||
m_mode->m_selected_index = m_selected_index;
|
m_mode->m_selected_index = m_selected_index;
|
||||||
m_mode->m_lines = m_lines;
|
m_mode->m_lines = m_lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void CanvasModeFill::init()
|
|
||||||
{
|
|
||||||
m_shape.create();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CanvasModeFill::leave(kCanvasMode next)
|
|
||||||
{
|
|
||||||
if (m_points.size() > 2)
|
|
||||||
{
|
|
||||||
auto drawer = [this](const glm::mat4& camera, const glm::mat4& proj) {
|
|
||||||
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();
|
|
||||||
Canvas::I->m_smask_active = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Canvas::I->m_smask_active = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CanvasModeFill::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();
|
|
||||||
m_dragging = true;
|
|
||||||
glm::vec3 ro, rd, hit_o, hit_d;
|
|
||||||
glm::vec2 hit_fb;
|
|
||||||
int plane_id;
|
|
||||||
if (Canvas::I->point_trace_plane(loc, ro, rd, hit_o, hit_d, hit_fb, 0))
|
|
||||||
{
|
|
||||||
m_dirty_planes[plane_id]++;
|
|
||||||
vertex_t v;
|
|
||||||
v.pos = glm::vec4(hit_o, 1);
|
|
||||||
v.uvs = glm::vec2(0);
|
|
||||||
if (m_points.size() < 3)
|
|
||||||
{
|
|
||||||
m_points.push_back(v);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto last = m_points.back();
|
|
||||||
m_points.push_back(m_points[0]);
|
|
||||||
m_points.push_back(last);
|
|
||||||
m_points.push_back(v);
|
|
||||||
}
|
|
||||||
m_shape.update_vertices(m_points.data(), (int)m_points.size());
|
|
||||||
}
|
|
||||||
Canvas::I->m_smask.clear({0, 0, 0, 0});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case kEventType::MouseUpL:
|
|
||||||
pp::panopainter::release_legacy_mouse_capture(*node);
|
|
||||||
m_dragging = false;
|
|
||||||
break;
|
|
||||||
case kEventType::MouseMove:
|
|
||||||
{
|
|
||||||
glm::vec3 ro, rd, hit_o, hit_d;
|
|
||||||
glm::vec2 fb_pos;
|
|
||||||
int plane_id;
|
|
||||||
if (m_dragging && Canvas::I->point_trace(loc, ro, rd, hit_o, fb_pos, hit_d, plane_id))
|
|
||||||
{
|
|
||||||
vertex_t v;
|
|
||||||
v.pos = glm::vec4(hit_o, 1);
|
|
||||||
v.uvs = glm::vec2(0);
|
|
||||||
m_points.back() = v;
|
|
||||||
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 CanvasModeFill::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera)
|
|
||||||
{
|
|
||||||
if (!m_points.empty())
|
|
||||||
{
|
|
||||||
pp::panopainter::setup_legacy_vr_color_shader({
|
|
||||||
.color = { 0, 0, 0, .25 },
|
|
||||||
.mvp = proj * camera,
|
|
||||||
});
|
|
||||||
m_dragging ? m_shape.draw_fill() : m_shape.draw_stroke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void CanvasModeFloodFill::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
|
||||||
{
|
|
||||||
m_draw_tip = App::I->draws_canvas_tip_for_input(me->m_source, me->m_type);
|
|
||||||
if (Canvas::I->m_touch_lock && me->m_source == kEventSource::Touch)
|
|
||||||
return;
|
|
||||||
|
|
||||||
struct ActionFloodFill : public Action
|
|
||||||
{
|
|
||||||
std::shared_ptr<Layer> m_layer;
|
|
||||||
std::shared_ptr<LayerFrame::Snapshot> m_snap;
|
|
||||||
std::array<bool, 6> m_dirty_face = SIXPLETTE(false);
|
|
||||||
std::array<glm::vec4, 6> m_dirty_box = SIXPLETTE(glm::vec4(0));
|
|
||||||
glm::ivec2 m_pos;
|
|
||||||
glm::vec4 m_color;
|
|
||||||
float m_threshold;
|
|
||||||
int m_layer_index;
|
|
||||||
int m_plane;
|
|
||||||
virtual void run() override { }
|
|
||||||
virtual size_t memory() override { return m_snap->memsize(); }
|
|
||||||
virtual Action* get_redo() override
|
|
||||||
{
|
|
||||||
auto a = new ActionFloodFill;
|
|
||||||
a->m_direction = reverse_direction();
|
|
||||||
a->m_layer = m_layer;
|
|
||||||
a->m_snap = m_snap;
|
|
||||||
a->m_pos = m_pos;
|
|
||||||
a->m_color = m_color;
|
|
||||||
a->m_layer_index = m_layer_index;
|
|
||||||
a->m_threshold = m_threshold;
|
|
||||||
a->m_plane = m_plane;
|
|
||||||
a->m_dirty_box = m_dirty_box;
|
|
||||||
a->m_dirty_face = m_dirty_face;
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
virtual void undo() override
|
|
||||||
{
|
|
||||||
if (m_direction == Direction::Undo)
|
|
||||||
{
|
|
||||||
m_layer->restore(*m_snap);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Canvas::FloodData plane_data;
|
|
||||||
std::unique_ptr<glm::vec4> color;
|
|
||||||
Canvas::I->flood_fill(m_layer_index, m_plane, { m_pos },
|
|
||||||
plane_data, m_threshold, m_color, color);
|
|
||||||
plane_data.apply();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
switch (me->m_type)
|
|
||||||
{
|
|
||||||
case kEventType::MouseUpL:
|
|
||||||
glm::vec3 ro, rd, hit, n;
|
|
||||||
glm::vec2 pos;
|
|
||||||
int plane;
|
|
||||||
if (Canvas::I->point_trace(loc, ro, rd, hit, pos, n, plane))
|
|
||||||
{
|
|
||||||
Canvas::FloodData plane_data;
|
|
||||||
std::unique_ptr<glm::vec4> color;
|
|
||||||
Canvas::I->flood_fill(Canvas::I->m_current_layer_idx, plane, { (glm::ivec2)pos },
|
|
||||||
plane_data, m_tool->get_threshold(), Canvas::I->m_current_brush->m_tip_color, color);
|
|
||||||
|
|
||||||
auto a = new ActionFloodFill;
|
|
||||||
a->m_direction = Action::Direction::Undo;
|
|
||||||
a->m_layer = plane_data.layer;
|
|
||||||
a->m_snap = std::make_shared<LayerFrame::Snapshot>(plane_data.layer->snapshot());
|
|
||||||
a->m_pos = (glm::ivec2)pos;
|
|
||||||
a->m_color = Canvas::I->m_current_brush->m_tip_color;
|
|
||||||
a->m_layer_index = Canvas::I->m_current_layer_idx;
|
|
||||||
a->m_threshold = m_tool->get_threshold();
|
|
||||||
a->m_plane = plane;
|
|
||||||
a->m_dirty_box = plane_data.layer->frame().m_dirty_box;
|
|
||||||
a->m_dirty_face = plane_data.layer->frame().m_dirty_face;
|
|
||||||
ActionManager::add(a);
|
|
||||||
|
|
||||||
plane_data.apply();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CanvasModeFloodFill::init()
|
|
||||||
{
|
|
||||||
TextureManager::load(m_cursor_path.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void CanvasModeFloodFill::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera)
|
|
||||||
{
|
|
||||||
if (m_draw_tip)
|
|
||||||
{
|
|
||||||
pp::panopainter::setup_legacy_canvas_draw_merge_texture_shader({
|
|
||||||
.mvp = glm::scale(glm::vec3(1, -1, 1))
|
|
||||||
* ortho
|
|
||||||
* glm::translate(glm::vec3(Canvas::I->m_cur_pos, 0.f))
|
|
||||||
* glm::scale(glm::vec3(32, 32, 1))
|
|
||||||
* glm::translate(glm::vec3(0.5f, -0.5f, 0)),
|
|
||||||
.texture_slot = 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
auto& t = TextureManager::get(m_cursor_id);
|
|
||||||
|
|
||||||
Canvas::I->m_sampler_linear.bind(0);
|
|
||||||
t.bind();
|
|
||||||
Canvas::I->m_plane.draw_fill();
|
|
||||||
t.unbind();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CanvasModeFloodFill::enter(kCanvasMode prev)
|
|
||||||
{
|
|
||||||
auto tools = App::I->layout[App::I->main_id]->find("tools-container");
|
|
||||||
m_tool = tools->add_child<NodeToolBucket>();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CanvasModeFloodFill::leave(kCanvasMode next)
|
|
||||||
{
|
|
||||||
pp::panopainter::destroy_legacy_node(*m_tool);
|
|
||||||
m_tool = nullptr;
|
|
||||||
}
|
|
||||||
|
|||||||
90
src/legacy_brush_panel_item_ui.cpp
Normal file
90
src/legacy_brush_panel_item_ui.cpp
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
|
||||||
|
#include "legacy_brush_panel_item_ui.h"
|
||||||
|
|
||||||
|
#include "app.h"
|
||||||
|
#include "texture.h"
|
||||||
|
|
||||||
|
namespace pp::panopainter {
|
||||||
|
|
||||||
|
Node* clone_legacy_brush_button(const NodeButtonBrush&)
|
||||||
|
{
|
||||||
|
return new NodeButtonBrush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_legacy_brush_button(NodeButtonBrush& owner)
|
||||||
|
{
|
||||||
|
owner.init_template_file("data/dialogs/panel-brushes.xml", "tpl-brush-icon");
|
||||||
|
owner.color_hover = glm::vec4(.7, .7, .7, 1);
|
||||||
|
owner.color_normal = glm::vec4(.3, .3, .3, 1);
|
||||||
|
owner.m_color = owner.color_normal;
|
||||||
|
owner.img = (NodeImage*)owner.m_children[0].get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_legacy_brush_button_icon(NodeButtonBrush& owner, const char* path)
|
||||||
|
{
|
||||||
|
owner.img->m_path = path;
|
||||||
|
owner.img->m_tex_id = const_hash(owner.img->m_path.c_str());
|
||||||
|
owner.img->m_use_mipmaps = true;
|
||||||
|
owner.img->create();
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_legacy_brush_button(NodeButtonBrush& owner)
|
||||||
|
{
|
||||||
|
owner.m_color = owner.m_mouse_inside ? owner.color_hover : owner.color_normal;
|
||||||
|
owner.m_color = owner.m_selected ? glm::vec4(.9, 0, 0, 1) : owner.m_color;
|
||||||
|
owner.NodeButtonCustom::draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool read_legacy_brush_button(NodeButtonBrush& owner, BinaryStreamReader& r)
|
||||||
|
{
|
||||||
|
Serializer::Descriptor d;
|
||||||
|
r >> d;
|
||||||
|
d.value<Serializer::CString>("brush_name", owner.brush_name);
|
||||||
|
d.value<Serializer::CString>("high_path", owner.high_path);
|
||||||
|
d.value<Serializer::CString>("thumb_path", owner.thumb_path);
|
||||||
|
d.value<Serializer::Boolean>("m_user_brush", owner.m_user_brush);
|
||||||
|
owner.high_path = str_replace(owner.high_path, "{data_path}", App::I->data_path);
|
||||||
|
owner.thumb_path = str_replace(owner.thumb_path, "{data_path}", App::I->data_path);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_legacy_brush_button(const NodeButtonBrush& owner, BinaryStreamWriter& w)
|
||||||
|
{
|
||||||
|
Serializer::Descriptor d;
|
||||||
|
d.class_id = "brush";
|
||||||
|
d.name = L"Brush class";
|
||||||
|
d.props["brush_name"] = std::make_shared<Serializer::CString>(owner.brush_name);
|
||||||
|
d.props["high_path"] = std::make_shared<Serializer::CString>(
|
||||||
|
str_replace(owner.high_path, App::I->data_path, "{data_path}"));
|
||||||
|
d.props["thumb_path"] = std::make_shared<Serializer::CString>(
|
||||||
|
str_replace(owner.thumb_path, App::I->data_path, "{data_path}"));
|
||||||
|
d.props["m_user_brush"] = std::make_shared<Serializer::Boolean>(owner.m_user_brush);
|
||||||
|
w << d;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* clone_legacy_brush_preset_item(const NodeBrushPresetItem&)
|
||||||
|
{
|
||||||
|
return new NodeBrushPresetItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_legacy_brush_preset_item(NodeBrushPresetItem& owner)
|
||||||
|
{
|
||||||
|
owner.init_template_file("data/dialogs/panel-brushes.xml", "tpl-brush-preset");
|
||||||
|
owner.color_hover = glm::vec4(.7, .7, .7, 1);
|
||||||
|
owner.color_normal = glm::vec4(.3, .3, .3, 1);
|
||||||
|
owner.m_color = owner.color_normal;
|
||||||
|
owner.m_thumb = owner.find<NodeImage>("thumb");
|
||||||
|
owner.m_caption_size = owner.find<NodeText>("caption-size");
|
||||||
|
owner.m_preview = owner.find<NodeStrokePreview>("canvas");
|
||||||
|
owner.m_preview->m_min_flow = 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_legacy_brush_preset_item(NodeBrushPresetItem& owner)
|
||||||
|
{
|
||||||
|
owner.m_color = owner.m_mouse_inside ? owner.color_hover : owner.color_normal;
|
||||||
|
owner.m_color = owner.m_selected ? glm::vec4(.9, 0, 0, 1) : owner.m_color;
|
||||||
|
owner.NodeButtonCustom::draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace pp::panopainter
|
||||||
18
src/legacy_brush_panel_item_ui.h
Normal file
18
src/legacy_brush_panel_item_ui.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "node_panel_brush.h"
|
||||||
|
|
||||||
|
namespace pp::panopainter {
|
||||||
|
|
||||||
|
Node* clone_legacy_brush_button(const NodeButtonBrush& owner);
|
||||||
|
void init_legacy_brush_button(NodeButtonBrush& owner);
|
||||||
|
void set_legacy_brush_button_icon(NodeButtonBrush& owner, const char* path);
|
||||||
|
void draw_legacy_brush_button(NodeButtonBrush& owner);
|
||||||
|
bool read_legacy_brush_button(NodeButtonBrush& owner, BinaryStreamReader& r);
|
||||||
|
void write_legacy_brush_button(const NodeButtonBrush& owner, BinaryStreamWriter& w);
|
||||||
|
|
||||||
|
Node* clone_legacy_brush_preset_item(const NodeBrushPresetItem& owner);
|
||||||
|
void init_legacy_brush_preset_item(NodeBrushPresetItem& owner);
|
||||||
|
void draw_legacy_brush_preset_item(NodeBrushPresetItem& owner);
|
||||||
|
|
||||||
|
} // namespace pp::panopainter
|
||||||
245
src/legacy_canvas_mode_fill.cpp
Normal file
245
src/legacy_canvas_mode_fill.cpp
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
|
||||||
|
#include "canvas_modes.h"
|
||||||
|
|
||||||
|
#include "app.h"
|
||||||
|
#include "canvas.h"
|
||||||
|
#include "legacy_canvas_draw_merge_services.h"
|
||||||
|
#include "legacy_ui_overlay_services.h"
|
||||||
|
#include "node_tool_bucket.h"
|
||||||
|
#include "texture.h"
|
||||||
|
|
||||||
|
void CanvasModeFill::init()
|
||||||
|
{
|
||||||
|
m_shape.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasModeFill::leave(kCanvasMode next)
|
||||||
|
{
|
||||||
|
if (m_points.size() > 2)
|
||||||
|
{
|
||||||
|
auto drawer = [this](const glm::mat4& camera, const glm::mat4& proj) {
|
||||||
|
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();
|
||||||
|
Canvas::I->m_smask_active = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Canvas::I->m_smask_active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasModeFill::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();
|
||||||
|
m_dragging = true;
|
||||||
|
glm::vec3 ro, rd, hit_o, hit_d;
|
||||||
|
glm::vec2 hit_fb;
|
||||||
|
int plane_id;
|
||||||
|
if (Canvas::I->point_trace_plane(loc, ro, rd, hit_o, hit_d, hit_fb, 0))
|
||||||
|
{
|
||||||
|
m_dirty_planes[plane_id]++;
|
||||||
|
vertex_t v;
|
||||||
|
v.pos = glm::vec4(hit_o, 1);
|
||||||
|
v.uvs = glm::vec2(0);
|
||||||
|
if (m_points.size() < 3)
|
||||||
|
{
|
||||||
|
m_points.push_back(v);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto last = m_points.back();
|
||||||
|
m_points.push_back(m_points[0]);
|
||||||
|
m_points.push_back(last);
|
||||||
|
m_points.push_back(v);
|
||||||
|
}
|
||||||
|
m_shape.update_vertices(m_points.data(), (int)m_points.size());
|
||||||
|
}
|
||||||
|
Canvas::I->m_smask.clear({0, 0, 0, 0});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case kEventType::MouseUpL:
|
||||||
|
pp::panopainter::release_legacy_mouse_capture(*node);
|
||||||
|
m_dragging = false;
|
||||||
|
break;
|
||||||
|
case kEventType::MouseMove:
|
||||||
|
{
|
||||||
|
glm::vec3 ro, rd, hit_o, hit_d;
|
||||||
|
glm::vec2 fb_pos;
|
||||||
|
int plane_id;
|
||||||
|
if (m_dragging && Canvas::I->point_trace(loc, ro, rd, hit_o, fb_pos, hit_d, plane_id))
|
||||||
|
{
|
||||||
|
vertex_t v;
|
||||||
|
v.pos = glm::vec4(hit_o, 1);
|
||||||
|
v.uvs = glm::vec2(0);
|
||||||
|
m_points.back() = v;
|
||||||
|
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 CanvasModeFill::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera)
|
||||||
|
{
|
||||||
|
if (!m_points.empty())
|
||||||
|
{
|
||||||
|
pp::panopainter::setup_legacy_vr_color_shader({
|
||||||
|
.color = { 0, 0, 0, .25 },
|
||||||
|
.mvp = proj * camera,
|
||||||
|
});
|
||||||
|
m_dragging ? m_shape.draw_fill() : m_shape.draw_stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasModeFloodFill::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
||||||
|
{
|
||||||
|
m_draw_tip = App::I->draws_canvas_tip_for_input(me->m_source, me->m_type);
|
||||||
|
if (Canvas::I->m_touch_lock && me->m_source == kEventSource::Touch)
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct ActionFloodFill : public Action
|
||||||
|
{
|
||||||
|
std::shared_ptr<Layer> m_layer;
|
||||||
|
std::shared_ptr<LayerFrame::Snapshot> m_snap;
|
||||||
|
std::array<bool, 6> m_dirty_face = SIXPLETTE(false);
|
||||||
|
std::array<glm::vec4, 6> m_dirty_box = SIXPLETTE(glm::vec4(0));
|
||||||
|
glm::ivec2 m_pos;
|
||||||
|
glm::vec4 m_color;
|
||||||
|
float m_threshold;
|
||||||
|
int m_layer_index;
|
||||||
|
int m_plane;
|
||||||
|
virtual void run() override { }
|
||||||
|
virtual size_t memory() override { return m_snap->memsize(); }
|
||||||
|
virtual Action* get_redo() override
|
||||||
|
{
|
||||||
|
auto a = new ActionFloodFill;
|
||||||
|
a->m_direction = reverse_direction();
|
||||||
|
a->m_layer = m_layer;
|
||||||
|
a->m_snap = m_snap;
|
||||||
|
a->m_pos = m_pos;
|
||||||
|
a->m_color = m_color;
|
||||||
|
a->m_layer_index = m_layer_index;
|
||||||
|
a->m_threshold = m_threshold;
|
||||||
|
a->m_plane = m_plane;
|
||||||
|
a->m_dirty_box = m_dirty_box;
|
||||||
|
a->m_dirty_face = m_dirty_face;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
virtual void undo() override
|
||||||
|
{
|
||||||
|
if (m_direction == Direction::Undo)
|
||||||
|
{
|
||||||
|
m_layer->restore(*m_snap);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Canvas::FloodData plane_data;
|
||||||
|
std::unique_ptr<glm::vec4> color;
|
||||||
|
Canvas::I->flood_fill(m_layer_index, m_plane, { m_pos },
|
||||||
|
plane_data, m_threshold, m_color, color);
|
||||||
|
plane_data.apply();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (me->m_type)
|
||||||
|
{
|
||||||
|
case kEventType::MouseUpL:
|
||||||
|
glm::vec3 ro, rd, hit, n;
|
||||||
|
glm::vec2 pos;
|
||||||
|
int plane;
|
||||||
|
if (Canvas::I->point_trace(loc, ro, rd, hit, pos, n, plane))
|
||||||
|
{
|
||||||
|
Canvas::FloodData plane_data;
|
||||||
|
std::unique_ptr<glm::vec4> color;
|
||||||
|
Canvas::I->flood_fill(Canvas::I->m_current_layer_idx, plane, { (glm::ivec2)pos },
|
||||||
|
plane_data, m_tool->get_threshold(), Canvas::I->m_current_brush->m_tip_color, color);
|
||||||
|
|
||||||
|
auto a = new ActionFloodFill;
|
||||||
|
a->m_direction = Action::Direction::Undo;
|
||||||
|
a->m_layer = plane_data.layer;
|
||||||
|
a->m_snap = std::make_shared<LayerFrame::Snapshot>(plane_data.layer->snapshot());
|
||||||
|
a->m_pos = (glm::ivec2)pos;
|
||||||
|
a->m_color = Canvas::I->m_current_brush->m_tip_color;
|
||||||
|
a->m_layer_index = Canvas::I->m_current_layer_idx;
|
||||||
|
a->m_threshold = m_tool->get_threshold();
|
||||||
|
a->m_plane = plane;
|
||||||
|
a->m_dirty_box = plane_data.layer->frame().m_dirty_box;
|
||||||
|
a->m_dirty_face = plane_data.layer->frame().m_dirty_face;
|
||||||
|
ActionManager::add(a);
|
||||||
|
|
||||||
|
plane_data.apply();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasModeFloodFill::init()
|
||||||
|
{
|
||||||
|
TextureManager::load(m_cursor_path.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasModeFloodFill::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera)
|
||||||
|
{
|
||||||
|
if (m_draw_tip)
|
||||||
|
{
|
||||||
|
pp::panopainter::setup_legacy_canvas_draw_merge_texture_shader({
|
||||||
|
.mvp = glm::scale(glm::vec3(1, -1, 1))
|
||||||
|
* ortho
|
||||||
|
* glm::translate(glm::vec3(Canvas::I->m_cur_pos, 0.f))
|
||||||
|
* glm::scale(glm::vec3(32, 32, 1))
|
||||||
|
* glm::translate(glm::vec3(0.5f, -0.5f, 0)),
|
||||||
|
.texture_slot = 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
auto& t = TextureManager::get(m_cursor_id);
|
||||||
|
|
||||||
|
Canvas::I->m_sampler_linear.bind(0);
|
||||||
|
t.bind();
|
||||||
|
Canvas::I->m_plane.draw_fill();
|
||||||
|
t.unbind();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasModeFloodFill::enter(kCanvasMode prev)
|
||||||
|
{
|
||||||
|
auto tools = App::I->layout[App::I->main_id]->find("tools-container");
|
||||||
|
m_tool = tools->add_child<NodeToolBucket>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasModeFloodFill::leave(kCanvasMode next)
|
||||||
|
{
|
||||||
|
pp::panopainter::destroy_legacy_node(*m_tool);
|
||||||
|
m_tool = nullptr;
|
||||||
|
}
|
||||||
@@ -24,6 +24,79 @@
|
|||||||
|
|
||||||
namespace pp::panopainter {
|
namespace pp::panopainter {
|
||||||
|
|
||||||
|
void execute_legacy_node_stroke_preview_background_capture_pass(
|
||||||
|
const LegacyNodeStrokePreviewBackgroundCaptureRequest& request)
|
||||||
|
{
|
||||||
|
if (!request.draw_checkerboard) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float aspect = request.size.x / request.size.y;
|
||||||
|
pp::panopainter::setup_legacy_canvas_draw_merge_checkerboard_shader(
|
||||||
|
pp::panopainter::LegacyCanvasDrawMergeCheckerboardUniforms {
|
||||||
|
.mvp = glm::ortho(-.5f, .5f, -.5f / aspect, .5f / aspect, -1.f, 1.f),
|
||||||
|
.colorize = request.colorize,
|
||||||
|
});
|
||||||
|
request.draw_checkerboard();
|
||||||
|
const auto copy_status = pp::paint_renderer::copy_stroke_preview_result_to_texture(
|
||||||
|
[&] {
|
||||||
|
request.background_texture.bind();
|
||||||
|
},
|
||||||
|
[](
|
||||||
|
int src_x,
|
||||||
|
int src_y,
|
||||||
|
int dst_x,
|
||||||
|
int dst_y,
|
||||||
|
int width,
|
||||||
|
int height) {
|
||||||
|
copy_framebuffer_to_texture_2d(src_x, src_y, dst_x, dst_y, width, height);
|
||||||
|
},
|
||||||
|
pp::paint_renderer::StrokePreviewCopySize {
|
||||||
|
.width = static_cast<int>(request.size.x),
|
||||||
|
.height = static_cast<int>(request.size.y),
|
||||||
|
});
|
||||||
|
assert(copy_status.ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<LegacyNodeStrokePreviewFrame> plan_legacy_node_stroke_preview_stroke_frames(
|
||||||
|
const LegacyNodeStrokePreviewStrokeComputeRequest& request)
|
||||||
|
{
|
||||||
|
auto samples = const_cast<Stroke&>(request.stroke).compute_samples();
|
||||||
|
StrokeSample previous_sample = request.stroke.m_prev_sample;
|
||||||
|
previous_sample.size *= request.zoom;
|
||||||
|
for (auto& sample : samples) {
|
||||||
|
sample.size *= request.zoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pp::panopainter::plan_legacy_canvas_stroke_frames(
|
||||||
|
pp::panopainter::LegacyCanvasStrokeComputeRequest {
|
||||||
|
.previous_sample = previous_sample,
|
||||||
|
.samples = samples,
|
||||||
|
.zoom = 1.0f,
|
||||||
|
.mixer_size = request.mixer_size,
|
||||||
|
},
|
||||||
|
[](
|
||||||
|
std::array<vertex_t, 4>& brush_quad,
|
||||||
|
bool /*project_3d*/,
|
||||||
|
glm::mat4 /*model_view*/) {
|
||||||
|
return brush_quad;
|
||||||
|
},
|
||||||
|
[](
|
||||||
|
glm::vec4 mixer_rect,
|
||||||
|
glm::vec4 color,
|
||||||
|
float flow,
|
||||||
|
float opacity,
|
||||||
|
std::array<vertex_t, 4>&& shapes) -> LegacyNodeStrokePreviewFrame {
|
||||||
|
return LegacyNodeStrokePreviewFrame {
|
||||||
|
.col = color,
|
||||||
|
.flow = flow,
|
||||||
|
.opacity = opacity,
|
||||||
|
.shapes = std::move(shapes),
|
||||||
|
.mixer_rect = mixer_rect,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
bool execute_legacy_node_stroke_preview_immediate_runtime(
|
bool execute_legacy_node_stroke_preview_immediate_runtime(
|
||||||
const LegacyNodeStrokePreviewImmediateRuntimeRequest& request)
|
const LegacyNodeStrokePreviewImmediateRuntimeRequest& request)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,9 +12,29 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace pp::panopainter {
|
namespace pp::panopainter {
|
||||||
|
|
||||||
|
struct LegacyNodeStrokePreviewBackgroundCaptureRequest {
|
||||||
|
glm::vec2 size {};
|
||||||
|
bool colorize = false;
|
||||||
|
Texture2D& background_texture;
|
||||||
|
std::function<void()> draw_checkerboard;
|
||||||
|
};
|
||||||
|
|
||||||
|
void execute_legacy_node_stroke_preview_background_capture_pass(
|
||||||
|
const LegacyNodeStrokePreviewBackgroundCaptureRequest& request);
|
||||||
|
|
||||||
|
struct LegacyNodeStrokePreviewStrokeComputeRequest {
|
||||||
|
const Stroke& stroke;
|
||||||
|
float zoom = 1.0f;
|
||||||
|
glm::vec2 mixer_size {};
|
||||||
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] std::vector<LegacyNodeStrokePreviewFrame> plan_legacy_node_stroke_preview_stroke_frames(
|
||||||
|
const LegacyNodeStrokePreviewStrokeComputeRequest& request);
|
||||||
|
|
||||||
struct LegacyNodeStrokePreviewImmediateRuntimeRequest {
|
struct LegacyNodeStrokePreviewImmediateRuntimeRequest {
|
||||||
const std::shared_ptr<Brush>& brush;
|
const std::shared_ptr<Brush>& brush;
|
||||||
glm::vec2 preview_size {};
|
glm::vec2 preview_size {};
|
||||||
|
|||||||
@@ -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_item_ui.h"
|
||||||
#include "legacy_brush_panel_ui.h"
|
#include "legacy_brush_panel_ui.h"
|
||||||
#include "legacy_brush_preset_panel_ui.h"
|
#include "legacy_brush_preset_panel_ui.h"
|
||||||
#include "legacy_brush_preset_list_services.h"
|
#include "legacy_brush_preset_list_services.h"
|
||||||
@@ -8,71 +9,35 @@
|
|||||||
#include "app_core/brush_ui.h"
|
#include "app_core/brush_ui.h"
|
||||||
#include "legacy_brush_ui_services.h"
|
#include "legacy_brush_ui_services.h"
|
||||||
#include "legacy_brush_preset_services.h"
|
#include "legacy_brush_preset_services.h"
|
||||||
#include "legacy_ui_overlay_services.h"
|
|
||||||
#include "texture.h"
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#include <Foundation/Foundation.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "canvas.h"
|
|
||||||
#include "app.h"
|
|
||||||
#include "abr.h"
|
|
||||||
|
|
||||||
Node* NodeButtonBrush::clone_instantiate() const
|
Node* NodeButtonBrush::clone_instantiate() const
|
||||||
{
|
{
|
||||||
return new NodeButtonBrush();
|
return pp::panopainter::clone_legacy_brush_button(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeButtonBrush::init()
|
void NodeButtonBrush::init()
|
||||||
{
|
{
|
||||||
init_template_file("data/dialogs/panel-brushes.xml", "tpl-brush-icon");
|
pp::panopainter::init_legacy_brush_button(*this);
|
||||||
color_hover = glm::vec4(.7, .7, .7, 1);
|
|
||||||
color_normal = glm::vec4(.3, .3, .3, 1);
|
|
||||||
m_color = color_normal;
|
|
||||||
img = (NodeImage*)m_children[0].get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeButtonBrush::set_icon(const char* path)
|
void NodeButtonBrush::set_icon(const char* path)
|
||||||
{
|
{
|
||||||
img->m_path = path;
|
pp::panopainter::set_legacy_brush_button_icon(*this, path);
|
||||||
img->m_tex_id = const_hash(img->m_path.c_str());
|
|
||||||
img->m_use_mipmaps = true;
|
|
||||||
img->create();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeButtonBrush::draw()
|
void NodeButtonBrush::draw()
|
||||||
{
|
{
|
||||||
m_color = m_mouse_inside ? color_hover : color_normal;
|
pp::panopainter::draw_legacy_brush_button(*this);
|
||||||
m_color = m_selected ? glm::vec4(.9, 0, 0, 1) : m_color;
|
|
||||||
NodeButtonCustom::draw();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NodeButtonBrush::read(BinaryStreamReader& r)
|
bool NodeButtonBrush::read(BinaryStreamReader& r)
|
||||||
{
|
{
|
||||||
Serializer::Descriptor d;
|
return pp::panopainter::read_legacy_brush_button(*this, r);
|
||||||
r >> d;
|
|
||||||
d.value<Serializer::CString>("brush_name", brush_name);
|
|
||||||
d.value<Serializer::CString>("high_path", high_path);
|
|
||||||
d.value<Serializer::CString>("thumb_path", thumb_path);
|
|
||||||
d.value<Serializer::Boolean>("m_user_brush", m_user_brush);
|
|
||||||
high_path = str_replace(high_path, "{data_path}", App::I->data_path);
|
|
||||||
thumb_path = str_replace(thumb_path, "{data_path}", App::I->data_path);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeButtonBrush::write(BinaryStreamWriter& w) const
|
void NodeButtonBrush::write(BinaryStreamWriter& w) const
|
||||||
{
|
{
|
||||||
Serializer::Descriptor d;
|
pp::panopainter::write_legacy_brush_button(*this, w);
|
||||||
d.class_id = "brush";
|
|
||||||
d.name = L"Brush class";
|
|
||||||
d.props["brush_name"] = std::make_shared<Serializer::CString>(brush_name);
|
|
||||||
d.props["high_path"] = std::make_shared<Serializer::CString>(
|
|
||||||
str_replace(high_path, App::I->data_path, "{data_path}"));
|
|
||||||
d.props["thumb_path"] = std::make_shared<Serializer::CString>(
|
|
||||||
str_replace(thumb_path, App::I->data_path, "{data_path}"));
|
|
||||||
d.props["m_user_brush"] = std::make_shared<Serializer::Boolean>(m_user_brush);
|
|
||||||
w << d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* NodePanelBrush::clone_instantiate() const
|
Node* NodePanelBrush::clone_instantiate() const
|
||||||
@@ -155,26 +120,17 @@ std::vector<NodePanelBrushPreset*> NodePanelBrushPreset::s_panels;
|
|||||||
|
|
||||||
Node* NodeBrushPresetItem::clone_instantiate() const
|
Node* NodeBrushPresetItem::clone_instantiate() const
|
||||||
{
|
{
|
||||||
return new NodeBrushPresetItem();
|
return pp::panopainter::clone_legacy_brush_preset_item(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeBrushPresetItem::init()
|
void NodeBrushPresetItem::init()
|
||||||
{
|
{
|
||||||
init_template_file("data/dialogs/panel-brushes.xml", "tpl-brush-preset");
|
pp::panopainter::init_legacy_brush_preset_item(*this);
|
||||||
color_hover = glm::vec4(.7, .7, .7, 1);
|
|
||||||
color_normal = glm::vec4(.3, .3, .3, 1);
|
|
||||||
m_color = color_normal;
|
|
||||||
m_thumb = find<NodeImage>("thumb");
|
|
||||||
m_caption_size = find<NodeText>("caption-size");
|
|
||||||
m_preview = find<NodeStrokePreview>("canvas");
|
|
||||||
m_preview->m_min_flow = 1.f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeBrushPresetItem::draw()
|
void NodeBrushPresetItem::draw()
|
||||||
{
|
{
|
||||||
m_color = m_mouse_inside ? color_hover : color_normal;
|
pp::panopainter::draw_legacy_brush_preset_item(*this);
|
||||||
m_color = m_selected ? glm::vec4(.9, 0, 0, 1) : m_color;
|
|
||||||
NodeButtonCustom::draw();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NodePanelBrushPreset::NodePanelBrushPreset()
|
NodePanelBrushPreset::NodePanelBrushPreset()
|
||||||
|
|||||||
@@ -3,19 +3,13 @@
|
|||||||
#include "node_stroke_preview.h"
|
#include "node_stroke_preview.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
#include "bezier.h"
|
|
||||||
#include "canvas.h"
|
#include "canvas.h"
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
#include "legacy_canvas_draw_merge_services.h"
|
|
||||||
#include "legacy_canvas_stroke_execution_services.h"
|
|
||||||
#include "legacy_canvas_stroke_preview_services.h"
|
|
||||||
#include "legacy_canvas_stroke_shader_services.h"
|
#include "legacy_canvas_stroke_shader_services.h"
|
||||||
#include "legacy_canvas_stroke_services.h"
|
|
||||||
#include "legacy_node_stroke_preview_execution_services.h"
|
#include "legacy_node_stroke_preview_execution_services.h"
|
||||||
#include "legacy_node_stroke_preview_runtime_services.h"
|
#include "legacy_node_stroke_preview_runtime_services.h"
|
||||||
#include "legacy_node_stroke_preview_sample_services.h"
|
#include "legacy_node_stroke_preview_sample_services.h"
|
||||||
#include "legacy_ui_gl_dispatch.h"
|
#include "legacy_ui_gl_dispatch.h"
|
||||||
#include "paint_renderer/compositor.h"
|
|
||||||
#include "renderer_gl/opengl_capabilities.h"
|
#include "renderer_gl/opengl_capabilities.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include <array>
|
#include <array>
|
||||||
@@ -119,39 +113,6 @@ void copy_stroke_preview_destination_texture_region(
|
|||||||
copy_framebuffer_to_texture_2d(src_x, src_y, dst_x, dst_y, width, height);
|
copy_framebuffer_to_texture_2d(src_x, src_y, dst_x, dst_y, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void execute_stroke_preview_background_capture_pass(
|
|
||||||
glm::vec2 size,
|
|
||||||
bool colorize,
|
|
||||||
Texture2D& background_texture,
|
|
||||||
const std::function<void()>& draw_checkerboard)
|
|
||||||
{
|
|
||||||
const float aspect = size.x / size.y;
|
|
||||||
pp::panopainter::setup_legacy_canvas_draw_merge_checkerboard_shader(
|
|
||||||
pp::panopainter::LegacyCanvasDrawMergeCheckerboardUniforms {
|
|
||||||
.mvp = glm::ortho(-.5f, .5f, -.5f / aspect, .5f / aspect, -1.f, 1.f),
|
|
||||||
.colorize = colorize,
|
|
||||||
});
|
|
||||||
draw_checkerboard();
|
|
||||||
const auto copy_status = pp::paint_renderer::copy_stroke_preview_result_to_texture(
|
|
||||||
[&] {
|
|
||||||
background_texture.bind();
|
|
||||||
},
|
|
||||||
[](
|
|
||||||
int src_x,
|
|
||||||
int src_y,
|
|
||||||
int dst_x,
|
|
||||||
int dst_y,
|
|
||||||
int width,
|
|
||||||
int height) {
|
|
||||||
copy_framebuffer_to_texture_2d(src_x, src_y, dst_x, dst_y, width, height);
|
|
||||||
},
|
|
||||||
pp::paint_renderer::StrokePreviewCopySize {
|
|
||||||
.width = static_cast<int>(size.x),
|
|
||||||
.height = static_cast<int>(size.y),
|
|
||||||
});
|
|
||||||
assert(copy_status.ok());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* NodeStrokePreview::clone_instantiate() const
|
Node* NodeStrokePreview::clone_instantiate() const
|
||||||
@@ -240,39 +201,11 @@ glm::vec4 NodeStrokePreview::stroke_draw_samples(
|
|||||||
|
|
||||||
std::vector<NodeStrokePreview::StrokeFrame> NodeStrokePreview::stroke_draw_compute(const Stroke& stroke, float zoom) const
|
std::vector<NodeStrokePreview::StrokeFrame> NodeStrokePreview::stroke_draw_compute(const Stroke& stroke, float zoom) const
|
||||||
{
|
{
|
||||||
auto samples = const_cast<Stroke&>(stroke).compute_samples();
|
return pp::panopainter::plan_legacy_node_stroke_preview_stroke_frames(
|
||||||
StrokeSample previous_sample = stroke.m_prev_sample;
|
pp::panopainter::LegacyNodeStrokePreviewStrokeComputeRequest {
|
||||||
previous_sample.size *= zoom;
|
.stroke = stroke,
|
||||||
for (auto& sample : samples) {
|
.zoom = zoom,
|
||||||
sample.size *= zoom;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pp::panopainter::plan_legacy_canvas_stroke_frames(
|
|
||||||
pp::panopainter::LegacyCanvasStrokeComputeRequest {
|
|
||||||
.previous_sample = previous_sample,
|
|
||||||
.samples = samples,
|
|
||||||
.zoom = 1.0f,
|
|
||||||
.mixer_size = glm::vec2(m_rtt.getWidth(), m_rtt.getHeight()),
|
.mixer_size = glm::vec2(m_rtt.getWidth(), m_rtt.getHeight()),
|
||||||
},
|
|
||||||
[](
|
|
||||||
std::array<vertex_t, 4>& brush_quad,
|
|
||||||
bool /*project_3d*/,
|
|
||||||
glm::mat4 /*model_view*/) {
|
|
||||||
return brush_quad;
|
|
||||||
},
|
|
||||||
[](
|
|
||||||
glm::vec4 mixer_rect,
|
|
||||||
glm::vec4 color,
|
|
||||||
float flow,
|
|
||||||
float opacity,
|
|
||||||
std::array<vertex_t, 4>&& shapes) -> StrokeFrame {
|
|
||||||
return StrokeFrame {
|
|
||||||
.col = color,
|
|
||||||
.flow = flow,
|
|
||||||
.opacity = opacity,
|
|
||||||
.shapes = std::move(shapes),
|
|
||||||
.mixer_rect = mixer_rect,
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,12 +272,14 @@ void NodeStrokePreview::draw_stroke_immediate()
|
|||||||
bind_stroke_preview_dual_pass_textures(dual_brush);
|
bind_stroke_preview_dual_pass_textures(dual_brush);
|
||||||
},
|
},
|
||||||
.capture_background = [&](bool colorize) {
|
.capture_background = [&](bool colorize) {
|
||||||
execute_stroke_preview_background_capture_pass(
|
pp::panopainter::execute_legacy_node_stroke_preview_background_capture_pass(
|
||||||
size,
|
pp::panopainter::LegacyNodeStrokePreviewBackgroundCaptureRequest {
|
||||||
colorize,
|
.size = size,
|
||||||
m_tex_background,
|
.colorize = colorize,
|
||||||
[&] {
|
.background_texture = m_tex_background,
|
||||||
|
.draw_checkerboard = [&] {
|
||||||
m_plane.draw_fill();
|
m_plane.draw_fill();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
.compute_frames = [&](const Stroke& stroke, float frame_zoom) {
|
.compute_frames = [&](const Stroke& stroke, float frame_zoom) {
|
||||||
|
|||||||
Reference in New Issue
Block a user