move presets panel out of stroke panel, implement brush buttons in quick panel

This commit is contained in:
2019-03-05 17:49:14 +01:00
parent 1f794a6811
commit 1cbe9a4a76
10 changed files with 141 additions and 38 deletions

View File

@@ -11,11 +11,11 @@
<!-- PANEL LAYERS -->
<layout id="tpl-panel-layers">
<node width="300" margin="0 0 10 0" rtl="ltr">
<border height="30" color=".5" align="center" justify="center" margin="0 0 0 0">
<border height="30" color=".4" align="center" justify="center" margin="0 0 0 0">
<text text="Layers" color="1 1 1 1"/>
</border>
<border height="35" color=".5" dir="row" align="center" flood-events="1" pad="0 0 5 0">
<border height="35" color=".4" dir="row" align="center" flood-events="1" pad="0 0 5 0">
<checkbox id="alpha-lock" icon="data/ui/check-lock-transparency.png" width="30" margin="0 5 0 5"/>
<combobox id="blend-mode" width="100" height="30" margin="0 5 0 0" combo-list="Normal,-,Multiply,Screen,-,Color Dodge,Overlay"/>
<slider-h id="opacity" value="1" grow="1" width="1" margin="0 5 0 0"/>
@@ -125,10 +125,10 @@
<!-- PANEL COLOR PICKER -->
<layout id="tpl-panel-color">
<node width="350" margin="0 0 10 0" rtl="ltr">
<border height="30" color=".5" align="center" justify="center">
<border height="30" color=".4" align="center" justify="center">
<text text="Colors" color="1 1 1 1"/>
</border>
<border color=".3" pad="5" dir="row" height="350">
<border color=".4" pad="5" dir="row" height="350">
<color-quad id="quad" color="1 0 0 1" height="100%" grow="1"/>
<node width="30" dir="col" pad="0 0 0 5"><slider-hue id="hue"/></node>
</border>
@@ -637,10 +637,10 @@
<!-- PANEL GRIDS -->
<layout id="tpl-panel-grid">
<node width="350" margin="0 0 10 0" rtl="ltr">
<border height="30" color=".5" align="center" justify="center">
<border height="30" color=".4" align="center" justify="center">
<text text="Grids" color="1 1 1 1"/>
</border>
<border color=".3" pad="5" dir="col" width="100%">
<border color=".4" pad="5" dir="col" width="100%">
<node dir="row" margin="0 0 10 0">
<node width="200" grow="1" margin="0 5 0 0">
@@ -658,7 +658,7 @@
</node>
</node>
<scroll id="scroller" color=".3" scroll-color=".2">
<scroll id="scroller" color=".4" scroll-color=".2">
<node dir="row">
<node width="36%" dir="col">
<node height="20" justify="center">
@@ -1496,9 +1496,15 @@ Here's a list of what's available in this release.
<border color="1 1 1 1" width="60" height="30"/>
</button-custom>
<!--brushes-->
<text text="Brushes" margin="20 0 10 0"/>
<button-custom height="35" pad="4">
<stroke-preview id="quick-brush1" width="60" height="100%"/>
<text text="Brushes" margin="10 0 5 0"/>
<button-custom id="quick-brush1" height="45" pad="4">
<stroke-preview width="60" height="100%"/>
</button-custom>
<button-custom id="quick-brush2" height="45" pad="4" margin="4 0 0 0">
<stroke-preview width="60" height="100%"/>
</button-custom>
<button-custom id="quick-brush3" height="45" pad="4" margin="4 0 0 0">
<stroke-preview width="60" height="100%"/>
</button-custom>
</border>
</layout>

View File

@@ -686,6 +686,7 @@ void App::terminate()
color.reset();
stroke.reset();
grid.reset();
presets.reset();
rec_stop();
}

View File

@@ -65,6 +65,7 @@ public:
std::shared_ptr<NodePanelColor> color;
std::shared_ptr<NodePanelStroke> stroke;
std::shared_ptr<NodePanelGrid> grid;
std::shared_ptr<NodePanelBrushPreset> presets;
NodePanelQuick* quick;
NodeCanvas* canvas;
Node* current_panel = nullptr;

View File

