Thin brush panel, preview, and node utility shells

This commit is contained in:
2026-06-16 23:57:39 +02:00
parent cb9751dcc7
commit acee4db356
14 changed files with 402 additions and 302 deletions

View File

@@ -5,6 +5,51 @@
#include "app.h"
#include "texture.h"
Node* NodeButtonBrush::clone_instantiate() const
{
return pp::panopainter::clone_legacy_brush_button(*this);
}
void NodeButtonBrush::init()
{
pp::panopainter::init_legacy_brush_button(*this);
}
void NodeButtonBrush::set_icon(const char* path)
{
pp::panopainter::set_legacy_brush_button_icon(*this, path);
}
void NodeButtonBrush::draw()
{
pp::panopainter::draw_legacy_brush_button(*this);
}
bool NodeButtonBrush::read(BinaryStreamReader& r)
{
return pp::panopainter::read_legacy_brush_button(*this, r);
}
void NodeButtonBrush::write(BinaryStreamWriter& w) const
{
pp::panopainter::write_legacy_brush_button(*this, w);
}
Node* NodeBrushPresetItem::clone_instantiate() const
{
return pp::panopainter::clone_legacy_brush_preset_item(*this);
}
void NodeBrushPresetItem::init()
{
pp::panopainter::init_legacy_brush_preset_item(*this);
}
void NodeBrushPresetItem::draw()
{
pp::panopainter::draw_legacy_brush_preset_item(*this);
}
namespace pp::panopainter {
Node* clone_legacy_brush_button(const NodeButtonBrush&)

View File

@@ -4,12 +4,61 @@
#include "app.h"
#include "asset.h"
#include "legacy_brush_ui_services.h"
#include "node_panel_brush.h"
#include <fstream>
#include <functional>
#include <memory>
void NodePanelBrush::execute_texture_list_plan(const pp::app::BrushTextureListPlan& plan)
{
const auto status = pp::panopainter::execute_legacy_brush_texture_list_plan(*this, plan);
if (!status.ok()) {
LOG("Brush texture list action failed: %s", status.message);
}
}
int NodePanelBrush::find_brush(const std::string& name) const
{
return pp::panopainter::LegacyBrushPanelServices(const_cast<NodePanelBrush&>(*this)).find_brush(name);
}
std::string NodePanelBrush::get_texture_path(int index) const
{
return pp::panopainter::LegacyBrushPanelServices(const_cast<NodePanelBrush&>(*this)).get_texture_path(index);
}
std::string NodePanelBrush::get_thumb_path(int index) const
{
return pp::panopainter::LegacyBrushPanelServices(const_cast<NodePanelBrush&>(*this)).get_thumb_path(index);
}
bool NodePanelBrush::save()
{
return pp::panopainter::LegacyBrushPanelServices(*this).save();
}
bool NodePanelBrush::restore()
{
return pp::panopainter::LegacyBrushPanelServices(*this).restore();
}
void NodePanelBrush::clear()
{
pp::panopainter::LegacyBrushPanelServices(*this).clear();
}
void NodePanelBrush::scan()
{
pp::panopainter::LegacyBrushPanelServices(*this).scan();
}
void NodePanelBrush::reload()
{
pp::panopainter::LegacyBrushPanelServices(*this).reload();
}
namespace pp::panopainter {
LegacyBrushPanelServices::LegacyBrushPanelServices(NodePanelBrush& panel) noexcept

View File

@@ -7,6 +7,32 @@
#include "asset.h"
#include "legacy_ui_overlay_services.h"
Node* NodePanelBrush::clone_instantiate() const
{
return new NodePanelBrush();
}
void NodePanelBrush::init()
{
pp::panopainter::LegacyBrushPanelUi::init(*this);
}
kEventResult NodePanelBrush::handle_event(Event* e)
{
return pp::panopainter::LegacyBrushPanelUi::handle_event(*this, e);
}
void NodePanelBrush::handle_click(Node* target)
{
pp::panopainter::LegacyBrushPanelUi::handle_click(*this, target);
}
void NodePanelBrush::added(Node* parent)
{
(void)parent;
pp::panopainter::LegacyBrushPanelUi::added(*this);
}
namespace pp::panopainter {
void LegacyBrushPanelUi::init(NodePanelBrush& owner)

View File

@@ -5,12 +5,30 @@
#include "canvas.h"
#include "legacy_ui_overlay_services.h"
namespace pp::panopainter {
namespace {
std::vector<NodePanelBrushPreset*> s_legacy_brush_preset_panels;
}
void NodePanelBrushPreset::execute_preset_list_plan(const pp::app::BrushPresetListPlan& plan)
{
pp::panopainter::LegacyBrushPresetListServices services(*this);
const auto status = pp::app::execute_brush_preset_list_plan(plan, services);
if (!status.ok()) {
LOG("Brush preset list action failed: %s", status.message);
}
}
void NodePanelBrushPreset::clear_brushes()
{
const auto plan = pp::app::plan_brush_preset_list_clear(
static_cast<int>(m_container->m_children.size()));
if (plan) {
execute_preset_list_plan(plan.value());
}
}
namespace pp::panopainter {
void register_legacy_brush_preset_panel(NodePanelBrushPreset& panel)
{
s_legacy_brush_preset_panels.push_back(&panel);

View File

@@ -6,10 +6,52 @@
#include "app_core/brush_ui.h"
#include "asset.h"
#include "canvas.h"
#include "legacy_brush_preset_list_services.h"
#include "legacy_ui_overlay_services.h"
#include "node_message_box.h"
#include "node_popup_menu.h"
NodePanelBrushPreset::NodePanelBrushPreset()
{
pp::panopainter::register_legacy_brush_preset_panel(*this);
}
NodePanelBrushPreset::~NodePanelBrushPreset()
{
pp::panopainter::unregister_legacy_brush_preset_panel(*this);
}
Node* NodePanelBrushPreset::clone_instantiate() const
{
return new NodePanelBrushPreset();
}
void NodePanelBrushPreset::init()
{
pp::panopainter::LegacyBrushPresetPanelUi::init(*this);
}
kEventResult NodePanelBrushPreset::handle_event(Event* e)
{
return pp::panopainter::LegacyBrushPresetPanelUi::handle_event(*this, e);
}
void NodePanelBrushPreset::handle_click(Node* target)
{
pp::panopainter::LegacyBrushPresetPanelUi::handle_click(*this, target);
}
void NodePanelBrushPreset::add_brush(std::shared_ptr<Brush> brush)
{
pp::panopainter::LegacyBrushPresetPanelUi::add_brush(*this, std::move(brush));
}
void NodePanelBrushPreset::added(Node* parent)
{
(void)parent;
pp::panopainter::LegacyBrushPresetPanelUi::added(*this);
}
namespace pp::panopainter {
void LegacyBrushPresetPanelUi::init(NodePanelBrushPreset& owner)

View File

@@ -14,13 +14,43 @@
#include <regex>
#include <set>
namespace pp::panopainter {
LegacyBrushPresetServices::LegacyBrushPresetServices(NodePanelBrushPreset& owner) noexcept
pp::panopainter::LegacyBrushPresetServices::LegacyBrushPresetServices(NodePanelBrushPreset& owner) noexcept
: owner_(owner)
{
}
bool NodePanelBrushPreset::save()
{
return pp::panopainter::LegacyBrushPresetServices(*this).save();
}
bool NodePanelBrushPreset::restore()
{
return pp::panopainter::LegacyBrushPresetServices(*this).restore();
}
bool NodePanelBrushPreset::export_ppbr(const std::string& path_in, const PPBRInfo& info_data)
{
return pp::panopainter::LegacyBrushPresetServices(*this).export_ppbr(path_in, info_data);
}
bool NodePanelBrushPreset::import_ppbr(const std::string& path)
{
return pp::panopainter::LegacyBrushPresetServices(*this).import_ppbr(path);
}
bool NodePanelBrushPreset::import_abr(const std::string& path)
{
return pp::panopainter::LegacyBrushPresetServices(*this).import_abr(path);
}
bool NodePanelBrushPreset::import_brush(const std::string& path)
{
return pp::panopainter::LegacyBrushPresetServices(*this).import_brush(path);
}
namespace pp::panopainter {
bool LegacyBrushPresetServices::save()
{
auto path = App::I->data_path + "/settings/presets.bin";

View File

@@ -136,6 +136,96 @@ void copy_legacy_node_stroke_preview_destination_texture_region(
copy_framebuffer_to_texture_2d(src_x, src_y, dst_x, dst_y, width, height);
}
bool execute_legacy_node_stroke_preview_immediate_draw(
const LegacyNodeStrokePreviewImmediateDrawRequest& request)
{
if (!request.brush ||
!request.prepare_render_target ||
!request.finish_render_target ||
!request.compute_frames ||
!request.draw_samples ||
!request.draw_mix ||
!request.draw_checkerboard ||
!request.draw_composite) {
return false;
}
if (!ensure_legacy_node_stroke_preview_render_targets(
LegacyNodeStrokePreviewRenderTargetSetup {
.preview_rtt = request.preview_rtt,
.preview_rtt_mixer = request.preview_rtt_mixer,
.preview_stroke_texture = request.preview_stroke_texture,
.preview_dual_texture = request.preview_dual_texture,
.preview_background_texture = request.preview_background_texture,
.preview_image_texture = request.preview_image_texture,
.size = request.preview_size,
})) {
return false;
}
const auto vp = query_legacy_node_stroke_preview_viewport();
const auto cc = query_legacy_node_stroke_preview_clear_color();
const glm::vec2 size = {
static_cast<float>(request.preview_rtt.getWidth()),
static_cast<float>(request.preview_rtt.getHeight()),
};
const bool sequence_ok = execute_legacy_node_stroke_preview_immediate_runtime(
LegacyNodeStrokePreviewImmediateRuntimeRequest {
.brush = request.brush,
.preview_size = request.preview_size,
.zoom = request.zoom,
.min_flow = request.min_flow,
.stroke_max_size_override = request.stroke_max_size_override,
.pad_override = request.pad_override,
.camera_fov = request.camera_fov,
.camera_rot = request.camera_rot,
.render_device_features = request.render_device_features,
.preview_rtt = request.preview_rtt,
.preview_rtt_mixer = request.preview_rtt_mixer,
.preview_stroke_texture = request.preview_stroke_texture,
.preview_dual_texture = request.preview_dual_texture,
.preview_background_texture = request.preview_background_texture,
.preview_image_texture = request.preview_image_texture,
.linear_sampler = request.linear_sampler,
.repeat_sampler = request.repeat_sampler,
.prepare_render_target = request.prepare_render_target,
.finish_render_target = request.finish_render_target,
.set_blend_enabled = [](bool enabled) {
apply_legacy_node_stroke_preview_capability(pp::renderer::gl::blend_state(), enabled);
},
.setup_stroke_shader = [](const LegacyStrokeShaderSetupUniforms& uniforms) {
setup_legacy_stroke_shader(uniforms);
},
.bind_dual_pass_textures = [](const Brush& dual_brush) {
bind_legacy_node_stroke_preview_dual_pass_textures(dual_brush);
},
.capture_background = [&](bool colorize) {
execute_legacy_node_stroke_preview_background_capture_pass(
LegacyNodeStrokePreviewBackgroundCaptureRequest {
.size = size,
.colorize = colorize,
.background_texture = request.preview_background_texture,
.draw_checkerboard = [&] {
request.draw_checkerboard();
},
});
},
.compute_frames = request.compute_frames,
.draw_samples = request.draw_samples,
.draw_mix = request.draw_mix,
.unbind_mixer_texture = [&] {
unbind_legacy_node_stroke_preview_mixer_texture(request.preview_rtt_mixer);
},
.bind_pattern_texture = [&] {
bind_legacy_node_stroke_preview_pattern_texture(*request.brush);
},
.draw_composite = request.draw_composite,
});
apply_legacy_node_stroke_preview_viewport(vp.x, vp.y, vp.width, vp.height);
apply_legacy_node_stroke_preview_clear_color(cc);
return sequence_ok;
}
void execute_legacy_node_stroke_preview_background_capture_pass(
const LegacyNodeStrokePreviewBackgroundCaptureRequest& request)
{

View File

@@ -95,6 +95,36 @@ struct LegacyNodeStrokePreviewImmediateRuntimeRequest {
std::function<void()> draw_composite;
};
struct LegacyNodeStrokePreviewImmediateDrawRequest {
const std::shared_ptr<Brush>& brush;
glm::vec2 preview_size {};
float zoom = 1.0f;
float min_flow = 0.0f;
float stroke_max_size_override = 0.0f;
float pad_override = NAN;
float camera_fov = 0.0f;
glm::mat4 camera_rot { 1.0f };
pp::renderer::RenderDeviceFeatures render_device_features {};
RTT& preview_rtt;
RTT& preview_rtt_mixer;
Texture2D& preview_stroke_texture;
Texture2D& preview_dual_texture;
Texture2D& preview_background_texture;
Texture2D& preview_image_texture;
Sampler& linear_sampler;
Sampler& repeat_sampler;
std::function<void()> prepare_render_target;
std::function<void()> finish_render_target;
std::function<std::vector<LegacyNodeStrokePreviewFrame>(const Stroke&, float)> compute_frames;
std::function<glm::vec4(std::array<vertex_t, 4>&, Texture2D&, bool)> draw_samples;
std::function<void(const glm::vec2&, const glm::vec2&)> draw_mix;
std::function<void()> draw_checkerboard;
std::function<void()> draw_composite;
};
[[nodiscard]] bool execute_legacy_node_stroke_preview_immediate_draw(
const LegacyNodeStrokePreviewImmediateDrawRequest& request);
[[nodiscard]] bool execute_legacy_node_stroke_preview_immediate_runtime(
const LegacyNodeStrokePreviewImmediateRuntimeRequest& request);

View File

@@ -1,4 +1,5 @@
#include "pch.h"
#include "app.h"
#include "node.h"
void Node::restore_context()
@@ -13,6 +14,25 @@ void Node::clear_context()
c->clear_context();
}
void Node::app_redraw()
{
App::I->redraw = true;
App::I->runtime().notify_render_worker();
}
void Node::watch(std::function<bool(Node*)> observer)
{
bool cont = observer(this);
if (cont)
{
for (auto& c : m_children)
{
//if (!glm::any(glm::lessThanEqual(zw(c->m_clip), { 0, 0 })))
c->watch(observer);
}
}
}
void Node::update(float width, float height, float zoom)
{
m_zoom = zoom;

View File

@@ -10,25 +10,6 @@
#include "util.h"
#include "asset.h"
void Node::app_redraw()
{
App::I->redraw = true;
App::I->runtime().notify_render_worker();
}
void Node::watch(std::function<bool(Node*)> observer)
{
bool cont = observer(this);
if (cont)
{
for (auto& c : m_children)
{
//if (!glm::any(glm::lessThanEqual(zw(c->m_clip), { 0, 0 })))
c->watch(observer);
}
}
}
kEventResult Node::on_event(Event* e)
{
return pp::panopainter::handle_legacy_ui_node_event(*this, e);

View File

@@ -1,223 +1,2 @@
#include "pch.h"
#include "log.h"
#include "node_panel_brush.h"
#include "legacy_brush_panel_item_ui.h"
#include "legacy_brush_panel_ui.h"
#include "legacy_brush_preset_panel_ui.h"
#include "legacy_brush_preset_list_services.h"
#include "legacy_brush_panel_services.h"
#include "app_core/brush_ui.h"
#include "legacy_brush_ui_services.h"
#include "legacy_brush_preset_services.h"
Node* NodeButtonBrush::clone_instantiate() const
{
return pp::panopainter::clone_legacy_brush_button(*this);
}
void NodeButtonBrush::init()
{
pp::panopainter::init_legacy_brush_button(*this);
}
void NodeButtonBrush::set_icon(const char* path)
{
pp::panopainter::set_legacy_brush_button_icon(*this, path);
}
void NodeButtonBrush::draw()
{
pp::panopainter::draw_legacy_brush_button(*this);
}
bool NodeButtonBrush::read(BinaryStreamReader& r)
{
return pp::panopainter::read_legacy_brush_button(*this, r);
}
void NodeButtonBrush::write(BinaryStreamWriter& w) const
{
pp::panopainter::write_legacy_brush_button(*this, w);
}
Node* NodePanelBrush::clone_instantiate() const
{
return new NodePanelBrush();
}
void NodePanelBrush::execute_texture_list_plan(const pp::app::BrushTextureListPlan& plan)
{
const auto status = pp::panopainter::execute_legacy_brush_texture_list_plan(*this, plan);
if (!status.ok()) {
LOG("Brush texture list action failed: %s", status.message);
}
}
void NodePanelBrush::init()
{
pp::panopainter::LegacyBrushPanelUi::init(*this);
}
kEventResult NodePanelBrush::handle_event(Event* e)
{
return pp::panopainter::LegacyBrushPanelUi::handle_event(*this, e);
}
void NodePanelBrush::handle_click(Node* target)
{
pp::panopainter::LegacyBrushPanelUi::handle_click(*this, target);
}
int NodePanelBrush::find_brush(const std::string & name) const
{
return pp::panopainter::LegacyBrushPanelServices(const_cast<NodePanelBrush&>(*this)).find_brush(name);
}
std::string NodePanelBrush::get_texture_path(int index) const
{
return pp::panopainter::LegacyBrushPanelServices(const_cast<NodePanelBrush&>(*this)).get_texture_path(index);
}
std::string NodePanelBrush::get_thumb_path(int index) const
{
return pp::panopainter::LegacyBrushPanelServices(const_cast<NodePanelBrush&>(*this)).get_thumb_path(index);
}
bool NodePanelBrush::save()
{
return pp::panopainter::LegacyBrushPanelServices(*this).save();
}
bool NodePanelBrush::restore()
{
return pp::panopainter::LegacyBrushPanelServices(*this).restore();
}
void NodePanelBrush::clear()
{
pp::panopainter::LegacyBrushPanelServices(*this).clear();
}
void NodePanelBrush::scan()
{
pp::panopainter::LegacyBrushPanelServices(*this).scan();
}
void NodePanelBrush::reload()
{
pp::panopainter::LegacyBrushPanelServices(*this).reload();
}
void NodePanelBrush::added(Node* parent)
{
(void)parent;
pp::panopainter::LegacyBrushPanelUi::added(*this);
}
// -----------------------------------------------------------------------
Node* NodeBrushPresetItem::clone_instantiate() const
{
return pp::panopainter::clone_legacy_brush_preset_item(*this);
}
void NodeBrushPresetItem::init()
{
pp::panopainter::init_legacy_brush_preset_item(*this);
}
void NodeBrushPresetItem::draw()
{
pp::panopainter::draw_legacy_brush_preset_item(*this);
}
NodePanelBrushPreset::NodePanelBrushPreset()
{
pp::panopainter::register_legacy_brush_preset_panel(*this);
}
NodePanelBrushPreset::~NodePanelBrushPreset()
{
pp::panopainter::unregister_legacy_brush_preset_panel(*this);
}
//---
Node* NodePanelBrushPreset::clone_instantiate() const
{
return new NodePanelBrushPreset();
}
void NodePanelBrushPreset::execute_preset_list_plan(const pp::app::BrushPresetListPlan& plan)
{
pp::panopainter::LegacyBrushPresetListServices services(*this);
const auto status = pp::app::execute_brush_preset_list_plan(plan, services);
if (!status.ok()) {
LOG("Brush preset list action failed: %s", status.message);
}
}
void NodePanelBrushPreset::init()
{
pp::panopainter::LegacyBrushPresetPanelUi::init(*this);
}
kEventResult NodePanelBrushPreset::handle_event(Event* e)
{
return pp::panopainter::LegacyBrushPresetPanelUi::handle_event(*this, e);
}
void NodePanelBrushPreset::handle_click(Node* target)
{
pp::panopainter::LegacyBrushPresetPanelUi::handle_click(*this, target);
}
bool NodePanelBrushPreset::save()
{
return pp::panopainter::LegacyBrushPresetServices(*this).save();
}
bool NodePanelBrushPreset::restore()
{
return pp::panopainter::LegacyBrushPresetServices(*this).restore();
}
void NodePanelBrushPreset::add_brush(std::shared_ptr<Brush> brush)
{
pp::panopainter::LegacyBrushPresetPanelUi::add_brush(*this, std::move(brush));
}
bool NodePanelBrushPreset::export_ppbr(const std::string& path_in, const PPBRInfo& info_data)
{
return pp::panopainter::LegacyBrushPresetServices(*this).export_ppbr(path_in, info_data);
}
bool NodePanelBrushPreset::import_ppbr(const std::string& path)
{
return pp::panopainter::LegacyBrushPresetServices(*this).import_ppbr(path);
}
bool NodePanelBrushPreset::import_abr(const std::string& path)
{
return pp::panopainter::LegacyBrushPresetServices(*this).import_abr(path);
}
bool NodePanelBrushPreset::import_brush(const std::string& path)
{
return pp::panopainter::LegacyBrushPresetServices(*this).import_brush(path);
}
void NodePanelBrushPreset::clear_brushes()
{
const auto plan = pp::app::plan_brush_preset_list_clear(
static_cast<int>(m_container->m_children.size()));
if (plan) {
execute_preset_list_plan(plan.value());
}
}
void NodePanelBrushPreset::added(Node* parent)
{
(void)parent;
pp::panopainter::LegacyBrushPresetPanelUi::added(*this);
}

View File

@@ -109,29 +109,11 @@ void NodeStrokePreview::draw_stroke_immediate()
{
if (m_size.x == 0 || m_size.y == 0)
return;
if (!pp::panopainter::ensure_legacy_node_stroke_preview_render_targets(
pp::panopainter::LegacyNodeStrokePreviewRenderTargetSetup {
.preview_rtt = m_rtt,
.preview_rtt_mixer = m_rtt_mixer,
.preview_stroke_texture = m_tex,
.preview_dual_texture = m_tex_dual,
.preview_background_texture = m_tex_background,
.preview_image_texture = m_tex_preview,
.size = m_preview_size,
})) {
return;
}
const auto vp = pp::panopainter::query_legacy_node_stroke_preview_viewport();
const auto cc = pp::panopainter::query_legacy_node_stroke_preview_clear_color();
const glm::vec2 size = { m_rtt.getWidth(), m_rtt.getHeight() };
const float zoom = root()->m_zoom;
const bool sequence_ok = pp::panopainter::execute_legacy_node_stroke_preview_immediate_runtime(
pp::panopainter::LegacyNodeStrokePreviewImmediateRuntimeRequest {
const bool sequence_ok = pp::panopainter::execute_legacy_node_stroke_preview_immediate_draw(
pp::panopainter::LegacyNodeStrokePreviewImmediateDrawRequest {
.brush = m_brush,
.preview_size = m_size,
.zoom = zoom,
.zoom = root()->m_zoom,
.min_flow = m_min_flow,
.stroke_max_size_override = m_max_size,
.pad_override = m_pad_override,
@@ -158,26 +140,6 @@ void NodeStrokePreview::draw_stroke_immediate()
.finish_render_target = [&] {
m_rtt.unbindFramebuffer();
},
.set_blend_enabled = [&](bool enabled) {
pp::panopainter::apply_legacy_node_stroke_preview_capability(pp::renderer::gl::blend_state(), enabled);
},
.setup_stroke_shader = [](const pp::panopainter::LegacyStrokeShaderSetupUniforms& uniforms) {
pp::panopainter::setup_legacy_stroke_shader(uniforms);
},
.bind_dual_pass_textures = [](const Brush& dual_brush) {
pp::panopainter::bind_legacy_node_stroke_preview_dual_pass_textures(dual_brush);
},
.capture_background = [&](bool colorize) {
pp::panopainter::execute_legacy_node_stroke_preview_background_capture_pass(
pp::panopainter::LegacyNodeStrokePreviewBackgroundCaptureRequest {
.size = size,
.colorize = colorize,
.background_texture = m_tex_background,
.draw_checkerboard = [&] {
m_plane.draw_fill();
},
});
},
.compute_frames = [&](const Stroke& stroke, float frame_zoom) {
return stroke_draw_compute(stroke, frame_zoom);
},
@@ -187,18 +149,12 @@ void NodeStrokePreview::draw_stroke_immediate()
.draw_mix = [&](const glm::vec2& bb_min, const glm::vec2& bb_sz) {
stroke_draw_mix(bb_min, bb_sz);
},
.unbind_mixer_texture = [&] {
pp::panopainter::unbind_legacy_node_stroke_preview_mixer_texture(m_rtt_mixer);
},
.bind_pattern_texture = [&] {
pp::panopainter::bind_legacy_node_stroke_preview_pattern_texture(*m_brush);
.draw_checkerboard = [&] {
m_plane.draw_fill();
},
.draw_composite = [&] {
m_plane.draw_fill();
},
});
assert(sequence_ok);
pp::panopainter::apply_legacy_node_stroke_preview_viewport(vp.x, vp.y, vp.width, vp.height);
pp::panopainter::apply_legacy_node_stroke_preview_clear_color(cc);
}