mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 23:50:19 +00:00
PixelPaint: Rebuild FilterGallery tree using TreeViewModel
This commit is contained in:
parent
5bb38296b1
commit
ffc5fed79f
Notes:
sideshowbarker
2024-07-17 10:54:50 +09:00
Author: https://github.com/linusg Commit: https://github.com/SerenityOS/serenity/commit/ffc5fed79f Pull-request: https://github.com/SerenityOS/serenity/pull/14014 Reviewed-by: https://github.com/alimpfard Reviewed-by: https://github.com/kennethmyhra
7 changed files with 105 additions and 208 deletions
|
@ -16,7 +16,7 @@ set(SOURCES
|
|||
EditGuideDialogGML.h
|
||||
FilterGallery.cpp
|
||||
FilterGalleryGML.h
|
||||
FilterModel.cpp
|
||||
FilterTreeModel.cpp
|
||||
FilterPreviewWidget.cpp
|
||||
Filters/Bloom.cpp
|
||||
Filters/BoxBlur3.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);
|
||||
};
|
||||
|
|
|
@ -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 {};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
Userland/Applications/PixelPaint/FilterTreeModel.cpp
Normal file
63
Userland/Applications/PixelPaint/FilterTreeModel.cpp
Normal file
|
@ -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
Userland/Applications/PixelPaint/FilterTreeModel.h
Normal file
34
Userland/Applications/PixelPaint/FilterTreeModel.h
Normal file
|
@ -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*);
|
||||
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "Filter.h"
|
||||
#include <LibGUI/CheckBox.h>
|
||||
#include <LibGUI/ValueSlider.h>
|
||||
|
||||
namespace PixelPaint::Filters {
|
||||
|
|
Loading…
Reference in a new issue