1715 lines
70 KiB
C++
1715 lines
70 KiB
C++
#include "pch.h"
|
|
#include "app.h"
|
|
#include "node_icon.h"
|
|
#include "node_dialog_open.h"
|
|
#include "node_text.h"
|
|
#include "node_progress_bar.h"
|
|
#include "node_dialog_picker.h"
|
|
#include "node_panel_floating.h"
|
|
#include "settings.h"
|
|
#include "serializer.h"
|
|
#include "font.h"
|
|
|
|
void App::title_update()
|
|
{
|
|
static char str[256];
|
|
snprintf(str, 256, "Panodoc: %s%s (%s)", doc_name.c_str(), canvas->m_canvas->m_unsaved ? "*" : "", res_to_string(canvas->m_canvas->m_width).c_str());
|
|
if (auto docname = layout[main_id]->find<NodeText>("txt-docname"))
|
|
docname->set_text(str);
|
|
if (auto node = layout[main_id]->find<NodeText>("txt-dpi"))
|
|
node->set_text(fmt::format("{:.1f}x-dpi", zoom).c_str());
|
|
}
|
|
|
|
void App::init_toolbar_main()
|
|
{
|
|
if (auto* button = layout[main_id]->find<NodeButton>("btn-anim"))
|
|
{
|
|
button->on_click = [this, button](Node*) {
|
|
if (canvas)
|
|
{
|
|
//canvas->m_canvas->export_anim();
|
|
}
|
|
};
|
|
}
|
|
if (auto* button = layout[main_id]->find<NodeButton>("btn-open"))
|
|
{
|
|
button->on_click = [this, button](Node*) {
|
|
dialog_open();
|
|
};
|
|
}
|
|
if (auto* button = layout[main_id]->find<NodeButton>("btn-save"))
|
|
{
|
|
button->on_click = [this, button](Node*) {
|
|
dialog_save();
|
|
};
|
|
}
|
|
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-undo"))
|
|
{
|
|
button->on_click = [this, button](Node*) {
|
|
ActionManager::undo();
|
|
};
|
|
}
|
|
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-redo"))
|
|
{
|
|
button->on_click = [this, button](Node*) {
|
|
ActionManager::redo();
|
|
};
|
|
}
|
|
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-clean-memory"))
|
|
{
|
|
button->on_click = [this](Node*) {
|
|
ActionManager::clear();
|
|
};
|
|
}
|
|
if (auto* button = layout[main_id]->find<NodeButton>("btn-clear"))
|
|
{
|
|
button->on_click = [this](Node*) {
|
|
//exit(0);
|
|
if (canvas)
|
|
canvas->m_canvas->clear({ 0, 0, 0, 0 });
|
|
};
|
|
}
|
|
if (auto* button = layout[main_id]->find<NodeButton>("btn-popup"))
|
|
{
|
|
button->on_click = [this](Node*) {
|
|
msgbox = new NodeMessageBox();
|
|
msgbox->set_manager(&layout);
|
|
msgbox->init();
|
|
layout[main_id]->add_child(msgbox);
|
|
};
|
|
}
|
|
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-settings"))
|
|
{
|
|
button->on_click = [this](Node*) {
|
|
settings = new NodeSettings();
|
|
settings->set_manager(&layout);
|
|
settings->init();
|
|
layout[main_id]->add_child(settings);
|
|
};
|
|
}
|
|
}
|
|
|
|
template <class T> std::shared_ptr<T> create_panel(LayoutManager& manager)
|
|
{
|
|
std::shared_ptr<T> ret;
|
|
ret = std::make_shared<T>();
|
|
ret->set_manager(&manager);
|
|
ret->init();
|
|
ret->create();
|
|
ret->loaded();
|
|
return ret;
|
|
}
|
|
|
|
void App::init_sidebar()
|
|
{
|
|
sidebar = layout[main_id]->find<NodeBorder>("sidebar");
|
|
canvas = layout[main_id]->find<NodeCanvas>("paint-canvas");
|
|
quick = layout[main_id]->find<NodePanelQuick>("panel-quick");
|
|
floatings_container = layout[main_id]->find<Node>("floatings");
|
|
|
|
//brushes = layout[main_id]->find<NodePanelBrush>("panel-brush");
|
|
//layers = layout[main_id]->find<NodePanelLayer>("panel-layer");
|
|
//color = layout[main_id]->find<NodePanelColor>("panel-color");
|
|
//stroke = layout[main_id]->find<NodePanelStroke>("panel-stroke");
|
|
|
|
//brushes = find_or_create_panel<NodePanelBrush>(panels);
|
|
layers = create_panel<NodePanelLayer>(layout);
|
|
color = create_panel<NodePanelColor>(layout);
|
|
stroke = create_panel<NodePanelStroke>(layout);
|
|
grid = create_panel<NodePanelGrid>(layout);
|
|
presets = create_panel<NodePanelBrushPreset>(layout);
|
|
animation = create_panel<NodePanelAnimation>(layout);
|
|
//presets = find_or_create_panel<NodePanelBrushPreset>(panels);
|
|
|
|
canvas->m_canvas->on_mode_changed = [this](kCanvasMode prev, kCanvasMode mode) {
|
|
quick_mode_state[prev] = quick->get_state();
|
|
if (quick_mode_state.find(mode) != quick_mode_state.end())
|
|
quick->set_state(quick_mode_state[mode], true);
|
|
else
|
|
quick->reset_state(true);
|
|
brush_update(true, true);
|
|
};
|
|
color->on_color_changed = [this](Node* target, glm::vec4 color) {
|
|
Canvas::I->m_current_brush->m_tip_color = color;
|
|
quick->set_color(color);
|
|
brush_update(true, false);
|
|
};
|
|
|
|
stroke->on_brush_changed = [this](Node* target, const std::string& path, const std::string& thumb) {
|
|
Canvas::I->m_current_brush->load_tip(path, thumb);
|
|
brush_update(true, true);
|
|
};
|
|
stroke->on_pattern_changed = [this](Node*target, const std::string& path, const std::string& thumb) {
|
|
Canvas::I->m_current_brush->load_pattern(path, thumb);
|
|
brush_update(true, true);
|
|
};
|
|
stroke->on_dual_changed = [this](Node*target, const std::string& path, const std::string& thumb) {
|
|
Canvas::I->m_current_brush->load_dual(path, thumb);
|
|
brush_update(true, true);
|
|
};
|
|
stroke->on_stroke_change = [this](Node*) {
|
|
brush_update(true, true);
|
|
};
|
|
|
|
quick->on_color_change = [this](Node*, glm::vec3 c) {
|
|
Canvas::I->m_current_brush->m_tip_color = glm::vec4(c, 1.f);
|
|
color->set_color(c);
|
|
};
|
|
quick->on_flow_change = [this](Node*, float value) {
|
|
stroke->set_flow(value, true, true);
|
|
};
|
|
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) {
|
|
auto c = Canvas::I->m_current_brush->m_tip_color;
|
|
*Canvas::I->m_current_brush = *b;
|
|
Canvas::I->m_current_brush->m_tip_color = c;
|
|
brush_update(true, true);
|
|
};
|
|
|
|
layers->on_layer_add = [this](Node*, std::shared_ptr<class Layer> layer, int index) {
|
|
canvas->m_canvas->layer_add(layers->m_layers.back()->m_label_text.c_str(), layer, index);
|
|
canvas->m_canvas->m_unsaved = true;
|
|
animation->load_layers();
|
|
title_update();
|
|
};
|
|
|
|
layers->on_layer_duplicate = [this](Node*, int source_index) {
|
|
Canvas::I->layer_add(layers->m_layers.back()->m_label_text.c_str(), nullptr, source_index + 1);
|
|
auto& dst = Canvas::I->m_layers[source_index + 1];
|
|
auto& src = Canvas::I->m_layers[source_index];
|
|
for (int i = 0; i < 6; i++)
|
|
{
|
|
if (!src->face(i))
|
|
continue;
|
|
dst->rtt(i).copy(src->rtt(i));
|
|
dst->face(i) = src->face(i);
|
|
dst->box(i) = src->box(i);
|
|
dst->m_opacity = src->m_opacity;
|
|
dst->m_blend_mode = src->m_blend_mode;
|
|
dst->m_alpha_locked = src->m_alpha_locked;
|
|
}
|
|
Canvas::I->m_unsaved = true;
|
|
animation->load_layers();
|
|
title_update();
|
|
};
|
|
|
|
layers->on_layer_change = [this](Node*, int old_idx, int new_idx) {
|
|
canvas->m_canvas->m_current_layer_idx = new_idx;
|
|
animation->load_layers();
|
|
};
|
|
|
|
layers->on_layer_order = [this](Node*, int old_idx, int new_idx) {
|
|
canvas->m_canvas->layer_order(old_idx, new_idx);
|
|
canvas->m_canvas->m_unsaved = true;
|
|
animation->load_layers();
|
|
title_update();
|
|
};
|
|
|
|
layers->on_layer_delete = [this](Node*, int idx) {
|
|
canvas->m_canvas->layer_remove(idx);
|
|
canvas->m_canvas->m_unsaved = true;
|
|
animation->load_layers();
|
|
title_update();
|
|
};
|
|
|
|
layers->on_layer_opacity_changed = [this](Node*, int idx, float value) {
|
|
canvas->m_canvas->m_layers[idx]->m_opacity = value;
|
|
canvas->m_canvas->m_unsaved = true;
|
|
title_update();
|
|
};
|
|
|
|
layers->on_layer_visibility_changed = [this](Node*, int idx, bool visible) {
|
|
canvas->m_canvas->m_layers[idx]->m_visible = visible;
|
|
canvas->m_canvas->m_unsaved = true;
|
|
animation->load_layers();
|
|
title_update();
|
|
};
|
|
|
|
layers->on_layer_alpha_lock_changed = [this](Node*, int idx, bool locked) {
|
|
canvas->m_canvas->m_layers[idx]->m_alpha_locked = locked;
|
|
canvas->m_canvas->m_unsaved = true;
|
|
title_update();
|
|
};
|
|
|
|
layers->on_layer_blend_mode_changed = [this](Node*, int idx, int mode) {
|
|
canvas->m_canvas->m_layers[idx]->m_blend_mode = mode;
|
|
canvas->m_canvas->m_unsaved = true;
|
|
title_update();
|
|
};
|
|
|
|
layers->on_layer_highlight_changed = [this](Node*, int idx, bool highlight) {
|
|
canvas->m_canvas->m_layers[idx]->m_hightlight = highlight;
|
|
};
|
|
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-stroke"))
|
|
{
|
|
button->on_click = [this, button](Node*) {
|
|
auto screen = layout[main_id]->m_size;
|
|
glm::vec2 pos = button->m_pos + glm::vec2(button->m_size.x * 0.5f, button->m_size.y);
|
|
if (stroke->m_parent)
|
|
{
|
|
if (auto fp = dynamic_cast<NodePanelFloating*>(stroke->m_parent->m_parent))
|
|
{
|
|
stroke->remove_from_parent();
|
|
fp->destroy();
|
|
}
|
|
}
|
|
layout[main_id]->add_child(stroke);
|
|
stroke->SetSize(350, glm::max(100.f, screen.y - pos.y - 50.f));
|
|
stroke->find("title")->SetVisibility(true);
|
|
auto tick = layout[main_id]->add_child<NodeImage>();
|
|
tick->SetPositioning(YGPositionTypeAbsolute);
|
|
tick->SetSize(32, 16);
|
|
tick->SetPosition(pos.x - 16, pos.y);
|
|
tick->set_image("data/ui/popup-tick-up.png");
|
|
layout[main_id]->update();
|
|
|
|
stroke->SetPosition(pos.x - stroke->m_size.x / 2.f, pos.y + 16);
|
|
stroke->SetPositioning(YGPositionTypeAbsolute);
|
|
stroke->m_capture_children = false;
|
|
stroke->m_mouse_ignore = false;
|
|
stroke->mouse_capture();
|
|
auto scroll = stroke->find<NodeScroll>("scroller");
|
|
//scroll->SetHeight(glm::max(100.f, screen.y - pos.y - 200.f));
|
|
|
|
stroke->on_popup_close = [this, tick](Node*) {
|
|
tick->destroy();
|
|
};
|
|
};
|
|
}
|
|
//if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-brush"))
|
|
//{
|
|
// button->on_click = [this, button](Node*) {
|
|
// panels->get_child_index(brushes.get()) == -1 ? panels->add_child(brushes) : panels->remove_child(brushes.get());
|
|
// panels->fix_scroll();
|
|
// button->set_color(panels->get_child_index(brushes.get()) == -1 ? color_button_normal : color_button_hlight);
|
|
// };
|
|
//}
|
|
//if (auto* button = layout[main_id]->find<NodeButton>("btn-brush-preset"))
|
|
//{
|
|
// button->on_click = [this, button](Node*) {
|
|
// panels->get_child_index(presets.get()) == -1 ? panels->add_child(presets) : panels->remove_child(presets.get());
|
|
// panels->fix_scroll();
|
|
// button->set_color(panels->get_child_index(presets.get()) == -1 ? color_button_normal : color_button_hlight);
|
|
// };
|
|
//}
|
|
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-color"))
|
|
{
|
|
button->on_click = [this, button](Node*) {
|
|
auto screen = layout[main_id]->m_size;
|
|
glm::vec2 pos = button->m_pos + glm::vec2(button->m_size.x * 0.5f, button->m_size.y);
|
|
layout[main_id]->add_child(color);
|
|
color->find("title")->SetVisibility(true);
|
|
color->SetSize(350, 350);
|
|
auto tick = layout[main_id]->add_child<NodeImage>();
|
|
tick->SetPositioning(YGPositionTypeAbsolute);
|
|
tick->SetSize(32, 16);
|
|
tick->SetPosition(pos.x - 16, pos.y);
|
|
tick->set_image("data/ui/popup-tick-up.png");
|
|
layout[main_id]->update();
|
|
|
|
color->SetPosition(pos.x - color->m_size.x / 2.f, pos.y + 16);
|
|
color->SetPositioning(YGPositionTypeAbsolute);
|
|
color->m_capture_children = false;
|
|
color->m_mouse_ignore = false;
|
|
color->mouse_capture();
|
|
|
|
color->on_popup_close = [this, tick](Node*) {
|
|
tick->destroy();
|
|
};
|
|
};
|
|
}
|
|
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-layer"))
|
|
{
|
|
button->on_click = [this, button](Node*) {
|
|
auto screen = layout[main_id]->m_size;
|
|
glm::vec2 pos = button->m_pos + glm::vec2(button->m_size.x * 0.5f, button->m_size.y);
|
|
layers->find("title")->SetVisibility(true);
|
|
layers->SetSize(350, YGUndefined);
|
|
if (layers->m_parent)
|
|
{
|
|
if (auto fp = dynamic_cast<NodePanelFloating*>(layers->m_parent->m_parent))
|
|
{
|
|
layers->remove_from_parent();
|
|
fp->destroy();
|
|
}
|
|
}
|
|
layout[main_id]->add_child(layers);
|
|
auto tick = layout[main_id]->add_child<NodeImage>();
|
|
tick->SetPositioning(YGPositionTypeAbsolute);
|
|
tick->SetSize(32, 16);
|
|
tick->SetPosition(pos.x - 16, pos.y);
|
|
tick->set_image("data/ui/popup-tick-up.png");
|
|
layout[main_id]->update();
|
|
|
|
layers->SetPosition(pos.x - layers->m_size.x / 2.f, pos.y + 16);
|
|
layers->SetPositioning(YGPositionTypeAbsolute);
|
|
layers->m_capture_children = false;
|
|
layers->m_mouse_ignore = false;
|
|
layers->mouse_capture();
|
|
auto scroll = layers->find<NodeScroll>("layers-container");
|
|
scroll->SetMaxHeight(glm::max(100.f, screen.y - pos.y - 200.f));
|
|
|
|
layers->on_popup_close = [this, tick](Node*) {
|
|
tick->destroy();
|
|
};
|
|
};
|
|
}
|
|
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-grids-panel"))
|
|
{
|
|
button->on_click = [this, button](Node*) {
|
|
auto screen = layout[main_id]->m_size;
|
|
glm::vec2 pos = button->m_pos + glm::vec2(button->m_size.x * 0.5f, button->m_size.y);
|
|
grid->find("title")->SetVisibility(true);
|
|
grid->SetSize(350, YGUndefined);
|
|
if (grid->m_parent)
|
|
{
|
|
if (auto fp = dynamic_cast<NodePanelFloating*>(grid->m_parent->m_parent))
|
|
{
|
|
grid->remove_from_parent();
|
|
fp->destroy();
|
|
}
|
|
}
|
|
layout[main_id]->add_child(grid);
|
|
auto tick = layout[main_id]->add_child<NodeImage>();
|
|
tick->SetPositioning(YGPositionTypeAbsolute);
|
|
tick->SetSize(32, 16);
|
|
tick->SetPosition(pos.x - 16, pos.y);
|
|
tick->set_image("data/ui/popup-tick-up.png");
|
|
layout[main_id]->update();
|
|
|
|
grid->SetPosition(pos.x - grid->m_size.x / 2.f, pos.y + 16);
|
|
grid->SetPositioning(YGPositionTypeAbsolute);
|
|
grid->m_capture_children = false;
|
|
grid->m_mouse_ignore = false;
|
|
grid->mouse_capture();
|
|
auto scroll = grid->find<NodeScroll>("scroller");
|
|
scroll->SetMaxHeight(glm::max(100.f, screen.y - pos.y - 250.f));
|
|
|
|
grid->on_popup_close = [this, tick](Node*) {
|
|
tick->destroy();
|
|
};
|
|
};
|
|
}
|
|
}
|
|
template<class T>
|
|
void select_button(Node* main, T* button) {
|
|
main->find<NodeButtonCustom>("btn-pen")->set_active(false);
|
|
main->find<NodeButtonCustom>("btn-erase")->set_active(false);
|
|
main->find<NodeButtonCustom>("btn-line")->set_active(false);
|
|
main->find<NodeButton>("btn-cam")->set_active(false);
|
|
main->find<NodeButton>("btn-grid")->set_active(false);
|
|
main->find<NodeButton>("btn-copy")->set_active(false);
|
|
main->find<NodeButton>("btn-cut")->set_active(false);
|
|
//main->find<NodeButton>("btn-fill")->set_color(color_button_normal);
|
|
main->find<NodeButtonCustom>("btn-mask-free")->set_active(false);
|
|
main->find<NodeButtonCustom>("btn-mask-line")->set_active(false);
|
|
main->find<NodeButtonCustom>("btn-bucket")->set_active(false);
|
|
button->set_active(false);
|
|
};
|
|
|
|
void App::init_toolbar_draw()
|
|
{
|
|
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-pen"))
|
|
{
|
|
button->on_click = [this, button](Node*) {
|
|
select_button(layout[main_id], button);
|
|
Canvas::set_mode(kCanvasMode::Draw);
|
|
};
|
|
//button->set_active(true);
|
|
Canvas::set_mode(kCanvasMode::Draw);
|
|
}
|
|
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-pick"))
|
|
{
|
|
button->on_click = [this](Node*) {
|
|
CanvasModePen* mode = (CanvasModePen*)canvas->m_canvas->modes[(int)kCanvasMode::Draw][0];
|
|
if (mode && canvas->m_canvas->m_current_mode == kCanvasMode::Draw)
|
|
{
|
|
mode->m_picking = !mode->m_picking;
|
|
}
|
|
};
|
|
}
|
|
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-touchlock"))
|
|
{
|
|
button->on_click = [this](Node*) {
|
|
canvas->m_canvas->m_touch_lock = !canvas->m_canvas->m_touch_lock;
|
|
};
|
|
}
|
|
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-erase"))
|
|
{
|
|
button->on_click = [this, button](Node*) {
|
|
select_button(layout[main_id], button);
|
|
Canvas::set_mode(kCanvasMode::Erase);
|
|
};
|
|
}
|
|
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-line"))
|
|
{
|
|
button->on_click = [this, button](Node*) {
|
|
select_button(layout[main_id], button);
|
|
Canvas::set_mode(kCanvasMode::Line);
|
|
};
|
|
}
|
|
if (auto* button = layout[main_id]->find<NodeButton>("btn-cam"))
|
|
{
|
|
button->on_click = [this, button](Node*) {
|
|
select_button(layout[main_id], button);
|
|
Canvas::set_mode(kCanvasMode::Camera);
|
|
};
|
|
}
|
|
if (auto* button = layout[main_id]->find<NodeButton>("btn-grid"))
|
|
{
|
|
button->on_click = [this, button](Node*) {
|
|
select_button(layout[main_id], button);
|
|
Canvas::set_mode(kCanvasMode::Grid);
|
|
};
|
|
}
|
|
if (auto* button = layout[main_id]->find<NodeButton>("btn-copy"))
|
|
{
|
|
button->on_click = [this, button](Node*) {
|
|
select_button(layout[main_id], button);
|
|
auto m = static_cast<CanvasModeTransform*>(canvas->m_canvas->modes[(int)kCanvasMode::Copy][0]);
|
|
m->m_action = CanvasModeTransform::ActionType::Copy;
|
|
Canvas::set_mode(kCanvasMode::Copy);
|
|
};
|
|
}
|
|
if (auto* button = layout[main_id]->find<NodeButton>("btn-cut"))
|
|
{
|
|
button->on_click = [this, button](Node*) {
|
|
select_button(layout[main_id], button);
|
|
auto m = static_cast<CanvasModeTransform*>(canvas->m_canvas->modes[(int)kCanvasMode::Cut][0]);
|
|
m->m_action = CanvasModeTransform::ActionType::Cut;
|
|
Canvas::set_mode(kCanvasMode::Cut);
|
|
};
|
|
}
|
|
if (auto* button = layout[main_id]->find<NodeButton>("btn-fill"))
|
|
{
|
|
// polygon fill
|
|
button->on_click = [this, button](Node*) {
|
|
select_button(layout[main_id], button);
|
|
Canvas::set_mode(kCanvasMode::Fill);
|
|
};
|
|
}
|
|
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-mask-free"))
|
|
{
|
|
button->on_click = [this, button](Node*) {
|
|
select_button(layout[main_id], button);
|
|
Canvas::set_mode(kCanvasMode::MaskFree);
|
|
};
|
|
}
|
|
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-mask-line"))
|
|
{
|
|
button->on_click = [this, button](Node*) {
|
|
select_button(layout[main_id], button);
|
|
Canvas::set_mode(kCanvasMode::MaskLine);
|
|
};
|
|
}
|
|
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-bucket"))
|
|
{
|
|
button->on_click = [this, button](Node*) {
|
|
select_button(layout[main_id], button);
|
|
Canvas::set_mode(kCanvasMode::FloodFill);
|
|
};
|
|
}
|
|
}
|
|
|
|
void App::init_menu_file()
|
|
{
|
|
if (auto* menu_file = layout[main_id]->find<NodeButtonCustom>("menu-file"))
|
|
{
|
|
menu_file->on_click = [=](Node*) {
|
|
glm::vec2 pos = menu_file->m_pos + glm::vec2(0, menu_file->m_size.y);
|
|
auto popup = layout[const_hash("file-menu")]->m_children[0]->clone<NodePopupMenu>();
|
|
popup->update();
|
|
if (YGNodeStyleGetDirection(layout[main_id]->y_node) == YGDirectionRTL)
|
|
pos.x = pos.x - popup->m_size.x + menu_file->m_size.x;
|
|
popup->SetPositioning(YGPositionTypeAbsolute);
|
|
popup->SetPosition(pos.x, pos.y);
|
|
layout[main_id]->add_child(popup);
|
|
|
|
if (auto b = popup->find<NodeButtonCustom>("file-newdoc"))
|
|
b->on_click = [this, popup](Node*) {
|
|
dialog_newdoc();
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
};
|
|
if (auto b = popup->find<NodeButtonCustom>("file-import"))
|
|
b->on_click = [this, popup](Node*) {
|
|
pick_image([this](std::string path){
|
|
Image img;
|
|
img.load_file(path);
|
|
if (img.width == img.height / 6 || img.width == img.height * 2)
|
|
{
|
|
Canvas::I->import_equirectangular(path);
|
|
}
|
|
else
|
|
{
|
|
auto m = static_cast<CanvasModeTransform*>(canvas->m_canvas->modes[(int)kCanvasMode::Import][0]);
|
|
m->m_action = CanvasModeTransform::ActionType::Import;
|
|
m->m_source_image = std::move(img);
|
|
Canvas::set_mode(kCanvasMode::Import);
|
|
}
|
|
});
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
};
|
|
if (auto b = popup->find<NodeButtonCustom>("file-open"))
|
|
b->on_click = [this, popup](Node*) {
|
|
//dialog_open();
|
|
pick_file({"ppi"}, [this](std::string path){
|
|
open_document(path);
|
|
});
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
};
|
|
if (auto b = popup->find<NodeButtonCustom>("file-browse"))
|
|
b->on_click = [this, popup](Node*) {
|
|
dialog_browse();
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
};
|
|
if (auto b = popup->find<NodeButtonCustom>("file-save"))
|
|
b->on_click = [this, popup](Node*) {
|
|
if (Canvas::I->m_newdoc)
|
|
{
|
|
dialog_save();
|
|
}
|
|
else if(Canvas::I->m_unsaved)
|
|
{
|
|
canvas->m_canvas->project_save();
|
|
}
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
};
|
|
if (auto b = popup->find<NodeButtonCustom>("file-save-as"))
|
|
b->on_click = [this, popup](Node*) {
|
|
dialog_save();
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
};
|
|
if (auto b = popup->find<NodeButtonCustom>("file-save-ver"))
|
|
b->on_click = [this, popup](Node*) {
|
|
Canvas::I->m_newdoc ? dialog_save() : dialog_save_ver();
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
};
|
|
if (auto b = popup->find<NodeButtonCustom>("file-export"))
|
|
b->on_click = [this, popup](Node*) {
|
|
dialog_export(".jpg");
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
};
|
|
if (auto b = popup->find<NodeButtonCustom>("file-export-tick"))
|
|
b->on_click = [this, b, popup](Node*) {
|
|
glm::vec2 pos = b->m_pos + glm::vec2(b->m_size.x, 0);
|
|
auto subpopup = layout[const_hash("file-submenu-export")]->m_children[0]->clone<NodePopupMenu>();
|
|
subpopup->update();
|
|
if (YGNodeStyleGetDirection(layout[main_id]->y_node) == YGDirectionRTL)
|
|
pos.x = pos.x - subpopup->m_size.x + b->m_size.x;
|
|
subpopup->SetPositioning(YGPositionTypeAbsolute);
|
|
subpopup->SetPosition(pos.x, pos.y);
|
|
layout[main_id]->add_child(subpopup);
|
|
subpopup->find<NodeButtonCustom>("file-submenu-export-png")->on_click = [this, subpopup, popup](Node*) {
|
|
dialog_export(".png");
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
subpopup->mouse_release();
|
|
subpopup->destroy();
|
|
};
|
|
subpopup->find<NodeButtonCustom>("file-submenu-export-layers")->on_click = [this, subpopup, popup](Node*) {
|
|
dialog_export_layers();
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
subpopup->mouse_release();
|
|
subpopup->destroy();
|
|
};
|
|
subpopup->find<NodeButtonCustom>("file-submenu-export-cube")->on_click = [this, subpopup, popup](Node*) {
|
|
dialog_export_cube_faces();
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
subpopup->mouse_release();
|
|
subpopup->destroy();
|
|
};
|
|
subpopup->find<NodeButtonCustom>("file-submenu-export-depth")->on_click = [this, subpopup, popup](Node*) {
|
|
dialog_export_depth();
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
subpopup->mouse_release();
|
|
subpopup->destroy();
|
|
};
|
|
subpopup->find<NodeButtonCustom>("file-submenu-export-anim")->on_click = [this, subpopup, popup](Node*) {
|
|
dialog_export_layers();
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
subpopup->mouse_release();
|
|
subpopup->destroy();
|
|
};
|
|
subpopup->find<NodeButtonCustom>("file-submenu-export-timelapse")->on_click = [this, subpopup, popup](Node*) {
|
|
dialog_timelapse_export();
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
subpopup->mouse_release();
|
|
subpopup->destroy();
|
|
};
|
|
};
|
|
if (auto b = popup->find<NodeButtonCustom>("file-share"))
|
|
b->on_click = [this, popup](Node*) {
|
|
share_file(doc_path);
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
};
|
|
if (auto b = popup->find<NodeButtonCustom>("file-resize"))
|
|
b->on_click = [this, popup](Node*) {
|
|
dialog_resize();
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
};
|
|
if (auto b = popup->find<NodeButtonCustom>("file-cloud-upload"))
|
|
b->on_click = [this, popup](Node*) {
|
|
cloud_upload();
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
};
|
|
if (auto b = popup->find<NodeButtonCustom>("file-cloud-browse"))
|
|
b->on_click = [this, popup](Node*) {
|
|
cloud_browse();
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
};
|
|
};
|
|
}
|
|
}
|
|
|
|
void App::init_menu_edit()
|
|
{
|
|
if (auto* menu_file = layout[main_id]->find<NodeButtonCustom>("menu-edit"))
|
|
{
|
|
menu_file->on_click = [=](Node*) {
|
|
glm::vec2 pos = menu_file->m_pos + glm::vec2(0, menu_file->m_size.y);
|
|
auto popup = layout[const_hash("edit-menu")]->m_children[0]->clone<NodePopupMenu>();
|
|
popup->update();
|
|
if (YGNodeStyleGetDirection(layout[main_id]->y_node) == YGDirectionRTL)
|
|
pos.x = pos.x - popup->m_size.x + menu_file->m_size.x;
|
|
popup->SetPositioning(YGPositionTypeAbsolute);
|
|
popup->SetPosition(pos.x, pos.y);
|
|
layout[main_id]->add_child(popup);
|
|
};
|
|
}
|
|
}
|
|
|
|
void App::init_menu_tools()
|
|
{
|
|
auto main = layout[main_id];
|
|
|
|
if (auto menu_exp = main->find<NodeButtonCustom>("menu-tools"))
|
|
{
|
|
menu_exp->on_click = [this, menu_exp, main](Node*) {
|
|
glm::vec2 pos = menu_exp->m_pos + glm::vec2(0, menu_exp->m_size.y);
|
|
auto popup_exp = layout[const_hash("tools-menu")]->m_children[0]->clone<NodePopupMenu>();
|
|
popup_exp->update();
|
|
if (YGNodeStyleGetDirection(layout[main_id]->y_node) == YGDirectionRTL)
|
|
pos.x = pos.x - popup_exp->m_size.x + menu_exp->m_size.x;
|
|
popup_exp->SetPositioning(YGPositionTypeAbsolute);
|
|
popup_exp->SetPosition(pos.x, pos.y);
|
|
layout[main_id]->add_child(popup_exp);
|
|
|
|
if (auto tick = popup_exp->find<NodeButtonCustom>("tools-timelapse-tick")) tick->on_click = [this, popup_exp](Node* b)
|
|
{
|
|
if (auto menu_time = popup_exp->find<NodePopupMenu>("tools-timelapse"))
|
|
{
|
|
glm::vec2 pos = b->m_pos + glm::vec2(b->m_size.x, 0);
|
|
auto popup_time = layout[const_hash("timelapse-menu")]->m_children[0]->clone<NodePopupMenu>();
|
|
popup_time->update();
|
|
if (YGNodeStyleGetDirection(layout[main_id]->y_node) == YGDirectionRTL)
|
|
pos.x = pos.x - popup_time->m_size.x + b->m_size.x;
|
|
popup_time->SetPositioning(YGPositionTypeAbsolute);
|
|
popup_time->SetPosition(pos.x, pos.y);
|
|
layout[main_id]->add_child(popup_time);
|
|
|
|
if (auto item = popup_time->find<NodeButtonCustom>("timelapse-start"))
|
|
{
|
|
if (auto text = popup_time->find<NodeText>("menu-label"))
|
|
{
|
|
text->set_text(rec_running ? "Stop Recording" : "Start Recording");
|
|
}
|
|
}
|
|
|
|
popup_time->find<NodeButtonCustom>("timelapse-start")->on_click = [this, popup_time, popup_exp](Node*) {
|
|
rec_running ? rec_stop() : rec_start();
|
|
popup_exp->destroy();
|
|
popup_time->destroy();
|
|
};
|
|
|
|
popup_time->find<NodeButtonCustom>("timelapse-clear")->on_click = [this, popup_time, popup_exp](Node*) {
|
|
rec_clear();
|
|
popup_exp->destroy();
|
|
popup_time->destroy();
|
|
};
|
|
|
|
popup_time->find<NodeButtonCustom>("timelapse-export")->on_click = [this, popup_time, popup_exp](Node*) {
|
|
rec_export("");
|
|
popup_exp->destroy();
|
|
popup_time->destroy();
|
|
};
|
|
}
|
|
};
|
|
|
|
if (auto tick = popup_exp->find<NodeButtonCustom>("tools-panels-tick")) tick->on_click = [this, popup_exp](Node* b)
|
|
{
|
|
if (auto menu_time = popup_exp->find<NodePopupMenu>("tools-panels"))
|
|
{
|
|
glm::vec2 pos = b->m_pos + glm::vec2(b->m_size.x, 0);
|
|
auto popup_time = layout[const_hash("panels-menu")]->m_children[0]->clone<NodePopupMenu>();
|
|
popup_time->update();
|
|
if (YGNodeStyleGetDirection(layout[main_id]->y_node) == YGDirectionRTL)
|
|
pos.x = pos.x - popup_time->m_size.x + b->m_size.x;
|
|
popup_time->SetPositioning(YGPositionTypeAbsolute);
|
|
popup_time->SetPosition(pos.x, pos.y);
|
|
layout[main_id]->add_child(popup_time);
|
|
|
|
auto visible = [this](Node* panel) {
|
|
if (!panel)
|
|
return false;
|
|
for (auto& c : floatings_container->m_children)
|
|
{
|
|
if (auto fp = std::static_pointer_cast<NodePanelFloating>(c))
|
|
{
|
|
if (fp->m_container->is_child(panel))
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
popup_time->find<NodeButtonCustom>("panel-presets")->on_click = [this, popup_time, popup_exp, visible](Node*) {
|
|
if (visible(floating_presets.get()))
|
|
return;
|
|
auto fpanel = floatings_container->add_child<NodePanelFloating>();
|
|
fpanel->m_class = NodePanelFloating::kClass::Presets;
|
|
fpanel->SetHeight(300);
|
|
fpanel->SetMinHeight(300);
|
|
fpanel->SetMinWidth(100);
|
|
fpanel->m_title->set_text("Brushes");
|
|
if (!floating_presets)
|
|
{
|
|
floating_presets = fpanel->m_container->add_child_ref<NodePanelBrushPreset>();
|
|
floating_presets->SetHeightP(100);
|
|
//floating_presets->SetFlexGrow(1);
|
|
//floating_presets->find("toolbar")->destroy();
|
|
floating_presets->on_brush_changed = [this](Node* target, std::shared_ptr<Brush>& b) {
|
|
auto c = Canvas::I->m_current_brush->m_tip_color;
|
|
*Canvas::I->m_current_brush = *b;
|
|
Canvas::I->m_current_brush->m_tip_color = c;
|
|
Canvas::I->m_current_brush->load();
|
|
brush_update(true, true);
|
|
};
|
|
}
|
|
else
|
|
{
|
|
fpanel->m_container->add_child(floating_presets);
|
|
}
|
|
popup_exp->destroy();
|
|
popup_time->destroy();
|
|
};
|
|
|
|
popup_time->find<NodeButtonCustom>("panel-color")->on_click = [this, popup_time, popup_exp, visible](Node*) {
|
|
if (visible(floating_color.get()))
|
|
return;
|
|
auto fpanel = floatings_container->add_child<NodePanelFloating>();
|
|
fpanel->m_class = NodePanelFloating::kClass::Color;
|
|
fpanel->SetHeight(300);
|
|
fpanel->SetMinHeight(300);
|
|
fpanel->m_title->set_text("Color Picker");
|
|
if (!floating_color)
|
|
{
|
|
floating_color = fpanel->m_container->add_child_ref<NodePanelColor>();
|
|
floating_color->SetHeightP(100);
|
|
//floating_color->SetMinHeight(300);
|
|
floating_color->find("title")->SetVisibility(false);
|
|
floating_color->on_color_changed = [this](Node* target, glm::vec4 color) {
|
|
Canvas::I->m_current_brush->m_tip_color = color;
|
|
brush_update(true, false);
|
|
};
|
|
}
|
|
else
|
|
{
|
|
fpanel->m_container->add_child(floating_color);
|
|
}
|
|
popup_exp->destroy();
|
|
popup_time->destroy();
|
|
};
|
|
popup_time->find<NodeButtonCustom>("panel-color-adv")->on_click = [this, popup_time, popup_exp, visible](Node*) {
|
|
if (visible(floating_picker.get()))
|
|
return;
|
|
auto fpanel = floatings_container->add_child<NodePanelFloating>();
|
|
fpanel->m_class = NodePanelFloating::kClass::ColorAdv;
|
|
fpanel->SetHeight(300);
|
|
fpanel->SetWidth(300);
|
|
fpanel->m_title->set_text("Color Picker");
|
|
if (!floating_picker)
|
|
{
|
|
floating_picker = fpanel->m_container->add_child_ref<NodeColorPicker>();
|
|
//floating_picker->find("title")->SetVisibility(false);
|
|
//floating_picker->SetHeightP(100);
|
|
//floating_picker->SetWidth(250);
|
|
floating_picker->m_autohide = false;
|
|
floating_picker->on_color_change = [this](Node* target, glm::vec3 color) {
|
|
Canvas::I->m_current_brush->m_tip_color = glm::vec4(color, 1.f);
|
|
brush_update(true, false);
|
|
};
|
|
}
|
|
else
|
|
{
|
|
fpanel->m_container->add_child(floating_picker);
|
|
}
|
|
popup_exp->destroy();
|
|
popup_time->destroy();
|
|
};
|
|
popup_time->find<NodeButtonCustom>("panel-layers")->on_click = [this, popup_time, popup_exp, visible](Node*) {
|
|
if (visible(layers.get()))
|
|
return;
|
|
auto fpanel = floatings_container->add_child<NodePanelFloating>();
|
|
fpanel->m_class = NodePanelFloating::kClass::Layers;
|
|
fpanel->SetMinHeight(100);
|
|
fpanel->SetHeight(300);
|
|
fpanel->m_container->add_child(layers);
|
|
fpanel->m_title->set_text("Layers");
|
|
layers->SetPositioning(YGPositionTypeRelative);
|
|
layers->SetPosition(0, 0);
|
|
layers->SetWidthP(100);
|
|
layers->SetHeightP(100);
|
|
layers->SetFlexShrink(0);
|
|
layers->find("title")->SetVisibility(false);
|
|
|
|
popup_exp->destroy();
|
|
popup_time->destroy();
|
|
};
|
|
popup_time->find<NodeButtonCustom>("panel-brush")->on_click = [this, popup_time, popup_exp, visible](Node*) {
|
|
if (visible(stroke.get()))
|
|
return;
|
|
auto fpanel = floatings_container->add_child<NodePanelFloating>();
|
|
fpanel->m_class = NodePanelFloating::kClass::Brush;
|
|
fpanel->m_container->add_child(stroke);
|
|
fpanel->SetHeight(300);
|
|
fpanel->m_title->set_text("Brush Settings");
|
|
stroke->SetPositioning(YGPositionTypeRelative);
|
|
stroke->SetPosition(0, 0);
|
|
stroke->SetWidthP(100);
|
|
stroke->SetHeightP(100);
|
|
stroke->find("title")->SetVisibility(false);
|
|
|
|
popup_exp->destroy();
|
|
popup_time->destroy();
|
|
};
|
|
popup_time->find<NodeButtonCustom>("panel-grids")->on_click = [this, popup_time, popup_exp, visible](Node*) {
|
|
if (visible(grid.get()))
|
|
return;
|
|
auto fpanel = floatings_container->add_child<NodePanelFloating>();
|
|
fpanel->m_class = NodePanelFloating::kClass::Grids;
|
|
fpanel->m_container->add_child(grid);
|
|
fpanel->SetHeight(300);
|
|
fpanel->m_title->set_text("Grid");
|
|
grid->SetPositioning(YGPositionTypeRelative);
|
|
grid->SetPosition(0, 0);
|
|
grid->SetWidthP(100);
|
|
grid->SetHeightP(100);
|
|
grid->find("title")->SetVisibility(false);
|
|
|
|
popup_exp->destroy();
|
|
popup_time->destroy();
|
|
};
|
|
popup_time->find<NodeButtonCustom>("panel-animation")->on_click = [this, popup_time, popup_exp, visible](Node*) {
|
|
if (visible(grid.get()))
|
|
return;
|
|
auto fpanel = floatings_container->add_child<NodePanelFloating>();
|
|
fpanel->m_class = NodePanelFloating::kClass::Animation;
|
|
fpanel->m_container->add_child(animation);
|
|
fpanel->SetSize(500, 300);
|
|
fpanel->m_title->set_text("Animation");
|
|
fpanel->m_droppable = false;
|
|
grid->SetPositioning(YGPositionTypeRelative);
|
|
grid->SetPosition(0, 0);
|
|
grid->SetWidthP(100);
|
|
grid->SetHeightP(100);
|
|
grid->find("title")->SetVisibility(false);
|
|
|
|
popup_exp->destroy();
|
|
popup_time->destroy();
|
|
};
|
|
}
|
|
};
|
|
|
|
if (auto ui_scale = popup_exp->find<NodeComboBox>("tools-ui-scale"))
|
|
{
|
|
// set index to current zoom level (or at least the closest in list)
|
|
for (int i = 0; i < ui_scale->m_data.size(); i++)
|
|
if (App::I->zoom >= ui_scale->get_float(i))
|
|
ui_scale->set_index(i);
|
|
|
|
ui_scale->on_select = [ui_scale](Node* target, int index)
|
|
{
|
|
App::I->set_ui_scale(ui_scale->get_float(index));
|
|
};
|
|
}
|
|
|
|
if (auto vp_scale = popup_exp->find<NodeComboBox>("tools-vp-scale"))
|
|
{
|
|
// set index to current zoom level (or at least the closest in list)
|
|
for (int i = 0; i < vp_scale->m_data.size(); i++)
|
|
if (App::I->canvas->m_density >= vp_scale->get_float(i))
|
|
vp_scale->set_index(i);
|
|
|
|
vp_scale->on_select = [vp_scale](Node* target, int index)
|
|
{
|
|
float d = vp_scale->get_float(index);
|
|
App::I->canvas->set_density(d);
|
|
Settings::set("vp-scale", Serializer::Float(d));
|
|
Settings::save();
|
|
};
|
|
}
|
|
|
|
if (auto rtl_btn = popup_exp->find<NodeButtonCustom>("tools-rtl"))
|
|
{
|
|
NodeCheckBox* cb = rtl_btn->find<NodeCheckBox>("tools-rtl-check");
|
|
cb->set_value(ui_rtl, false);
|
|
|
|
rtl_btn->on_click = [this, popup_exp, rtl_btn](Node* b)
|
|
{
|
|
NodeCheckBox* cb = rtl_btn->find<NodeCheckBox>("tools-rtl-check");
|
|
cb->set_value(!cb->checked, true);
|
|
};
|
|
|
|
rtl_btn->find<NodeCheckBox>("tools-rtl-check")->on_value_changed = [this, main](Node*, bool checked)
|
|
{
|
|
set_ui_rtl(checked);
|
|
};
|
|
}
|
|
|
|
if (auto vr_btn = popup_exp->find<NodeButtonCustom>("tools-vr"))
|
|
{
|
|
NodeCheckBox* cb = vr_btn->find<NodeCheckBox>("tools-vr-check");
|
|
cb->set_value(has_vr);
|
|
|
|
vr_btn->on_click = [this, popup_exp, vr_btn](Node* b)
|
|
{
|
|
NodeCheckBox* cb = vr_btn->find<NodeCheckBox>("tools-vr-check");
|
|
cb->set_value(!cb->checked, true);
|
|
};
|
|
|
|
vr_btn->find<NodeCheckBox>("tools-vr-check")->on_value_changed = [this, main](Node* target, bool checked)
|
|
{
|
|
if (checked)
|
|
{
|
|
if (!vr_start())
|
|
{
|
|
auto cb = static_cast<NodeCheckBox*>(target);
|
|
cb->set_value(false);
|
|
message_box("VR Failed", "Couldn't start Virtual Reality mode");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
vr_stop();
|
|
}
|
|
};
|
|
}
|
|
|
|
popup_exp->find<NodeButtonCustom>("clear-grids")->on_click = [this, popup_exp](Node*) {
|
|
CanvasModeGrid* mode = (CanvasModeGrid*)Canvas::modes[(int)kCanvasMode::Grid][0];
|
|
mode->clear();
|
|
popup_exp->mouse_release();
|
|
popup_exp->destroy();
|
|
};
|
|
|
|
popup_exp->find<NodeButtonCustom>("camera-reset")->on_click = [this, popup_exp](Node*) {
|
|
canvas->reset_camera();
|
|
popup_exp->mouse_release();
|
|
popup_exp->destroy();
|
|
};
|
|
|
|
/*
|
|
popup_exp->find<NodeButtonCustom>("mp4test")->on_click = [this, popup_exp](Node*) {
|
|
dialog_export_mp4();
|
|
popup_exp->mouse_release();
|
|
popup_exp->destroy();
|
|
};
|
|
*/
|
|
|
|
#if __IOS__
|
|
popup_exp->find<NodeButtonCustom>("sonarpen")->on_click = [this, popup_exp](Node*) {
|
|
[ios_app sonarpen_start];
|
|
popup_exp->mouse_release();
|
|
popup_exp->destroy();
|
|
};
|
|
#endif
|
|
};
|
|
}
|
|
}
|
|
|
|
void App::init_menu_about()
|
|
{
|
|
if (auto* menu_file = layout[main_id]->find<NodeButtonCustom>("menu-about"))
|
|
{
|
|
menu_file->on_click = [=](Node*) {
|
|
glm::vec2 pos = menu_file->m_pos + glm::vec2(0, menu_file->m_size.y);
|
|
auto popup = layout[const_hash("about-menu")]->m_children[0]->clone<NodePopupMenu>();
|
|
popup->update();
|
|
if (YGNodeStyleGetDirection(layout[main_id]->y_node) == YGDirectionRTL)
|
|
pos.x = pos.x - popup->m_size.x + menu_file->m_size.x;
|
|
popup->SetPositioning(YGPositionTypeAbsolute);
|
|
popup->SetPosition(pos.x, pos.y);
|
|
layout[main_id]->add_child(popup);
|
|
|
|
popup->find<NodeButtonCustom>("about-app")->on_click = [this, popup](Node*) {
|
|
dialog_about();
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
};
|
|
|
|
popup->find<NodeButtonCustom>("about-doc")->on_click = [this, popup](Node*) {
|
|
// auto path = Asset::absolute("data/doc/test.pdf");
|
|
// display_file(path);
|
|
dialog_usermanual();
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
};
|
|
|
|
if (auto item = popup->find<NodeButtonCustom>("about-news"))
|
|
{
|
|
if (auto text = item->find<NodeText>("menu-label"))
|
|
{
|
|
static char label[128];
|
|
sprintf(label, "What's new in %d.%d.%d?", g_version_major, g_version_minor, g_version_fix);
|
|
text->set_text(label);
|
|
}
|
|
item->on_click = [this, popup](Node*) {
|
|
dialog_changelog();
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
};
|
|
}
|
|
|
|
if (auto b = popup->find<NodeButtonCustom>("about-crash"))
|
|
{
|
|
b->on_click = [this, popup](Node*) {
|
|
LOG("crashing");
|
|
crash_test();
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
};
|
|
}
|
|
|
|
if (auto b = popup->find<NodeButtonCustom>("about-perf"))
|
|
{
|
|
b->on_click = [this, popup](Node*) {
|
|
LOG("perf");
|
|
static char str[256];
|
|
render_task([&]
|
|
{
|
|
auto start = std::chrono::high_resolution_clock::now();
|
|
Canvas::I->stroke_start({ 0, 0, 0 }, 0.9f);
|
|
for (int i = 0; i < 100; i++)
|
|
{
|
|
Canvas::I->stroke_update({ 100, 100, 0 }, 0.9f);
|
|
Canvas::I->stroke_update({ 200, 200, 0 }, 0.9f);
|
|
Canvas::I->stroke_update({ 200, 100, 0 }, 0.9f);
|
|
Canvas::I->stroke_update({ 100, 200, 0 }, 0.9f);
|
|
Canvas::I->stroke_update({ 300, 300, 0 }, 0.9f);
|
|
Canvas::I->stroke_update({ 200, 500, 0 }, 0.9f);
|
|
Canvas::I->stroke_update({ 500, 500, 0 }, 0.9f);
|
|
Canvas::I->stroke_update({ 400, 400, 0 }, 0.9f);
|
|
Canvas::I->stroke_update({ 0, 200, 0 }, 0.9f);
|
|
Canvas::I->stroke_update({ 200, 0, 0 }, 0.9f);
|
|
Canvas::I->stroke_draw();
|
|
}
|
|
Canvas::I->stroke_end();
|
|
auto diff = std::chrono::high_resolution_clock::now() - start;
|
|
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(diff).count();
|
|
LOG("%lld ms", ms);
|
|
sprintf(str, "Time %lld ms", ms);
|
|
});
|
|
message_box("Performance test", str);
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
};
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
void App::brush_update(bool update_color, bool update_brush)
|
|
{
|
|
// brushes->select_brush(canvas->m_brush->id);
|
|
// stroke->set_params(canvas->m_brush);
|
|
render_task_async([this, update_color, update_brush]
|
|
{
|
|
if (update_brush)
|
|
{
|
|
stroke->update_controls();
|
|
quick->m_slider_flow->set_value(stroke->m_tip_flow->get_value());
|
|
quick->m_slider_size->set_value(stroke->m_tip_size->get_value());
|
|
*quick->m_button_brush_current_preview->m_brush = *Canvas::I->m_current_brush;
|
|
quick->m_button_brush_current_preview->draw_stroke();
|
|
}
|
|
if (update_color)
|
|
{
|
|
quick->m_button_color_current_inner->m_color = Canvas::I->m_current_brush->m_tip_color;
|
|
if (floating_picker)
|
|
floating_picker->set_color(Canvas::I->m_current_brush->m_tip_color);
|
|
if (floating_color)
|
|
floating_color->set_color(Canvas::I->m_current_brush->m_tip_color);
|
|
}
|
|
}, true);
|
|
}
|
|
|
|
void App::init_menu_layer()
|
|
{
|
|
if (auto* menu_file = layout[main_id]->find<NodeButtonCustom>("menu-layers"))
|
|
{
|
|
menu_file->on_click = [=](Node*) {
|
|
glm::vec2 pos = menu_file->m_pos + glm::vec2(0, menu_file->m_size.y);
|
|
auto popup = layout[const_hash("layers-menu")]->m_children[0]->clone<NodePopupMenu>();
|
|
popup->update();
|
|
if (YGNodeStyleGetDirection(layout[main_id]->y_node) == YGDirectionRTL)
|
|
pos.x = pos.x - popup->m_size.x + menu_file->m_size.x;
|
|
popup->SetPositioning(YGPositionTypeAbsolute);
|
|
popup->SetPosition(pos.x, pos.y);
|
|
layout[main_id]->add_child(popup);
|
|
|
|
popup->find<NodeButtonCustom>("layer-clear")->on_click = [this, popup](Node*) {
|
|
canvas->m_canvas->clear();
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
};
|
|
if (layers->m_current_layer)
|
|
popup->find<NodeButtonCustom>("layer-clear")->
|
|
find<NodeText>("menu-label")->
|
|
set_text(("Clear Layer " + layers->m_current_layer->m_label_text).c_str());
|
|
|
|
popup->find<NodeButtonCustom>("layer-rename")->on_click = [this, popup](Node*) {
|
|
dialog_layer_rename();
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
};
|
|
if (layers->m_current_layer)
|
|
popup->find<NodeButtonCustom>("layer-rename")->
|
|
find<NodeText>("menu-label")->
|
|
set_text(("Rename Layer " + layers->m_current_layer->m_label_text).c_str());
|
|
else
|
|
popup->find<NodeButtonCustom>("layer-rename")->
|
|
find<NodeText>("menu-label")->
|
|
set_text("Rename Layer (Select a layer)");
|
|
|
|
popup->find<NodeButtonCustom>("layer-merge")->on_click = [this, popup](Node*) {
|
|
//layers->get_child_index(layers->)
|
|
int current_idx_order = Canvas::I->m_current_layer_idx;
|
|
if (current_idx_order > 0)
|
|
{
|
|
layers->merge(current_idx_order, current_idx_order - 1, true);
|
|
}
|
|
popup->mouse_release();
|
|
popup->destroy();
|
|
};
|
|
if (layers->m_current_layer)
|
|
{
|
|
int current_idx_order = canvas->m_canvas->m_current_layer_idx;
|
|
if (current_idx_order > 0)
|
|
{
|
|
int down_layer_idx = current_idx_order - 1;
|
|
popup->find<NodeButtonCustom>("layer-merge")->
|
|
find<NodeText>("menu-label")->
|
|
set_text(("Merge with " + canvas->m_canvas->m_layers[down_layer_idx]->m_name).c_str());
|
|
}
|
|
else
|
|
{
|
|
popup->find<NodeButtonCustom>("layer-merge")->
|
|
find<NodeText>("menu-label")->
|
|
set_text("Merge Layer (Select upper layers)");
|
|
}
|
|
}
|
|
else
|
|
popup->find<NodeButtonCustom>("layer-merge")->
|
|
find<NodeText>("menu-label")->
|
|
set_text("Merge Layer (Select a layer)");
|
|
|
|
};
|
|
}
|
|
}
|
|
|
|
void App::initLayout()
|
|
{
|
|
LOG("initializing layout statics");
|
|
NodeBorder::static_init();
|
|
NodeImage::static_init();
|
|
NodeIcon::static_init();
|
|
NodeStrokePreview::static_init();
|
|
|
|
static std::vector<std::shared_ptr<Layer>> saved_layers;
|
|
layout.on_reloading = [&] {
|
|
saved_layers = std::move(Canvas::I->m_layers);
|
|
ui_save();
|
|
NodeStrokePreview::empty_queue();
|
|
};
|
|
|
|
layout.on_loaded = [&] (bool reloaded) {
|
|
LOG("initializing layout updating after load %d x %d zoom %f", (int)width, (int)height, zoom);
|
|
layout[main_id]->update(width, height, zoom);
|
|
|
|
LOG("initializing layout components");
|
|
|
|
init_sidebar();
|
|
|
|
if (reloaded)
|
|
{
|
|
for (const auto& l : saved_layers)
|
|
layers->add_layer(l->m_name.c_str(), false, true, l);
|
|
}
|
|
else
|
|
{
|
|
layers->add_layer("Default", false, true);
|
|
Canvas::I->m_unsaved = false;
|
|
Canvas::I->timelapse_reset_encoder();
|
|
}
|
|
|
|
init_toolbar_draw();
|
|
init_toolbar_main();
|
|
init_menu_file();
|
|
init_menu_edit();
|
|
init_menu_layer();
|
|
init_menu_tools();
|
|
init_menu_about();
|
|
|
|
// set version string
|
|
if (auto* version_label = layout[main_id]->find<NodeText>("version"))
|
|
{
|
|
version_label->set_text(g_version);
|
|
}
|
|
|
|
if (auto x = layout[main_id]->find<NodeBorder>("ext-fbf"))
|
|
{
|
|
x->m_color = ShaderManager::ext_framebuffer_fetch ? glm::vec4(0, 1, 0, 1) : glm::vec4(1, 0, 0, 1);
|
|
}
|
|
|
|
if (auto x = layout[main_id]->find<NodeBorder>("ext-flt"))
|
|
{
|
|
if (ShaderManager::ext_float32 || ShaderManager::ext_float16)
|
|
{
|
|
if (auto t = x->find<NodeText>("ext-flt-text"))
|
|
{
|
|
if (ShaderManager::ext_float32_linear)
|
|
t->set_text("F32L");
|
|
else if (ShaderManager::ext_float32)
|
|
t->set_text("F32");
|
|
else if (ShaderManager::ext_float16)
|
|
t->set_text("F16");
|
|
}
|
|
x->m_color = glm::vec4(0, 1, 0, 1);
|
|
}
|
|
else
|
|
{
|
|
x->m_color = glm::vec4(1, 0, 0, 1);
|
|
}
|
|
}
|
|
|
|
brush_update(true, true);
|
|
|
|
// hacky thing to make the toolbar buttons not steal events when moving cursor fast
|
|
if (auto* toolbar = layout[main_id]->find<Node>("toolbar"))
|
|
toolbar->m_flood_events = true;
|
|
|
|
NodeImage* n = new NodeImage;
|
|
n->m_path = "data/ui/p-black.png";
|
|
n->m_tex_id = const_hash("data/ui/p-black.png");
|
|
n->SetSize(30, 45);
|
|
n->create();
|
|
|
|
NodeButtonCustom* butt = new NodeButtonCustom;
|
|
butt->create();
|
|
butt->add_child(n);
|
|
butt->SetPositioning(YGPositionTypeAbsolute);
|
|
butt->set_color({ 0, 0, 0, 0 });
|
|
//n->SetPosition(100, 100);
|
|
YGNodeStyleSetPosition(butt->y_node, YGEdgeBottom, 8);
|
|
YGNodeStyleSetPosition(butt->y_node, YGEdgeLeft, 10);
|
|
//butt->SetSize(30, 45);
|
|
layout[main_id]->add_child(butt);
|
|
|
|
butt->on_click = [this](Node*){
|
|
toggle_ui();
|
|
};
|
|
|
|
ui_restore();
|
|
|
|
redraw = true;
|
|
};
|
|
|
|
LOG("initializing layout xml");
|
|
if (layout.m_loaded)
|
|
{
|
|
LOG("restore layout");
|
|
layout.restore_context();
|
|
}
|
|
else
|
|
layout.load("data/layout.xml");
|
|
LOG("initializing layout completed");
|
|
|
|
LOG("initializing layout designer xml");
|
|
layout_designer.on_loaded = [&](bool reloaded) {
|
|
layout_designer.create();
|
|
//layout_designer[main_id]->add_child(layout_designer.instantiate("tpl-panel-animation"));
|
|
auto p = layout_designer[main_id]->add_child<NodePanelFloating>();
|
|
p->SetPosition(300, 300);
|
|
p->SetSize(600, 400);
|
|
p->m_container->add_child<NodePanelAnimation>();
|
|
};
|
|
//layout_designer.load("data/dialogs/panel-animation.xml");
|
|
}
|
|
|
|
void App::set_ui_scale(float scale)
|
|
{
|
|
zoom = scale;
|
|
FontManager::change_scale(zoom * display_density);
|
|
Settings::set("ui-scale", Serializer::Float(zoom));
|
|
Settings::save();
|
|
App::I->title_update();
|
|
}
|
|
|
|
void App::set_ui_rtl(bool rtl)
|
|
{
|
|
ui_rtl = rtl;
|
|
layout[main_id]->find("central-row")->SetRTL(rtl ? YGDirectionRTL : YGDirectionLTR);
|
|
}
|
|
|
|
bool App::get_ui_rtl() const
|
|
{
|
|
return ui_rtl;
|
|
}
|
|
|
|
void App::ui_save()
|
|
{
|
|
Serializer::Descriptor d;
|
|
d.class_id = "ui-state";
|
|
|
|
Serializer::List list_floatings;
|
|
for (auto const& c : layout[main_id]->find("floatings")->m_children)
|
|
{
|
|
if (auto const& f = std::dynamic_pointer_cast<NodePanelFloating>(c))
|
|
{
|
|
auto fd = list_floatings.add<Serializer::Descriptor>();
|
|
fd->class_id = "ui-flt";
|
|
fd->set("pos", Serializer::Vec2(f->GetPosition()));
|
|
fd->set("size", Serializer::Vec2(f->m_size));
|
|
fd->set("class", Serializer::Integer((int)f->m_class));
|
|
fd->set("title", Serializer::CString(f->m_title->m_text));
|
|
}
|
|
}
|
|
d.set("floatings", list_floatings);
|
|
|
|
Serializer::List list_drop_left;
|
|
for (auto const& c : layout[main_id]->find("drop-left")->m_children)
|
|
{
|
|
if (auto const& f = std::dynamic_pointer_cast<NodePanelFloating>(c))
|
|
{
|
|
auto fd = list_drop_left.add<Serializer::Descriptor>();
|
|
fd->class_id = "ui-dpl";
|
|
fd->set("size", Serializer::Vec2(f->m_size));
|
|
fd->set("class", Serializer::Integer((int)f->m_class));
|
|
fd->set("title", Serializer::CString(f->m_title->m_text));
|
|
}
|
|
}
|
|
d.set("drop-left", list_drop_left);
|
|
|
|
Serializer::List list_drop_right;
|
|
for (auto const& c : layout[main_id]->find("drop-right")->m_children)
|
|
{
|
|
if (auto const& f = std::dynamic_pointer_cast<NodePanelFloating>(c))
|
|
{
|
|
auto fd = list_drop_right.add<Serializer::Descriptor>();
|
|
fd->class_id = "ui-dpr";
|
|
fd->set("size", Serializer::Vec2(f->m_size));
|
|
fd->set("class", Serializer::Integer((int)f->m_class));
|
|
fd->set("title", Serializer::CString(f->m_title->m_text));
|
|
}
|
|
}
|
|
d.set("drop-right", list_drop_right);
|
|
|
|
Settings::set("ui", d);
|
|
Settings::set("ui-rtl", Serializer::Boolean(ui_rtl));
|
|
|
|
#if _WIN32
|
|
extern void win32_save_window_state();
|
|
win32_save_window_state();
|
|
#elif __OSX__
|
|
[osx_app save_ui_state];
|
|
#endif
|
|
|
|
Settings::save();
|
|
}
|
|
|
|
void App::ui_restore()
|
|
{
|
|
if (Settings::has("ui-rtl"))
|
|
set_ui_rtl(Settings::value<Serializer::Integer>("ui-rtl"));
|
|
|
|
if (!Settings::has("ui"))
|
|
return;
|
|
|
|
auto floatings = layout[main_id]->find_ref("floatings");
|
|
auto drop_left = layout[main_id]->find_ref("drop-left");
|
|
auto drop_right = layout[main_id]->find_ref("drop-right");
|
|
auto d = Settings::get<Serializer::Descriptor>("ui");
|
|
for (auto const& l : d->get<Serializer::List>("floatings")->items)
|
|
{
|
|
auto ld = std::static_pointer_cast<Serializer::Descriptor>(l);
|
|
auto pos = ld->value<Serializer::Vec2>("pos");
|
|
auto size = ld->value<Serializer::Vec2>("size");
|
|
auto cls = static_cast<NodePanelFloating::kClass>(ld->value<Serializer::Integer>("class"));
|
|
auto f = floatings->add_child<NodePanelFloating>();
|
|
std::string title = "Floating Panel";
|
|
ld->value<Serializer::CString>("title", title);
|
|
f->m_title->set_text(title.c_str());
|
|
switch (cls)
|
|
{
|
|
case NodePanelFloating::kClass::Presets:
|
|
{
|
|
floating_presets = f->m_container->add_child_ref<NodePanelBrushPreset>();
|
|
floating_presets->SetHeightP(100);
|
|
//floating_presets->find("toolbar")->destroy();
|
|
floating_presets->on_brush_changed = [this](Node* target, std::shared_ptr<Brush>& b) {
|
|
auto c = Canvas::I->m_current_brush->m_tip_color;
|
|
*Canvas::I->m_current_brush = *b;
|
|
Canvas::I->m_current_brush->m_tip_color = c;
|
|
Canvas::I->m_current_brush->load();
|
|
brush_update(true, true);
|
|
};
|
|
break;
|
|
}
|
|
case NodePanelFloating::kClass::Color:
|
|
{
|
|
floating_color = f->m_container->add_child_ref<NodePanelColor>();
|
|
floating_color->SetHeightP(100);
|
|
floating_color->find("title")->SetVisibility(false);
|
|
floating_color->on_color_changed = [this](Node* target, glm::vec4 color) {
|
|
Canvas::I->m_current_brush->m_tip_color = color;
|
|
brush_update(true, false);
|
|
};
|
|
break;
|
|
}
|
|
case NodePanelFloating::kClass::ColorAdv:
|
|
{
|
|
floating_picker = f->m_container->add_child_ref<NodeColorPicker>();
|
|
floating_picker->m_autohide = false;
|
|
floating_picker->on_color_change = [this](Node* target, glm::vec3 color) {
|
|
Canvas::I->m_current_brush->m_tip_color = glm::vec4(color, 1.f);
|
|
brush_update(true, false);
|
|
};
|
|
break;
|
|
}
|
|
case NodePanelFloating::kClass::Layers:
|
|
f->m_container->add_child(layers);
|
|
f->SetMinHeight(100);
|
|
f->SetHeight(300);
|
|
layers->find("title")->SetVisibility(false);
|
|
layers->SetPositioning(YGPositionTypeRelative);
|
|
layers->SetPosition(0, 0);
|
|
layers->SetWidthP(100);
|
|
layers->SetHeightP(100);
|
|
layers->SetFlexShrink(0);
|
|
break;
|
|
case NodePanelFloating::kClass::Brush:
|
|
f->m_container->add_child(stroke);
|
|
stroke->find("title")->SetVisibility(false);
|
|
stroke->SetPositioning(YGPositionTypeRelative);
|
|
stroke->SetPosition(0, 0);
|
|
stroke->SetWidthP(100);
|
|
stroke->SetHeightP(100);
|
|
break;
|
|
case NodePanelFloating::kClass::Grids:
|
|
f->m_container->add_child(grid);
|
|
grid->find("title")->SetVisibility(false);
|
|
grid->SetPositioning(YGPositionTypeRelative);
|
|
grid->SetPosition(0, 0);
|
|
grid->SetWidthP(100);
|
|
grid->SetHeightP(100);
|
|
break;
|
|
case NodePanelFloating::kClass::Animation:
|
|
f->m_container->add_child(animation);
|
|
f->m_droppable = false;
|
|
//grid->find("title")->SetVisibility(false);
|
|
animation->SetPositioning(YGPositionTypeRelative);
|
|
animation->SetPosition(0, 0);
|
|
animation->SetWidthP(100);
|
|
animation->SetHeightP(100);
|
|
break;
|
|
case NodePanelFloating::kClass::Generic:
|
|
default:
|
|
f->m_container->add_child<Node>();
|
|
break;
|
|
}
|
|
f->m_class = cls;
|
|
f->SetSize(size);
|
|
f->SetPosition(pos);
|
|
f->SetPositioning(YGPositionTypeAbsolute);
|
|
}
|
|
|
|
for (auto const& l : d->get<Serializer::List>("drop-left")->items)
|
|
{
|
|
auto ld = std::static_pointer_cast<Serializer::Descriptor>(l);
|
|
auto size = ld->value<Serializer::Vec2>("size");
|
|
auto cls = static_cast<NodePanelFloating::kClass>(ld->value<Serializer::Integer>("class"));
|
|
auto f = drop_left->add_child<NodePanelFloating>();
|
|
std::string title = "Floating Panel";
|
|
ld->value<Serializer::CString>("title", title);
|
|
f->m_title->set_text(title.c_str());
|
|
switch (cls)
|
|
{
|
|
case NodePanelFloating::kClass::Presets:
|
|
{
|
|
auto floating_presets = f->m_container->add_child<NodePanelBrushPreset>();
|
|
floating_presets->SetHeightP(100);
|
|
//floating_presets->find("toolbar")->destroy();
|
|
floating_presets->on_brush_changed = [this](Node* target, std::shared_ptr<Brush>& b) {
|
|
auto c = Canvas::I->m_current_brush->m_tip_color;
|
|
*Canvas::I->m_current_brush = *b;
|
|
Canvas::I->m_current_brush->m_tip_color = c;
|
|
Canvas::I->m_current_brush->load();
|
|
brush_update(true, true);
|
|
};
|
|
break;
|
|
}
|
|
case NodePanelFloating::kClass::Color:
|
|
{
|
|
auto floating_color = f->m_container->add_child<NodePanelColor>();
|
|
floating_color->SetHeightP(100);
|
|
floating_color->find("title")->destroy();
|
|
floating_color->on_color_changed = [this](Node* target, glm::vec4 color) {
|
|
Canvas::I->m_current_brush->m_tip_color = color;
|
|
brush_update(true, false);
|
|
};
|
|
break;
|
|
}
|
|
case NodePanelFloating::kClass::ColorAdv:
|
|
{
|
|
floating_picker = f->m_container->add_child_ref<NodeColorPicker>();
|
|
floating_picker->m_autohide = false;
|
|
floating_picker->on_color_change = [this](Node* target, glm::vec3 color) {
|
|
Canvas::I->m_current_brush->m_tip_color = glm::vec4(color, 1.f);
|
|
brush_update(true, false);
|
|
};
|
|
break;
|
|
}
|
|
case NodePanelFloating::kClass::Layers:
|
|
f->m_container->add_child(layers);
|
|
layers->SetPositioning(YGPositionTypeRelative);
|
|
layers->SetPosition(0, 0);
|
|
layers->SetWidthP(100);
|
|
layers->SetHeightP(100);
|
|
layers->SetFlexShrink(0);
|
|
break;
|
|
case NodePanelFloating::kClass::Brush:
|
|
f->m_container->add_child(stroke);
|
|
stroke->SetPositioning(YGPositionTypeRelative);
|
|
stroke->SetPosition(0, 0);
|
|
stroke->SetWidthP(100);
|
|
stroke->SetHeightP(100);
|
|
break;
|
|
case NodePanelFloating::kClass::Grids:
|
|
f->m_container->add_child(grid);
|
|
grid->SetPositioning(YGPositionTypeRelative);
|
|
grid->SetPosition(0, 0);
|
|
grid->SetWidthP(100);
|
|
grid->SetHeightP(100);
|
|
break;
|
|
case NodePanelFloating::kClass::Generic:
|
|
default:
|
|
f->m_container->add_child<Node>();
|
|
break;
|
|
}
|
|
f->m_class = cls;
|
|
f->m_dock = drop_left;
|
|
f->SetPositioning(YGPositionTypeRelative);
|
|
f->SetPosition(0, 0);
|
|
f->SetSize(size);
|
|
}
|
|
|
|
for (auto const& l : d->get<Serializer::List>("drop-right")->items)
|
|
{
|
|
auto ld = std::static_pointer_cast<Serializer::Descriptor>(l);
|
|
auto size = ld->value<Serializer::Vec2>("size");
|
|
auto cls = static_cast<NodePanelFloating::kClass>(ld->value<Serializer::Integer>("class"));
|
|
auto f = drop_right->add_child<NodePanelFloating>();
|
|
std::string title = "Floating Panel";
|
|
ld->value<Serializer::CString>("title", title);
|
|
f->m_title->set_text(title.c_str());
|
|
switch (cls)
|
|
{
|
|
case NodePanelFloating::kClass::Presets:
|
|
{
|
|
auto floating_presets = f->m_container->add_child<NodePanelBrushPreset>();
|
|
floating_presets->SetHeightP(100);
|
|
//floating_presets->find("toolbar")->destroy();
|
|
floating_presets->on_brush_changed = [this](Node* target, std::shared_ptr<Brush>& b) {
|
|
auto c = Canvas::I->m_current_brush->m_tip_color;
|
|
*Canvas::I->m_current_brush = *b;
|
|
Canvas::I->m_current_brush->m_tip_color = c;
|
|
Canvas::I->m_current_brush->load();
|
|
brush_update(true, true);
|
|
};
|
|
break;
|
|
}
|
|
case NodePanelFloating::kClass::Color:
|
|
{
|
|
auto floating_color = f->m_container->add_child<NodePanelColor>();
|
|
floating_color->SetHeightP(100);
|
|
floating_color->find("title")->destroy();
|
|
floating_color->on_color_changed = [this](Node* target, glm::vec4 color) {
|
|
Canvas::I->m_current_brush->m_tip_color = color;
|
|
brush_update(true, false);
|
|
};
|
|
break;
|
|
}
|
|
case NodePanelFloating::kClass::ColorAdv:
|
|
{
|
|
floating_picker = f->m_container->add_child_ref<NodeColorPicker>();
|
|
floating_picker->m_autohide = false;
|
|
floating_picker->on_color_change = [this](Node* target, glm::vec3 color) {
|
|
Canvas::I->m_current_brush->m_tip_color = glm::vec4(color, 1.f);
|
|
brush_update(true, false);
|
|
};
|
|
break;
|
|
}
|
|
case NodePanelFloating::kClass::Layers:
|
|
f->m_container->add_child(layers);
|
|
layers->SetPositioning(YGPositionTypeRelative);
|
|
layers->SetPosition(0, 0);
|
|
layers->SetWidthP(100);
|
|
layers->SetHeightP(100);
|
|
layers->SetFlexShrink(0);
|
|
break;
|
|
case NodePanelFloating::kClass::Brush:
|
|
f->m_container->add_child(stroke);
|
|
stroke->SetPositioning(YGPositionTypeRelative);
|
|
stroke->SetPosition(0, 0);
|
|
stroke->SetWidthP(100);
|
|
stroke->SetHeightP(100);
|
|
break;
|
|
case NodePanelFloating::kClass::Grids:
|
|
f->m_container->add_child(grid);
|
|
grid->SetPositioning(YGPositionTypeRelative);
|
|
grid->SetPosition(0, 0);
|
|
grid->SetWidthP(100);
|
|
grid->SetHeightP(100);
|
|
break;
|
|
case NodePanelFloating::kClass::Generic:
|
|
default:
|
|
f->m_container->add_child<Node>();
|
|
break;
|
|
}
|
|
f->m_class = cls;
|
|
f->m_dock = drop_right;
|
|
f->SetPositioning(YGPositionTypeRelative);
|
|
f->SetPosition(0, 0);
|
|
f->SetSize(size);
|
|
}
|
|
}
|