1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 16:57:35 +00:00

PixelPaint: Propagate errors from making filter settings widgets

This commit is contained in:
Karol Kosek 2023-02-12 17:14:43 +01:00 committed by Andrew Kaster
parent 4cd3a84c4b
commit ba5df46a49
14 changed files with 158 additions and 140 deletions

View file

@ -36,6 +36,9 @@ FilterGallery::FilterGallery(GUI::Window* parent_window, ImageEditor* editor)
VERIFY(m_config_widget);
VERIFY(m_preview_widget);
m_error_label = GUI::Label::try_create().release_value_but_fixme_should_propagate_errors();
m_error_label->set_enabled(false);
auto filter_tree_model = MUST(create_filter_tree_model(editor));
m_filter_tree->set_model(filter_tree_model);
m_filter_tree->expand_tree();
@ -59,7 +62,13 @@ FilterGallery::FilterGallery(GUI::Window* parent_window, ImageEditor* editor)
};
m_preview_widget->set_filter(m_selected_filter);
m_selected_filter_config_widget = m_selected_filter->get_settings_widget();
auto settings_widget_or_error = m_selected_filter->get_settings_widget();
if (settings_widget_or_error.is_error()) {
m_error_label->set_text(DeprecatedString::formatted("Error creating settings: {}", settings_widget_or_error.error()));
m_selected_filter_config_widget = m_error_label;
} else {
m_selected_filter_config_widget = settings_widget_or_error.release_value();
}
m_config_widget->remove_all_children();
m_config_widget->add_child(*m_selected_filter_config_widget);
};

View file

@ -10,6 +10,7 @@
#include "Filters/Filter.h"
#include "ImageEditor.h"
#include <LibGUI/Dialog.h>
#include <LibGUI/Label.h>
namespace PixelPaint {
@ -21,6 +22,7 @@ private:
GUI::TreeView* m_filter_tree { nullptr };
GUI::Widget* m_config_widget { nullptr };
FilterPreviewWidget* m_preview_widget { nullptr };
RefPtr<GUI::Label> m_error_label { nullptr };
RefPtr<GUI::Widget> m_selected_filter_config_widget { nullptr };
Filter* m_selected_filter { nullptr };
};

View file