@@ -112,6 +112,7 @@ void App::init_sidebar()
color = create_panel<NodePanelColor>(layout);
stroke = create_panel<NodePanelStroke>(layout);
grid = create_panel<NodePanelGrid>(layout);
presets = create_panel<NodePanelBrushPreset>(layout);
//presets = find_or_create_panel<NodePanelBrushPreset>(panels);
canvas->m_canvas->on_mode_changed = [this](kCanvasMode prev, kCanvasMode mode) {
@@ -148,6 +149,11 @@ void App::init_sidebar()
quick->on_size_change = [this](Node*, float value) {
stroke->set_size(value, true, true);
};
quick->on_brush_change = [this](Node*, std::shared_ptr<Brush> b) {
Canvas::I->m_current_brush = b;
stroke->m_preview->m_brush = b;
stroke->m_preview->draw_stroke();
};
layers->on_layer_add = [this](Node*) {
canvas->m_canvas->layer_add(layers->m_layers.back()->m_label_text.c_str());

View File

@@ -2,6 +2,7 @@
#include "node_panel_quick.h"
#include "node_stroke_preview.h"
#include "node_image.h"
#include "app.h"
Node* NodePanelQuick::clone_instantiate() const
{
@@ -29,11 +30,11 @@ void NodePanelQuick::set_color(glm::vec3 color)
void NodePanelQuick::init_controls()
{
auto s = find<NodeStrokePreview>("quick-brush1");
s->m_brush = std::make_shared<Brush>();
s->m_max_size = 10;
s->m_brush->load_tip("data/brushes/Round-Hard.png", "data/brushes/thumbs/Round-Hard.png");
s->draw_stroke();
//auto s = find<NodeStrokePreview>("quick-brush1");
//s->m_brush = std::make_shared<Brush>();
//s->m_max_size = 10;
//s->m_brush->load_tip("data/brushes/Round-Hard.png", "data/brushes/thumbs/Round-Hard.png");
//s->draw_stroke();
m_picker = std::make_shared<NodeColorPicker>();
m_picker->m_manager = m_manager;
@@ -46,11 +47,13 @@ void NodePanelQuick::init_controls()
m_slider_size = find<NodeSliderV>("quick-size");
m_slider_size->on_value_changed = [this](Node* target, float value) {
static_cast<NodeStrokePreview*>(m_button_brush_current->m_children[0].get())->draw_stroke();
if (on_size_change)
on_size_change(target, value);
};
m_slider_flow = find<NodeSliderV>("quick-flow");
m_slider_flow->on_value_changed = [this](Node* target, float value) {
static_cast<NodeStrokePreview*>(m_button_brush_current->m_children[0].get())->draw_stroke();
if (on_flow_change)
on_flow_change(target, value);
};
@@ -69,6 +72,79 @@ void NodePanelQuick::init_controls()
m_button_color1->set_color({ 0, 0, 0, 0 });
m_button_color2->set_color({ 0, 0, 0, 0 });
m_button_color3->set_color({ 0, 0, 0, 0 });
m_button_brush1 = init_button_brush("quick-brush1");
m_button_brush2 = init_button_brush("quick-brush2");
m_button_brush3 = init_button_brush("quick-brush3");
m_button_brush_current = m_button_brush1;
m_button_brush_current->set_active(true);
}
NodeButtonCustom* NodePanelQuick::init_button_brush(const std::string& name)
{
auto button = find<NodeButtonCustom>(name.c_str());
button->on_click = std::bind(&this_class::handle_button_brush_click, this, std::placeholders::_1);
auto pr = static_cast<NodeStrokePreview*>(button->m_children[0].get());
pr->m_brush = std::make_shared<Brush>();
pr->m_max_size = 20;
pr->m_pad_override = 0;
pr->m_draw_first = true;
pr->m_brush->load_tip("data/brushes/Round-Hard.png", "data/brushes/thumbs/Round-Hard.png");
pr->draw_stroke();
return button;
}
void NodePanelQuick::handle_button_brush_click(Node* button)
{
// the first time select the box
if (m_button_brush_current != button)
{
auto b = static_cast<NodeButtonCustom*>(button);
b->set_active(true);
m_button_brush_current->set_active(false);
m_button_brush_current = b;
if (on_brush_change)
on_brush_change(this, static_cast<NodeStrokePreview*>(button->m_children[0].get())->m_brush);
return;
}
// if the box is already selected show the popup
auto screen = root()->m_size;
glm::vec2 pos = button->m_pos + glm::vec2(button->m_size.x, 0);
root()->add_child(App::I.presets);
auto tick = root()->add_child<NodeImage>();
tick->SetPositioning(YGPositionTypeAbsolute);
tick->SetSize(16, 32);
tick->SetPosition(pos.x, pos.y + (button->m_size.y - 32) * 0.5f);
tick->set_image("data/ui/popup-tick.png");
float hh = App::I.presets->m_container->m_children.size() > 10 ? App::I.height / App::I.zoom * .75f : 400.f;
App::I.presets->SetHeight(glm::max(hh, 400.f));
root()->update();
if ((pos.y + App::I.presets->m_size.y) > screen.y)
pos.y = screen.y - App::I.presets->m_size.y;
if (pos.y < 0)
pos.y = 0;
App::I.presets->SetPosition(pos.x + 16, pos.y);
App::I.presets->SetPositioning(YGPositionTypeAbsolute);
App::I.presets->m_mouse_ignore = false;
App::I.presets->m_flood_events = true;
App::I.presets->m_capture_children = false;
App::I.presets->mouse_capture();
root()->update();
App::I.presets->on_popup_close = [this, tick](Node*) {
tick->destroy();
};
App::I.presets->on_brush_changed = [this, button](Node* target, std::shared_ptr<Brush>& b) {
auto pr = static_cast<NodeStrokePreview*>(button->m_children[0].get());
*pr->m_brush = *b;
pr->m_brush->load();
pr->draw_stroke();
if (on_brush_change)
on_brush_change(button, pr->m_brush);
};
}
void NodePanelQuick::handle_button_color_click(Node* target)

View File

@@ -3,6 +3,7 @@
#include "node_button_custom.h"
#include "node_border.h"
#include "node_dialog_picker.h"
#include "brush.h"
class NodePanelQuick : public NodeBorder
{
@@ -10,6 +11,7 @@ public:
std::function<void(Node* target, glm::vec3 rgb)> on_color_change;
std::function<void(Node* target, float value)> on_flow_change;
std::function<void(Node* target, float value)> on_size_change;
std::function<void(Node* target, std::shared_ptr<Brush> b)> on_brush_change;
using this_class = NodePanelQuick;
using parent = NodeBorder;
@@ -19,6 +21,10 @@ public:
NodeButtonCustom* m_button_color2;
NodeButtonCustom* m_button_color3;
NodeButtonCustom* m_button_color_current;
NodeButtonCustom* m_button_brush1;
NodeButtonCustom* m_button_brush2;
NodeButtonCustom* m_button_brush3;
NodeButtonCustom* m_button_brush_current;
std::shared_ptr<NodeColorPicker> m_picker;
virtual Node* clone_instantiate() const override;
virtual void clone_finalize(Node* dest) const override;
@@ -26,6 +32,8 @@ public:
void set_color(glm::vec3 color);
private:
void init_controls();
NodeButtonCustom* init_button_brush(const std::string& name);
void handle_button_brush_click(Node* target);
void handle_button_color_click(Node* target);
};

View File

@@ -119,12 +119,11 @@ bool NodePanelStroke::import_abr(const std::string& path)
auto brushes = abr.compute_brushes(App::I.data_path);
for (const auto& pr : brushes)
{
auto presets = App::I.stroke->m_presets_popup;
async_start();
if (pr->valid())
{
LOG("add preset %s", pr->m_name.c_str());
presets->add_brush(pr);
App::I.presets->add_brush(pr);
}
count++;
float prog = (float)count / (float)tot;
@@ -135,7 +134,7 @@ bool NodePanelStroke::import_abr(const std::string& path)
}
async_start();
m_presets_popup->save();
App::I.presets->save();
pb->destroy();
app_redraw();
async_update();
@@ -265,16 +264,16 @@ void NodePanelStroke::init_controls()
m_pattern_popup->m_flood_events = true;
m_pattern_popup->m_capture_children = false;
m_presets_popup = std::make_shared<NodePanelBrushPreset>();
m_presets_popup->m_manager = m_manager;
m_presets_popup->init();
m_presets_popup->create();
m_presets_popup->loaded();
m_presets_popup->SetPositioning(YGPositionTypeAbsolute);
m_presets_popup->SetSize(YGUndefined, 400);
m_presets_popup->m_mouse_ignore = false;
m_presets_popup->m_flood_events = true;
m_presets_popup->m_capture_children = false;
//m_presets_popup = std::make_shared<NodePanelBrushPreset>();
//m_presets_popup->m_manager = m_manager;
//m_presets_popup->init();
//m_presets_popup->create();
//m_presets_popup->loaded();
//m_presets_popup->SetPositioning(YGPositionTypeAbsolute);
//m_presets_popup->SetSize(YGUndefined, 400);
//m_presets_popup->m_mouse_ignore = false;
//m_presets_popup->m_flood_events = true;
//m_presets_popup->m_capture_children = false;
int br_idx = std::max(m_brush_popup->find_brush("Round-Hard"), 0);
@@ -295,28 +294,32 @@ void NodePanelStroke::init_controls()
m_preset_button->on_click = [this](Node*) {
auto screen = root()->m_size;
glm::vec2 pos = m_preset_button->m_pos + glm::vec2(m_preset_button->m_size.x, 0);
root()->add_child(m_presets_popup);
root()->add_child(App::I.presets);
auto tick = root()->add_child<NodeImage>();
tick->SetPositioning(YGPositionTypeAbsolute);
tick->SetSize(16, 32);
tick->SetPosition(pos.x, pos.y + (m_preset_button->m_size.y - 32) * 0.5f);
tick->set_image("data/ui/popup-tick.png");
float hh = m_presets_popup->m_container->m_children.size() > 10 ? App::I.height / App::I.zoom * .75f : 400.f;
m_presets_popup->SetHeight(glm::max(hh, 400.f));
float hh = App::I.presets->m_container->m_children.size() > 10 ? App::I.height / App::I.zoom * .75f : 400.f;
App::I.presets->SetHeight(glm::max(hh, 400.f));
root()->update();
if ((pos.y + m_presets_popup->m_size.y) > screen.y)
pos.y = screen.y - m_presets_popup->m_size.y;
if ((pos.y + App::I.presets->m_size.y) > screen.y)
pos.y = screen.y - App::I.presets->m_size.y;
if (pos.y < 0)
pos.y = 0;
m_presets_popup->SetPosition(pos.x + 16, pos.y);
m_presets_popup->mouse_capture();
App::I.presets->SetPosition(pos.x + 16, pos.y);
App::I.presets->SetPositioning(YGPositionTypeAbsolute);
App::I.presets->m_mouse_ignore = false;
App::I.presets->m_flood_events = true;
App::I.presets->m_capture_children = false;
App::I.presets->mouse_capture();
root()->update();
m_presets_popup->on_popup_close = [this, tick](Node*) {
App::I.presets->on_popup_close = [this, tick](Node*) {
tick->destroy();
};
m_presets_popup->on_brush_changed = [this](Node* target, std::shared_ptr<Brush>& b) {
App::I.presets->on_brush_changed = [this](Node* target, std::shared_ptr<Brush>& b) {
// don't change some params
//b->m_tip_size = Canvas::I->m_current_brush->m_tip_size;
auto old_color = Canvas::I->m_current_brush->m_tip_color;

View File

@@ -85,7 +85,6 @@ public:
std::shared_ptr<NodePanelBrush> m_brush_popup;
std::shared_ptr<NodePanelBrush> m_pattern_popup;
std::shared_ptr<NodePanelBrushPreset> m_presets_popup;
std::function<void(Node* target)> on_stroke_change;
std::function<void(Node* target, const std::string& path, const std::string& thumb)> on_pattern_changed;
std::function<void(Node* target, const std::string& path, const std::string& thumb)> on_brush_changed;

View File

@@ -302,6 +302,8 @@ void NodeStrokePreview::draw_stroke_immediate()
float pad = (5.f + glm::max(glm::min(m_stroke.m_max_size, m_brush->m_tip_size) / 2.f, min_pad)) * App::I.zoom;
if (b->m_tip_size_pressure)
pad = min_pad * App::I.zoom;
if (!glm::isnan(m_pad_override))
pad = m_pad_override;
float w = m_size.x * App::I.zoom;
float h = m_size.y * App::I.zoom;
std::vector<glm::vec2> kp = {

View File

@@ -38,6 +38,7 @@ public:
std::vector<glm::vec2> m_bez_points;
float m_min_flow = 0.f;
float m_max_size = 0.f;
float m_pad_override = NAN;
virtual Node* clone_instantiate() const override;
virtual void clone_copy(Node* dest) const override;
virtual void clone_children(Node* dest) const override;