Add brush texture list boundary
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#include "pch.h"
|
||||
#include "log.h"
|
||||
#include "node_panel_brush.h"
|
||||
#include "app_core/brush_ui.h"
|
||||
#include "asset.h"
|
||||
#include "texture.h"
|
||||
|
||||
@@ -75,6 +76,116 @@ Node* NodePanelBrush::clone_instantiate() const
|
||||
return new NodePanelBrush();
|
||||
}
|
||||
|
||||
void NodePanelBrush::execute_texture_list_plan(const pp::app::BrushTextureListPlan& plan)
|
||||
{
|
||||
class LegacyBrushTextureListServices final : public pp::app::BrushTextureListServices {
|
||||
public:
|
||||
explicit LegacyBrushTextureListServices(NodePanelBrush& panel) noexcept
|
||||
: panel_(panel)
|
||||
{
|
||||
}
|
||||
|
||||
pp::foundation::Status add_texture_from_source(
|
||||
std::string_view source_path,
|
||||
std::string_view high_path,
|
||||
std::string_view thumbnail_path,
|
||||
std::string_view brush_name,
|
||||
bool converts_brush_alpha) override
|
||||
{
|
||||
Image img;
|
||||
if (!img.load_file(std::string(source_path))) {
|
||||
return pp::foundation::Status::invalid_argument("brush texture source could not be loaded");
|
||||
}
|
||||
|
||||
if (converts_brush_alpha) {
|
||||
img.gayscale_alpha();
|
||||
}
|
||||
|
||||
auto thumbnail_image = img.resize(64, 64).resize_squared(glm::u8vec4(255));
|
||||
thumbnail_image.save_png(std::string(thumbnail_path));
|
||||
img.save_png(std::string(high_path));
|
||||
|
||||
NodeButtonBrush* brush = new NodeButtonBrush;
|
||||
panel_.m_container->add_child(brush);
|
||||
brush->init();
|
||||
brush->create();
|
||||
brush->loaded();
|
||||
const auto thumbnail_path_string = std::string(thumbnail_path);
|
||||
brush->set_icon(thumbnail_path_string.c_str());
|
||||
brush->thumb_path = std::string(thumbnail_path);
|
||||
brush->high_path = std::string(high_path);
|
||||
brush->brush_name = std::string(brush_name);
|
||||
brush->m_user_brush = true;
|
||||
brush->on_click = std::bind(&NodePanelBrush::handle_click, &panel_, std::placeholders::_1);
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
void remove_texture(int index, bool delete_texture_files) override
|
||||
{
|
||||
auto* brush = brush_at(index);
|
||||
if (!brush) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (delete_texture_files) {
|
||||
Asset::delete_file(brush->thumb_path);
|
||||
Asset::delete_file(brush->high_path);
|
||||
}
|
||||
|
||||
if (panel_.m_current == brush) {
|
||||
panel_.m_current = nullptr;
|
||||
}
|
||||
panel_.m_container->remove_child(brush);
|
||||
}
|
||||
|
||||
void move_texture(int from_index, int to_index) override
|
||||
{
|
||||
if (auto* brush = brush_at(from_index)) {
|
||||
panel_.m_container->move_child(brush, to_index);
|
||||
}
|
||||
}
|
||||
|
||||
void select_texture(int index) override
|
||||
{
|
||||
if (panel_.m_current) {
|
||||
panel_.m_current->m_selected = false;
|
||||
}
|
||||
|
||||
panel_.m_current = brush_at(index);
|
||||
if (!panel_.m_current) {
|
||||
return;
|
||||
}
|
||||
|
||||
panel_.m_current->m_selected = true;
|
||||
if (panel_.on_brush_changed) {
|
||||
panel_.on_brush_changed(&panel_, index);
|
||||
}
|
||||
}
|
||||
|
||||
void save_texture_list() override
|
||||
{
|
||||
panel_.save();
|
||||
}
|
||||
|
||||
private:
|
||||
NodeButtonBrush* brush_at(int index) const
|
||||
{
|
||||
if (index < 0 || index >= static_cast<int>(panel_.m_container->m_children.size())) {
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<NodeButtonBrush*>(panel_.m_container->m_children[index].get());
|
||||
}
|
||||
|
||||
NodePanelBrush& panel_;
|
||||
};
|
||||
|
||||
LegacyBrushTextureListServices services(*this);
|
||||
const auto status = pp::app::execute_brush_texture_list_plan(plan, services);
|
||||
if (!status.ok()) {
|
||||
LOG("Brush texture list action failed: %s", status.message);
|
||||
}
|
||||
}
|
||||
|
||||
void NodePanelBrush::init()
|
||||
{
|
||||
init_template_file("data/dialogs/panel-brushes.xml", "tpl-panel-brushes");
|
||||
@@ -82,41 +193,9 @@ void NodePanelBrush::init()
|
||||
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));
|
||||
if (m_dir_name == "brushes")
|
||||
img.gayscale_alpha();
|
||||
|
||||
auto thumb = img.resize(64, 64).resize_squared(glm::u8vec4(255));
|
||||
thumb.save_png(path_thumb);
|
||||
//auto po2 = img.resize_power2();
|
||||
img.save_png(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 = true;
|
||||
brush->on_click = std::bind(&NodePanelBrush::handle_click, this, std::placeholders::_1);
|
||||
save();
|
||||
const auto plan = pp::app::plan_brush_texture_list_add(m_dir_name, App::I->data_path, path);
|
||||
if (plan) {
|
||||
execute_texture_list_plan(plan.value());
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -126,26 +205,13 @@ void NodePanelBrush::init()
|
||||
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);
|
||||
const auto plan = pp::app::plan_brush_texture_list_remove(
|
||||
static_cast<int>(m_container->m_children.size()),
|
||||
idx,
|
||||
m_current->m_user_brush);
|
||||
if (plan) {
|
||||
execute_texture_list_plan(plan.value());
|
||||
}
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -154,9 +220,13 @@ void NodePanelBrush::init()
|
||||
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();
|
||||
const auto plan = pp::app::plan_brush_texture_list_move(
|
||||
static_cast<int>(m_container->m_children.size()),
|
||||
idx,
|
||||
-1);
|
||||
if (plan) {
|
||||
execute_texture_list_plan(plan.value());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -165,9 +235,13 @@ void NodePanelBrush::init()
|
||||
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();
|
||||
const auto plan = pp::app::plan_brush_texture_list_move(
|
||||
static_cast<int>(m_container->m_children.size()),
|
||||
idx,
|
||||
1);
|
||||
if (plan) {
|
||||
execute_texture_list_plan(plan.value());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user