mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-24 10:22:05 -05:00
PixelPaint: Use the wrapped filters for the Filter Gallery
Now, the filters can supply the Filter Gallery with a GUI::Widget such that the user can interact with the filter. The Filter Gallery in turn only calls apply() on the filter once it should be run. This decouples the PixelPaint filters a lot from the ones supported by LibGfx and paves the way to filters with settings. For now there still are just the plain LibGfx filters so this change feels like introducing a lot of boilerplate, but in the future there will be a lot more to see.
This commit is contained in:
parent
0deadcdb28
commit
d42abb3c7b
4 changed files with 55 additions and 141 deletions
|
@ -25,30 +25,41 @@ FilterGallery::FilterGallery(GUI::Window* parent_window, ImageEditor* editor)
|
|||
if (!main_widget.load_from_gml(filter_gallery_gml))
|
||||
VERIFY_NOT_REACHED();
|
||||
|
||||
auto filter_tree = main_widget.find_descendant_of_type_named<GUI::TreeView>("tree_view");
|
||||
m_filter_tree = main_widget.find_descendant_of_type_named<GUI::TreeView>("tree_view");
|
||||
auto apply_button = main_widget.find_descendant_of_type_named<GUI::Button>("apply_button");
|
||||
auto cancel_button = main_widget.find_descendant_of_type_named<GUI::Button>("cancel_button");
|
||||
auto config_widget = main_widget.find_descendant_of_type_named<GUI::Widget>("config_widget");
|
||||
m_config_widget = main_widget.find_descendant_of_type_named<GUI::Widget>("config_widget");
|
||||
|
||||
VERIFY(filter_tree);
|
||||
VERIFY(m_filter_tree);
|
||||
VERIFY(apply_button);
|
||||
VERIFY(cancel_button);
|
||||
VERIFY(config_widget);
|
||||
VERIFY(m_config_widget);
|
||||
|
||||
auto filter_model = FilterModel::create(editor);
|
||||
filter_tree->set_model(filter_model);
|
||||
filter_tree->expand_tree();
|
||||
m_filter_tree->set_model(filter_model);
|
||||
m_filter_tree->expand_tree();
|
||||
|
||||
apply_button->on_click = [this, filter_tree](auto) {
|
||||
auto selected_index = filter_tree->selection().first();
|
||||
m_filter_tree->on_selection_change = [this]() {
|
||||
auto selected_index = m_filter_tree->selection().first();
|
||||
if (!selected_index.is_valid())
|
||||
done(ExecResult::ExecAborted);
|
||||
return;
|
||||
|
||||
auto selected_filter = static_cast<const FilterModel::FilterInfo*>(selected_index.internal_data());
|
||||
if (selected_filter->type != FilterModel::FilterInfo::Type::Filter)
|
||||
return;
|
||||
|
||||
m_selected_filter = selected_filter->filter;
|
||||
|
||||
m_selected_filter_config_widget = m_selected_filter->get_settings_widget();
|
||||
m_config_widget->remove_all_children();
|
||||
m_config_widget->add_child(*m_selected_filter_config_widget);
|
||||
};
|
||||
|
||||
apply_button->on_click = [this](auto) {
|
||||
if (!m_selected_filter)
|
||||
done(ExecResult::ExecAborted);
|
||||
|
||||
selected_filter->apply_filter();
|
||||
m_selected_filter->apply();
|
||||
done(ExecResult::ExecOK);
|
||||
};
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "Filters/Filter.h"
|
||||
#include "ImageEditor.h"
|
||||
#include <LibGUI/Dialog.h>
|
||||
|
||||
|
@ -16,6 +17,10 @@ class FilterGallery final : public GUI::Dialog {
|
|||
|
||||
private:
|
||||
FilterGallery(GUI::Window* parent_window, ImageEditor*);
|
||||
GUI::TreeView* m_filter_tree { nullptr };
|
||||
GUI::Widget* m_config_widget { nullptr };
|
||||
RefPtr<GUI::Widget> m_selected_filter_config_widget { nullptr };
|
||||
Filter* m_selected_filter { nullptr };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -7,144 +7,39 @@
|
|||
|
||||
#include "FilterModel.h"
|
||||
#include "FilterParams.h"
|
||||
#include "Filters/BoxBlur3.h"
|
||||
#include "Filters/BoxBlur5.h"
|
||||
#include "Filters/GaussBlur3.h"
|
||||
#include "Filters/GaussBlur5.h"
|
||||
#include "Filters/Grayscale.h"
|
||||
#include "Filters/Invert.h"
|
||||
#include "Filters/LaplaceCardinal.h"
|
||||
#include "Filters/LaplaceDiagonal.h"
|
||||
#include "Filters/Sharpen.h"
|
||||
#include "Layer.h"
|
||||
#include <LibGUI/FileIconProvider.h>
|
||||
#include <LibGfx/Filters/LaplacianFilter.h>
|
||||
|
||||
namespace PixelPaint {
|
||||
FilterModel::FilterModel(ImageEditor* editor)
|
||||
{
|
||||
auto spatial_category = FilterInfo::create_category("Spatial");
|
||||
|
||||
auto edge_detect_category = FilterInfo::create_category("Edge Detect", spatial_category);
|
||||
auto laplace_cardinal_filter = FilterInfo::create_filter(
|
||||
"Laplacian (Cardinal)", [editor]() {
|
||||
if (!editor)
|
||||
return;
|
||||
if (auto* layer = editor->active_layer()) {
|
||||
Gfx::LaplacianFilter filter;
|
||||
if (auto parameters = PixelPaint::FilterParameters<Gfx::LaplacianFilter>::get(false)) {
|
||||
filter.apply(layer->bitmap(), layer->rect(), layer->bitmap(), layer->rect(), *parameters);
|
||||
layer->did_modify_bitmap(layer->rect());
|
||||
editor->did_complete_action();
|
||||
}
|
||||
}
|
||||
},
|
||||
edge_detect_category);
|
||||
auto laplace_diagonal_filter = FilterInfo::create_filter(
|
||||
"Laplacian (Diagonal)", [editor]() {
|
||||
if (!editor)
|
||||
return;
|
||||
if (auto* layer = editor->active_layer()) {
|
||||
Gfx::LaplacianFilter filter;
|
||||
if (auto parameters = PixelPaint::FilterParameters<Gfx::LaplacianFilter>::get(true)) {
|
||||
filter.apply(layer->bitmap(), layer->rect(), layer->bitmap(), layer->rect(), *parameters);
|
||||
layer->did_modify_bitmap(layer->rect());
|
||||
editor->did_complete_action();
|
||||
}
|
||||
}
|
||||
},
|
||||
edge_detect_category);
|
||||
auto edge_detect_category = FilterInfo::create_category("Edge Detection", spatial_category);
|
||||
auto laplace_cardinal_filter = FilterInfo::create_filter<Filters::LaplaceCardinal>(editor, edge_detect_category);
|
||||
auto laplace_diagonal_filter = FilterInfo::create_filter<Filters::LaplaceDiagonal>(editor, edge_detect_category);
|
||||
|
||||
auto blur_category = FilterInfo::create_category("Blur & Sharpen", spatial_category);
|
||||
auto gaussian_blur_filter_3 = FilterInfo::create_filter(
|
||||
"Gaussian Blur (3x3)", [editor]() {
|
||||
if (!editor)
|
||||
return;
|
||||
if (auto* layer = editor->active_layer()) {
|
||||
Gfx::SpatialGaussianBlurFilter<3> filter;
|
||||
if (auto parameters = PixelPaint::FilterParameters<Gfx::SpatialGaussianBlurFilter<3>>::get()) {
|
||||
filter.apply(layer->bitmap(), layer->rect(), layer->bitmap(), layer->rect(), *parameters);
|
||||
layer->did_modify_bitmap(layer->rect());
|
||||
editor->did_complete_action();
|
||||
}
|
||||
}
|
||||
},
|
||||
blur_category);
|
||||
auto gaussian_blur_filter_5 = FilterInfo::create_filter(
|
||||
"Gaussian Blur (5x5)", [editor]() {
|
||||
if (!editor)
|
||||
return;
|
||||
if (auto* layer = editor->active_layer()) {
|
||||
Gfx::SpatialGaussianBlurFilter<5> filter;
|
||||
if (auto parameters = PixelPaint::FilterParameters<Gfx::SpatialGaussianBlurFilter<3>>::get()) {
|
||||
filter.apply(layer->bitmap(), layer->rect(), layer->bitmap(), layer->rect(), *parameters);
|
||||
layer->did_modify_bitmap(layer->rect());
|
||||
editor->did_complete_action();
|
||||
}
|
||||
}
|
||||
},
|
||||
blur_category);
|
||||
auto box_blur_filter_3 = FilterInfo::create_filter(
|
||||
"Box Blur (3x3)", [editor]() {
|
||||
if (!editor)
|
||||
return;
|
||||
if (auto* layer = editor->active_layer()) {
|
||||
Gfx::BoxBlurFilter<3> filter;
|
||||
if (auto parameters = PixelPaint::FilterParameters<Gfx::BoxBlurFilter<3>>::get()) {
|
||||
filter.apply(layer->bitmap(), layer->rect(), layer->bitmap(), layer->rect(), *parameters);
|
||||
layer->did_modify_bitmap(layer->rect());
|
||||
editor->did_complete_action();
|
||||
}
|
||||
}
|
||||
},
|
||||
blur_category);
|
||||
auto box_blur_filter_5 = FilterInfo::create_filter(
|
||||
"Box Blur (5x5)", [editor]() {
|
||||
if (!editor)
|
||||
return;
|
||||
if (auto* layer = editor->active_layer()) {
|
||||
Gfx::BoxBlurFilter<5> filter;
|
||||
if (auto parameters = PixelPaint::FilterParameters<Gfx::BoxBlurFilter<3>>::get()) {
|
||||
filter.apply(layer->bitmap(), layer->rect(), layer->bitmap(), layer->rect(), *parameters);
|
||||
layer->did_modify_bitmap(layer->rect());
|
||||
editor->did_complete_action();
|
||||
}
|
||||
}
|
||||
},
|
||||
blur_category);
|
||||
auto sharpen_filter = FilterInfo::create_filter(
|
||||
"Sharpen", [editor]() {
|
||||
if (!editor)
|
||||
return;
|
||||
if (auto* layer = editor->active_layer()) {
|
||||
Gfx::SharpenFilter filter;
|
||||
if (auto parameters = PixelPaint::FilterParameters<Gfx::SharpenFilter>::get()) {
|
||||
filter.apply(layer->bitmap(), layer->rect(), layer->bitmap(), layer->rect(), *parameters);
|
||||
layer->did_modify_bitmap(layer->rect());
|
||||
editor->did_complete_action();
|
||||
}
|
||||
}
|
||||
},
|
||||
blur_category);
|
||||
auto gaussian_blur_filter_3 = FilterInfo::create_filter<Filters::GaussBlur3>(editor, blur_category);
|
||||
auto gaussian_blur_filter_5 = FilterInfo::create_filter<Filters::GaussBlur5>(editor, blur_category);
|
||||
auto box_blur_filter_3 = FilterInfo::create_filter<Filters::BoxBlur3>(editor, blur_category);
|
||||
auto box_blur_filter_5 = FilterInfo::create_filter<Filters::BoxBlur5>(editor, blur_category);
|
||||
auto sharpen_filter = FilterInfo::create_filter<Filters::Sharpen>(editor, blur_category);
|
||||
|
||||
m_filters.append(spatial_category);
|
||||
|
||||
auto color_category = FilterInfo::create_category("Color");
|
||||
auto grayscale_filter = FilterInfo::create_filter(
|
||||
"Grayscale", [editor]() {
|
||||
if (!editor)
|
||||
return;
|
||||
if (auto* layer = editor->active_layer()) {
|
||||
Gfx::GrayscaleFilter filter;
|
||||
filter.apply(layer->bitmap(), layer->rect(), layer->bitmap(), layer->rect());
|
||||
layer->did_modify_bitmap(layer->rect());
|
||||
editor->did_complete_action();
|
||||
}
|
||||
},
|
||||
color_category);
|
||||
auto invert_filter = FilterInfo::create_filter(
|
||||
"Invert", [editor]() {
|
||||
if (!editor)
|
||||
return;
|
||||
if (auto* layer = editor->active_layer()) {
|
||||
Gfx::InvertFilter filter;
|
||||
filter.apply(layer->bitmap(), layer->rect(), layer->bitmap(), layer->rect());
|
||||
layer->did_modify_bitmap(layer->rect());
|
||||
editor->did_complete_action();
|
||||
}
|
||||
},
|
||||
color_category);
|
||||
auto grayscale_filter = FilterInfo::create_filter<Filters::Grayscale>(editor, color_category);
|
||||
auto invert_filter = FilterInfo::create_filter<Filters::Invert>(editor, color_category);
|
||||
|
||||
m_filters.append(color_category);
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "Filters/Filter.h"
|
||||
#include "ImageEditor.h"
|
||||
#include <AK/NonnullRefPtr.h>
|
||||
#include <LibGUI/Model.h>
|
||||
|
@ -24,19 +25,21 @@ public:
|
|||
|
||||
String text;
|
||||
|
||||
Function<void()> apply_filter;
|
||||
Filter* filter { nullptr };
|
||||
|
||||
NonnullRefPtrVector<FilterInfo> children;
|
||||
FilterInfo* parent;
|
||||
|
||||
static NonnullRefPtr<FilterInfo> create_filter(String const& text, Function<void()> apply_filter, FilterInfo* parent = nullptr)
|
||||
template<typename FilterType>
|
||||
static NonnullRefPtr<FilterInfo> create_filter(ImageEditor* editor, FilterInfo* parent = nullptr)
|
||||
{
|
||||
auto filter = adopt_ref(*new FilterInfo(Type::Filter, text, parent));
|
||||
filter->ref();
|
||||
filter->apply_filter = move(apply_filter);
|
||||
auto filter = static_cast<Filter*>(new FilterType(editor));
|
||||
auto filter_info = adopt_ref(*new FilterInfo(Type::Filter, filter->filter_name(), parent));
|
||||
filter_info->filter = filter;
|
||||
filter_info->ref();
|
||||
if (parent)
|
||||
parent->children.append(filter);
|
||||
return filter;
|
||||
parent->children.append(filter_info);
|
||||
return filter_info;
|
||||
}
|
||||
|
||||
static NonnullRefPtr<FilterInfo> create_category(String const& text, FilterInfo* parent = nullptr)
|
||||
|
|
Loading…
Add table
Reference in a new issue