Route brush refresh view through app core

This commit is contained in:
2026-06-05 01:13:34 +02:00
parent d5403f082c
commit 31c26c3127
8 changed files with 384 additions and 11 deletions

View File

@@ -212,6 +212,37 @@ struct BrushStrokePanelView {
bool updates_thumbnails = true;
};
struct BrushUiRefreshInput {
bool update_color = false;
bool update_brush = false;
bool has_current_brush = true;
bool has_floating_picker = false;
bool has_floating_color_panel = false;
float tip_flow = 0.0F;
float tip_size = 0.0F;
float r = 0.0F;
float g = 0.0F;
float b = 0.0F;
float a = 1.0F;
};
struct BrushUiRefreshView {
bool updates_stroke_controls = false;
bool updates_quick_flow = false;
bool updates_quick_size = false;
bool updates_quick_brush_preview = false;
bool updates_quick_color = false;
bool updates_floating_picker = false;
bool updates_floating_color_panel = false;
bool no_op = false;
float tip_flow = 0.0F;
float tip_size = 0.0F;
float r = 0.0F;
float g = 0.0F;
float b = 0.0F;
float a = 1.0F;
};
class BrushUiServices {
public:
virtual ~BrushUiServices() = default;
@@ -342,6 +373,57 @@ public:
return pp::foundation::Result<BrushStrokePanelView>::success(std::move(view));
}
[[nodiscard]] inline pp::foundation::Result<BrushUiRefreshView> plan_brush_ui_refresh(
const BrushUiRefreshInput& input)
{
if (!input.update_color && !input.update_brush) {
BrushUiRefreshView view;
view.no_op = true;
return pp::foundation::Result<BrushUiRefreshView>::success(view);
}
if (!input.has_current_brush) {
return pp::foundation::Result<BrushUiRefreshView>::failure(
pp::foundation::Status::invalid_argument("brush refresh requires a current brush"));
}
if (input.update_brush) {
const auto flow_status = validate_brush_stroke_float(input.tip_flow);
if (!flow_status.ok()) {
return pp::foundation::Result<BrushUiRefreshView>::failure(flow_status);
}
const auto size_status = validate_brush_stroke_float(input.tip_size);
if (!size_status.ok()) {
return pp::foundation::Result<BrushUiRefreshView>::failure(size_status);
}
}
if (input.update_color) {
for (const auto value : { input.r, input.g, input.b, input.a }) {
const auto channel_status = validate_brush_ui_color_channel(value);
if (!channel_status.ok()) {
return pp::foundation::Result<BrushUiRefreshView>::failure(channel_status);
}
}
}
BrushUiRefreshView view;
view.updates_stroke_controls = input.update_brush;
view.updates_quick_flow = input.update_brush;
view.updates_quick_size = input.update_brush;
view.updates_quick_brush_preview = input.update_brush;
view.updates_quick_color = input.update_color;
view.updates_floating_picker = input.update_color && input.has_floating_picker;
view.updates_floating_color_panel = input.update_color && input.has_floating_color_panel;
view.tip_flow = input.tip_flow;
view.tip_size = input.tip_size;
view.r = input.r;
view.g = input.g;
view.b = input.b;
view.a = input.a;
return pp::foundation::Result<BrushUiRefreshView>::success(view);
}
[[nodiscard]] inline pp::foundation::Result<BrushUiPlan> plan_brush_ui_color(
float r,
float g,

View File

@@ -1398,21 +1398,54 @@ void App::brush_update(bool update_color, bool update_brush)
// stroke->set_params(canvas->m_brush);
render_task_async([this, update_color, update_brush]
{
if (update_brush)
pp::app::BrushUiRefreshInput input;
input.update_color = update_color;
input.update_brush = update_brush;
auto current_brush = Canvas::I ? Canvas::I->m_current_brush : nullptr;
input.has_current_brush = current_brush != nullptr;
input.has_floating_picker = floating_picker != nullptr;
input.has_floating_color_panel = floating_color != nullptr;
if (input.has_current_brush)
{
input.tip_flow = current_brush->m_tip_flow;
input.tip_size = current_brush->m_tip_size;
input.r = current_brush->m_tip_color.r;
input.g = current_brush->m_tip_color.g;
input.b = current_brush->m_tip_color.b;
input.a = current_brush->m_tip_color.a;
}
const auto view = pp::app::plan_brush_ui_refresh(input);
if (!view) {
LOG("Brush UI refresh failed: %s", view.status().message);
return;
}
if (view.value().updates_stroke_controls)
{
stroke->update_controls();
}
if (view.value().updates_quick_flow)
{
quick->m_slider_flow->set_value(stroke->m_tip_flow->get_value());
}
if (view.value().updates_quick_size)
{
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;
}
if (view.value().updates_quick_brush_preview && current_brush)
{
*quick->m_button_brush_current_preview->m_brush = *current_brush;
quick->m_button_brush_current_preview->draw_stroke();
}
if (update_color)
if (view.value().updates_quick_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);
const glm::vec4 color(view.value().r, view.value().g, view.value().b, view.value().a);
quick->m_button_color_current_inner->m_color = color;
if (view.value().updates_floating_picker)
floating_picker->set_color(color);
if (view.value().updates_floating_color_panel)
floating_color->set_color(color);
}
}, true);
}