Centralize quick and grid UI bridges

This commit is contained in:
2026-06-04 12:43:00 +02:00
parent bd2ee54617
commit 65e9fdf1b9
12 changed files with 574 additions and 252 deletions

View File

@@ -35,6 +35,17 @@ struct GridUiPlan {
bool mutates_grid_state = false;
};
class GridUiServices {
public:
virtual ~GridUiServices() = default;
virtual void request_heightmap_pick() = 0;
virtual pp::foundation::Status load_heightmap(std::string_view path, bool raise_ground_opacity) = 0;
virtual void clear_heightmap(bool updates_preview) = 0;
virtual void render_lightmap(bool shows_unsupported_message, bool renders_lightmap) = 0;
virtual void commit_heightmap(bool updates_ground_opacity) = 0;
};
[[nodiscard]] inline pp::foundation::Status validate_grid_texture_resolution(int texture_resolution) noexcept
{
if (texture_resolution <= 0 || texture_resolution > 16384) {
@@ -142,4 +153,57 @@ struct GridUiPlan {
return plan;
}
[[nodiscard]] inline pp::foundation::Status execute_grid_ui_plan(
const GridUiPlan& plan,
GridUiServices& services)
{
switch (plan.operation) {
case GridUiOperation::request_heightmap_pick:
if (!plan.opens_picker) {
return pp::foundation::Status::invalid_argument("grid heightmap pick plan must open a picker");
}
services.request_heightmap_pick();
return pp::foundation::Status::success();
case GridUiOperation::load_heightmap:
case GridUiOperation::reload_heightmap:
if (!plan.loads_heightmap || plan.path.empty()) {
return pp::foundation::Status::invalid_argument("grid heightmap load plan must provide a path");
}
return services.load_heightmap(plan.path, plan.updates_ground_opacity);
case GridUiOperation::clear_heightmap:
if (!plan.clears_heightmap) {
return pp::foundation::Status::invalid_argument("grid heightmap clear plan must clear heightmap state");
}
services.clear_heightmap(plan.updates_preview);
return pp::foundation::Status::success();
case GridUiOperation::render_lightmap:
{
const auto texture_status = validate_grid_texture_resolution(plan.texture_resolution);
if (!texture_status.ok()) {
return texture_status;
}
const auto sample_status = validate_grid_lightmap_samples(plan.sample_count);
if (!sample_status.ok()) {
return sample_status;
}
if (!plan.shows_unsupported_message && !plan.renders_lightmap) {
return pp::foundation::Status::success();
}
services.render_lightmap(plan.shows_unsupported_message, plan.renders_lightmap);
return pp::foundation::Status::success();
}
case GridUiOperation::commit_heightmap:
if (plan.commits_heightmap) {
services.commit_heightmap(plan.updates_ground_opacity);
}
return pp::foundation::Status::success();
}
return pp::foundation::Status::invalid_argument("unknown grid UI operation");
}
} // namespace pp::app

View File

@@ -0,0 +1,101 @@
#include "pch.h"
#include "legacy_grid_ui_services.h"
#include "app.h"
#include "canvas.h"
#include "image.h"
#include "node_panel_grid.h"
namespace pp::panopainter {
namespace {
class LegacyGridUiServices final : public pp::app::GridUiServices {
public:
explicit LegacyGridUiServices(NodePanelGrid& panel) noexcept
: panel_(panel)
{
}
void request_heightmap_pick() override
{
auto* panel = &panel_;
App::I->pick_image([panel](std::string path) {
panel->load_heightmap_file(path, true);
});
}
pp::foundation::Status load_heightmap(std::string_view path, bool raise_ground_opacity) override
{
Image img;
if (!img.load_file(std::string(path)))
return pp::foundation::Status::invalid_argument("heightmap image could not be loaded");
panel_.m_file_path = std::string(path);
panel_.m_hm_image = img.resize(128, 128);
panel_.m_hm_preview->tex = std::make_shared<Texture2D>();
panel_.m_hm_preview->tex->create(panel_.m_hm_image);
panel_.m_hm_preview->tex->create_mipmaps();
auto sz = panel_.m_hm_preview->tex->size();
panel_.m_hm_preview->SetAspectRatio(sz.x / sz.y);
panel_.m_hm_plane.create(1, 1, panel_.m_hm_image, panel_.get_resolution(), panel_.get_height());
panel_.m_hm_preview->SetHeight(100);
if (raise_ground_opacity && panel_.m_groud_opacity->get_value() == 0.f)
panel_.m_groud_opacity->set_value(1.f);
panel_.m_rt_dirty = true;
return pp::foundation::Status::success();
}
void clear_heightmap(bool updates_preview) override
{
panel_.m_hm_plane.create(1, 1, 100 * panel_.get_resolution());
panel_.m_hm_image.destroy();
panel_.m_hm_preview->tex.reset();
panel_.m_hm_preview->SetHeight(0);
}
void render_lightmap(bool shows_unsupported_message, bool renders_lightmap) override
{
if (shows_unsupported_message)
{
App::I->message_box("Rendering failed",
"Your hardware does not support lightmap rendering.");
return;
}
if (!renders_lightmap)
return;
auto* panel = &panel_;
std::thread([panel] {
BT_SetTerminate();
panel->bake_uvs();
panel->m_hm_shading->set_index(3);
panel->m_shade_mode = NodePanelGrid::ShadeMode::Textured;
}).detach();
}
void commit_heightmap(bool updates_ground_opacity) override
{
Canvas::I->draw_objects([this](const glm::mat4& camera, const glm::mat4& proj, int i) {
panel_.draw_heightmap(proj, camera, true);
}, Canvas::I->layer().m_frame_index, true);
if (updates_ground_opacity)
panel_.m_groud_opacity->set_value(0);
}
private:
NodePanelGrid& panel_;
};
} // namespace
pp::foundation::Status execute_legacy_grid_ui_plan(
NodePanelGrid& panel,
const pp::app::GridUiPlan& plan)
{
LegacyGridUiServices services(panel);
return pp::app::execute_grid_ui_plan(plan, services);
}
} // namespace pp::panopainter

View File

@@ -0,0 +1,14 @@
#pragma once
#include "app_core/grid_ui.h"
#include "foundation/result.h"
class NodePanelGrid;
namespace pp::panopainter {
[[nodiscard]] pp::foundation::Status execute_legacy_grid_ui_plan(
NodePanelGrid& panel,
const pp::app::GridUiPlan& plan);
} // namespace pp::panopainter

View File

@@ -0,0 +1,207 @@
#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

View File

@@ -0,0 +1,14 @@
#pragma once
#include "app_core/quick_ui.h"
#include "foundation/result.h"
#include "node_panel_quick.h"
namespace pp::panopainter {
[[nodiscard]] pp::foundation::Status execute_legacy_quick_ui_plan(
NodePanelQuick& panel,
const pp::app::QuickUiPlan& plan,
const NodePanelQuick::MiniState* restore_state = nullptr);
} // namespace pp::panopainter

View File

@@ -1,5 +1,6 @@
#include "pch.h"
#include "app_core/grid_ui.h"
#include "legacy_grid_ui_services.h"
#include "log.h"
#include "node_panel_grid.h"
#include "canvas.h"
@@ -79,22 +80,17 @@ void NodePanelGrid::init_controls()
m_hm_load->on_click = [this](Node*) {
const auto plan = pp::app::plan_grid_heightmap_pick();
if (!plan.opens_picker)
return;
App::I->pick_image([this](std::string path) {
load_heightmap_file(path, true);
});
const auto status = pp::panopainter::execute_legacy_grid_ui_plan(*this, plan);
if (!status.ok())
LOG("Grid heightmap pick action failed: %s", status.message);
};
m_hm_clear->on_click = [this](Node*)
{
const auto plan = pp::app::plan_grid_heightmap_clear(static_cast<bool>(m_hm_image.data()));
if (!plan.clears_heightmap)
return;
m_hm_plane.create(1, 1, 100 * get_resolution());
m_hm_image.destroy();
m_hm_preview->tex.reset();
m_hm_preview->SetHeight(0);
const auto status = pp::panopainter::execute_legacy_grid_ui_plan(*this, plan);
if (!status.ok())
LOG("Grid heightmap clear action failed: %s", status.message);
};
m_hm_reload->on_click = [this](Node*)
@@ -112,32 +108,16 @@ void NodePanelGrid::init_controls()
get_samples());
if (!plan)
return;
if (plan.value().shows_unsupported_message)
{
App::I->message_box("Rendering failed",
"Your hardware does not support lightmap rendering.");
return;
}
if (plan.value().renders_lightmap)
{
std::thread([this] {
BT_SetTerminate();
bake_uvs();
m_hm_shading->set_index(3);
m_shade_mode = ShadeMode::Textured;
}).detach();
}
const auto status = pp::panopainter::execute_legacy_grid_ui_plan(*this, plan.value());
if (!status.ok())
LOG("Grid lightmap render action failed: %s", status.message);
};
m_commit->on_click = [this](Node*)
{
const auto plan = pp::app::plan_grid_heightmap_commit(Canvas::I != nullptr);
if (!plan.commits_heightmap)
return;
Canvas::I->draw_objects([this](const glm::mat4& camera, const glm::mat4& proj, int i) {
draw_heightmap(proj, camera, true);
}, Canvas::I->layer().m_frame_index, true);
if (plan.updates_ground_opacity)
m_groud_opacity->set_value(0);
const auto status = pp::panopainter::execute_legacy_grid_ui_plan(*this, plan);
if (!status.ok())
LOG("Grid heightmap commit action failed: %s", status.message);
};
m_hm_texres->on_select = [this](Node*, int index) {
int texres = get_texres();
@@ -227,23 +207,10 @@ bool NodePanelGrid::load_heightmap_file(const std::string& path, bool raise_grou
if (!plan)
return false;
Image img;
if (!img.load_file(plan.value().path))
return false;
m_file_path = plan.value().path;
m_hm_image = img.resize(128, 128);
m_hm_preview->tex = std::make_shared<Texture2D>();
m_hm_preview->tex->create(m_hm_image);
m_hm_preview->tex->create_mipmaps();
auto sz = m_hm_preview->tex->size();
m_hm_preview->SetAspectRatio(sz.x / sz.y);
m_hm_plane.create(1, 1, m_hm_image, get_resolution(), get_height());
m_hm_preview->SetHeight(100);
if (plan.value().updates_ground_opacity && m_groud_opacity->get_value() == 0.f)
m_groud_opacity->set_value(1.f);
m_rt_dirty = true;
return true;
const auto status = pp::panopainter::execute_legacy_grid_ui_plan(*this, plan.value());
if (!status.ok())
LOG("Grid heightmap load action failed: %s", status.message);
return status.ok();
}
void NodePanelGrid::draw_heightmap(const glm::mat4& proj, const glm::mat4& camera, bool commit) const

View File

@@ -1,198 +1,11 @@
#include "pch.h"
#include "app_core/quick_ui.h"
#include "legacy_quick_ui_services.h"
#include "node_panel_quick.h"
#include "node_stroke_preview.h"
#include "node_image.h"
#include "app.h"
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
Node* NodePanelQuick::clone_instantiate() const
{
return new this_class;
@@ -278,8 +91,7 @@ void NodePanelQuick::set_state(const MiniState& state, bool fire_event /*= false
if (!plan)
return;
LegacyQuickUiServices services(*this, &state);
const auto status = pp::app::execute_quick_ui_plan(plan.value(), services);
const auto status = pp::panopainter::execute_legacy_quick_ui_plan(*this, plan.value(), &state);
if (!status.ok())
LOG("Quick restore action failed: %s", status.message);
}
@@ -290,8 +102,7 @@ void NodePanelQuick::reset_state(bool fire_event /*= false*/)
if (!plan)
return;
LegacyQuickUiServices services(*this);
const auto status = pp::app::execute_quick_ui_plan(plan.value(), services);
const auto status = pp::panopainter::execute_legacy_quick_ui_plan(*this, plan.value());
if (!status.ok())
LOG("Quick reset action failed: %s", status.message);
}
@@ -400,8 +211,7 @@ void NodePanelQuick::handle_button_brush_click(Node* button)
if (!plan)
return;
LegacyQuickUiServices services(*this);
const auto status = pp::app::execute_quick_ui_plan(plan.value(), services);
const auto status = pp::panopainter::execute_legacy_quick_ui_plan(*this, plan.value());
if (!status.ok())
LOG("Quick brush action failed: %s", status.message);
}
@@ -418,8 +228,7 @@ void NodePanelQuick::handle_button_color_click(Node* target)
if (!plan)
return;
LegacyQuickUiServices services(*this);
const auto status = pp::app::execute_quick_ui_plan(plan.value(), services);
const auto status = pp::panopainter::execute_legacy_quick_ui_plan(*this, plan.value());
if (!status.ok())
LOG("Quick color action failed: %s", status.message);
}