208 lines
7.3 KiB
C++
208 lines
7.3 KiB
C++
#include "pch.h"
|
|
|
|
#include "legacy_quick_ui_services.h"
|
|
|
|
#include "app.h"
|
|
#include "node_image.h"
|
|
#include "node_stroke_preview.h"
|
|
|
|
namespace pp::panopainter {
|
|
namespace {
|
|
|
|
class LegacyQuickUiServices final : public pp::app::QuickUiServices {
|
|
public:
|
|
LegacyQuickUiServices(NodePanelQuick& panel, const NodePanelQuick::MiniState* restore_state = nullptr) noexcept
|
|
: panel_(panel)
|
|
, restore_state_(restore_state)
|
|
{
|
|
}
|
|
|
|
void select_slot(pp::app::QuickUiSlotKind slot_kind, int slot_index, bool fire_event) override
|
|
{
|
|
if (slot_kind == pp::app::QuickUiSlotKind::brush) {
|
|
panel_.set_selected_brush_index(slot_index, fire_event);
|
|
return;
|
|
}
|
|
|
|
panel_.set_selected_color_index(slot_index, fire_event);
|
|
}
|
|
|
|
void open_slot_popup(pp::app::QuickUiSlotKind slot_kind, int slot_index) override
|
|
{
|
|
if (slot_kind == pp::app::QuickUiSlotKind::brush) {
|
|
open_brush_popup(slot_index);
|
|
return;
|
|
}
|
|
|
|
open_color_picker(slot_index);
|
|
}
|
|
|
|
void restore_state(int brush_index, int color_index, bool fire_event) override
|
|
{
|
|
if (!restore_state_)
|
|
return;
|
|
|
|
for (int i = 0; i < static_cast<int>(panel_.m_button_brushes.size()); i++)
|
|
{
|
|
auto b = static_cast<NodeStrokePreview*>(panel_.m_button_brushes[i]->m_children[0].get());
|
|
b->m_brush = restore_state_->brushes[i];
|
|
b->draw_stroke();
|
|
auto c = static_cast<NodeBorder*>(panel_.m_button_colors[i]->m_children[0].get());
|
|
c->m_color = restore_state_->colors[i];
|
|
}
|
|
panel_.set_selected_color_index(color_index, fire_event);
|
|
panel_.set_selected_brush_index(brush_index, fire_event);
|
|
}
|
|
|
|
void reset_state(bool fire_event) override
|
|
{
|
|
for (int i = 0; i < static_cast<int>(panel_.m_button_brushes.size()); i++)
|
|
{
|
|
auto b = static_cast<NodeStrokePreview*>(panel_.m_button_brushes[i]->m_children[0].get());
|
|
b->m_brush = std::make_shared<Brush>();
|
|
b->m_brush->load_tip("data/brushes/Round-Hard.png", "data/brushes/thumbs/Round-Hard.png");
|
|
b->draw_stroke();
|
|
}
|
|
static_cast<NodeBorder*>(panel_.m_button_colors[0]->m_children[0].get())->m_color = glm::vec4(0, 0, 0, 1);
|
|
static_cast<NodeBorder*>(panel_.m_button_colors[1]->m_children[0].get())->m_color = glm::vec4(.5, .5, .5, 1);
|
|
static_cast<NodeBorder*>(panel_.m_button_colors[2]->m_children[0].get())->m_color = glm::vec4(1, 1, 1, 1);
|
|
panel_.set_selected_brush_index(0, fire_event);
|
|
panel_.set_selected_color_index(0, fire_event);
|
|
}
|
|
|
|
private:
|
|
void open_brush_popup(int slot_index)
|
|
{
|
|
auto button = panel_.m_button_brushes[slot_index];
|
|
if (!button)
|
|
return;
|
|
|
|
auto popup = App::I->presets;
|
|
auto screen = panel_.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 = panel_.root()->add_child<NodeImage>();
|
|
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->SetWidth(350);
|
|
popup->SetHeight(glm::max(hh, 400.f));
|
|
popup->SetPositioning(YGPositionTypeAbsolute);
|
|
popup->SetPosition(popup_pos);
|
|
panel_.root()->add_child(popup);
|
|
|
|
panel_.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 = [tick](Node*) {
|
|
tick->destroy();
|
|
};
|
|
|
|
auto* panel = &panel_;
|
|
popup->on_brush_changed = [panel, button](Node*, 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 (panel->on_brush_change)
|
|
panel->on_brush_change(button, pr->m_brush);
|
|
};
|
|
}
|
|
|
|
void open_color_picker(int slot_index)
|
|
{
|
|
auto target = panel_.m_button_colors[slot_index];
|
|
if (!target)
|
|
return;
|
|
|
|
auto popup = panel_.m_picker;
|
|
auto screen = panel_.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 = panel_.root()->add_child<NodeImage>();
|
|
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 };
|
|
|
|
popup->SetPositioning(YGPositionTypeAbsolute);
|
|
popup->SetPosition(popup_pos);
|
|
panel_.root()->add_child(popup);
|
|
|
|
panel_.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<NodeBorder*>(target->m_children[0].get());
|
|
panel_.m_picker->set_color(c->m_color);
|
|
panel_.m_picker->on_popup_close = [tick](Node*) {
|
|
tick->destroy();
|
|
};
|
|
|
|
auto* panel = &panel_;
|
|
panel_.m_picker->on_color_change = [panel, c](Node*, glm::vec3 rgb) {
|
|
c->m_color = glm::vec4(rgb, 1.f);
|
|
if (panel->on_color_change)
|
|
panel->on_color_change(panel, rgb);
|
|
};
|
|
}
|
|
|
|
NodePanelQuick& panel_;
|
|
const NodePanelQuick::MiniState* restore_state_ = nullptr;
|
|
};
|
|
|
|
} // namespace
|
|
|
|
pp::foundation::Status execute_legacy_quick_ui_plan(
|
|
NodePanelQuick& panel,
|
|
const pp::app::QuickUiPlan& plan,
|
|
const NodePanelQuick::MiniState* restore_state)
|
|
{
|
|
LegacyQuickUiServices services(panel, restore_state);
|
|
return pp::app::execute_quick_ui_plan(plan, services);
|
|
}
|
|
|
|
} // namespace pp::panopainter
|