summaryrefslogtreecommitdiff
path: root/Userland/Applications
diff options
context:
space:
mode:
authorsnooze <alaaps1@gmail.com>2022-02-09 11:00:36 +0530
committerAndreas Kling <kling@serenityos.org>2022-02-12 12:21:35 +0100
commite9d3f3793c26c343001ab5eb87dc92dec46d6a9e (patch)
treebe8b6e465f7d115797e0c2a0e56b01f7b3c76245 /Userland/Applications
parent44cf3ac60f0ae16c4300d9c312f793b4f018f0da (diff)
downloadserenity-e9d3f3793c26c343001ab5eb87dc92dec46d6a9e.zip
PixelPaint: Add a preview in FilterGallery
Now FilterGallery shows the preview of the currently selected filter applied on the currently active layer
Diffstat (limited to 'Userland/Applications')
-rw-r--r--Userland/Applications/PixelPaint/CMakeLists.txt1
-rw-r--r--Userland/Applications/PixelPaint/FilterGallery.cpp16
-rw-r--r--Userland/Applications/PixelPaint/FilterGallery.gml24
-rw-r--r--Userland/Applications/PixelPaint/FilterGallery.h2
-rw-r--r--Userland/Applications/PixelPaint/FilterPreviewWidget.cpp67
-rw-r--r--Userland/Applications/PixelPaint/FilterPreviewWidget.h35
-rw-r--r--Userland/Applications/PixelPaint/Filters/Bloom.cpp2
-rw-r--r--Userland/Applications/PixelPaint/Filters/FastBoxBlur.cpp2
-rw-r--r--Userland/Applications/PixelPaint/Filters/Filter.cpp6
-rw-r--r--Userland/Applications/PixelPaint/Filters/Filter.h3
-rw-r--r--Userland/Applications/PixelPaint/Filters/Sepia.cpp1
11 files changed, 155 insertions, 4 deletions
diff --git a/Userland/Applications/PixelPaint/CMakeLists.txt b/Userland/Applications/PixelPaint/CMakeLists.txt
index d3ca024630..65aeef7394 100644
--- a/Userland/Applications/PixelPaint/CMakeLists.txt
+++ b/Userland/Applications/PixelPaint/CMakeLists.txt
@@ -17,6 +17,7 @@ set(SOURCES
FilterGallery.cpp
FilterGalleryGML.h
FilterModel.cpp
+ FilterPreviewWidget.cpp
Filters/Bloom.cpp
Filters/BoxBlur3.cpp
Filters/BoxBlur5.cpp
diff --git a/Userland/Applications/PixelPaint/FilterGallery.cpp b/Userland/Applications/PixelPaint/FilterGallery.cpp
index 325e40b940..48844ffa9d 100644
--- a/Userland/Applications/PixelPaint/FilterGallery.cpp
+++ b/Userland/Applications/PixelPaint/FilterGallery.cpp
@@ -29,11 +29,13 @@ FilterGallery::FilterGallery(GUI::Window* parent_window, ImageEditor* editor)
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");
m_config_widget = main_widget.find_descendant_of_type_named<GUI::Widget>("config_widget");
+ m_preview_widget = main_widget.find_descendant_of_type_named<FilterPreviewWidget>("preview_widget");
VERIFY(m_filter_tree);
VERIFY(apply_button);
VERIFY(cancel_button);
VERIFY(m_config_widget);
+ VERIFY(m_preview_widget);
auto filter_model = FilterModel::create(editor);
m_filter_tree->set_model(filter_model);
@@ -41,20 +43,30 @@ FilterGallery::FilterGallery(GUI::Window* parent_window, ImageEditor* editor)
m_filter_tree->on_selection_change = [this]() {
auto selected_index = m_filter_tree->selection().first();
- if (!selected_index.is_valid())
+ if (!selected_index.is_valid()) {
+ m_preview_widget->clear_filter();
return;
+ }
auto selected_filter = static_cast<const FilterModel::FilterInfo*>(selected_index.internal_data());
- if (selected_filter->type != FilterModel::FilterInfo::Type::Filter)
+ if (selected_filter->type != FilterModel::FilterInfo::Type::Filter) {
+ m_preview_widget->clear_filter();
return;
+ }
m_selected_filter = selected_filter->filter;
+ m_selected_filter->on_settings_change = [&]() {
+ m_preview_widget->set_filter(m_selected_filter);
+ };
+ m_preview_widget->set_filter(m_selected_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);
};
+ m_preview_widget->set_bitmap(editor->active_layer()->bitmap().clone().release_value());
+
apply_button->on_click = [this](auto) {
if (!m_selected_filter) {
done(ExecResult::ExecAborted);
diff --git a/Userland/Applications/PixelPaint/FilterGallery.gml b/Userland/Applications/PixelPaint/FilterGallery.gml
index 833b95aa31..082e9012d8 100644
--- a/Userland/Applications/PixelPaint/FilterGallery.gml
+++ b/Userland/Applications/PixelPaint/FilterGallery.gml
@@ -13,11 +13,29 @@
}
@GUI::Widget {
- name: "config_widget"
- layout: @GUI::VerticalBoxLayout {
+ layout:@GUI::VerticalBoxLayout {
margins: [4]
}
+ @GUI::Widget {
+ name: "config_widget"
+
+ layout:@GUI::VerticalBoxLayout {
+ margins: [4]
+ }
+ }
+
+ @GUI::GroupBox {
+ title: "Preview"
+ layout: @GUI::VerticalBoxLayout {
+ margins: [4]
+ }
+
+ @PixelPaint::FilterPreviewWidget {
+ name: "preview_widget"
+ }
+ }
+
}
}
@@ -29,6 +47,8 @@
@GUI::Widget
+
+
@GUI::Button {
name: "apply_button"
text: "Apply"
diff --git a/Userland/Applications/PixelPaint/FilterGallery.h b/Userland/Applications/PixelPaint/FilterGallery.h
index 39ddcea584..fcf67ee761 100644
--- a/Userland/Applications/PixelPaint/FilterGallery.h
+++ b/Userland/Applications/PixelPaint/FilterGallery.h
@@ -6,6 +6,7 @@
#pragma once
+#include "FilterPreviewWidget.h"
#include "Filters/Filter.h"
#include "ImageEditor.h"
#include <LibGUI/Dialog.h>
@@ -19,6 +20,7 @@ private:
FilterGallery(GUI::Window* parent_window, ImageEditor*);
GUI::TreeView* m_filter_tree { nullptr };
GUI::Widget* m_config_widget { nullptr };
+ FilterPreviewWidget* m_preview_widget { nullptr };
RefPtr<GUI::Widget> m_selected_filter_config_widget { nullptr };
Filter* m_selected_filter { nullptr };
};
diff --git a/Userland/Applications/PixelPaint/FilterPreviewWidget.cpp b/Userland/Applications/PixelPaint/FilterPreviewWidget.cpp
new file mode 100644
index 0000000000..f86fe42769
--- /dev/null
+++ b/Userland/Applications/PixelPaint/FilterPreviewWidget.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2022, the SerenityOS developers.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include "FilterPreviewWidget.h"
+#include <LibGUI/Painter.h>
+#include <LibGfx/Palette.h>
+#include <LibGfx/Rect.h>
+
+REGISTER_WIDGET(PixelPaint, FilterPreviewWidget);
+
+namespace PixelPaint {
+
+FilterPreviewWidget::FilterPreviewWidget()
+{
+}
+
+FilterPreviewWidget::~FilterPreviewWidget()
+{
+}
+
+void FilterPreviewWidget::set_bitmap(const RefPtr<Gfx::Bitmap>& bitmap)
+{
+ m_bitmap = bitmap;
+ clear_filter();
+}
+
+void FilterPreviewWidget::set_filter(Filter* filter)
+{
+ if (filter)
+ filter->apply(*m_filtered_bitmap, *m_bitmap);
+ else
+ m_filtered_bitmap = m_bitmap->clone().release_value();
+ repaint();
+}
+
+void FilterPreviewWidget::clear_filter()
+{
+ set_filter(nullptr);
+}
+
+void FilterPreviewWidget::paint_event(GUI::PaintEvent& event)
+{
+ GUI::Painter painter(*this);
+ painter.add_clip_rect(event.rect());
+ auto preview_rect = event.rect();
+ auto bitmap_rect = m_filtered_bitmap->rect();
+
+ int scaled_width, scaled_height, dx = 0, dy = 0;
+ if (preview_rect.height() > preview_rect.width()) {
+ scaled_width = preview_rect.width();
+ scaled_height = ((float)bitmap_rect.height() / bitmap_rect.width()) * scaled_width;
+ dy = (preview_rect.height() - scaled_height) / 2;
+ } else {
+ scaled_height = preview_rect.height();
+ scaled_width = ((float)bitmap_rect.width() / bitmap_rect.height()) * scaled_height;
+ dx = (preview_rect.width() - scaled_width) / 2;
+ }
+
+ Gfx::IntRect scaled_rect(preview_rect.x() + dx, preview_rect.y() + dy, scaled_width, scaled_height);
+
+ painter.draw_scaled_bitmap(scaled_rect, *m_filtered_bitmap, m_filtered_bitmap->rect());
+}
+
+}
diff --git a/Userland/Applications/PixelPaint/FilterPreviewWidget.h b/Userland/Applications/PixelPaint/FilterPreviewWidget.h
new file mode 100644
index 0000000000..451ff90569
--- /dev/null
+++ b/Userland/Applications/PixelPaint/FilterPreviewWidget.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2022, the SerenityOS developers.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include "Filters/Filter.h"
+#include "ImageEditor.h"
+#include "Layer.h"
+#include <LibGUI/Frame.h>
+#include <LibGfx/Bitmap.h>
+
+namespace PixelPaint {
+
+class FilterPreviewWidget final : public GUI::Frame {
+ C_OBJECT(FilterPreviewWidget);
+
+public:
+ virtual ~FilterPreviewWidget() override;
+ void set_bitmap(const RefPtr<Gfx::Bitmap>& bitmap);
+ void set_filter(Filter* filter);
+ void clear_filter();
+
+private:
+ explicit FilterPreviewWidget();
+
+ RefPtr<Gfx::Bitmap> m_bitmap;
+ RefPtr<Gfx::Bitmap> m_filtered_bitmap;
+
+ virtual void paint_event(GUI::PaintEvent&) override;
+};
+
+}
diff --git a/Userland/Applications/PixelPaint/Filters/Bloom.cpp b/Userland/Applications/PixelPaint/Filters/Bloom.cpp
index 3c1ec93674..614388a606 100644
--- a/Userland/Applications/PixelPaint/Filters/Bloom.cpp
+++ b/Userland/Applications/PixelPaint/Filters/Bloom.cpp
@@ -59,6 +59,7 @@ RefPtr<GUI::Widget> Bloom::get_settings_widget()
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>();
@@ -75,6 +76,7 @@ RefPtr<GUI::Widget> Bloom::get_settings_widget()
radius_slider.set_value(m_blur_radius);
radius_slider.on_change = [&](int value) {
m_blur_radius = value;
+ update_preview();
};
}
diff --git a/Userland/Applications/PixelPaint/Filters/FastBoxBlur.cpp b/Userland/Applications/PixelPaint/Filters/FastBoxBlur.cpp
index 9375b487fa..4b9f62ccc7 100644
--- a/Userland/Applications/PixelPaint/Filters/FastBoxBlur.cpp
+++ b/Userland/Applications/PixelPaint/Filters/FastBoxBlur.cpp
@@ -54,6 +54,7 @@ RefPtr<GUI::Widget> FastBoxBlur::get_settings_widget()
radius_slider.set_value(m_radius);
radius_slider.on_change = [&](int value) {
m_radius = value;
+ update_preview();
};
auto& gaussian_container = m_settings_widget->add<GUI::Widget>();
@@ -66,6 +67,7 @@ RefPtr<GUI::Widget> FastBoxBlur::get_settings_widget()
gaussian_checkbox.set_tooltip("A real gaussian blur can be approximated by running the box blur multiple times with different weights.");
gaussian_checkbox.on_checked = [this](bool checked) {
m_approximate_gauss = checked;
+ update_preview();
};
}
diff --git a/Userland/Applications/PixelPaint/Filters/Filter.cpp b/Userland/Applications/PixelPaint/Filters/Filter.cpp
index a7dcfa5058..27f0f2d65d 100644
--- a/Userland/Applications/PixelPaint/Filters/Filter.cpp
+++ b/Userland/Applications/PixelPaint/Filters/Filter.cpp
@@ -37,4 +37,10 @@ void Filter::apply() const
}
}
+void Filter::update_preview()
+{
+ if (on_settings_change)
+ on_settings_change();
+}
+
}
diff --git a/Userland/Applications/PixelPaint/Filters/Filter.h b/Userland/Applications/PixelPaint/Filters/Filter.h
index 7752c931ad..3d201a0282 100644
--- a/Userland/Applications/PixelPaint/Filters/Filter.h
+++ b/Userland/Applications/PixelPaint/Filters/Filter.h
@@ -27,9 +27,12 @@ public:
Filter(ImageEditor* editor)
: m_editor(editor) {};
+ Function<void(void)> on_settings_change;
+
protected:
ImageEditor* m_editor { nullptr };
RefPtr<GUI::Widget> m_settings_widget { nullptr };
+ void update_preview();
};
}
diff --git a/Userland/Applications/PixelPaint/Filters/Sepia.cpp b/Userland/Applications/PixelPaint/Filters/Sepia.cpp
index 4a3b87099b..e3e0851502 100644
--- a/Userland/Applications/PixelPaint/Filters/Sepia.cpp
+++ b/Userland/Applications/PixelPaint/Filters/Sepia.cpp
@@ -42,6 +42,7 @@ RefPtr<GUI::Widget> Sepia::get_settings_widget()
amount_slider.set_value(m_amount * 100);
amount_slider.on_change = [&](int value) {
m_amount = value * 0.01f;
+ update_preview();
};
}