PixelPaint: Expand FastBoxBlur settings to allow vector input

This expands the previously added settings for the asymmetric radii of
th FastBoxBlurFilter to allow the user to specify an angle and the
desired magnitude of blur.
The given values are then calculated forward to corresponding x and y
blur radii.
This commit is contained in:
Tobias Christiansen 2022-03-16 15:06:46 +01:00 committed by Andreas Kling
parent ffcc11c31b
commit be58e5c35b
2 changed files with 66 additions and 0 deletions

View file

@ -26,6 +26,13 @@ void FastBoxBlur::apply(Gfx::Bitmap& target_bitmap, Gfx::Bitmap const& source_bi
Gfx::FastBoxBlurFilter filter(target_bitmap);
if (m_use_asymmetric_radii) {
if (m_use_vector) {
auto radius_x = m_radius * fabs(cos((double)m_angle * M_DEG2RAD));
auto radius_y = m_radius * fabs(sin((double)m_angle * M_DEG2RAD));
filter.apply_single_pass(radius_x, radius_y);
return;
}
filter.apply_single_pass(m_radius_x, m_radius_y);
return;
}
@ -53,6 +60,7 @@ RefPtr<GUI::Widget> FastBoxBlur::get_settings_widget()
asymmetric_checkbox.on_checked = [&](bool checked) {
m_use_asymmetric_radii = checked;
if (m_use_asymmetric_radii) {
m_vector_checkbox->set_visible(true);
m_radius_x_slider->set_value(m_radius);
m_radius_y_slider->set_value(m_radius);
m_asymmetric_radius_container->set_visible(true);
@ -62,6 +70,23 @@ RefPtr<GUI::Widget> FastBoxBlur::get_settings_widget()
m_asymmetric_radius_container->set_visible(false);
m_radius_container->set_visible(true);
m_gaussian_checkbox->set_visible(true);
m_vector_checkbox->set_visible(false);
}
update_preview();
};
m_vector_checkbox = m_settings_widget->add<GUI::CheckBox>("Use Direction and magnitude");
m_vector_checkbox->set_checked(false);
m_vector_checkbox->set_visible(false);
m_vector_checkbox->set_fixed_height(15);
m_vector_checkbox->on_checked = [&](bool checked) {
m_use_vector = checked;
if (m_use_vector) {
m_asymmetric_radius_container->set_visible(false);
m_vector_container->set_visible(true);
} else {
m_asymmetric_radius_container->set_visible(true);
m_vector_container->set_visible(false);
}
update_preview();
};
@ -121,6 +146,44 @@ RefPtr<GUI::Widget> FastBoxBlur::get_settings_widget()
update_preview();
};
m_vector_container = m_settings_widget->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& angle_container = m_vector_container->add<GUI::Widget>();
angle_container.set_fixed_height(20);
angle_container.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);
m_angle_slider = angle_container.add<GUI::ValueSlider>(Orientation::Horizontal, "°");
m_angle_slider->set_range(0, 360);
m_angle_slider->set_value(m_angle);
m_angle_slider->on_change = [&](int value) {
m_angle = value;
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_label = magnitude_container.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, "px");
m_magnitude_slider->set_range(0, 50);
m_magnitude_slider->set_value(m_radius);
m_magnitude_slider->on_change = [&](int value) {
m_radius = value;
update_preview();
};
auto& gaussian_container = m_settings_widget->add<GUI::Widget>();
gaussian_container.set_fixed_height(20);
gaussian_container.set_layout<GUI::HorizontalBoxLayout>();

View file

@ -28,12 +28,15 @@ private:
bool m_use_vector { false };
size_t m_radius_x { 0 };
size_t m_radius_y { 0 };
size_t m_angle { 0 };
bool m_approximate_gauss { false };
RefPtr<GUI::Widget> m_radius_container { nullptr };
RefPtr<GUI::Widget> m_asymmetric_radius_container { nullptr };
RefPtr<GUI::Widget> m_vector_container { nullptr };
RefPtr<GUI::CheckBox> m_gaussian_checkbox { nullptr };
RefPtr<GUI::CheckBox> m_vector_checkbox { nullptr };
RefPtr<GUI::ValueSlider> m_radius_x_slider { nullptr };
RefPtr<GUI::ValueSlider> m_radius_y_slider { nullptr };
RefPtr<GUI::ValueSlider> m_angle_slider { nullptr };