695 lines
25 KiB
C++
695 lines
25 KiB
C++
#include "pch.h"
|
|
#include "log.h"
|
|
#include "node_panel_brush.h"
|
|
#include "asset.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
|
|
{
|
|
return new NodeButtonBrush();
|
|
}
|
|
|
|
void NodeButtonBrush::init()
|
|
{
|
|
init_template("tpl-brush-icon");
|
|
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)
|
|
{
|
|
img->m_path = path;
|
|
img->m_tex_id = const_hash(img->m_path.c_str());
|
|
img->m_use_mipmaps = true;
|
|
img->create();
|
|
}
|
|
|
|
void NodeButtonBrush::draw()
|
|
{
|
|
m_color = m_mouse_inside ? color_hover : color_normal;
|
|
m_color = m_selected ? glm::vec4(.9, 0, 0, 1) : m_color;
|
|
NodeButtonCustom::draw();
|
|
}
|
|
|
|
Node* NodePanelBrush::clone_instantiate() const
|
|
{
|
|
return new NodePanelBrush();
|
|
}
|
|
|
|
void NodePanelBrush::init()
|
|
{
|
|
init_template("tpl-panel-brushes");
|
|
|
|
m_btn_add = find<NodeButtonCustom>("btn-add");
|
|
m_btn_add->on_click = [this](Node*) {
|
|
App::I.pick_file({ "JPG", "PNG" }, [this](std::string path) {
|
|
std::string name, base, ext;
|
|
std::regex r(R"((.*)[\\/]([^\\/]+)\.(\w+)$)");
|
|
std::smatch m;
|
|
if (!std::regex_search(path, m, r))
|
|
return;
|
|
base = m[1].str();
|
|
name = m[2].str();
|
|
ext = m[3].str();
|
|
Image img;
|
|
if (!m_dir_name.empty() && img.load_file(path))
|
|
{
|
|
std::string path_high = App::I.data_path + "/" + m_dir_name + "/" + name + ".png";
|
|
std::string path_thumb = App::I.data_path + "/" + m_dir_name + "/thumbs/" + name + ".png";
|
|
|
|
img = img.resize_squared(glm::u8vec4(255));
|
|
//img.gayscale_alpha();
|
|
|
|
auto thumb = img.resize(64, 64);
|
|
thumb.save(path_thumb);
|
|
auto po2 = img.resize_power2();
|
|
po2.save(path_high);
|
|
|
|
async_start();
|
|
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 = name;
|
|
brush->m_user_brush = true;
|
|
brush->on_click = std::bind(&NodePanelBrush::handle_click, this, std::placeholders::_1);
|
|
app_redraw();
|
|
async_end();
|
|
save();
|
|
}
|
|
});
|
|
};
|
|
|
|
m_btn_remove = find<NodeButtonCustom>("btn-remove");
|
|
m_btn_remove->on_click = [this](Node*) {
|
|
if (m_current)
|
|
{
|
|
int idx = m_container->get_child_index(m_current);
|
|
if (m_current->m_user_brush)
|
|
{
|
|
// only delete user brushes
|
|
Asset::delete_file(m_current->thumb_path);
|
|
Asset::delete_file(m_current->high_path);
|
|
}
|
|
m_container->remove_child(m_current);
|
|
if (m_container->m_children.size() > 0)
|
|
{
|
|
idx = std::max(0, std::min(idx, (int)m_container->m_children.size() - 1));
|
|
m_current = (NodeButtonBrush*)m_container->m_children[idx].get();
|
|
m_current->m_selected = true;
|
|
if (on_brush_changed)
|
|
on_brush_changed(this, idx);
|
|
}
|
|
else
|
|
{
|
|
m_current = nullptr;
|
|
}
|
|
save();
|
|
}
|
|
};
|
|
|
|
m_btn_up = find<NodeButtonCustom>("btn-up");
|
|
m_btn_up->on_click = [this](Node*) {
|
|
if (m_current)
|
|
{
|
|
int idx = m_container->get_child_index(m_current);
|
|
idx = std::max(0, std::min(idx - 1, (int)m_container->m_children.size() - 1));
|
|
m_container->move_child(m_current, idx);
|
|
save();
|
|
}
|
|
};
|
|
|
|
m_btn_down = find<NodeButtonCustom>("btn-down");
|
|
m_btn_down->on_click = [this](Node*) {
|
|
if (m_current)
|
|
{
|
|
int idx = m_container->get_child_index(m_current);
|
|
idx = std::max(0, std::min(idx + 1, (int)m_container->m_children.size() - 1));
|
|
m_container->move_child(m_current, idx);
|
|
save();
|
|
}
|
|
};
|
|
|
|
m_container = find<NodeScroll>("brushes");
|
|
restore();
|
|
if (m_container->m_children.empty() && !m_dir_name.empty())
|
|
{
|
|
auto icons = Asset::list_files("data/" + m_dir_name, true, ".*\\.png$");
|
|
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, true, ".*\\.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);
|
|
}
|
|
}
|
|
save();
|
|
}
|
|
|
|
kEventResult NodePanelBrush::handle_event(Event* e)
|
|
{
|
|
switch (e->m_type)
|
|
{
|
|
case kEventType::MouseUpL:
|
|
if (!m_mouse_inside)
|
|
{
|
|
mouse_release();
|
|
parent->remove_child(this);
|
|
if (on_popup_close)
|
|
on_popup_close(this);
|
|
}
|
|
break;
|
|
default:
|
|
return kEventResult::Available;
|
|
break;
|
|
}
|
|
return kEventResult::Consumed;
|
|
}
|
|
|
|
void NodePanelBrush::handle_click(Node* target)
|
|
{
|
|
if (target == m_current)
|
|
return;
|
|
if (m_current)
|
|
m_current->m_selected = false;
|
|
m_current = (NodeButtonBrush*)target;
|
|
m_current->m_selected = true;
|
|
if (on_brush_changed)
|
|
on_brush_changed(this, m_container->get_child_index(target));
|
|
}
|
|
|
|
int NodePanelBrush::find_brush(const std::string & name) const
|
|
{
|
|
for (int i = 0; i < m_container->m_children.size(); i++)
|
|
{
|
|
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
|
|
{
|
|
if (index < 0 || index >= m_container->m_children.size())
|
|
return "";
|
|
return ((NodeButtonBrush*)m_container->m_children[index].get())->high_path;
|
|
}
|
|
|
|
std::string NodePanelBrush::get_thumb_path(int index) const
|
|
{
|
|
if (index < 0 || index >= m_container->m_children.size())
|
|
return "";
|
|
return ((NodeButtonBrush*)m_container->m_children[index].get())->thumb_path;
|
|
}
|
|
|
|
bool NodePanelBrush::save()
|
|
{
|
|
auto path = App::I.data_path + "/settings/" + m_dir_name + ".bin";
|
|
if (FILE* fp = fopen(path.c_str(), "wb"))
|
|
{
|
|
header_t h;
|
|
h.brushes = m_container->m_children.size();
|
|
fwrite(&h, sizeof(h), 1, fp);
|
|
for (const auto& child : m_container->m_children)
|
|
{
|
|
auto b = std::static_pointer_cast<NodeButtonBrush>(child);
|
|
item_t i;
|
|
i.m_name_len = b->brush_name.size();
|
|
i.m_high_len = b->high_path.size();
|
|
i.m_thumb_len = b->thumb_path.size();
|
|
fwrite(&i, sizeof(i), 1, fp);
|
|
fwrite(b->brush_name.c_str(), 1, b->brush_name.size(), fp);
|
|
fwrite(b->high_path.c_str(), 1, b->high_path.size(), fp);
|
|
fwrite(b->thumb_path.c_str(), 1, b->thumb_path.size(), fp);
|
|
}
|
|
for (const auto& d : m_deleted)
|
|
{
|
|
item_t i;
|
|
i.m_high_len = d.size();
|
|
i.m_thumb_len = 0;
|
|
fwrite(&i, sizeof(i), 1, fp);
|
|
fwrite(d.c_str(), 1, d.size(), fp);
|
|
}
|
|
fclose(fp);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool NodePanelBrush::restore()
|
|
{
|
|
auto path = App::I.data_path + "/settings/" + m_dir_name + ".bin";
|
|
if (FILE* fp = fopen(path.c_str(), "rb"))
|
|
{
|
|
header_t h;
|
|
fread(&h, sizeof(h), 1, fp);
|
|
if (strcmp(h.magic, "PPBR") != 0)
|
|
{
|
|
fclose(fp);
|
|
LOG("Brushes file malformed: %s", path.c_str());
|
|
return false;
|
|
}
|
|
if (h.version < 0 || h.version > 0)
|
|
{
|
|
fclose(fp);
|
|
LOG("Brushes file version %d not supported: %s", h.version, path.c_str());
|
|
return false;
|
|
}
|
|
|
|
for (int k = 0; k < h.brushes; k++)
|
|
{
|
|
item_t i;
|
|
fread(&i, sizeof(i), 1, fp);
|
|
std::string name(i.m_name_len, 0);
|
|
std::string path_high(i.m_high_len, 0);
|
|
std::string path_thumb(i.m_thumb_len, 0);
|
|
fread((char*)name.c_str(), 1, name.size(), fp);
|
|
fread((char*)path_high.c_str(), 1, path_high.size(), fp);
|
|
fread((char*)path_thumb.c_str(), 1, path_thumb.size(), fp);
|
|
|
|
if (Asset::exist(path_high))
|
|
{
|
|
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 = name;
|
|
brush->m_user_brush = i.m_user_brush;
|
|
brush->on_click = std::bind(&NodePanelBrush::handle_click, this, std::placeholders::_1);
|
|
}
|
|
}
|
|
fclose(fp);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
Node* NodeBrushPresetItem::clone_instantiate() const
|
|
{
|
|
return new NodeBrushPresetItem();
|
|
}
|
|
|
|
void NodeBrushPresetItem::init()
|
|
{
|
|
init_template("tpl-brush-preset");
|
|
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_preview = find<NodeStrokePreview>("canvas");
|
|
m_preview->m_min_flow = 1.f;
|
|
}
|
|
|
|
void NodeBrushPresetItem::draw()
|
|
{
|
|
m_color = m_mouse_inside ? color_hover : color_normal;
|
|
m_color = m_selected ? glm::vec4(.9, 0, 0, 1) : m_color;
|
|
NodeButtonCustom::draw();
|
|
}
|
|
|
|
//---
|
|
|
|
Node* NodePanelBrushPreset::clone_instantiate() const
|
|
{
|
|
return new NodePanelBrushPreset();
|
|
}
|
|
|
|
void NodePanelBrushPreset::init()
|
|
{
|
|
init_template("tpl-panel-brush-preset");
|
|
m_container = find<Node>("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->m_use_mipmaps = true;
|
|
brush->m_thumb->set_image(brush->m_brush->m_brush_thumb_path);
|
|
brush->on_click = std::bind(&NodePanelBrushPreset::handle_click, this, std::placeholders::_1);
|
|
save();
|
|
};
|
|
m_btn_up = find<NodeButtonCustom>("btn-up");
|
|
m_btn_up->on_click = [this](Node*) {
|
|
if (m_current)
|
|
{
|
|
m_container->move_child(m_current, std::max(m_container->get_child_index(m_current) - 1, 0));
|
|
save();
|
|
}
|
|
};
|
|
m_btn_down = find<NodeButtonCustom>("btn-down");
|
|
m_btn_down->on_click = [this](Node*) {
|
|
if (m_current)
|
|
{
|
|
m_container->move_child(m_current,
|
|
std::min(m_container->get_child_index(m_current) + 1, (int)m_container->m_children.size() - 1));
|
|
save();
|
|
}
|
|
};
|
|
m_btn_save = find<NodeButtonCustom>("btn-save");
|
|
m_btn_save->on_click = [this](Node*) {
|
|
if (m_current)
|
|
{
|
|
*m_current->m_brush = *Canvas::I->m_current_brush;
|
|
m_current->m_preview->draw_stroke();
|
|
m_current->m_thumb->set_image(m_current->m_brush->m_brush_thumb_path);
|
|
save();
|
|
}
|
|
};
|
|
m_btn_delete = find<NodeButtonCustom>("btn-remove");
|
|
m_btn_delete->on_click = [this](Node*) {
|
|
if (!m_current)
|
|
return;
|
|
int index = m_container->get_child_index(m_current);
|
|
m_current->destroy();
|
|
if (m_container->m_children.empty())
|
|
{
|
|
m_current = nullptr;
|
|
}
|
|
else
|
|
{
|
|
int next = std::min<int>(m_container->m_children.size() - 1, index);
|
|
m_current = (NodeBrushPresetItem*)m_container->m_children[next].get();
|
|
m_current->m_selected = true;
|
|
}
|
|
save();
|
|
};
|
|
|
|
restore();
|
|
}
|
|
|
|
kEventResult NodePanelBrushPreset::handle_event(Event* e)
|
|
{
|
|
switch (e->m_type)
|
|
{
|
|
case kEventType::MouseUpL:
|
|
if (!m_mouse_inside)
|
|
{
|
|
mouse_release();
|
|
parent->remove_child(this);
|
|
if (on_popup_close)
|
|
on_popup_close(this);
|
|
}
|
|
break;
|
|
default:
|
|
return kEventResult::Available;
|
|
break;
|
|
}
|
|
return kEventResult::Consumed;
|
|
}
|
|
|
|
void NodePanelBrushPreset::handle_click(Node* target)
|
|
{
|
|
if (target == m_current)
|
|
return;
|
|
if (m_current)
|
|
m_current->m_selected = false;
|
|
m_current = (NodeBrushPresetItem*)target;
|
|
m_current->m_selected = true;
|
|
if (on_brush_changed)
|
|
on_brush_changed(this, m_current->m_brush);
|
|
}
|
|
|
|
bool NodePanelBrushPreset::save()
|
|
{
|
|
auto path = App::I.data_path + "/settings/presets.bin";
|
|
if (FILE* fp = fopen(path.c_str(), "wb"))
|
|
{
|
|
header_t h;
|
|
h.count = m_container->m_children.size();
|
|
fwrite(&h, sizeof(h), 1, fp);
|
|
for (int ci = 0; ci < m_container->m_children.size(); ci++)
|
|
{
|
|
auto bpi = static_cast<NodeBrushPresetItem*>(m_container->get_child_at(ci));
|
|
auto& b = bpi->m_brush;
|
|
item_t i;
|
|
i.m_name_len = b->m_name.size();
|
|
i.m_brush_path_len = b->m_brush_path.size();
|
|
i.m_brush_thumb_path_len = b->m_brush_thumb_path.size();
|
|
i.m_dual_path_len = b->m_brush_path.size();
|
|
i.m_dual_thumb_path_len = b->m_brush_thumb_path.size();
|
|
i.m_stencil_path_len = b->m_pattern_path.size();
|
|
i.m_stencil_thumb_path_len = b->m_pattern_thumb_path.size();
|
|
i.m_tip_color = b->m_tip_color;
|
|
i.m_tip_size = b->m_tip_size;
|
|
i.m_tip_spacing = b->m_tip_spacing;
|
|
i.m_tip_flow = b->m_tip_flow;
|
|
i.m_tip_opacity = b->m_tip_opacity;
|
|
i.m_tip_angle = b->m_tip_angle;
|
|
i.m_tip_angle_delay = b->m_tip_angle_delay;
|
|
i.m_tip_mix = b->m_tip_mix;
|
|
i.m_tip_wet = b->m_tip_wet;
|
|
i.m_tip_noise = b->m_tip_noise;
|
|
i.m_tip_hue = b->m_tip_hue;
|
|
i.m_tip_sat = b->m_tip_sat;
|
|
i.m_tip_val = b->m_tip_val;
|
|
i.m_tip_angle_follow = b->m_tip_angle_follow;
|
|
i.m_tip_flow_pressure = b->m_tip_flow_pressure;
|
|
i.m_tip_size_pressure = b->m_tip_size_pressure;
|
|
i.m_jitter_scale = b->m_jitter_scale;
|
|
i.m_jitter_angle = b->m_jitter_angle;
|
|
i.m_jitter_spread = b->m_jitter_spread;
|
|
i.m_jitter_flow = b->m_jitter_flow;
|
|
i.m_jitter_hue = b->m_jitter_hue;
|
|
i.m_jitter_sat = b->m_jitter_sat;
|
|
i.m_jitter_val = b->m_jitter_val;
|
|
i.m_blend_mode = b->m_blend_mode;
|
|
|
|
i.m_tip_invert = b->m_tip_invert;
|
|
i.m_tip_flipx = b->m_tip_flipx;
|
|
i.m_tip_flipy = b->m_tip_flipy;
|
|
i.m_pattern_enabled = b->m_pattern_enabled;
|
|
i.m_dual_enabled = b->m_dual_enabled;
|
|
i.m_dual_blend_mode = b->m_dual_blend_mode;
|
|
i.m_dual_randflip = b->m_dual_randflip;
|
|
i.m_dual_size = b->m_dual_size;
|
|
i.m_dual_spacing = b->m_dual_spacing;
|
|
i.m_dual_scatter = b->m_dual_scatter;
|
|
i.m_dual_scatter_axis = b->m_dual_scatter_axis;
|
|
i.m_dual_invert = b->m_dual_invert;
|
|
i.m_dual_flipx = b->m_dual_flipx;
|
|
i.m_dual_flipy = b->m_dual_flipy;
|
|
i.m_tip_randflipx = b->m_tip_randflipx;
|
|
i.m_tip_randflipy = b->m_tip_randflipy;
|
|
i.m_tip_aspect = b->m_tip_aspect;
|
|
i.m_dual_flow = b->m_dual_flow;
|
|
i.m_dual_opacity = b->m_dual_opacity;
|
|
i.m_dual_rotate = b->m_dual_rotate;
|
|
|
|
i.m_pattern_eachsample = b->m_pattern_eachsample;
|
|
i.m_pattern_invert = b->m_pattern_invert;
|
|
i.m_pattern_flipx = b->m_pattern_flipx;
|
|
i.m_pattern_flipy = b->m_pattern_flipy;
|
|
i.m_pattern_scale = b->m_pattern_scale;
|
|
i.m_pattern_brightness = b->m_pattern_brightness;
|
|
i.m_pattern_contrast = b->m_pattern_contrast;
|
|
i.m_pattern_rand_offset = b->m_pattern_rand_offset;
|
|
i.m_pattern_depth = b->m_pattern_depth;
|
|
|
|
fwrite(&i, sizeof(i), 1, fp);
|
|
fwrite(b->m_name.c_str(), 1, b->m_name.size(), fp);
|
|
fwrite(b->m_brush_path.c_str(), 1, b->m_brush_path.size(), fp);
|
|
fwrite(b->m_brush_thumb_path.c_str(), 1, b->m_brush_thumb_path.size(), fp);
|
|
fwrite(b->m_dual_path.c_str(), 1, b->m_brush_path.size(), fp);
|
|
fwrite(b->m_dual_thumb_path.c_str(), 1, b->m_brush_thumb_path.size(), fp);
|
|
fwrite(b->m_pattern_path.c_str(), 1, b->m_pattern_path.size(), fp);
|
|
fwrite(b->m_pattern_thumb_path.c_str(), 1, b->m_pattern_thumb_path.size(), fp);
|
|
}
|
|
fclose(fp);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool NodePanelBrushPreset::restore()
|
|
{
|
|
auto path = App::I.data_path + "/settings/presets.bin";
|
|
if (FILE* fp = fopen(path.c_str(), "rb"))
|
|
{
|
|
header_t h;
|
|
fread(&h, sizeof(h), 1, fp);
|
|
if (strcmp(h.magic, "PPPR") != 0)
|
|
{
|
|
fclose(fp);
|
|
LOG("Presets file malformed: %s", path.c_str());
|
|
return false;
|
|
}
|
|
if (h.version < 0 || h.version > 0)
|
|
{
|
|
fclose(fp);
|
|
LOG("Presets file version %d not supported: %s", h.version, path.c_str());
|
|
return false;
|
|
}
|
|
|
|
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_angle_delay = i.m_tip_angle_delay;
|
|
b->m_tip_mix = i.m_tip_mix;
|
|
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_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_tip_invert = i.m_tip_invert;
|
|
b->m_tip_flipx = i.m_tip_flipx;
|
|
b->m_tip_flipy = i.m_tip_flipy;
|
|
b->m_pattern_enabled = i.m_pattern_enabled;
|
|
b->m_dual_enabled = i.m_dual_enabled;
|
|
b->m_dual_blend_mode = i.m_dual_blend_mode;
|
|
b->m_dual_randflip = i.m_dual_randflip;
|
|
b->m_dual_size = i.m_dual_size;
|
|
b->m_dual_spacing = i.m_dual_spacing;
|
|
b->m_dual_scatter = i.m_dual_scatter;
|
|
b->m_dual_scatter_axis = i.m_dual_scatter_axis;
|
|
b->m_dual_invert = i.m_dual_invert;
|
|
b->m_dual_flipx = i.m_dual_flipx;
|
|
b->m_dual_flipy = i.m_dual_flipy;
|
|
b->m_tip_aspect = i.m_tip_aspect;
|
|
b->m_dual_flow = i.m_dual_flow;
|
|
b->m_dual_opacity = i.m_dual_opacity;
|
|
b->m_dual_rotate = i.m_dual_rotate;
|
|
|
|
b->m_pattern_eachsample = i.m_pattern_eachsample;
|
|
b->m_pattern_invert = i.m_pattern_invert;
|
|
b->m_pattern_flipx = i.m_pattern_flipx;
|
|
b->m_pattern_flipy = i.m_pattern_flipy;
|
|
b->m_pattern_scale = i.m_pattern_scale;
|
|
b->m_pattern_brightness = i.m_pattern_brightness;
|
|
b->m_pattern_contrast = i.m_pattern_contrast;
|
|
b->m_pattern_rand_offset = i.m_pattern_rand_offset;
|
|
b->m_pattern_depth = i.m_pattern_depth;
|
|
|
|
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_dual_path.resize(i.m_brush_path_len);
|
|
b->m_dual_thumb_path.resize(i.m_brush_thumb_path_len);
|
|
b->m_pattern_path.resize(i.m_stencil_path_len);
|
|
b->m_pattern_thumb_path.resize(i.m_stencil_thumb_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_dual_path.c_str(), 1, b->m_brush_path.size(), fp);
|
|
fread((char*)b->m_dual_thumb_path.c_str(), 1, b->m_brush_thumb_path.size(), fp);
|
|
fread((char*)b->m_pattern_path.c_str(), 1, b->m_pattern_path.size(), fp);
|
|
fread((char*)b->m_pattern_thumb_path.c_str(), 1, b->m_pattern_thumb_path.size(), fp);
|
|
|
|
if (b->load_tip(b->m_brush_path, b->m_brush_thumb_path))
|
|
{
|
|
if (!b->m_pattern_path.empty())
|
|
b->load_pattern(b->m_pattern_path, b->m_pattern_thumb_path);
|
|
|
|
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);
|
|
brush->on_click = std::bind(&NodePanelBrushPreset::handle_click, this, std::placeholders::_1);
|
|
}
|
|
}
|
|
fclose(fp);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void NodePanelBrushPreset::add_brush(std::shared_ptr<Brush> brush)
|
|
{
|
|
NodeBrushPresetItem* b = new NodeBrushPresetItem;
|
|
m_container->add_child(b);
|
|
b->init();
|
|
b->create();
|
|
b->loaded();
|
|
b->thumb_path = brush->m_brush_thumb_path;
|
|
b->high_path = brush->m_brush_path;
|
|
b->m_brush = brush;
|
|
//brush->m_brush->m_tip_size = .05f;
|
|
b->m_preview->m_brush = brush;
|
|
b->m_preview->draw_stroke();
|
|
b->m_thumb->m_use_mipmaps = true;
|
|
b->m_thumb->set_image(brush->m_brush_thumb_path);
|
|
b->on_click = std::bind(&NodePanelBrushPreset::handle_click, this, std::placeholders::_1);
|
|
}
|