Add brush UI service boundary

This commit is contained in:
2026-06-03 13:28:50 +02:00
parent 6427f218e7
commit de9bca8bb5
5 changed files with 301 additions and 37 deletions

View File

@@ -29,22 +29,91 @@
namespace {
class LegacyBrushUiServices final : public pp::app::BrushUiServices {
public:
LegacyBrushUiServices(
App& app,
bool update_quick = false,
bool update_color_panel = false,
const std::shared_ptr<Brush>& preset_brush = nullptr) noexcept
: app_(app)
, update_quick_(update_quick)
, update_color_panel_(update_color_panel)
, preset_brush_(preset_brush)
{
}
void set_tip_color(float r, float g, float b, float a) override
{
if (!Canvas::I || !Canvas::I->m_current_brush)
return;
Canvas::I->m_current_brush->m_tip_color = glm::vec4(r, g, b, a);
if (update_quick_ && app_.quick)
app_.quick->set_color(Canvas::I->m_current_brush->m_tip_color);
if (update_color_panel_ && app_.color)
app_.color->set_color(Canvas::I->m_current_brush->m_tip_color);
}
void set_texture(
pp::app::BrushUiTextureSlot slot,
std::string_view path,
std::string_view thumbnail_path) override
{
if (!Canvas::I || !Canvas::I->m_current_brush)
return;
const std::string texture_path(path);
const std::string thumbnail(thumbnail_path);
switch (slot)
{
case pp::app::BrushUiTextureSlot::tip:
Canvas::I->m_current_brush->load_tip(texture_path, thumbnail);
break;
case pp::app::BrushUiTextureSlot::pattern:
Canvas::I->m_current_brush->load_pattern(texture_path, thumbnail);
break;
case pp::app::BrushUiTextureSlot::dual:
Canvas::I->m_current_brush->load_dual(texture_path, thumbnail);
break;
}
}
void replace_brush_from_preset(bool preserve_existing_color, bool load_resources) override
{
if (!Canvas::I || !Canvas::I->m_current_brush || !preset_brush_)
return;
const auto color = Canvas::I->m_current_brush->m_tip_color;
*Canvas::I->m_current_brush = *preset_brush_;
if (preserve_existing_color)
Canvas::I->m_current_brush->m_tip_color = color;
if (load_resources)
Canvas::I->m_current_brush->load();
}
void refresh_brush_ui(bool update_color_ui, bool update_brush_ui) override
{
app_.brush_update(update_color_ui, update_brush_ui);
}
private:
App& app_;
bool update_quick_ = false;
bool update_color_panel_ = false;
std::shared_ptr<Brush> preset_brush_;
};
bool apply_brush_color_plan(App& app, glm::vec4 color, bool update_quick, bool update_color_panel)
{
const auto plan = pp::app::plan_brush_ui_color(color.r, color.g, color.b, color.a);
if (!plan)
return false;
Canvas::I->m_current_brush->m_tip_color = glm::vec4(
plan.value().r,
plan.value().g,
plan.value().b,
plan.value().a);
if (update_quick)
app.quick->set_color(Canvas::I->m_current_brush->m_tip_color);
if (update_color_panel)
app.color->set_color(Canvas::I->m_current_brush->m_tip_color);
app.brush_update(plan.value().update_color_ui, plan.value().update_brush_ui);
return true;
LegacyBrushUiServices services(app, update_quick, update_color_panel);
const auto status = pp::app::execute_brush_ui_plan(plan.value(), services);
if (!status.ok())
LOG("Brush color action failed: %s", status.message);
return status.ok();
}
bool apply_brush_texture_plan(pp::app::BrushUiTextureSlot slot, const std::string& path, const std::string& thumb)
@@ -52,20 +121,11 @@ bool apply_brush_texture_plan(pp::app::BrushUiTextureSlot slot, const std::strin
const auto plan = pp::app::plan_brush_ui_texture(slot, path, thumb);
if (!plan)
return false;
switch (plan.value().texture_slot)
{
case pp::app::BrushUiTextureSlot::tip:
Canvas::I->m_current_brush->load_tip(plan.value().path, plan.value().thumbnail_path);
break;
case pp::app::BrushUiTextureSlot::pattern:
Canvas::I->m_current_brush->load_pattern(plan.value().path, plan.value().thumbnail_path);
break;
case pp::app::BrushUiTextureSlot::dual:
Canvas::I->m_current_brush->load_dual(plan.value().path, plan.value().thumbnail_path);
break;
}
App::I->brush_update(plan.value().update_color_ui, plan.value().update_brush_ui);
return true;
LegacyBrushUiServices services(*App::I);
const auto status = pp::app::execute_brush_ui_plan(plan.value(), services);
if (!status.ok())
LOG("Brush texture action failed: %s", status.message);
return status.ok();
}
bool apply_brush_preset_plan(App& app, const std::shared_ptr<Brush>& brush)
@@ -73,14 +133,11 @@ bool apply_brush_preset_plan(App& app, const std::shared_ptr<Brush>& brush)
const auto plan = pp::app::plan_brush_ui_preset_replace(static_cast<bool>(brush));
if (!plan)
return false;
auto color = Canvas::I->m_current_brush->m_tip_color;
*Canvas::I->m_current_brush = *brush;
if (plan.value().preserves_existing_color)
Canvas::I->m_current_brush->m_tip_color = color;
if (plan.value().loads_brush_resources)
Canvas::I->m_current_brush->load();
app.brush_update(plan.value().update_color_ui, plan.value().update_brush_ui);
return true;
LegacyBrushUiServices services(app, false, false, brush);
const auto status = pp::app::execute_brush_ui_plan(plan.value(), services);
if (!status.ok())
LOG("Brush preset action failed: %s", status.message);
return status.ok();
}
bool apply_document_export_menu_plan(App& app, pp::app::DocumentExportMenuKind kind)
@@ -750,7 +807,10 @@ void App::init_sidebar()
};
stroke->on_stroke_change = [this](Node*) {
const auto plan = pp::app::plan_brush_ui_stroke_settings_changed();
brush_update(plan.update_color_ui, plan.update_brush_ui);
LegacyBrushUiServices services(*this);
const auto status = pp::app::execute_brush_ui_plan(plan, services);
if (!status.ok())
LOG("Brush stroke settings action failed: %s", status.message);
};
quick->on_color_change = [this](Node*, glm::vec3 c) {