implement brush presets save and restore from file, fix stencil nullptr, limit preview stroke max size
This commit is contained in:
@@ -7,6 +7,8 @@
|
||||
#ifdef __APPLE__
|
||||
#include <Foundation/Foundation.h>
|
||||
#endif
|
||||
#include "canvas.h"
|
||||
#include "app.h"
|
||||
|
||||
Node* NodeButtonBrush::clone_instantiate() const
|
||||
{
|
||||
@@ -186,7 +188,29 @@ Node* NodePanelBrushPreset::clone_instantiate() const
|
||||
void NodePanelBrushPreset::init()
|
||||
{
|
||||
init_template("tpl-panel-brush-preset");
|
||||
m_container = find<NodeBorder>("brushes");
|
||||
m_btn_add = find<NodeButtonCustom>("btn-add");
|
||||
m_btn_add->on_click = [this] (Node*) {
|
||||
NodeBrushPresetItem* brush = new NodeBrushPresetItem;
|
||||
m_container->add_child(brush);
|
||||
brush->init();
|
||||
brush->create();
|
||||
brush->loaded();
|
||||
brush->thumb_path = Canvas::I->m_current_brush->m_brush_thumb_path;
|
||||
brush->high_path = Canvas::I->m_current_brush->m_brush_path;
|
||||
brush->m_brush = std::make_shared<Brush>(*Canvas::I->m_current_brush);
|
||||
brush->m_brush->m_tip_size = .05f;
|
||||
brush->m_preview->m_brush = brush->m_brush;
|
||||
brush->m_preview->draw_stroke();
|
||||
brush->m_thumb->set_image(brush->m_brush->m_brush_thumb_path);
|
||||
m_brushes.push_back(brush);
|
||||
brush->on_click = std::bind(&NodePanelBrushPreset::handle_click, this, std::placeholders::_1);
|
||||
save();
|
||||
};
|
||||
|
||||
restore();
|
||||
|
||||
/*
|
||||
static auto icons = Asset::list_files("data/thumbs", true, ".*\\.png$");
|
||||
|
||||
if ((m_container = find<NodeBorder>("brushes")))
|
||||
@@ -222,6 +246,7 @@ void NodePanelBrushPreset::init()
|
||||
brush->on_click = std::bind(&NodePanelBrushPreset::handle_click, this, std::placeholders::_1);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void NodePanelBrushPreset::handle_click(Node* target)
|
||||
@@ -230,32 +255,132 @@ void NodePanelBrushPreset::handle_click(Node* target)
|
||||
return;
|
||||
if (m_current)
|
||||
m_current->m_selected = false;
|
||||
m_current = (NodeButtonBrush*)target;
|
||||
m_current = (NodeBrushPresetItem*)target;
|
||||
m_current->m_selected = true;
|
||||
if (on_brush_changed)
|
||||
on_brush_changed(this, m_current->m_brushID);
|
||||
on_brush_changed(this, m_current->m_brush);
|
||||
}
|
||||
|
||||
std::shared_ptr<Brush> NodePanelBrushPreset::get_brush(int index) const
|
||||
bool NodePanelBrushPreset::save()
|
||||
{
|
||||
auto& b = m_brushes[index]->m_brush;
|
||||
TextureManager::load(m_brushes[index]->high_path.c_str(), true);
|
||||
//b->m_tex_id = m_brushes[index]->high_id;
|
||||
return b;
|
||||
auto path = App::I.data_path + "/presets.bin";
|
||||
if (FILE* fp = fopen(path.c_str(), "wb"))
|
||||
{
|
||||
header_t h;
|
||||
h.count = m_brushes.size();
|
||||
fwrite(&h, sizeof(h), 1, fp);
|
||||
for (const auto& b : m_brushes)
|
||||
{
|
||||
item_t i;
|
||||
i.m_name_len = b->m_brush->m_name.size();
|
||||
i.m_brush_path_len = b->m_brush->m_brush_path.size();
|
||||
i.m_brush_thumb_path_len = b->m_brush->m_brush_thumb_path.size();
|
||||
i.m_stencil_path_len = b->m_brush->m_stencil_path.size();
|
||||
i.m_tip_color = b->m_brush->m_tip_color;
|
||||
i.m_tip_size = b->m_brush->m_tip_size;
|
||||
i.m_tip_spacing = b->m_brush->m_tip_spacing;
|
||||
i.m_tip_flow = b->m_brush->m_tip_flow;
|
||||
i.m_tip_opacity = b->m_brush->m_tip_opacity;
|
||||
i.m_tip_angle = b->m_brush->m_tip_angle;
|
||||
i.m_tip_mix = b->m_brush->m_tip_mix;
|
||||
i.m_tip_stencil = b->m_brush->m_tip_stencil;
|
||||
i.m_tip_wet = b->m_brush->m_tip_wet;
|
||||
i.m_tip_noise = b->m_brush->m_tip_noise;
|
||||
i.m_tip_hue = b->m_brush->m_tip_hue;
|
||||
i.m_tip_sat = b->m_brush->m_tip_sat;
|
||||
i.m_tip_val = b->m_brush->m_tip_val;
|
||||
i.m_tip_angle_follow = b->m_brush->m_tip_angle_follow;
|
||||
i.m_tip_flow_pressure = b->m_brush->m_tip_flow_pressure;
|
||||
i.m_tip_size_pressure = b->m_brush->m_tip_size_pressure;
|
||||
i.m_tip_hue_pressure = b->m_brush->m_tip_hue_pressure;
|
||||
i.m_tip_sat_pressure = b->m_brush->m_tip_sat_pressure;
|
||||
i.m_tip_val_pressure = b->m_brush->m_tip_val_pressure;
|
||||
i.m_jitter_scale = b->m_brush->m_jitter_scale;
|
||||
i.m_jitter_angle = b->m_brush->m_jitter_angle;
|
||||
i.m_jitter_spread = b->m_brush->m_jitter_spread;
|
||||
i.m_jitter_flow = b->m_brush->m_jitter_flow;
|
||||
i.m_jitter_hue = b->m_brush->m_jitter_hue;
|
||||
i.m_jitter_sat = b->m_brush->m_jitter_sat;
|
||||
i.m_jitter_val = b->m_brush->m_jitter_val;
|
||||
i.m_blend_mode = b->m_brush->m_blend_mode;
|
||||
fwrite(&i, sizeof(i), 1, fp);
|
||||
fwrite(b->m_brush->m_name.c_str(), 1, b->m_brush->m_name.size(), fp);
|
||||
fwrite(b->m_brush->m_brush_path.c_str(), 1, b->m_brush->m_brush_path.size(), fp);
|
||||
fwrite(b->m_brush->m_brush_thumb_path.c_str(), 1, b->m_brush->m_brush_thumb_path.size(), fp);
|
||||
fwrite(b->m_brush->m_stencil_path.c_str(), 1, b->m_brush->m_stencil_path.size(), fp);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t NodePanelBrushPreset::get_texture_id(int index) const
|
||||
bool NodePanelBrushPreset::restore()
|
||||
{
|
||||
TextureManager::load(m_brushes[index]->high_path.c_str(), true);
|
||||
return m_brushes[index]->high_id;
|
||||
}
|
||||
auto path = App::I.data_path + "/presets.bin";
|
||||
if (FILE* fp = fopen(path.c_str(), "rb"))
|
||||
{
|
||||
header_t h;
|
||||
fread(&h, sizeof(h), 1, fp);
|
||||
|
||||
for (int k = 0; k < h.count; k++)
|
||||
{
|
||||
item_t i;
|
||||
fread(&i, sizeof(i), 1, fp);
|
||||
auto b = std::make_shared<Brush>();
|
||||
b->m_tip_color = i.m_tip_color;
|
||||
b->m_tip_size = i.m_tip_size;
|
||||
b->m_tip_spacing = i.m_tip_spacing;
|
||||
b->m_tip_flow = i.m_tip_flow;
|
||||
b->m_tip_opacity = i.m_tip_opacity;
|
||||
b->m_tip_angle = i.m_tip_angle;
|
||||
b->m_tip_mix = i.m_tip_mix;
|
||||
b->m_tip_stencil = i.m_tip_stencil;
|
||||
b->m_tip_wet = i.m_tip_wet;
|
||||
b->m_tip_noise = i.m_tip_noise;
|
||||
b->m_tip_hue = i.m_tip_hue;
|
||||
b->m_tip_sat = i.m_tip_sat;
|
||||
b->m_tip_val = i.m_tip_val;
|
||||
b->m_tip_angle_follow = i.m_tip_angle_follow;
|
||||
b->m_tip_flow_pressure = i.m_tip_flow_pressure;
|
||||
b->m_tip_size_pressure = i.m_tip_size_pressure;
|
||||
b->m_tip_hue_pressure = i.m_tip_hue_pressure;
|
||||
b->m_tip_sat_pressure = i.m_tip_sat_pressure;
|
||||
b->m_tip_val_pressure = i.m_tip_val_pressure;
|
||||
b->m_jitter_scale = i.m_jitter_scale;
|
||||
b->m_jitter_angle = i.m_jitter_angle;
|
||||
b->m_jitter_spread = i.m_jitter_spread;
|
||||
b->m_jitter_flow = i.m_jitter_flow;
|
||||
b->m_jitter_hue = i.m_jitter_hue;
|
||||
b->m_jitter_sat = i.m_jitter_sat;
|
||||
b->m_jitter_val = i.m_jitter_val;
|
||||
b->m_blend_mode = i.m_blend_mode;
|
||||
b->m_name.resize(i.m_name_len);
|
||||
b->m_brush_path.resize(i.m_brush_path_len);
|
||||
b->m_brush_thumb_path.resize(i.m_brush_thumb_path_len);
|
||||
b->m_stencil_path.resize(i.m_stencil_path_len);
|
||||
fread((char*)b->m_name.c_str(), 1, b->m_name.size(), fp);
|
||||
fread((char*)b->m_brush_path.c_str(), 1, b->m_brush_path.size(), fp);
|
||||
fread((char*)b->m_brush_thumb_path.c_str(), 1, b->m_brush_thumb_path.size(), fp);
|
||||
fread((char*)b->m_stencil_path.c_str(), 1, b->m_stencil_path.size(), fp);
|
||||
|
||||
std::string NodePanelBrushPreset::get_texture_path(int index) const
|
||||
{
|
||||
return m_brushes[index]->high_path;
|
||||
}
|
||||
b->load_texture(b->m_brush_path, b->m_brush_thumb_path);
|
||||
|
||||
int NodePanelBrushPreset::get_brush_id(int index) const
|
||||
{
|
||||
return m_brushes[index]->m_brushID;
|
||||
NodeBrushPresetItem* brush = new NodeBrushPresetItem;
|
||||
m_container->add_child(brush);
|
||||
brush->init();
|
||||
brush->create();
|
||||
brush->loaded();
|
||||
brush->thumb_path = b->m_brush_thumb_path;
|
||||
brush->high_path = b->m_brush_path;
|
||||
brush->m_brush = b;
|
||||
brush->m_brush->m_tip_size = .05f;
|
||||
brush->m_preview->m_brush = b;
|
||||
brush->m_preview->draw_stroke();
|
||||
brush->m_thumb->set_image(brush->m_brush->m_brush_thumb_path);
|
||||
m_brushes.push_back(brush);
|
||||
brush->on_click = std::bind(&NodePanelBrushPreset::handle_click, this, std::placeholders::_1);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user