implement add and remove custom brushes
This commit is contained in:
45
src/app.cpp
45
src/app.cpp
@@ -125,31 +125,50 @@ void App::initLog()
|
|||||||
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||||
NSString* docpath = (NSString*)[paths objectAtIndex:0];
|
NSString* docpath = (NSString*)[paths objectAtIndex:0];
|
||||||
data_path = [docpath cStringUsingEncoding:NSASCIIStringEncoding];
|
data_path = [docpath cStringUsingEncoding:NSASCIIStringEncoding];
|
||||||
|
|
||||||
|
NSError* err = nil;
|
||||||
|
|
||||||
NSString* recpath = [docpath stringByAppendingString:@"/rec"];
|
NSString* recpath = [docpath stringByAppendingString:@"/rec"];
|
||||||
rec_path = [recpath cStringUsingEncoding:NSASCIIStringEncoding];
|
rec_path = [recpath cStringUsingEncoding:NSASCIIStringEncoding];
|
||||||
NSError* recerr = nil;
|
if (![[NSFileManager defaultManager] createDirectoryAtPath:recpath withIntermediateDirectories:YES attributes:nil error:&err])
|
||||||
if (![[NSFileManager defaultManager] createDirectoryAtPath:recpath withIntermediateDirectories:YES attributes:nil error:&recerr])
|
|
||||||
{
|
{
|
||||||
LOG("error creating rec path: %s", [[recerr localizedDescription] cStringUsingEncoding:NSASCIIStringEncoding]);
|
LOG("error creating rec path: %s", [[err localizedDescription] cStringUsingEncoding:NSASCIIStringEncoding]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (![[NSFileManager defaultManager] createDirectoryAtPath:[docpath stringByAppendingString:@"/brushes"] withIntermediateDirectories:YES attributes:nil error:&err])
|
||||||
|
{
|
||||||
|
LOG("error creating brushes path: %s", [[err localizedDescription] cStringUsingEncoding:NSASCIIStringEncoding]);
|
||||||
|
}
|
||||||
|
if (![[NSFileManager defaultManager] createDirectoryAtPath:[docpath stringByAppendingString:@"/brushes/thumbs"] withIntermediateDirectories:YES attributes:nil error:&err])
|
||||||
|
{
|
||||||
|
LOG("error creating thumbs path: %s", [[err localizedDescription] cStringUsingEncoding:NSASCIIStringEncoding]);
|
||||||
}
|
}
|
||||||
#elif defined(__OSX__)
|
#elif defined(__OSX__)
|
||||||
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSPicturesDirectory, NSUserDomainMask, YES);
|
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSPicturesDirectory, NSUserDomainMask, YES);
|
||||||
NSString* docpath = [(NSString*)[paths objectAtIndex:0] stringByAppendingString:@"/PanoPainter"];
|
NSString* docpath = [(NSString*)[paths objectAtIndex:0] stringByAppendingString:@"/PanoPainter"];
|
||||||
|
|
||||||
NSError* docerr = nil;
|
NSError* err = nil;
|
||||||
if (![[NSFileManager defaultManager] createDirectoryAtPath:docpath withIntermediateDirectories:YES attributes:nil error:&docerr])
|
|
||||||
|
if (![[NSFileManager defaultManager] createDirectoryAtPath:docpath withIntermediateDirectories:YES attributes:nil error:&err])
|
||||||
{
|
{
|
||||||
LOG("error creating rec path: %s", [[docerr localizedDescription] cStringUsingEncoding:NSASCIIStringEncoding]);
|
LOG("error creating rec path: %s", [[err localizedDescription] cStringUsingEncoding:NSASCIIStringEncoding]);
|
||||||
}
|
}
|
||||||
data_path = [docpath cStringUsingEncoding:NSASCIIStringEncoding];
|
data_path = [docpath cStringUsingEncoding:NSASCIIStringEncoding];
|
||||||
|
|
||||||
NSString* recpath = [docpath stringByAppendingString:@"/rec"];
|
NSString* recpath = [docpath stringByAppendingString:@"/rec"];
|
||||||
rec_path = [recpath cStringUsingEncoding:NSASCIIStringEncoding];
|
rec_path = [recpath cStringUsingEncoding:NSASCIIStringEncoding];
|
||||||
NSError* recerr = nil;
|
if (![[NSFileManager defaultManager] createDirectoryAtPath:recpath withIntermediateDirectories:YES attributes:nil error:&err])
|
||||||
if (![[NSFileManager defaultManager] createDirectoryAtPath:recpath withIntermediateDirectories:YES attributes:nil error:&recerr])
|
|
||||||
{
|
{
|
||||||
LOG("error creating rec path: %s", [[recerr localizedDescription] cStringUsingEncoding:NSASCIIStringEncoding]);
|
LOG("error creating rec path: %s", [[err localizedDescription] cStringUsingEncoding:NSASCIIStringEncoding]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (![[NSFileManager defaultManager] createDirectoryAtPath:[docpath stringByAppendingString:@"/brushes"] withIntermediateDirectories:YES attributes:nil error:&err])
|
||||||
|
{
|
||||||
|
LOG("error creating brushes path: %s", [[err localizedDescription] cStringUsingEncoding:NSASCIIStringEncoding]);
|
||||||
|
}
|
||||||
|
if (![[NSFileManager defaultManager] createDirectoryAtPath:[docpath stringByAppendingString:@"/brushes/thumbs"] withIntermediateDirectories:YES attributes:nil error:&err])
|
||||||
|
{
|
||||||
|
LOG("error creating thumbs path: %s", [[err localizedDescription] cStringUsingEncoding:NSASCIIStringEncoding]);
|
||||||
}
|
}
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
//CHAR my_documents[MAX_PATH];
|
//CHAR my_documents[MAX_PATH];
|
||||||
@@ -184,6 +203,12 @@ void App::initLog()
|
|||||||
rec_path = data_path + "\\frames";
|
rec_path = data_path + "\\frames";
|
||||||
if (!PathFileExistsA(rec_path.c_str()))
|
if (!PathFileExistsA(rec_path.c_str()))
|
||||||
CreateDirectoryA(rec_path.c_str(), NULL);
|
CreateDirectoryA(rec_path.c_str(), NULL);
|
||||||
|
|
||||||
|
if (!PathFileExistsA((data_path + "\\brushes").c_str()))
|
||||||
|
CreateDirectoryA((data_path + "\\brushes").c_str(), NULL);
|
||||||
|
|
||||||
|
if (!PathFileExistsA((data_path + "\\brushes\\thumbs").c_str()))
|
||||||
|
CreateDirectoryA((data_path + "\\brushes\\thumbs").c_str(), NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO: save this path somewhere in the settings, don't overwrite every start
|
// TODO: save this path somewhere in the settings, don't overwrite every start
|
||||||
|
|||||||
@@ -39,6 +39,11 @@ bool Image::load_file(std::string filename)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Image::save(const std::string& path)
|
||||||
|
{
|
||||||
|
return stbi_write_png(path.c_str(), width, height, comp, data(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
void Image::flip()
|
void Image::flip()
|
||||||
{
|
{
|
||||||
auto flipped = std::make_unique<uint8_t[]>(width*height*4);
|
auto flipped = std::make_unique<uint8_t[]>(width*height*4);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ public:
|
|||||||
bool load_file(std::string filename);
|
bool load_file(std::string filename);
|
||||||
const uint8_t* data() const { return m_data.get(); }
|
const uint8_t* data() const { return m_data.get(); }
|
||||||
int size() const { return width * height * comp; }
|
int size() const { return width * height * comp; }
|
||||||
|
bool save(const std::string& path);
|
||||||
void create(int w, int h)
|
void create(int w, int h)
|
||||||
{
|
{
|
||||||
width = w;
|
width = w;
|
||||||
|
|||||||
@@ -47,10 +47,72 @@ Node* NodePanelBrush::clone_instantiate() const
|
|||||||
void NodePanelBrush::init()
|
void NodePanelBrush::init()
|
||||||
{
|
{
|
||||||
init_template("tpl-panel-brushes");
|
init_template("tpl-panel-brushes");
|
||||||
//m_layers_container = find<NodeBorder>("layers-container");
|
|
||||||
static auto icons = Asset::list_files("data/thumbs", true, ".*\\.png$");
|
static auto icons = Asset::list_files("data/thumbs", true, ".*\\.png$");
|
||||||
|
|
||||||
if ((m_container = find<NodeBorder>("brushes")))
|
m_btn_add = find<NodeButtonCustom>("btn-add");
|
||||||
|
m_btn_add->on_click = [this](Node*) {
|
||||||
|
App::I.pick_image([this](std::string path) {
|
||||||
|
Image img;
|
||||||
|
if (img.load_file(path))
|
||||||
|
{
|
||||||
|
std::string name, base, ext;
|
||||||
|
std::regex r(R"((.*)[\\/]([^\\/]+)\.(\w+)$)");
|
||||||
|
std::smatch m;
|
||||||
|
if (std::regex_search(path, m, r))
|
||||||
|
{
|
||||||
|
base = m[1].str();
|
||||||
|
name = m[2].str();
|
||||||
|
ext = m[3].str();
|
||||||
|
|
||||||
|
std::string path_high = App::I.data_path + "/brushes/" + name + ".png";
|
||||||
|
std::string path_thumb = App::I.data_path + "/brushes/thumbs/" + name + ".png";
|
||||||
|
auto thumb = img.resize(64, 64);
|
||||||
|
thumb.save(path_thumb);
|
||||||
|
img.save(path_high);
|
||||||
|
|
||||||
|
async_start();
|
||||||
|
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_thumb;
|
||||||
|
brush->high_path = path_high;
|
||||||
|
brush->brush_name = name;
|
||||||
|
brush->on_click = std::bind(&NodePanelBrush::handle_click, this, std::placeholders::_1);
|
||||||
|
|
||||||
|
app_redraw();
|
||||||
|
async_end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if ((m_container = find<NodeScroll>("brushes")))
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (auto& i : icons)
|
for (auto& i : icons)
|
||||||
@@ -63,12 +125,26 @@ void NodePanelBrush::init()
|
|||||||
brush->create();
|
brush->create();
|
||||||
brush->loaded();
|
brush->loaded();
|
||||||
brush->set_icon(path.c_str());
|
brush->set_icon(path.c_str());
|
||||||
brush->m_brushID = count++;
|
|
||||||
brush->thumb_path = path;
|
brush->thumb_path = path;
|
||||||
brush->high_path = path_hi;
|
brush->high_path = path_hi;
|
||||||
brush->brush_name = i;
|
brush->brush_name = i;
|
||||||
brush->high_id = const_hash(path_hi.c_str());
|
brush->on_click = std::bind(&NodePanelBrush::handle_click, this, std::placeholders::_1);
|
||||||
m_brushes.push_back(brush);
|
}
|
||||||
|
|
||||||
|
auto custom_icons = Asset::list_files(App::I.data_path + "/brushes", true, ".*\\.png$");
|
||||||
|
for (auto& i : custom_icons)
|
||||||
|
{
|
||||||
|
std::string path_thumb = App::I.data_path + "/brushes/thumbs/" + i;
|
||||||
|
std::string path_high = App::I.data_path + "/brushes/" + 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->on_click = std::bind(&NodePanelBrush::handle_click, this, std::placeholders::_1);
|
brush->on_click = std::bind(&NodePanelBrush::handle_click, this, std::placeholders::_1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,46 +179,45 @@ void NodePanelBrush::handle_click(Node* target)
|
|||||||
m_current = (NodeButtonBrush*)target;
|
m_current = (NodeButtonBrush*)target;
|
||||||
m_current->m_selected = true;
|
m_current->m_selected = true;
|
||||||
if (on_brush_changed)
|
if (on_brush_changed)
|
||||||
on_brush_changed(this, m_current->m_brushID);
|
on_brush_changed(this, m_container->get_child_index(target));
|
||||||
}
|
}
|
||||||
|
|
||||||
int NodePanelBrush::find_brush(const std::string & name) const
|
int NodePanelBrush::find_brush(const std::string & name) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < m_brushes.size(); i++)
|
for (int i = 0; i < m_container->m_children.size(); i++)
|
||||||
{
|
{
|
||||||
if (m_brushes[i]->brush_name.find(name) != std::string::npos)
|
NodeButtonBrush* b = (NodeButtonBrush*)m_container->m_children[i].get();
|
||||||
{
|
if (b->brush_name.find(name) != std::string::npos)
|
||||||
return i;
|
return i;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string NodePanelBrush::get_texture_path(int index) const
|
std::string NodePanelBrush::get_texture_path(int index) const
|
||||||
{
|
{
|
||||||
return m_brushes[index]->high_path;
|
return ((NodeButtonBrush*)m_container->m_children[index].get())->high_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string NodePanelBrush::get_thumb_path(int index) const
|
std::string NodePanelBrush::get_thumb_path(int index) const
|
||||||
{
|
{
|
||||||
return m_brushes[index]->thumb_path;
|
return ((NodeButtonBrush*)m_container->m_children[index].get())->thumb_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
// select the current brush based on the texture id
|
// select the current brush based on the texture id
|
||||||
void NodePanelBrush::select_brush(int brush_id)
|
//void NodePanelBrush::select_brush(int brush_id)
|
||||||
{
|
//{
|
||||||
if (m_current)
|
// if (m_current)
|
||||||
m_current->m_selected = false;
|
// m_current->m_selected = false;
|
||||||
for (auto b : m_brushes)
|
// for (auto b : m_brushes)
|
||||||
{
|
// {
|
||||||
if (b->m_brushID == brush_id)
|
// if (b->m_brushID == brush_id)
|
||||||
{
|
// {
|
||||||
b->m_selected = true;
|
// b->m_selected = true;
|
||||||
m_current = b;
|
// m_current = b;
|
||||||
TextureManager::load(b->high_path.c_str(), true);
|
// TextureManager::load(b->high_path.c_str(), true);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -4,16 +4,17 @@
|
|||||||
#include "node_image.h"
|
#include "node_image.h"
|
||||||
#include "node_stroke_preview.h"
|
#include "node_stroke_preview.h"
|
||||||
#include "brush.h"
|
#include "brush.h"
|
||||||
|
#include "node_scroll.h"
|
||||||
|
|
||||||
class NodeButtonBrush : public NodeButtonCustom
|
class NodeButtonBrush : public NodeButtonCustom
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int m_brushID;
|
//int m_brushID;
|
||||||
bool m_selected = false;
|
bool m_selected = false;
|
||||||
std::string brush_name;
|
std::string brush_name;
|
||||||
std::string high_path;
|
std::string high_path;
|
||||||
std::string thumb_path;
|
std::string thumb_path;
|
||||||
uint16_t high_id;
|
//uint16_t high_id;
|
||||||
NodeImage* img;
|
NodeImage* img;
|
||||||
virtual Node* clone_instantiate() const override;
|
virtual Node* clone_instantiate() const override;
|
||||||
virtual void init() override;
|
virtual void init() override;
|
||||||
@@ -23,11 +24,15 @@ public:
|
|||||||
|
|
||||||
class NodePanelBrush : public Node
|
class NodePanelBrush : public Node
|
||||||
{
|
{
|
||||||
std::vector<NodeButtonBrush*> m_brushes;
|
//std::vector<NodeButtonBrush*> m_brushes;
|
||||||
NodeButtonBrush* m_current = nullptr;
|
NodeButtonBrush* m_current = nullptr;
|
||||||
Node* m_container;
|
NodeScroll* m_container;
|
||||||
|
NodeButtonCustom* m_btn_add;
|
||||||
|
NodeButtonCustom* m_btn_up;
|
||||||
|
NodeButtonCustom* m_btn_down;
|
||||||
|
NodeButtonCustom* m_btn_remove;
|
||||||
public:
|
public:
|
||||||
std::function<void(Node* target, int id)> on_brush_changed;
|
std::function<void(Node* target, int index)> on_brush_changed;
|
||||||
std::function<void(Node* target)> on_popup_close;
|
std::function<void(Node* target)> on_popup_close;
|
||||||
virtual Node* clone_instantiate() const override;
|
virtual Node* clone_instantiate() const override;
|
||||||
virtual void init() override;
|
virtual void init() override;
|
||||||
@@ -36,7 +41,7 @@ public:
|
|||||||
int find_brush(const std::string& name) const;
|
int find_brush(const std::string& name) const;
|
||||||
std::string get_texture_path(int index) const;
|
std::string get_texture_path(int index) const;
|
||||||
std::string get_thumb_path(int index) const;
|
std::string get_thumb_path(int index) const;
|
||||||
void select_brush(int brush_id);
|
//void select_brush(int brush_id);
|
||||||
};
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user