mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 05:07:45 +00:00
PixelPaint: Add Image>Resize Image... dialog. (Front end)
This commit is contained in:
parent
abaecb878b
commit
02399d4775
11 changed files with 302 additions and 0 deletions
|
@ -8,6 +8,7 @@ serenity_component(
|
||||||
compile_gml(PixelPaintWindow.gml PixelPaintWindowGML.h pixel_paint_window_gml)
|
compile_gml(PixelPaintWindow.gml PixelPaintWindowGML.h pixel_paint_window_gml)
|
||||||
compile_gml(EditGuideDialog.gml EditGuideDialogGML.h edit_guide_dialog_gml)
|
compile_gml(EditGuideDialog.gml EditGuideDialogGML.h edit_guide_dialog_gml)
|
||||||
compile_gml(FilterGallery.gml FilterGalleryGML.h filter_gallery_gml)
|
compile_gml(FilterGallery.gml FilterGalleryGML.h filter_gallery_gml)
|
||||||
|
compile_gml(ResizeImageDialog.gml ResizeImageDialogGML.h resize_image_dialog_gml)
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
CreateNewImageDialog.cpp
|
CreateNewImageDialog.cpp
|
||||||
|
@ -43,6 +44,8 @@ set(SOURCES
|
||||||
PaletteWidget.cpp
|
PaletteWidget.cpp
|
||||||
PixelPaintWindowGML.h
|
PixelPaintWindowGML.h
|
||||||
ProjectLoader.cpp
|
ProjectLoader.cpp
|
||||||
|
ResizeImageDialog.cpp
|
||||||
|
ResizeImageDialogGML.h
|
||||||
Selection.cpp
|
Selection.cpp
|
||||||
ToolPropertiesWidget.cpp
|
ToolPropertiesWidget.cpp
|
||||||
ToolboxWidget.cpp
|
ToolboxWidget.cpp
|
||||||
|
|
|
@ -26,6 +26,7 @@ ErrorOr<IconBag> IconBag::try_create()
|
||||||
icon_bag.clear_guides = TRY(Gfx::Bitmap::try_load_from_file("/res/icons/pixelpaint/clear-guides.png"));
|
icon_bag.clear_guides = TRY(Gfx::Bitmap::try_load_from_file("/res/icons/pixelpaint/clear-guides.png"));
|
||||||
icon_bag.edit_flip_vertical = TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/edit-flip-vertical.png"));
|
icon_bag.edit_flip_vertical = TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/edit-flip-vertical.png"));
|
||||||
icon_bag.edit_flip_horizontal = TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/edit-flip-horizontal.png"));
|
icon_bag.edit_flip_horizontal = TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/edit-flip-horizontal.png"));
|
||||||
|
icon_bag.resize_image = TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/selection-move.png"));
|
||||||
icon_bag.crop = TRY(Gfx::Bitmap::try_load_from_file("/res/icons/pixelpaint/crop.png"));
|
icon_bag.crop = TRY(Gfx::Bitmap::try_load_from_file("/res/icons/pixelpaint/crop.png"));
|
||||||
icon_bag.new_layer = TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/new-layer.png"));
|
icon_bag.new_layer = TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/new-layer.png"));
|
||||||
icon_bag.previous_layer = TRY(Gfx::Bitmap::try_load_from_file("/res/icons/pixelpaint/previous-layer.png"));
|
icon_bag.previous_layer = TRY(Gfx::Bitmap::try_load_from_file("/res/icons/pixelpaint/previous-layer.png"));
|
||||||
|
|
|
@ -27,6 +27,7 @@ struct IconBag final {
|
||||||
RefPtr<Gfx::Bitmap> clear_guides { nullptr };
|
RefPtr<Gfx::Bitmap> clear_guides { nullptr };
|
||||||
RefPtr<Gfx::Bitmap> edit_flip_vertical { nullptr };
|
RefPtr<Gfx::Bitmap> edit_flip_vertical { nullptr };
|
||||||
RefPtr<Gfx::Bitmap> edit_flip_horizontal { nullptr };
|
RefPtr<Gfx::Bitmap> edit_flip_horizontal { nullptr };
|
||||||
|
RefPtr<Gfx::Bitmap> resize_image { nullptr };
|
||||||
RefPtr<Gfx::Bitmap> crop { nullptr };
|
RefPtr<Gfx::Bitmap> crop { nullptr };
|
||||||
RefPtr<Gfx::Bitmap> new_layer { nullptr };
|
RefPtr<Gfx::Bitmap> new_layer { nullptr };
|
||||||
RefPtr<Gfx::Bitmap> previous_layer { nullptr };
|
RefPtr<Gfx::Bitmap> previous_layer { nullptr };
|
||||||
|
|
|
@ -527,6 +527,17 @@ void Image::crop(Gfx::IntRect const& cropped_rect)
|
||||||
did_change_rect(cropped_rect);
|
did_change_rect(cropped_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Image::resize(Gfx::IntSize const& new_size, Gfx::Painter::ScalingMode scaling_mode)
|
||||||
|
{
|
||||||
|
for (auto& layer : m_layers) {
|
||||||
|
layer.resize(new_size, scaling_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_size = { new_size.width(), new_size.height() };
|
||||||
|
did_change_rect();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Color Image::color_at(Gfx::IntPoint const& point) const
|
Color Image::color_at(Gfx::IntPoint const& point) const
|
||||||
{
|
{
|
||||||
Color color;
|
Color color;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <LibGUI/Forward.h>
|
#include <LibGUI/Forward.h>
|
||||||
#include <LibGfx/Bitmap.h>
|
#include <LibGfx/Bitmap.h>
|
||||||
#include <LibGfx/Forward.h>
|
#include <LibGfx/Forward.h>
|
||||||
|
#include <LibGfx/Painter.h>
|
||||||
#include <LibGfx/Rect.h>
|
#include <LibGfx/Rect.h>
|
||||||
#include <LibGfx/Size.h>
|
#include <LibGfx/Size.h>
|
||||||
|
|
||||||
|
@ -96,6 +97,7 @@ public:
|
||||||
void flip(Gfx::Orientation orientation);
|
void flip(Gfx::Orientation orientation);
|
||||||
void rotate(Gfx::RotationDirection direction);
|
void rotate(Gfx::RotationDirection direction);
|
||||||
void crop(Gfx::IntRect const& rect);
|
void crop(Gfx::IntRect const& rect);
|
||||||
|
void resize(Gfx::IntSize const& new_size, Gfx::Painter::ScalingMode scaling_mode);
|
||||||
|
|
||||||
Color color_at(Gfx::IntPoint const& point) const;
|
Color color_at(Gfx::IntPoint const& point) const;
|
||||||
|
|
||||||
|
|
|
@ -180,6 +180,31 @@ void Layer::crop(Gfx::IntRect const& rect)
|
||||||
did_modify_bitmap();
|
did_modify_bitmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Layer::resize(Gfx::IntSize const& new_size, Gfx::Painter::ScalingMode scaling_mode)
|
||||||
|
{
|
||||||
|
const Gfx::IntRect old_rect(Gfx::IntPoint(0, 0), size());
|
||||||
|
const Gfx::IntRect new_rect(Gfx::IntPoint(0, 0), new_size);
|
||||||
|
|
||||||
|
{
|
||||||
|
auto resized = Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, new_size).release_value_but_fixme_should_propagate_errors();
|
||||||
|
Gfx::Painter painter(resized);
|
||||||
|
|
||||||
|
painter.draw_scaled_bitmap(new_rect, *m_content_bitmap, old_rect, 1.0f, scaling_mode);
|
||||||
|
|
||||||
|
m_content_bitmap = move(resized);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_mask_bitmap) {
|
||||||
|
auto resized = Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, new_size).release_value_but_fixme_should_propagate_errors();
|
||||||
|
Gfx::Painter painter(resized);
|
||||||
|
|
||||||
|
painter.draw_scaled_bitmap(new_rect, *m_mask_bitmap, old_rect, 1.0f, scaling_mode);
|
||||||
|
m_mask_bitmap = move(resized);
|
||||||
|
}
|
||||||
|
|
||||||
|
did_modify_bitmap();
|
||||||
|
}
|
||||||
|
|
||||||
void Layer::update_cached_bitmap()
|
void Layer::update_cached_bitmap()
|
||||||
{
|
{
|
||||||
if (!is_masked()) {
|
if (!is_masked()) {
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
#include <AK/Weakable.h>
|
#include <AK/Weakable.h>
|
||||||
#include <LibGfx/Bitmap.h>
|
#include <LibGfx/Bitmap.h>
|
||||||
|
#include <LibGfx/Painter.h>
|
||||||
|
|
||||||
namespace PixelPaint {
|
namespace PixelPaint {
|
||||||
|
|
||||||
|
@ -56,6 +57,7 @@ public:
|
||||||
void flip(Gfx::Orientation orientation);
|
void flip(Gfx::Orientation orientation);
|
||||||
void rotate(Gfx::RotationDirection direction);
|
void rotate(Gfx::RotationDirection direction);
|
||||||
void crop(Gfx::IntRect const& rect);
|
void crop(Gfx::IntRect const& rect);
|
||||||
|
void resize(Gfx::IntSize const& new_size, Gfx::Painter::ScalingMode scaling_mode);
|
||||||
|
|
||||||
ErrorOr<void> try_set_bitmaps(NonnullRefPtr<Gfx::Bitmap> content, RefPtr<Gfx::Bitmap> mask);
|
ErrorOr<void> try_set_bitmaps(NonnullRefPtr<Gfx::Bitmap> content, RefPtr<Gfx::Bitmap> mask);
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "EditGuideDialog.h"
|
#include "EditGuideDialog.h"
|
||||||
#include "FilterGallery.h"
|
#include "FilterGallery.h"
|
||||||
#include "FilterParams.h"
|
#include "FilterParams.h"
|
||||||
|
#include "ResizeImageDialog.h"
|
||||||
#include <Applications/PixelPaint/PixelPaintWindowGML.h>
|
#include <Applications/PixelPaint/PixelPaintWindowGML.h>
|
||||||
#include <LibConfig/Client.h>
|
#include <LibConfig/Client.h>
|
||||||
#include <LibCore/File.h>
|
#include <LibCore/File.h>
|
||||||
|
@ -499,6 +500,14 @@ void MainWidget::initialize_menubar(GUI::Window& window)
|
||||||
editor->image().rotate(Gfx::RotationDirection::Clockwise);
|
editor->image().rotate(Gfx::RotationDirection::Clockwise);
|
||||||
}));
|
}));
|
||||||
m_image_menu->add_separator();
|
m_image_menu->add_separator();
|
||||||
|
m_image_menu->add_action(GUI::Action::create(
|
||||||
|
"&Resize Image...", { Mod_Ctrl | Mod_Shift, Key_R }, g_icon_bag.resize_image, [&](auto&) {
|
||||||
|
auto* editor = current_image_editor();
|
||||||
|
VERIFY(editor);
|
||||||
|
auto dialog = PixelPaint::ResizeImageDialog::construct(editor->image().size(), &window);
|
||||||
|
if (dialog->exec() == GUI::Dialog::ExecResult::OK)
|
||||||
|
editor->image().resize(dialog->desired_size(), dialog->scaling_mode());
|
||||||
|
}));
|
||||||
m_image_menu->add_action(GUI::Action::create(
|
m_image_menu->add_action(GUI::Action::create(
|
||||||
"&Crop To Selection", g_icon_bag.crop, [&](auto&) {
|
"&Crop To Selection", g_icon_bag.crop, [&](auto&) {
|
||||||
auto* editor = current_image_editor();
|
auto* editor = current_image_editor();
|
||||||
|
|
111
Userland/Applications/PixelPaint/ResizeImageDialog.cpp
Normal file
111
Userland/Applications/PixelPaint/ResizeImageDialog.cpp
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Andrew Smith <andrew@alsmith.net>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ResizeImageDialog.h"
|
||||||
|
#include <Applications/PixelPaint/ResizeImageDialogGML.h>
|
||||||
|
#include <LibGUI/BoxLayout.h>
|
||||||
|
#include <LibGUI/Button.h>
|
||||||
|
#include <LibGUI/CheckBox.h>
|
||||||
|
#include <LibGUI/ComboBox.h>
|
||||||
|
#include <LibGUI/Label.h>
|
||||||
|
#include <LibGUI/RadioButton.h>
|
||||||
|
#include <LibGUI/SpinBox.h>
|
||||||
|
|
||||||
|
namespace PixelPaint {
|
||||||
|
|
||||||
|
ResizeImageDialog::ResizeImageDialog(Gfx::IntSize const& suggested_size, GUI::Window* parent_window)
|
||||||
|
: Dialog(parent_window)
|
||||||
|
{
|
||||||
|
m_desired_size.set_width(max(1, suggested_size.width()));
|
||||||
|
m_desired_size.set_height(max(1, suggested_size.height()));
|
||||||
|
m_starting_aspect_ratio = m_desired_size.width() / static_cast<float>(m_desired_size.height());
|
||||||
|
|
||||||
|
set_title("Resize Image");
|
||||||
|
resize(260, 210);
|
||||||
|
set_icon(parent_window->icon());
|
||||||
|
|
||||||
|
auto& main_widget = set_main_widget<GUI::Widget>();
|
||||||
|
if (!main_widget.load_from_gml(resize_image_dialog_gml))
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
|
||||||
|
auto width_spinbox = main_widget.find_descendant_of_type_named<GUI::SpinBox>("width_spinbox");
|
||||||
|
auto height_spinbox = main_widget.find_descendant_of_type_named<GUI::SpinBox>("height_spinbox");
|
||||||
|
auto keep_aspect_ratio_checkbox = main_widget.find_descendant_of_type_named<GUI::CheckBox>("keep_aspect_ratio_checkbox");
|
||||||
|
|
||||||
|
VERIFY(width_spinbox);
|
||||||
|
VERIFY(height_spinbox);
|
||||||
|
VERIFY(keep_aspect_ratio_checkbox);
|
||||||
|
|
||||||
|
width_spinbox->set_value(m_desired_size.width());
|
||||||
|
width_spinbox->on_change = [this, height_spinbox, keep_aspect_ratio_checkbox](int value) {
|
||||||
|
if (keep_aspect_ratio_checkbox->is_checked()) {
|
||||||
|
int desired_height = static_cast<int>(roundf(value / m_starting_aspect_ratio));
|
||||||
|
height_spinbox->set_value(desired_height, GUI::AllowCallback::No);
|
||||||
|
m_desired_size.set_height(height_spinbox->value());
|
||||||
|
}
|
||||||
|
m_desired_size.set_width(value);
|
||||||
|
};
|
||||||
|
width_spinbox->on_return_pressed = [this]() {
|
||||||
|
done(ExecResult::OK);
|
||||||
|
};
|
||||||
|
|
||||||
|
height_spinbox->set_value(m_desired_size.height());
|
||||||
|
height_spinbox->on_change = [this, width_spinbox, keep_aspect_ratio_checkbox](int value) {
|
||||||
|
if (keep_aspect_ratio_checkbox->is_checked()) {
|
||||||
|
int desired_width = static_cast<int>(roundf(value * m_starting_aspect_ratio));
|
||||||
|
width_spinbox->set_value(desired_width, GUI::AllowCallback::No);
|
||||||
|
m_desired_size.set_width(width_spinbox->value());
|
||||||
|
}
|
||||||
|
m_desired_size.set_height(value);
|
||||||
|
};
|
||||||
|
height_spinbox->on_return_pressed = [this]() {
|
||||||
|
done(ExecResult::OK);
|
||||||
|
};
|
||||||
|
|
||||||
|
keep_aspect_ratio_checkbox->on_checked = [this, height_spinbox](bool is_checked) {
|
||||||
|
if (is_checked) {
|
||||||
|
int desired_height = static_cast<int>(roundf(m_desired_size.width() / m_starting_aspect_ratio));
|
||||||
|
height_spinbox->set_value(desired_height, GUI::AllowCallback::No);
|
||||||
|
m_desired_size.set_height(height_spinbox->value());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto nearest_neighbor_radio = main_widget.find_descendant_of_type_named<GUI::RadioButton>("nearest_neighbor_radio");
|
||||||
|
auto bilinear_radio = main_widget.find_descendant_of_type_named<GUI::RadioButton>("bilinear_radio");
|
||||||
|
|
||||||
|
VERIFY(nearest_neighbor_radio);
|
||||||
|
VERIFY(bilinear_radio);
|
||||||
|
|
||||||
|
m_scaling_mode = Gfx::Painter::ScalingMode::NearestNeighbor;
|
||||||
|
if (bilinear_radio->is_checked()) {
|
||||||
|
m_scaling_mode = Gfx::Painter::ScalingMode::BilinearBlend;
|
||||||
|
}
|
||||||
|
|
||||||
|
nearest_neighbor_radio->on_checked = [this](bool is_checked) {
|
||||||
|
if (is_checked)
|
||||||
|
m_scaling_mode = Gfx::Painter::ScalingMode::NearestNeighbor;
|
||||||
|
};
|
||||||
|
bilinear_radio->on_checked = [this](bool is_checked) {
|
||||||
|
if (is_checked)
|
||||||
|
m_scaling_mode = Gfx::Painter::ScalingMode::BilinearBlend;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto ok_button = main_widget.find_descendant_of_type_named<GUI::Button>("ok_button");
|
||||||
|
auto cancel_button = main_widget.find_descendant_of_type_named<GUI::Button>("cancel_button");
|
||||||
|
|
||||||
|
VERIFY(ok_button);
|
||||||
|
VERIFY(cancel_button);
|
||||||
|
|
||||||
|
ok_button->on_click = [this](auto) {
|
||||||
|
done(ExecResult::OK);
|
||||||
|
};
|
||||||
|
|
||||||
|
cancel_button->on_click = [this](auto) {
|
||||||
|
done(ExecResult::Cancel);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
108
Userland/Applications/PixelPaint/ResizeImageDialog.gml
Normal file
108
Userland/Applications/PixelPaint/ResizeImageDialog.gml
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
@GUI::Widget {
|
||||||
|
fill_with_background_color: true
|
||||||
|
min_width: 260
|
||||||
|
min_height: 210
|
||||||
|
layout: @GUI::VerticalBoxLayout {
|
||||||
|
margins: [4]
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::GroupBox {
|
||||||
|
title: "Size (px)"
|
||||||
|
shrink_to_fit: true
|
||||||
|
layout: @GUI::VerticalBoxLayout {
|
||||||
|
margins: [4]
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::Widget {
|
||||||
|
layout: @GUI::HorizontalBoxLayout {}
|
||||||
|
fixed_height: 24
|
||||||
|
|
||||||
|
@GUI::Label {
|
||||||
|
text: "Width:"
|
||||||
|
fixed_width: 60
|
||||||
|
text_alignment: "CenterRight"
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::SpinBox {
|
||||||
|
name: "width_spinbox"
|
||||||
|
min: 1
|
||||||
|
max: 16384
|
||||||
|
min_width: 140
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::Widget {
|
||||||
|
layout: @GUI::HorizontalBoxLayout {}
|
||||||
|
fixed_height: 24
|
||||||
|
|
||||||
|
@GUI::Label {
|
||||||
|
text: "Height:"
|
||||||
|
fixed_width: 60
|
||||||
|
text_alignment: "CenterRight"
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::SpinBox {
|
||||||
|
name: "height_spinbox"
|
||||||
|
min: 1
|
||||||
|
max: 16384
|
||||||
|
min_width: 140
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::Widget {
|
||||||
|
layout: @GUI::HorizontalBoxLayout {}
|
||||||
|
fixed_height: 24
|
||||||
|
min_width: 140
|
||||||
|
|
||||||
|
@GUI::Widget {
|
||||||
|
fixed_width: 60
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::CheckBox {
|
||||||
|
name: "keep_aspect_ratio_checkbox"
|
||||||
|
text: "Keep aspect ratio"
|
||||||
|
checked: true
|
||||||
|
autosize: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::GroupBox {
|
||||||
|
title: "Scaling Mode"
|
||||||
|
shrink_to_fit: true
|
||||||
|
layout: @GUI::VerticalBoxLayout {
|
||||||
|
margins: [4]
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::RadioButton {
|
||||||
|
name: "nearest_neighbor_radio"
|
||||||
|
text: "Nearest neighbor"
|
||||||
|
checked: true
|
||||||
|
autosize: true
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::RadioButton {
|
||||||
|
name: "bilinear_radio"
|
||||||
|
text: "Bilinear"
|
||||||
|
autosize: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::Widget {
|
||||||
|
layout: @GUI::HorizontalBoxLayout {}
|
||||||
|
|
||||||
|
@GUI::Widget {}
|
||||||
|
|
||||||
|
@GUI::Button {
|
||||||
|
name: "ok_button"
|
||||||
|
text: "OK"
|
||||||
|
max_width: 75
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::Button {
|
||||||
|
name: "cancel_button"
|
||||||
|
text: "Cancel"
|
||||||
|
max_width: 75
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
29
Userland/Applications/PixelPaint/ResizeImageDialog.h
Normal file
29
Userland/Applications/PixelPaint/ResizeImageDialog.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Andrew Smith <andrew@alsmith.net>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibGUI/Dialog.h>
|
||||||
|
#include <LibGfx/Painter.h>
|
||||||
|
|
||||||
|
namespace PixelPaint {
|
||||||
|
|
||||||
|
class ResizeImageDialog final : public GUI::Dialog {
|
||||||
|
C_OBJECT(ResizeImageDialog);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Gfx::IntSize const& desired_size() const { return m_desired_size; }
|
||||||
|
Gfx::Painter::ScalingMode scaling_mode() const { return m_scaling_mode; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
ResizeImageDialog(Gfx::IntSize const& starting_size, GUI::Window* parent_window);
|
||||||
|
|
||||||
|
Gfx::IntSize m_desired_size;
|
||||||
|
Gfx::Painter::ScalingMode m_scaling_mode;
|
||||||
|
float m_starting_aspect_ratio;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue