فهرست منبع

PixelPaint: Rebuild FilterGallery tree using TreeViewModel

Linus Groh 3 سال پیش
والد
کامیت
ffc5fed79f

+ 1 - 1
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

+ 6 - 6
Userland/Applications/PixelPaint/FilterGallery.cpp

@@ -5,7 +5,7 @@
  */
 
 #include "FilterGallery.h"
-#include "FilterModel.h"
+#include "FilterTreeModel.h"
 #include <Applications/PixelPaint/FilterGalleryGML.h>
 #include <LibGUI/Button.h>
 #include <LibGUI/TreeView.h>
@@ -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<const FilterModel::FilterInfo*>(selected_index.internal_data());
-        if (selected_filter->type != FilterModel::FilterInfo::Type::Filter) {
+        auto& node = *static_cast<GUI::TreeViewModel::Node*>(selected_index.internal_data());
+        if (!is<FilterNode>(node)) {
             m_preview_widget->clear_filter();
             return;
         }
 
-        m_selected_filter = selected_filter->filter;
+        m_selected_filter = &static_cast<FilterNode&>(node).filter();
         m_selected_filter->on_settings_change = [&]() {
             m_preview_widget->set_filter(m_selected_filter);
         };

+ 0 - 120
Userland/Applications/PixelPaint/FilterModel.cpp

@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 2021-2022, Tobias Christiansen <tobyase@serenityos.org>
- * Copyright (c) 2021, Mustafa Quraish <mustafa@serenityos.org>
- *
- * 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 <LibGUI/FileIconProvider.h>
-
-namespace PixelPaint {
-FilterModel::FilterModel(ImageEditor* editor)
-{
-    auto artistic_category = FilterInfo::create_category("Artistic");
-    auto bloom_filter = FilterInfo::create_filter<Filters::Bloom>(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<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 fast_box_filter = FilterInfo::create_filter<Filters::FastBoxBlur>(editor, 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<Filters::Grayscale>(editor, color_category);
-    auto invert_filter = FilterInfo::create_filter<Filters::Invert>(editor, color_category);
-    auto sepia_filter = FilterInfo::create_filter<Filters::Sepia>(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<size_t>(row) >= m_filters.size())
-            return {};
-        return create_index(row, column, &m_filters[row]);
-    }
-    auto* parent = static_cast<FilterInfo const*>(parent_index.internal_data());
-    if (static_cast<size_t>(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<FilterInfo const*>(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<FilterInfo const*>(index.internal_data());
-    return node->children.size();
-}
-
-GUI::Variant FilterModel::data(const GUI::ModelIndex& index, GUI::ModelRole role) const
-{
-    auto* filter = static_cast<FilterInfo const*>(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 {};
-    }
-}
-}

+ 0 - 81
Userland/Applications/PixelPaint/FilterModel.h

@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#pragma once
-
-#include "Filters/Filter.h"
-#include "ImageEditor.h"
-#include <AK/NonnullRefPtr.h>
-#include <LibGUI/Model.h>
-
-namespace PixelPaint {
-
-class FilterModel final : public GUI::Model {
-
-public:
-    class FilterInfo : public RefCounted<FilterInfo> {
-    public:
-        enum class Type {
-            Category,
-            Filter,
-        } type;
-
-        String text;
-
-        Filter* filter { nullptr };
-
-        NonnullRefPtrVector<FilterInfo> children;
-        FilterInfo* parent;
-
-        template<typename FilterType>
-        static NonnullRefPtr<FilterInfo> create_filter(ImageEditor* editor, FilterInfo* parent = nullptr)
-        {
-            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_info);
-            return filter_info;
-        }
-
-        static NonnullRefPtr<FilterInfo> 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<FilterModel> 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<FilterInfo> m_filters;
-    GUI::Icon m_filter_icon;
-};
-}

+ 63 - 0
Userland/Applications/PixelPaint/FilterTreeModel.cpp

@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2021-2022, Tobias Christiansen <tobyase@serenityos.org>
+ * Copyright (c) 2021, Mustafa Quraish <mustafa@serenityos.org>
+ * Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
+ *
+ * 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 <LibGUI/FileIconProvider.h>
+
+namespace PixelPaint {
+
+ErrorOr<NonnullRefPtr<GUI::TreeViewModel>> 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 = [&]<typename FilterType>(GUI::TreeViewModel::Node& node) {
+        auto filter = adopt_own(*new FilterType(editor));
+        (void)node.add_node<FilterNode>(filter->filter_name(), filter_icon, move(filter));
+    };
+
+    auto artistic_category = filter_tree_model->add_node("Artistic", directory_icon);
+    add_filter_node.template operator()<Filters::Bloom>(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()<Filters::LaplaceCardinal>(edge_detect_category);
+    add_filter_node.template operator()<Filters::LaplaceDiagonal>(edge_detect_category);
+
+    auto blur_category = spatial_category->add_node("Blur & Sharpen", directory_icon);
+    add_filter_node.template operator()<Filters::FastBoxBlur>(blur_category);
+    add_filter_node.template operator()<Filters::GaussBlur3>(blur_category);
+    add_filter_node.template operator()<Filters::GaussBlur5>(blur_category);
+    add_filter_node.template operator()<Filters::BoxBlur3>(blur_category);
+    add_filter_node.template operator()<Filters::BoxBlur5>(blur_category);
+    add_filter_node.template operator()<Filters::Sharpen>(blur_category);
+
+    auto color_category = filter_tree_model->add_node("Color", directory_icon);
+    add_filter_node.template operator()<Filters::Grayscale>(color_category);
+    add_filter_node.template operator()<Filters::Invert>(color_category);
+    add_filter_node.template operator()<Filters::Sepia>(color_category);
+
+    return filter_tree_model;
+}
+
+}

+ 34 - 0
Userland/Applications/PixelPaint/FilterTreeModel.h

@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org>
+ * Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include "Filters/Filter.h"
+#include "ImageEditor.h"
+#include <AK/NonnullOwnPtr.h>
+#include <LibGUI/TreeViewModel.h>
+
+namespace PixelPaint {
+
+class FilterNode final : public GUI::TreeViewModel::Node {
+public:
+    FilterNode(String text, Optional<GUI::Icon> icon, Node* parent_node, NonnullOwnPtr<Filter> 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<Filter> m_filter;
+};
+
+ErrorOr<NonnullRefPtr<GUI::TreeViewModel>> create_filter_tree_model(ImageEditor*);
+
+}

+ 1 - 0
Userland/Applications/PixelPaint/Filters/FastBoxBlur.h

@@ -7,6 +7,7 @@
 #pragma once
 
 #include "Filter.h"
+#include <LibGUI/CheckBox.h>
 #include <LibGUI/ValueSlider.h>
 
 namespace PixelPaint::Filters {