Serenity Operating System
1/*
2 * Copyright (c) 2022, Andrew Smith <andrew@alsmith.net>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include "ResizeImageDialog.h"
8#include <Applications/PixelPaint/ResizeImageDialogGML.h>
9#include <LibGUI/BoxLayout.h>
10#include <LibGUI/Button.h>
11#include <LibGUI/CheckBox.h>
12#include <LibGUI/ComboBox.h>
13#include <LibGUI/Label.h>
14#include <LibGUI/RadioButton.h>
15#include <LibGUI/SpinBox.h>
16
17namespace PixelPaint {
18
19ResizeImageDialog::ResizeImageDialog(Gfx::IntSize suggested_size, GUI::Window* parent_window)
20 : Dialog(parent_window)
21{
22 m_desired_size.set_width(max(1, suggested_size.width()));
23 m_desired_size.set_height(max(1, suggested_size.height()));
24 m_starting_aspect_ratio = m_desired_size.width() / static_cast<float>(m_desired_size.height());
25
26 set_title("Resize Image");
27 resize(260, 228);
28 set_icon(parent_window->icon());
29
30 auto main_widget = set_main_widget<GUI::Widget>().release_value_but_fixme_should_propagate_errors();
31 main_widget->load_from_gml(resize_image_dialog_gml).release_value_but_fixme_should_propagate_errors();
32
33 auto width_spinbox = main_widget->find_descendant_of_type_named<GUI::SpinBox>("width_spinbox");
34 auto height_spinbox = main_widget->find_descendant_of_type_named<GUI::SpinBox>("height_spinbox");
35 auto keep_aspect_ratio_checkbox = main_widget->find_descendant_of_type_named<GUI::CheckBox>("keep_aspect_ratio_checkbox");
36
37 VERIFY(width_spinbox);
38 VERIFY(height_spinbox);
39 VERIFY(keep_aspect_ratio_checkbox);
40
41 width_spinbox->set_value(m_desired_size.width());
42 width_spinbox->on_change = [this, height_spinbox, keep_aspect_ratio_checkbox](int value) {
43 if (keep_aspect_ratio_checkbox->is_checked()) {
44 int desired_height = static_cast<int>(roundf(value / m_starting_aspect_ratio));
45 height_spinbox->set_value(desired_height, GUI::AllowCallback::No);
46 m_desired_size.set_height(height_spinbox->value());
47 }
48 m_desired_size.set_width(value);
49 };
50
51 height_spinbox->set_value(m_desired_size.height());
52 height_spinbox->on_change = [this, width_spinbox, keep_aspect_ratio_checkbox](int value) {
53 if (keep_aspect_ratio_checkbox->is_checked()) {
54 int desired_width = static_cast<int>(roundf(value * m_starting_aspect_ratio));
55 width_spinbox->set_value(desired_width, GUI::AllowCallback::No);
56 m_desired_size.set_width(width_spinbox->value());
57 }
58 m_desired_size.set_height(value);
59 };
60
61 keep_aspect_ratio_checkbox->on_checked = [this, height_spinbox](bool is_checked) {
62 if (is_checked) {
63 int desired_height = static_cast<int>(roundf(m_desired_size.width() / m_starting_aspect_ratio));
64 height_spinbox->set_value(desired_height, GUI::AllowCallback::No);
65 m_desired_size.set_height(height_spinbox->value());
66 }
67 };
68
69 auto nearest_neighbor_radio = main_widget->find_descendant_of_type_named<GUI::RadioButton>("nearest_neighbor_radio");
70 auto smooth_pixels_radio = main_widget->find_descendant_of_type_named<GUI::RadioButton>("smooth_pixels_radio");
71 auto bilinear_radio = main_widget->find_descendant_of_type_named<GUI::RadioButton>("bilinear_radio");
72 auto resize_canvas_radio = main_widget->find_descendant_of_type_named<GUI::RadioButton>("resize_canvas");
73
74 VERIFY(nearest_neighbor_radio);
75 VERIFY(smooth_pixels_radio);
76 VERIFY(bilinear_radio);
77 VERIFY(resize_canvas_radio);
78
79 m_scaling_mode = Gfx::Painter::ScalingMode::NearestNeighbor;
80 if (bilinear_radio->is_checked()) {
81 m_scaling_mode = Gfx::Painter::ScalingMode::BilinearBlend;
82 }
83
84 nearest_neighbor_radio->on_checked = [this](bool is_checked) {
85 if (is_checked)
86 m_scaling_mode = Gfx::Painter::ScalingMode::NearestNeighbor;
87 };
88 smooth_pixels_radio->on_checked = [this](bool is_checked) {
89 if (is_checked)
90 m_scaling_mode = Gfx::Painter::ScalingMode::SmoothPixels;
91 };
92 bilinear_radio->on_checked = [this](bool is_checked) {
93 if (is_checked)
94 m_scaling_mode = Gfx::Painter::ScalingMode::BilinearBlend;
95 };
96 resize_canvas_radio->on_checked = [this](bool is_checked) {
97 if (is_checked)
98 m_scaling_mode = Gfx::Painter::ScalingMode::None;
99 };
100
101 auto ok_button = main_widget->find_descendant_of_type_named<GUI::Button>("ok_button");
102 auto cancel_button = main_widget->find_descendant_of_type_named<GUI::Button>("cancel_button");
103
104 VERIFY(ok_button);
105 VERIFY(cancel_button);
106
107 ok_button->on_click = [this](auto) {
108 done(ExecResult::OK);
109 };
110 ok_button->set_default(true);
111
112 cancel_button->on_click = [this](auto) {
113 done(ExecResult::Cancel);
114 };
115}
116
117}