@ -34,50 +34,51 @@ void Bloom::apply(Gfx::Bitmap& target_bitmap, Gfx::Bitmap const& source_bitmap)
mixer.mix_with(intermediate_bitmap, Gfx::BitmapMixer::MixingMethod::Lightest);
}
RefPtr<GUI::Widget> Bloom::get_settings_widget()
ErrorOr<RefPtr<GUI::Widget>> Bloom::get_settings_widget()
{
if (!m_settings_widget) {
m_settings_widget = GUI::Widget::construct();
m_settings_widget->set_layout<GUI::VerticalBoxLayout>();
auto settings_widget = TRY(GUI::Widget::try_create());
(void)TRY(settings_widget->try_set_layout<GUI::VerticalBoxLayout>());
auto& name_label = m_settings_widget->add<GUI::Label>("Bloom Filter");
name_label.set_font_weight(Gfx::FontWeight::Bold);
name_label.set_text_alignment(Gfx::TextAlignment::CenterLeft);
name_label.set_fixed_height(20);
auto name_label = TRY(settings_widget->try_add<GUI::Label>("Bloom Filter"));
name_label->set_font_weight(Gfx::FontWeight::Bold);
name_label->set_text_alignment(Gfx::TextAlignment::CenterLeft);
name_label->set_fixed_height(20);
auto& luma_lower_container = m_settings_widget->add<GUI::Widget>();
luma_lower_container.set_fixed_height(50);
luma_lower_container.set_layout<GUI::VerticalBoxLayout>();
luma_lower_container.layout()->set_margins({ 4, 0, 4, 0 });
auto luma_lower_container = TRY(settings_widget->try_add<GUI::Widget>());
luma_lower_container->set_fixed_height(50);
auto luma_lower_container_layout = TRY(luma_lower_container->try_set_layout<GUI::VerticalBoxLayout>());
luma_lower_container_layout->set_margins({ 4, 0, 4, 0 });
auto& luma_lower_label = luma_lower_container.add<GUI::Label>("Luma lower bound:");
luma_lower_label.set_text_alignment(Gfx::TextAlignment::CenterLeft);
luma_lower_label.set_fixed_height(20);
auto luma_lower_label = TRY(luma_lower_container->try_add<GUI::Label>("Luma lower bound:"));
luma_lower_label->set_text_alignment(Gfx::TextAlignment::CenterLeft);
luma_lower_label->set_fixed_height(20);
auto& luma_lower_slider = luma_lower_container.add<GUI::ValueSlider>(Orientation::Horizontal);
luma_lower_slider.set_range(0, 255);
luma_lower_slider.set_value(m_luma_lower);
luma_lower_slider.on_change = [&](int value) {
auto luma_lower_slider = TRY(luma_lower_container->try_add<GUI::ValueSlider>(Orientation::Horizontal));
luma_lower_slider->set_range(0, 255);
luma_lower_slider->set_value(m_luma_lower);
luma_lower_slider->on_change = [&](int value) {
m_luma_lower = value;
update_preview();
};
auto& radius_container = m_settings_widget->add<GUI::Widget>();
radius_container.set_fixed_height(50);
radius_container.set_layout<GUI::VerticalBoxLayout>();
radius_container.layout()->set_margins({ 4, 0, 4, 0 });
auto radius_container = TRY(settings_widget->try_add<GUI::Widget>());
radius_container->set_fixed_height(50);
auto radius_container_layout = TRY(radius_container->try_set_layout<GUI::VerticalBoxLayout>());
radius_container_layout->set_margins({ 4, 0, 4, 0 });
auto& radius_label = radius_container.add<GUI::Label>("Blur Radius:");
radius_label.set_text_alignment(Gfx::TextAlignment::CenterLeft);
radius_label.set_fixed_height(20);
auto radius_label = TRY(radius_container->try_add<GUI::Label>("Blur Radius:"));
radius_label->set_text_alignment(Gfx::TextAlignment::CenterLeft);
radius_label->set_fixed_height(20);
auto& radius_slider = radius_container.add<GUI::ValueSlider>(Orientation::Horizontal, String::from_utf8_short_string("px"sv));
radius_slider.set_range(0, 50);
radius_slider.set_value(m_blur_radius);
radius_slider.on_change = [&](int value) {
auto radius_slider = TRY(radius_container->try_add<GUI::ValueSlider>(Orientation::Horizontal, String::from_utf8_short_string("px"sv)));
radius_slider->set_range(0, 50);
radius_slider->set_value(m_blur_radius);
radius_slider->on_change = [&](int value) {
m_blur_radius = value;
update_preview();
};
m_settings_widget = settings_widget;
}
return m_settings_widget;

View file

@ -14,7 +14,7 @@ class Bloom final : public Filter {
public:
virtual void apply(Gfx::Bitmap& target_bitmap, Gfx::Bitmap const& source_bitmap) const override;
virtual RefPtr<GUI::Widget> get_settings_widget() override;
virtual ErrorOr<RefPtr<GUI::Widget>> get_settings_widget() override;
virtual StringView filter_name() const override { return "Bloom Filter"sv; }

View file

@ -36,21 +36,21 @@ void FastBoxBlur::apply(Gfx::Bitmap& target_bitmap) const
filter.apply_single_pass(m_radius);
}
RefPtr<GUI::Widget> FastBoxBlur::get_settings_widget()
ErrorOr<RefPtr<GUI::Widget>> FastBoxBlur::get_settings_widget()
{
if (!m_settings_widget) {
m_settings_widget = GUI::Widget::construct();
m_settings_widget->set_layout<GUI::VerticalBoxLayout>();
auto settings_widget = TRY(GUI::Widget::try_create());
(void)TRY(settings_widget->try_set_layout<GUI::VerticalBoxLayout>());
auto& name_label = m_settings_widget->add<GUI::Label>("Fast Box Blur Filter");
name_label.set_font_weight(Gfx::FontWeight::Bold);
name_label.set_text_alignment(Gfx::TextAlignment::CenterLeft);
name_label.set_fixed_height(10);
auto name_label = TRY(settings_widget->try_add<GUI::Label>("Fast Box Blur Filter"));
name_label->set_font_weight(Gfx::FontWeight::Bold);
name_label->set_text_alignment(Gfx::TextAlignment::CenterLeft);
name_label->set_fixed_height(10);
auto& asymmetric_checkbox = m_settings_widget->add<GUI::CheckBox>(String::from_utf8("Use Asymmetric Radii"sv).release_value_but_fixme_should_propagate_errors());
asymmetric_checkbox.set_checked(false);
asymmetric_checkbox.set_fixed_height(15);
asymmetric_checkbox.on_checked = [&](bool checked) {
auto asymmetric_checkbox = TRY(settings_widget->try_add<GUI::CheckBox>(TRY(String::from_utf8("Use Asymmetric Radii"sv))));
asymmetric_checkbox->set_checked(false);
asymmetric_checkbox->set_fixed_height(15);
asymmetric_checkbox->on_checked = [this](bool checked) {
m_use_asymmetric_radii = checked;
if (m_use_asymmetric_radii) {
m_vector_checkbox->set_visible(true);
@ -68,7 +68,7 @@ RefPtr<GUI::Widget> FastBoxBlur::get_settings_widget()
update_preview();
};
m_vector_checkbox = m_settings_widget->add<GUI::CheckBox>(String::from_utf8("Use Direction and magnitude"sv).release_value_but_fixme_should_propagate_errors());
m_vector_checkbox = TRY(settings_widget->try_add<GUI::CheckBox>(TRY(String::from_utf8("Use Direction and magnitude"sv))));
m_vector_checkbox->set_checked(false);
m_vector_checkbox->set_visible(false);
m_vector_checkbox->set_fixed_height(15);
@ -84,38 +84,38 @@ RefPtr<GUI::Widget> FastBoxBlur::get_settings_widget()
update_preview();
};
m_radius_container = m_settings_widget->add<GUI::Widget>();
m_radius_container = TRY(settings_widget->try_add<GUI::Widget>());
m_radius_container->set_fixed_height(20);
m_radius_container->set_layout<GUI::HorizontalBoxLayout>();
m_radius_container->layout()->set_margins({ 4, 0, 4, 0 });
auto radius_container_layout = TRY(m_radius_container->try_set_layout<GUI::HorizontalBoxLayout>());
radius_container_layout->set_margins({ 4, 0, 4, 0 });
auto& radius_label = m_radius_container->add<GUI::Label>("Radius:");
radius_label.set_text_alignment(Gfx::TextAlignment::CenterLeft);
radius_label.set_fixed_size(50, 20);
auto radius_label = TRY(m_radius_container->try_add<GUI::Label>("Radius:"));
radius_label->set_text_alignment(Gfx::TextAlignment::CenterLeft);
radius_label->set_fixed_size(50, 20);
auto& radius_slider = m_radius_container->add<GUI::ValueSlider>(Orientation::Horizontal, String::from_utf8_short_string("px"sv));
radius_slider.set_range(0, 25);
radius_slider.set_value(m_radius);
radius_slider.on_change = [&](int value) {
auto radius_slider = TRY(m_radius_container->try_add<GUI::ValueSlider>(Orientation::Horizontal, String::from_utf8_short_string("px"sv)));
radius_slider->set_range(0, 25);
radius_slider->set_value(m_radius);
radius_slider->on_change = [&](int value) {
m_radius = value;
update_preview();
};
m_asymmetric_radius_container = m_settings_widget->add<GUI::Widget>();
m_asymmetric_radius_container = TRY(settings_widget->try_add<GUI::Widget>());
m_asymmetric_radius_container->set_visible(false);
m_asymmetric_radius_container->set_fixed_height(50);
m_asymmetric_radius_container->set_layout<GUI::VerticalBoxLayout>();
m_asymmetric_radius_container->layout()->set_margins({ 4, 0, 4, 0 });
auto asymmetric_radius_container_label = TRY(m_asymmetric_radius_container->try_set_layout<GUI::VerticalBoxLayout>());
asymmetric_radius_container_label->set_margins({ 4, 0, 4, 0 });
auto& radius_x_container = m_asymmetric_radius_container->add<GUI::Widget>();
radius_x_container.set_fixed_height(20);
radius_x_container.set_layout<GUI::HorizontalBoxLayout>();
auto radius_x_container = TRY(m_asymmetric_radius_container->try_add<GUI::Widget>());
radius_x_container->set_fixed_height(20);
radius_x_container->set_layout<GUI::HorizontalBoxLayout>();
auto& radius_x_label = radius_x_container.add<GUI::Label>("Radius X:");
radius_x_label.set_text_alignment(Gfx::TextAlignment::CenterLeft);
radius_x_label.set_fixed_size(50, 20);
auto radius_x_label = TRY(radius_x_container->try_add<GUI::Label>("Radius X:"));
radius_x_label->set_text_alignment(Gfx::TextAlignment::CenterLeft);
radius_x_label->set_fixed_size(50, 20);
m_radius_x_slider = radius_x_container.add<GUI::ValueSlider>(Orientation::Horizontal, String::from_utf8_short_string("px"sv));
m_radius_x_slider = TRY(radius_x_container->try_add<GUI::ValueSlider>(Orientation::Horizontal, String::from_utf8_short_string("px"sv)));
m_radius_x_slider->set_range(0, 50);
m_radius_x_slider->set_value(m_radius_x);
m_radius_x_slider->on_change = [&](int value) {
@ -123,15 +123,15 @@ RefPtr<GUI::Widget> FastBoxBlur::get_settings_widget()
update_preview();
};
auto& radius_y_container = m_asymmetric_radius_container->add<GUI::Widget>();
radius_y_container.set_fixed_height(20);
radius_y_container.set_layout<GUI::HorizontalBoxLayout>();
auto radius_y_container = TRY(m_asymmetric_radius_container->try_add<GUI::Widget>());
radius_y_container->set_fixed_height(20);
(void)TRY(radius_y_container->try_set_layout<GUI::HorizontalBoxLayout>());
auto& radius_y_label = radius_y_container.add<GUI::Label>("Radius Y:");
radius_y_label.set_text_alignment(Gfx::TextAlignment::CenterLeft);
radius_y_label.set_fixed_size(50, 20);
auto radius_y_label = TRY(radius_y_container->try_add<GUI::Label>("Radius Y:"));
radius_y_label->set_text_alignment(Gfx::TextAlignment::CenterLeft);
radius_y_label->set_fixed_size(50, 20);
m_radius_y_slider = radius_y_container.add<GUI::ValueSlider>(Orientation::Horizontal, String::from_utf8_short_string("px"sv));
m_radius_y_slider = TRY(radius_y_container->try_add<GUI::ValueSlider>(Orientation::Horizontal, String::from_utf8_short_string("px"sv)));
m_radius_y_slider->set_range(0, 50);
m_radius_y_slider->set_value(m_radius_y);
m_radius_y_slider->on_change = [&](int value) {
@ -139,21 +139,21 @@ RefPtr<GUI::Widget> FastBoxBlur::get_settings_widget()
update_preview();
};
m_vector_container = m_settings_widget->add<GUI::Widget>();
m_vector_container = TRY(settings_widget->try_add<GUI::Widget>());
m_vector_container->set_visible(false);
m_vector_container->set_fixed_height(50);
m_vector_container->set_layout<GUI::VerticalBoxLayout>();
m_vector_container->layout()->set_margins({ 4, 0, 4, 0 });
auto vector_container_layout = TRY(m_vector_container->try_set_layout<GUI::VerticalBoxLayout>());
vector_container_layout->set_margins({ 4, 0, 4, 0 });
auto& angle_container = m_vector_container->add<GUI::Widget>();
angle_container.set_fixed_height(20);
angle_container.set_layout<GUI::HorizontalBoxLayout>();
auto angle_container = TRY(m_vector_container->try_add<GUI::Widget>());
angle_container->set_fixed_height(20);
(void)TRY(angle_container->try_set_layout<GUI::HorizontalBoxLayout>());
auto& angle_label = angle_container.add<GUI::Label>("Angle:");
angle_label.set_text_alignment(Gfx::TextAlignment::CenterLeft);
angle_label.set_fixed_size(60, 20);
auto angle_label = TRY(angle_container->try_add<GUI::Label>("Angle:"));
angle_label->set_text_alignment(Gfx::TextAlignment::CenterLeft);
angle_label->set_fixed_size(60, 20);
m_angle_slider = angle_container.add<GUI::ValueSlider>(Orientation::Horizontal, String::from_utf8_short_string("°"sv));
m_angle_slider = TRY(angle_container->try_add<GUI::ValueSlider>(Orientation::Horizontal, String::from_utf8_short_string("°"sv)));
m_angle_slider->set_range(0, 360);
m_angle_slider->set_value(m_angle);
m_angle_slider->on_change = [&](int value) {
@ -161,15 +161,15 @@ RefPtr<GUI::Widget> FastBoxBlur::get_settings_widget()
update_preview();
};
auto& magnitude_container = m_vector_container->add<GUI::Widget>();
magnitude_container.set_fixed_height(20);
magnitude_container.set_layout<GUI::HorizontalBoxLayout>();
auto magnitude_container = TRY(m_vector_container->try_add<GUI::Widget>());
magnitude_container->set_fixed_height(20);
(void)TRY(magnitude_container->try_set_layout<GUI::HorizontalBoxLayout>());
auto& magnitude_label = magnitude_container.add<GUI::Label>("Magnitude:");
magnitude_label.set_text_alignment(Gfx::TextAlignment::CenterLeft);
magnitude_label.set_fixed_size(60, 20);
auto magnitude_label = TRY(magnitude_container->try_add<GUI::Label>("Magnitude:"));
magnitude_label->set_text_alignment(Gfx::TextAlignment::CenterLeft);
magnitude_label->set_fixed_size(60, 20);
m_magnitude_slider = magnitude_container.add<GUI::ValueSlider>(Orientation::Horizontal, String::from_utf8_short_string("px"sv));
m_magnitude_slider = TRY(magnitude_container->try_add<GUI::ValueSlider>(Orientation::Horizontal, String::from_utf8_short_string("px"sv)));
m_magnitude_slider->set_range(0, 50);
m_magnitude_slider->set_value(m_radius);
m_magnitude_slider->on_change = [&](int value) {
@ -177,18 +177,19 @@ RefPtr<GUI::Widget> FastBoxBlur::get_settings_widget()
update_preview();
};
auto& gaussian_container = m_settings_widget->add<GUI::Widget>();
gaussian_container.set_fixed_height(20);
gaussian_container.set_layout<GUI::HorizontalBoxLayout>();
gaussian_container.layout()->set_margins({ 4, 0, 4, 0 });
auto gaussian_container = TRY(settings_widget->try_add<GUI::Widget>());
gaussian_container->set_fixed_height(20);
auto gaussian_container_layout = TRY(gaussian_container->try_set_layout<GUI::HorizontalBoxLayout>());
gaussian_container_layout->set_margins({ 4, 0, 4, 0 });
m_gaussian_checkbox = gaussian_container.add<GUI::CheckBox>(String::from_utf8("Approximate Gaussian Blur"sv).release_value_but_fixme_should_propagate_errors());
m_gaussian_checkbox = TRY(gaussian_container->try_add<GUI::CheckBox>(TRY(String::from_utf8("Approximate Gaussian Blur"sv))));
m_gaussian_checkbox->set_checked(m_approximate_gauss);
m_gaussian_checkbox->set_tooltip("A real gaussian blur can be approximated by running the box blur multiple times with different weights.");
m_gaussian_checkbox->on_checked = [this](bool checked) {
m_approximate_gauss = checked;
update_preview();
};
m_settings_widget = settings_widget;
}
return m_settings_widget;

View file

@ -15,7 +15,7 @@ namespace PixelPaint::Filters {
class FastBoxBlur final : public InplaceFilter {
public:
virtual void apply(Gfx::Bitmap& target_bitmap) const override;
virtual RefPtr<GUI::Widget> get_settings_widget() override;
virtual ErrorOr<RefPtr<GUI::Widget>> get_settings_widget() override;
virtual StringView filter_name() const override { return "Fast Box Blur (& Gauss)"sv; }

View file

@ -22,16 +22,17 @@ Filter::Filter(ImageEditor* editor)
m_update_timer->set_active(false);
}
RefPtr<GUI::Widget> Filter::get_settings_widget()
ErrorOr<RefPtr<GUI::Widget>> Filter::get_settings_widget()
{
if (!m_settings_widget) {
m_settings_widget = GUI::Widget::construct();
m_settings_widget->set_layout<GUI::VerticalBoxLayout>();
auto settings_widget = TRY(GUI::Widget::try_create());
(void)TRY(settings_widget->try_set_layout<GUI::VerticalBoxLayout>());
auto& name_label = m_settings_widget->add<GUI::Label>(filter_name());
name_label.set_text_alignment(Gfx::TextAlignment::TopLeft);
auto name_label = TRY(settings_widget->try_add<GUI::Label>(filter_name()));
name_label->set_text_alignment(Gfx::TextAlignment::TopLeft);
m_settings_widget->add<GUI::Widget>();
(void)TRY(settings_widget->try_add<GUI::Widget>());
m_settings_widget = settings_widget;
}
return m_settings_widget.ptr();

View file

@ -22,7 +22,7 @@ public:
virtual void apply() const;
virtual void apply(Gfx::Bitmap& target_bitmap, Gfx::Bitmap const& source_bitmap) const = 0;
virtual RefPtr<GUI::Widget> get_settings_widget();
virtual ErrorOr<RefPtr<GUI::Widget>> get_settings_widget();
virtual StringView filter_name() const = 0;

View file

@ -27,30 +27,32 @@ void HueAndSaturation::apply(Gfx::Bitmap& target_bitmap) const
: Gfx::TintFilter(Gfx::Color::White, lightness));
}
RefPtr<GUI::Widget> HueAndSaturation::get_settings_widget()
ErrorOr<RefPtr<GUI::Widget>> HueAndSaturation::get_settings_widget()
{
if (!m_settings_widget) {
m_settings_widget = GUI::Widget::construct();
m_settings_widget->set_layout<GUI::VerticalBoxLayout>();
auto settings_widget = TRY(GUI::Widget::try_create());
(void)TRY(settings_widget->try_set_layout<GUI::VerticalBoxLayout>());
auto add_slider = [&](auto name, int min, int max, auto member) {
auto& name_label = m_settings_widget->add<GUI::Label>(name);
name_label.set_font_weight(Gfx::FontWeight::Bold);
name_label.set_text_alignment(Gfx::TextAlignment::CenterLeft);
name_label.set_fixed_height(20);
auto add_slider = [&](auto name, int min, int max, auto member) -> ErrorOr<void> {
auto name_label = TRY(settings_widget->try_add<GUI::Label>(name));
name_label->set_font_weight(Gfx::FontWeight::Bold);
name_label->set_text_alignment(Gfx::TextAlignment::CenterLeft);
name_label->set_fixed_height(20);
auto& slider = m_settings_widget->add<GUI::ValueSlider>(Orientation::Horizontal);
slider.set_range(min, max);
slider.set_value(m_hue);
slider.on_change = [this, member](int value) {
auto slider = TRY(settings_widget->try_add<GUI::ValueSlider>(Orientation::Horizontal));
slider->set_range(min, max);
slider->set_value(m_hue);
slider->on_change = [this, member](int value) {
this->*member = value;
update_preview();
};
return {};
};
add_slider("Hue", -180, 180, &HueAndSaturation::m_hue);
add_slider("Saturation", -100, 100, &HueAndSaturation::m_saturation);
add_slider("Lightness", -100, 100, &HueAndSaturation::m_lightness);
TRY(add_slider("Hue", -180, 180, &HueAndSaturation::m_hue));
TRY(add_slider("Saturation", -100, 100, &HueAndSaturation::m_saturation));
TRY(add_slider("Lightness", -100, 100, &HueAndSaturation::m_lightness));
m_settings_widget = settings_widget;
}
return m_settings_widget;

View file

@ -13,7 +13,7 @@ namespace PixelPaint::Filters {
class HueAndSaturation final : public InplaceFilter {
public:
virtual void apply(Gfx::Bitmap& target_bitmap) const override;
virtual RefPtr<GUI::Widget> get_settings_widget() override;
virtual ErrorOr<RefPtr<GUI::Widget>> get_settings_widget() override;
virtual StringView filter_name() const override { return "Hue/Saturation"sv; }

View file

@ -42,15 +42,16 @@ void Median::apply(Gfx::Bitmap& target_bitmap, Gfx::Bitmap const& source_bitmap)
painter.blit({}, target, target->rect());
}
RefPtr<GUI::Widget> Median::get_settings_widget()
ErrorOr<RefPtr<GUI::Widget>> Median::get_settings_widget()
{
if (!m_settings_widget) {
m_settings_widget = GUI::Widget::construct();
m_settings_widget->load_from_gml(median_settings_gml).release_value_but_fixme_should_propagate_errors();
m_settings_widget->find_descendant_of_type_named<GUI::SpinBox>("filter_radius")->on_change = [this](auto value) {
auto settings_widget = TRY(GUI::Widget::try_create());
TRY(settings_widget->load_from_gml(median_settings_gml));
settings_widget->find_descendant_of_type_named<GUI::SpinBox>("filter_radius")->on_change = [this](auto value) {
m_filter_radius = value;
update_preview();
};
m_settings_widget = settings_widget;
}
return m_settings_widget;

View file

@ -15,7 +15,7 @@ class Median : public Filter {
public:
virtual void apply(Gfx::Bitmap& target_bitmap, Gfx::Bitmap const& source_bitmap) const override;
virtual RefPtr<GUI::Widget> get_settings_widget() override;
virtual ErrorOr<RefPtr<GUI::Widget>> get_settings_widget() override;
virtual StringView filter_name() const override { return "Median Filter"sv; }

View file

@ -17,33 +17,34 @@ void Sepia::apply(Gfx::Bitmap& target_bitmap, Gfx::Bitmap const& source_bitmap)
filter.apply(target_bitmap, target_bitmap.rect(), source_bitmap, source_bitmap.rect());
}
RefPtr<GUI::Widget> Sepia::get_settings_widget()
ErrorOr<RefPtr<GUI::Widget>> Sepia::get_settings_widget()
{
if (!m_settings_widget) {
m_settings_widget = GUI::Widget::construct();
m_settings_widget->set_layout<GUI::VerticalBoxLayout>();
auto settings_widget = TRY(GUI::Widget::try_create());
(void)TRY(settings_widget->try_set_layout<GUI::VerticalBoxLayout>());
auto& name_label = m_settings_widget->add<GUI::Label>("Sepia Filter");
name_label.set_font_weight(Gfx::FontWeight::Bold);
name_label.set_text_alignment(Gfx::TextAlignment::CenterLeft);
name_label.set_fixed_height(20);
auto name_label = TRY(settings_widget->try_add<GUI::Label>("Sepia Filter"));
name_label->set_font_weight(Gfx::FontWeight::Bold);
name_label->set_text_alignment(Gfx::TextAlignment::CenterLeft);
name_label->set_fixed_height(20);
auto& amount_container = m_settings_widget->add<GUI::Widget>();
amount_container.set_fixed_height(20);
amount_container.set_layout<GUI::HorizontalBoxLayout>();
amount_container.layout()->set_margins({ 4, 0, 4, 0 });
auto amount_container = TRY(settings_widget->try_add<GUI::Widget>());
amount_container->set_fixed_height(20);
auto amount_layout = TRY(amount_container->try_set_layout<GUI::HorizontalBoxLayout>());
amount_layout->set_margins({ 4, 0, 4, 0 });
auto& amount_label = amount_container.add<GUI::Label>("Amount:");
amount_label.set_text_alignment(Gfx::TextAlignment::CenterLeft);
amount_label.set_fixed_size(50, 20);
auto amount_label = TRY(amount_container->try_add<GUI::Label>("Amount:"));
amount_label->set_text_alignment(Gfx::TextAlignment::CenterLeft);
amount_label->set_fixed_size(50, 20);
auto& amount_slider = amount_container.add<GUI::ValueSlider>(Orientation::Horizontal, String::from_utf8_short_string("%"sv));
amount_slider.set_range(0, 100);
amount_slider.set_value(m_amount * 100);
amount_slider.on_change = [&](int value) {
auto amount_slider = TRY(amount_container->try_add<GUI::ValueSlider>(Orientation::Horizontal, String::from_utf8_short_string("%"sv)));
amount_slider->set_range(0, 100);
amount_slider->set_value(m_amount * 100);
amount_slider->on_change = [this](int value) {
m_amount = value * 0.01f;
update_preview();
};
m_settings_widget = settings_widget;
}
return m_settings_widget;

View file

@ -13,7 +13,7 @@ namespace PixelPaint::Filters {
class Sepia final : public Filter {
public:
virtual void apply(Gfx::Bitmap& target_bitmap, Gfx::Bitmap const& source_bitmap) const override;
virtual RefPtr<GUI::Widget> get_settings_widget() override;
virtual ErrorOr<RefPtr<GUI::Widget>> get_settings_widget() override;
virtual StringView filter_name() const override { return "Sepia"sv; }