#include "pch.h" #include "node_panel_quick.h" #include "node_stroke_preview.h" #include "node_image.h" #include "app.h" Node* NodePanelQuick::clone_instantiate() const { return new this_class; } void NodePanelQuick::clone_finalize(Node* dest) const { parent::clone_finalize(dest); auto n = static_cast(dest); n->init_controls(); } void NodePanelQuick::init() { parent::init(); init_template("tpl-panel-quick"); init_controls(); } void NodePanelQuick::set_color(glm::vec3 color) { m_button_color_current_inner->m_color = glm::vec4(color, 1.f); } int NodePanelQuick::get_selected_brush_index() const { auto it = std::find(m_button_brushes.begin(), m_button_brushes.end(), m_button_brush_current); return std::distance(m_button_brushes.begin(), it); } void NodePanelQuick::set_selected_brush_index(int idx, bool fire_event /*= false*/) { if (m_button_brush_current) m_button_brush_current->set_active(false); m_button_brush_current = m_button_brushes[idx]; m_button_brush_current->set_active(true); m_button_brush_current_preview = static_cast(m_button_brush_current->m_children[0].get()); if (fire_event && on_brush_change) on_brush_change(this, m_button_brush_current_preview->m_brush); } int NodePanelQuick::get_selected_color_index() const { auto it = std::find(m_button_colors.begin(), m_button_colors.end(), m_button_color_current); return std::distance(m_button_colors.begin(), it); } void NodePanelQuick::set_selected_color_index(int idx, bool fire_event /*= false*/) { if (m_button_color_current) m_button_color_current->set_active(false); m_button_color_current = m_button_colors[idx]; m_button_color_current->set_active(true); m_button_color_current_inner = static_cast(m_button_color_current->m_children[0].get()); if (fire_event && on_color_change) on_color_change(this, m_button_color_current_inner->m_color); } NodePanelQuick::MiniState NodePanelQuick::get_state() const { MiniState s; s.brush_index = get_selected_brush_index(); s.color_index = get_selected_color_index(); for (int i = 0; i < 3; i++) { s.brushes[i] = static_cast(m_button_brushes[i]->m_children[0].get())->m_brush; s.colors[i] = static_cast(m_button_colors[i]->m_children[0].get())->m_color; } return s; } void NodePanelQuick::set_state(const MiniState& state, bool fire_event /*= false*/) { for (int i = 0; i < 3; i++) { auto b = static_cast(m_button_brushes[i]->m_children[0].get()); b->m_brush = state.brushes[i]; b->draw_stroke(); auto c = static_cast(m_button_colors[i]->m_children[0].get()); c->m_color = state.colors[i]; } set_selected_color_index(state.color_index, fire_event); set_selected_brush_index(state.brush_index, fire_event); } void NodePanelQuick::reset_state(bool fire_event /*= false*/) { for (int i = 0; i < 3; i++) { auto b = static_cast(m_button_brushes[i]->m_children[0].get()); b->m_brush = std::make_shared(); b->m_brush->load_tip("data/brushes/Round-Hard.png", "data/brushes/thumbs/Round-Hard.png"); b->draw_stroke(); } static_cast(m_button_colors[0]->m_children[0].get())->m_color = glm::vec4(0, 0, 0, 1); static_cast(m_button_colors[1]->m_children[0].get())->m_color = glm::vec4(.5, .5, .5, 1); static_cast(m_button_colors[2]->m_children[0].get())->m_color = glm::vec4(1, 1, 1, 1); set_selected_brush_index(0, fire_event); set_selected_color_index(0, fire_event); } void NodePanelQuick::init_controls() { m_picker = std::make_shared(); m_picker->m_manager = m_manager; m_picker->init(); m_picker->create(); m_picker->loaded(); m_picker->m_mouse_ignore = false; m_picker->m_flood_events = true; m_picker->m_capture_children = false; m_picker->SetWidth(300); m_slider_size = find("quick-size"); m_slider_size->on_value_changed = [this](Node* target, float value) { float off = App::I.ui_rtl ? -100.f : 100.f; auto newpos = (m_slider_flow->m_pos + glm::vec2(off, m_slider_flow->m_size.y / 2.f)) * App::I.zoom; if (auto m = dynamic_cast(Canvas::I->modes[(int)Canvas::I->m_current_mode][0])) { m->m_cur_pos = newpos; m->m_draw_tip = true; m->m_draw_outline = false; } if (auto m = dynamic_cast(Canvas::I->modes[(int)Canvas::I->m_current_mode][0])) { m->m_cur_pos = newpos; m->m_draw_tip = true; } m_button_brush_current_preview->draw_stroke(); if (on_size_change) on_size_change(target, value); }; m_slider_flow = find("quick-flow"); m_slider_flow->on_value_changed = [this](Node* target, float value) { float off = App::I.ui_rtl ? -100.f : 100.f; auto newpos = (m_slider_flow->m_pos + glm::vec2(off, m_slider_flow->m_size.y / 2.f)) * App::I.zoom; if (auto m = dynamic_cast(Canvas::I->modes[(int)Canvas::I->m_current_mode][0])) { m->m_cur_pos = newpos; m->m_draw_tip = true; m->m_draw_outline = false; } if (auto m = dynamic_cast(Canvas::I->modes[(int)Canvas::I->m_current_mode][0])) { m->m_cur_pos = newpos; m->m_draw_tip = true; } m_button_brush_current_preview->draw_stroke(); if (on_flow_change) on_flow_change(target, value); }; for (int i = 0; i < m_button_colors.size(); i++) { m_button_colors[i] = find(fmt::format("quick-color{}", i + 1).c_str()); m_button_colors[i]->on_click = std::bind(&this_class::handle_button_color_click, this, std::placeholders::_1); m_button_colors[i]->color_active = { 0, 0, 0, 0.5f }; m_button_colors[i]->set_color({ 0, 0, 0, 0 }); } m_button_color_current = m_button_colors[0]; m_button_color_current->set_active(true); m_button_color_current_inner = static_cast(m_button_color_current->m_children[0].get()); for (int i = 0; i < m_button_brushes.size(); i++) m_button_brushes[i] = init_button_brush(fmt::format("quick-brush{}", i + 1)); m_button_brush_current = m_button_brushes[0]; m_button_brush_current->set_active(true); m_button_brush_current_preview = static_cast(m_button_brush_current->m_children[0].get()); } NodeButtonCustom* NodePanelQuick::init_button_brush(const std::string& name) { auto button = find(name.c_str()); button->on_click = std::bind(&this_class::handle_button_brush_click, this, std::placeholders::_1); auto pr = static_cast(button->m_children[0].get()); pr->m_brush = std::make_shared();; pr->m_brush->load_tip("data/brushes/Round-Hard.png", "data/brushes/thumbs/Round-Hard.png"); pr->m_max_size = 20; pr->m_pad_override = 0; pr->m_draw_first = true; 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(button); b->set_active(true); m_button_brush_current->set_active(false); m_button_brush_current = b; m_button_brush_current_preview = static_cast(button->m_children[0].get()); if (on_brush_change) on_brush_change(this, m_button_brush_current_preview->m_brush); return; } // if the box is already selected show the popup auto popup = App::I.presets; auto screen = root()->m_size; glm::vec2 tick_sz = { 16, 32 }; glm::vec2 tick_pos = button->m_pos + glm::vec2(button->m_size.x, 0); glm::vec2 popup_pos = { tick_pos.x + tick_sz.x, tick_pos.y }; auto tick = root()->add_child(); tick->SetPositioning(YGPositionTypeAbsolute); tick->SetPosition(tick_pos.x, tick_pos.y + (button->m_size.y - tick_sz.y) * 0.5f); tick->SetSize(tick_sz); tick->set_image("data/ui/popup-tick.png"); tick->m_scale = { 1, 1 }; float hh = popup->m_container->m_children.size() > 10 ? (screen.y - 90.f) : 400.f; popup->SetHeight(glm::max(hh, 400.f)); popup->SetPositioning(YGPositionTypeAbsolute); popup->SetPosition(popup_pos); root()->add_child(popup); root()->update(); popup->tick(0); popup->update(); if (tick_pos.x + popup->m_size.x > screen.x) { tick_pos = button->m_pos - glm::vec2(tick_sz.x, 0); popup_pos = { tick_pos.x - popup->GetWidth(), tick_pos.y }; tick->m_scale.x = -1.f; } popup_pos = glm::clamp(popup_pos, { 0, 0 }, screen - popup->m_size); popup->SetPosition(popup_pos); tick->SetPosition(tick_pos.x, tick_pos.y + (button->m_size.y - tick_sz.y) * 0.5f); popup->update(); popup->m_mouse_ignore = false; popup->m_flood_events = true; popup->m_capture_children = false; popup->mouse_capture(); popup->on_popup_close = [this, tick](Node*) { tick->destroy(); }; popup->on_brush_changed = [this, button](Node* target, std::shared_ptr& b) { auto pr = static_cast(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) { // the first time select the box if (m_button_color_current != target) { auto button = static_cast(target); button->set_active(true); m_button_color_current->set_active(false); m_button_color_current = button; m_button_color_current_inner = static_cast(m_button_color_current->m_children[0].get()); if (on_color_change) on_color_change(this, m_button_color_current_inner->m_color); return; } // if the box is already selected show the popup auto popup = m_picker; auto screen = root()->m_size; glm::vec2 tick_sz = { 16, 32 }; glm::vec2 tick_pos = target->m_pos + glm::vec2(target->m_size.x, 0); glm::vec2 popup_pos = { tick_pos.x + tick_sz.x, tick_pos.y - 140.f }; auto tick = root()->add_child(); tick->SetPositioning(YGPositionTypeAbsolute); tick->SetPosition(tick_pos.x, tick_pos.y + (target->m_size.y - tick_sz.y) * 0.5f); tick->SetSize(tick_sz); tick->set_image("data/ui/popup-tick.png"); tick->m_scale = { 1, 1 }; //float hh = popup->m_container->m_children.size() > 10 ? (screen.y / App::I.zoom - 90.f) : 400.f; //popup->SetHeight(glm::max(hh, 400.f)); popup->SetPositioning(YGPositionTypeAbsolute); popup->SetPosition(popup_pos); root()->add_child(popup); root()->update(); popup->tick(0); popup->update(); if (tick_pos.x + popup->m_size.x > screen.x) { tick_pos = target->m_pos - glm::vec2(tick_sz.x, 0); popup_pos = { tick_pos.x - popup->GetWidth(), tick_pos.y - 140.f }; tick->m_scale.x = -1.f; } popup_pos = glm::clamp(popup_pos, { 0, 0 }, screen - popup->m_size); popup->SetPosition(popup_pos); tick->SetPosition(tick_pos.x, tick_pos.y + (target->m_size.y - tick_sz.y) * 0.5f); popup->update(); popup->m_mouse_ignore = false; popup->m_flood_events = true; popup->m_capture_children = false; popup->mouse_capture(); auto c = static_cast(target->m_children[0].get()); m_picker->set_color(c->m_color); m_picker->on_popup_close = [this, tick](Node*) { tick->destroy(); }; m_picker->on_color_change = [this, c](Node*, glm::vec3 rgb) { c->m_color = glm::vec4(rgb, 1.f); if (on_color_change) on_color_change(this, rgb); }; }