From ffc5fed79f5aa988c87eeb9eb8350027980965d5 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Thu, 12 May 2022 21:37:43 +0200 Subject: [PATCH] PixelPaint: Rebuild FilterGallery tree using TreeViewModel --- .../Applications/PixelPaint/CMakeLists.txt | 2 +- .../Applications/PixelPaint/FilterGallery.cpp | 12 +- .../Applications/PixelPaint/FilterModel.cpp | 120 ------------------ .../Applications/PixelPaint/FilterModel.h | 81 ------------ .../PixelPaint/FilterTreeModel.cpp | 63 +++++++++ .../Applications/PixelPaint/FilterTreeModel.h | 34 +++++ .../PixelPaint/Filters/FastBoxBlur.h | 1 + 7 files changed, 105 insertions(+), 208 deletions(-) delete mode 100644 Userland/Applications/PixelPaint/FilterModel.cpp delete mode 100644 Userland/Applications/PixelPaint/FilterModel.h create mode 100644 Userland/Applications/PixelPaint/FilterTreeModel.cpp create mode 100644 Userland/Applications/PixelPaint/FilterTreeModel.h diff --git a/Userland/Applications/PixelPaint/CMakeLists.txt b/Userland/Applications/PixelPaint/CMakeLists.txt index e8c1f5f7e1f..62b181a8251 100644 --- a/Userland/Applications/PixelPaint/CMakeLists.txt +++ b/Userland/Applications/PixelPaint/CMakeLists.txt @@ -16,7 +16,7 @@ set(SOURCES EditGuideDialogGML.h FilterGallery.cpp FilterGalleryGML.h - FilterModel.cpp + FilterTreeModel.cpp FilterPreviewWidget.cpp Filters/Bloom.cpp Filters/BoxBlur3.cpp diff --git a/Userland/Applications/PixelPaint/FilterGallery.cpp b/Userland/Applications/PixelPaint/FilterGallery.cpp index 2ad6c8b3d9d..20ab3c32d2d 100644 --- a/Userland/Applications/PixelPaint/FilterGallery.cpp +++ b/Userland/Applications/PixelPaint/FilterGallery.cpp @@ -5,7 +5,7 @@ */ #include "FilterGallery.h" -#include "FilterModel.h" +#include "FilterTreeModel.h" #include #include #include @@ -37,8 +37,8 @@ FilterGallery::FilterGallery(GUI::Window* parent_window, ImageEditor* editor) VERIFY(m_config_widget); VERIFY(m_preview_widget); - auto filter_model = FilterModel::create(editor); - m_filter_tree->set_model(filter_model); + auto filter_tree_model = MUST(create_filter_tree_model(editor)); + m_filter_tree->set_model(filter_tree_model); m_filter_tree->expand_tree(); m_filter_tree->on_selection_change = [this]() { @@ -48,13 +48,13 @@ FilterGallery::FilterGallery(GUI::Window* parent_window, ImageEditor* editor) return; } - auto selected_filter = static_cast(selected_index.internal_data()); - if (selected_filter->type != FilterModel::FilterInfo::Type::Filter) { + auto& node = *static_cast(selected_index.internal_data()); + if (!is(node)) { m_preview_widget->clear_filter(); return; } - m_selected_filter = selected_filter->filter; + m_selected_filter = &static_cast(node).filter(); m_selected_filter->on_settings_change = [&]() { m_preview_widget->set_filter(m_selected_filter); }; diff --git a/Userland/Applications/PixelPaint/FilterModel.cpp b/Userland/Applications/PixelPaint/FilterModel.cpp deleted file mode 100644 index eb0fd6d57af..00000000000 --- a/Userland/Applications/PixelPaint/FilterModel.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2021-2022, Tobias Christiansen - * Copyright (c) 2021, Mustafa Quraish - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include "FilterModel.h" -#include "FilterParams.h" -#include "Filters/Bloom.h" -#include "Filters/BoxBlur3.h" -#include "Filters/BoxBlur5.h" -#include "Filters/FastBoxBlur.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/Sepia.h" -#include "Filters/Sharpen.h" -#include "Layer.h" -#include - -namespace PixelPaint { -FilterModel::FilterModel(ImageEditor* editor) -{ - auto artistic_category = FilterInfo::create_category("Artistic"); - auto bloom_filter = FilterInfo::create_filter(editor, artistic_category); - - m_filters.append(artistic_category); - - auto spatial_category = FilterInfo::create_category("Spatial"); - - auto edge_detect_category = FilterInfo::create_category("Edge Detection", spatial_category); - auto laplace_cardinal_filter = FilterInfo::create_filter(editor, edge_detect_category); - auto laplace_diagonal_filter = FilterInfo::create_filter(editor, edge_detect_category); - - auto blur_category = FilterInfo::create_category("Blur & Sharpen", spatial_category); - auto fast_box_filter = FilterInfo::create_filter(editor, blur_category); - auto gaussian_blur_filter_3 = FilterInfo::create_filter(editor, blur_category); - auto gaussian_blur_filter_5 = FilterInfo::create_filter(editor, blur_category); - auto box_blur_filter_3 = FilterInfo::create_filter(editor, blur_category); - auto box_blur_filter_5 = FilterInfo::create_filter(editor, blur_category); - auto sharpen_filter = FilterInfo::create_filter(editor, blur_category); - - m_filters.append(spatial_category); - - auto color_category = FilterInfo::create_category("Color"); - auto grayscale_filter = FilterInfo::create_filter(editor, color_category); - auto invert_filter = FilterInfo::create_filter(editor, color_category); - auto sepia_filter = FilterInfo::create_filter(editor, color_category); - - m_filters.append(color_category); - - auto filter_bitmap = Gfx::Bitmap::try_load_from_file("/res/icons/pixelpaint/filter.png").release_value_but_fixme_should_propagate_errors(); - m_filter_icon = GUI::Icon(filter_bitmap); -} - -GUI::ModelIndex FilterModel::index(int row, int column, const GUI::ModelIndex& parent_index) const -{ - if (!parent_index.is_valid()) { - if (static_cast(row) >= m_filters.size()) - return {}; - return create_index(row, column, &m_filters[row]); - } - auto* parent = static_cast(parent_index.internal_data()); - if (static_cast(row) >= parent->children.size()) - return {}; - auto* child = &parent->children[row]; - return create_index(row, column, child); -} - -GUI::ModelIndex FilterModel::parent_index(const GUI::ModelIndex& index) const -{ - if (!index.is_valid()) - return {}; - - auto* child = static_cast(index.internal_data()); - auto* parent = child->parent; - if (parent == nullptr) - return {}; - - if (parent->parent == nullptr) { - for (size_t row = 0; row < m_filters.size(); row++) - if (m_filters.ptr_at(row).ptr() == parent) - return create_index(row, 0, parent); - VERIFY_NOT_REACHED(); - } - for (size_t row = 0; row < parent->parent->children.size(); row++) { - FilterInfo* child_at_row = parent->parent->children.ptr_at(row).ptr(); - if (child_at_row == parent) - return create_index(row, 0, parent); - } - VERIFY_NOT_REACHED(); -} - -int FilterModel::row_count(const GUI::ModelIndex& index) const -{ - if (!index.is_valid()) - return m_filters.size(); - auto* node = static_cast(index.internal_data()); - return node->children.size(); -} - -GUI::Variant FilterModel::data(const GUI::ModelIndex& index, GUI::ModelRole role) const -{ - auto* filter = static_cast(index.internal_data()); - switch (role) { - case GUI::ModelRole::Display: - return filter->text; - case GUI::ModelRole::Icon: - if (filter->type == FilterInfo::Type::Category) - return GUI::FileIconProvider::directory_icon(); - return m_filter_icon; - default: - return {}; - } -} -} diff --git a/Userland/Applications/PixelPaint/FilterModel.h b/Userland/Applications/PixelPaint/FilterModel.h deleted file mode 100644 index 1393b90f75d..00000000000 --- a/Userland/Applications/PixelPaint/FilterModel.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2021, Tobias Christiansen - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "Filters/Filter.h" -#include "ImageEditor.h" -#include -#include - -namespace PixelPaint { - -class FilterModel final : public GUI::Model { - -public: - class FilterInfo : public RefCounted { - public: - enum class Type { - Category, - Filter, - } type; - - String text; - - Filter* filter { nullptr }; - - NonnullRefPtrVector children; - FilterInfo* parent; - - template - static NonnullRefPtr create_filter(ImageEditor* editor, FilterInfo* parent = nullptr) - { - auto filter = static_cast(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_info); - return filter_info; - } - - static NonnullRefPtr create_category(String const& text, FilterInfo* parent = nullptr) - { - auto category = adopt_ref(*new FilterInfo(Type::Category, text, parent)); - category->ref(); - if (parent) - parent->children.append(category); - return category; - } - - FilterInfo(Type type, String text, FilterInfo* parent) - : type(type) - , text(move(text)) - , parent(parent) - { - } - }; - - static NonnullRefPtr create(ImageEditor* editor) - { - return adopt_ref(*new FilterModel(editor)); - } - - virtual ~FilterModel() override {}; - - virtual int row_count(const GUI::ModelIndex& = GUI::ModelIndex()) const override; - virtual int column_count(const GUI::ModelIndex& = GUI::ModelIndex()) const override { return 1; } - virtual GUI::Variant data(const GUI::ModelIndex& index, GUI::ModelRole role) const override; - virtual GUI::ModelIndex parent_index(const GUI::ModelIndex&) const override; - virtual GUI::ModelIndex index(int row, int column = 0, const GUI::ModelIndex& = GUI::ModelIndex()) const override; - -private: - FilterModel(ImageEditor* editor); - - NonnullRefPtrVector m_filters; - GUI::Icon m_filter_icon; -}; -} diff --git a/Userland/Applications/PixelPaint/FilterTreeModel.cpp b/Userland/Applications/PixelPaint/FilterTreeModel.cpp new file mode 100644 index 00000000000..cdfc24bf1c1 --- /dev/null +++ b/Userland/Applications/PixelPaint/FilterTreeModel.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021-2022, Tobias Christiansen + * Copyright (c) 2021, Mustafa Quraish + * Copyright (c) 2022, Linus Groh + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "FilterTreeModel.h" +#include "Filters/Bloom.h" +#include "Filters/BoxBlur3.h" +#include "Filters/BoxBlur5.h" +#include "Filters/FastBoxBlur.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/Sepia.h" +#include "Filters/Sharpen.h" +#include + +namespace PixelPaint { + +ErrorOr> create_filter_tree_model(ImageEditor* editor) +{ + auto directory_icon = GUI::FileIconProvider::directory_icon(); + auto filter_icon = GUI::Icon(TRY(Gfx::Bitmap::try_load_from_file("/res/icons/pixelpaint/filter.png"))); + + auto filter_tree_model = GUI::TreeViewModel::create(); + + auto add_filter_node = [&](GUI::TreeViewModel::Node& node) { + auto filter = adopt_own(*new FilterType(editor)); + (void)node.add_node(filter->filter_name(), filter_icon, move(filter)); + }; + + auto artistic_category = filter_tree_model->add_node("Artistic", directory_icon); + add_filter_node.template operator()(artistic_category); + + auto spatial_category = filter_tree_model->add_node("Spatial", directory_icon); + + auto edge_detect_category = spatial_category->add_node("Edge Detection", directory_icon); + add_filter_node.template operator()(edge_detect_category); + add_filter_node.template operator()(edge_detect_category); + + auto blur_category = spatial_category->add_node("Blur & Sharpen", directory_icon); + add_filter_node.template operator()(blur_category); + add_filter_node.template operator()(blur_category); + add_filter_node.template operator()(blur_category); + add_filter_node.template operator()(blur_category); + add_filter_node.template operator()(blur_category); + add_filter_node.template operator()(blur_category); + + auto color_category = filter_tree_model->add_node("Color", directory_icon); + add_filter_node.template operator()(color_category); + add_filter_node.template operator()(color_category); + add_filter_node.template operator()(color_category); + + return filter_tree_model; +} + +} diff --git a/Userland/Applications/PixelPaint/FilterTreeModel.h b/Userland/Applications/PixelPaint/FilterTreeModel.h new file mode 100644 index 00000000000..48a4645c893 --- /dev/null +++ b/Userland/Applications/PixelPaint/FilterTreeModel.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021, Tobias Christiansen + * Copyright (c) 2022, Linus Groh + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "Filters/Filter.h" +#include "ImageEditor.h" +#include +#include + +namespace PixelPaint { + +class FilterNode final : public GUI::TreeViewModel::Node { +public: + FilterNode(String text, Optional icon, Node* parent_node, NonnullOwnPtr filter) + : Node(move(text), move(icon), parent_node) + , m_filter(move(filter)) + { + } + + Filter const& filter() const { return *m_filter; } + Filter& filter() { return *m_filter; } + +private: + NonnullOwnPtr m_filter; +}; + +ErrorOr> create_filter_tree_model(ImageEditor*); + +} diff --git a/Userland/Applications/PixelPaint/Filters/FastBoxBlur.h b/Userland/Applications/PixelPaint/Filters/FastBoxBlur.h index bf48e5f6b8b..9a501361248 100644 --- a/Userland/Applications/PixelPaint/Filters/FastBoxBlur.h +++ b/Userland/Applications/PixelPaint/Filters/FastBoxBlur.h @@ -7,6 +7,7 @@ #pragma once #include "Filter.h" +#include #include namespace PixelPaint::Filters {