mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 15:37:46 +00:00
PixelPaint: Add Filter Gallery Dialog to the Filter Menu
This patch adds the bare bones of the new Filter Gallery. For now, only the gml and the basic layout got added, a fairly boringw indow pops up when "Filter Gallery" is called. The code for the Model used by the TreeView is taken in large parts from HackStudio's VariableModel.
This commit is contained in:
parent
b46ea5158d
commit
f47026b1d6
7 changed files with 277 additions and 0 deletions
|
@ -7,12 +7,16 @@ serenity_component(
|
|||
|
||||
compile_gml(PixelPaintWindow.gml PixelPaintWindowGML.h pixel_paint_window_gml)
|
||||
compile_gml(EditGuideDialog.gml EditGuideDialogGML.h edit_guide_dialog_gml)
|
||||
compile_gml(FilterGallery.gml FilterGalleryGML.h filter_gallery_gml)
|
||||
|
||||
set(SOURCES
|
||||
CreateNewImageDialog.cpp
|
||||
CreateNewLayerDialog.cpp
|
||||
EditGuideDialog.cpp
|
||||
EditGuideDialogGML.h
|
||||
FilterGallery.cpp
|
||||
FilterGalleryGML.h
|
||||
FilterModel.cpp
|
||||
Image.cpp
|
||||
ImageEditor.cpp
|
||||
Layer.cpp
|
||||
|
|
51
Userland/Applications/PixelPaint/FilterGallery.cpp
Normal file
51
Userland/Applications/PixelPaint/FilterGallery.cpp
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "FilterGallery.h"
|
||||
#include "FilterModel.h"
|
||||
#include <Applications/PixelPaint/FilterGalleryGML.h>
|
||||
#include <LibGUI/Button.h>
|
||||
#include <LibGUI/TreeView.h>
|
||||
#include <LibGUI/Widget.h>
|
||||
|
||||
namespace PixelPaint {
|
||||
|
||||
FilterGallery::FilterGallery(GUI::Window* parent_window)
|
||||
: GUI::Dialog(parent_window)
|
||||
{
|
||||
set_title("Filter Gallery");
|
||||
set_icon(parent_window->icon());
|
||||
resize(200, 250);
|
||||
set_resizable(true);
|
||||
|
||||
auto& main_widget = set_main_widget<GUI::Widget>();
|
||||
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");
|
||||
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");
|
||||
|
||||
VERIFY(filter_tree);
|
||||
VERIFY(apply_button);
|
||||
VERIFY(cancel_button);
|
||||
|
||||
auto filter_model = FilterModel::create();
|
||||
filter_tree->set_model(filter_model);
|
||||
filter_tree->expand_tree();
|
||||
|
||||
apply_button->on_click = [this](auto) {
|
||||
dbgln("Click!");
|
||||
|
||||
done(ExecResult::ExecOK);
|
||||
};
|
||||
|
||||
cancel_button->on_click = [this](auto) {
|
||||
done(ExecResult::ExecCancel);
|
||||
};
|
||||
}
|
||||
|
||||
}
|
40
Userland/Applications/PixelPaint/FilterGallery.gml
Normal file
40
Userland/Applications/PixelPaint/FilterGallery.gml
Normal file
|
@ -0,0 +1,40 @@
|
|||
@GUI::Frame {
|
||||
layout: @GUI::VerticalBoxLayout {
|
||||
}
|
||||
|
||||
fill_with_background_color: true
|
||||
|
||||
@GUI::Widget {
|
||||
|
||||
layout:@GUI::HorizontalBoxLayout {
|
||||
margins: [4]
|
||||
}
|
||||
|
||||
@GUI::TreeView {
|
||||
name: "tree_view"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@GUI::Widget {
|
||||
max_height: 24
|
||||
|
||||
layout:@GUI::HorizontalBoxLayout {
|
||||
margins: [4]
|
||||
}
|
||||
|
||||
@GUI::Widget {}
|
||||
|
||||
@GUI::Button {
|
||||
name: "apply_button"
|
||||
text: "Apply"
|
||||
max_width: 75
|
||||
}
|
||||
|
||||
@GUI::Button {
|
||||
name: "cancel_button"
|
||||
text: "Cancel"
|
||||
max_width: 75
|
||||
}
|
||||
}
|
||||
}
|
20
Userland/Applications/PixelPaint/FilterGallery.h
Normal file
20
Userland/Applications/PixelPaint/FilterGallery.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibGUI/Dialog.h>
|
||||
|
||||
namespace PixelPaint {
|
||||
|
||||
class FilterGallery final : public GUI::Dialog {
|
||||
C_OBJECT(FilterGallery);
|
||||
|
||||
private:
|
||||
FilterGallery(GUI::Window* parent_window);
|
||||
};
|
||||
|
||||
}
|
79
Userland/Applications/PixelPaint/FilterModel.cpp
Normal file
79
Userland/Applications/PixelPaint/FilterModel.cpp
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* 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 <LibGUI/FileIconProvider.h>
|
||||
|
||||
namespace PixelPaint {
|
||||
FilterModel::FilterModel()
|
||||
{
|
||||
|
||||
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<const FilterInfo*>(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<const FilterInfo*>(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<const FilterInfo*>(index.internal_data());
|
||||
return node->children.size();
|
||||
}
|
||||
|
||||
GUI::Variant FilterModel::data(const GUI::ModelIndex& index, GUI::ModelRole role) const
|
||||
{
|
||||
auto* filter = static_cast<const FilterInfo*>(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 {};
|
||||
}
|
||||
}
|
||||
}
|
75
Userland/Applications/PixelPaint/FilterModel.h
Normal file
75
Userland/Applications/PixelPaint/FilterModel.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/NonnullRefPtr.h>
|
||||
#include <LibGUI/Model.h>
|
||||
|
||||
namespace PixelPaint {
|
||||
|
||||
class FilterModel final : public GUI::Model {
|
||||
|
||||
public:
|
||||
class FilterInfo : public RefCounted {
|
||||
public:
|
||||
enum class Type {
|
||||
Category,
|
||||
Filter,
|
||||
} type;
|
||||
|
||||
String text;
|
||||
|
||||
NonnullRefPtrVector<FilterInfo> children;
|
||||
FilterInfo* parent;
|
||||
|
||||
static NonnullRefPtr<FilterInfo> create_filter(String const& text, FilterInfo* parent = nullptr)
|
||||
{
|
||||
auto filter = adopt_ref(*new FilterInfo(Type::Filter, text, parent));
|
||||
filter->ref();
|
||||
|
||||
if (parent)
|
||||
parent->children.append(filter);
|
||||
return filter;
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
return adopt_ref(*new FilterModel());
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
NonnullRefPtrVector<FilterInfo> m_filters;
|
||||
GUI::Icon m_filter_icon;
|
||||
};
|
||||
}
|
|
@ -10,6 +10,7 @@
|
|||
#include "CreateNewImageDialog.h"
|
||||
#include "CreateNewLayerDialog.h"
|
||||
#include "EditGuideDialog.h"
|
||||
#include "FilterGallery.h"
|
||||
#include "FilterParams.h"
|
||||
#include <Applications/PixelPaint/PixelPaintWindowGML.h>
|
||||
#include <LibConfig/Client.h>
|
||||
|
@ -587,6 +588,13 @@ void MainWidget::initialize_menubar(GUI::Window& window)
|
|||
}));
|
||||
|
||||
auto& filter_menu = window.add_menu("&Filter");
|
||||
|
||||
filter_menu.add_action(GUI::Action::create("Filter &Gallery", [&](auto&) {
|
||||
auto dialog = PixelPaint::FilterGallery::construct(&window);
|
||||
if (dialog->exec() != GUI::Dialog::ExecOK)
|
||||
return;
|
||||
}));
|
||||
|
||||
auto& spatial_filters_menu = filter_menu.add_submenu("&Spatial");
|
||||
|
||||
auto& edge_detect_submenu = spatial_filters_menu.add_submenu("&Edge Detect");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue