summaryrefslogtreecommitdiff
path: root/Userland/Applications/PixelPaint/ResizeImageDialog.cpp
blob: edc2e26d011e2f4b99079d4cca6c180761658f0e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
 * 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 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, 228);
    set_icon(parent_window->icon());

    auto main_widget = set_main_widget<GUI::Widget>().release_value_but_fixme_should_propagate_errors();
    main_widget->load_from_gml(resize_image_dialog_gml).release_value_but_fixme_should_propagate_errors();

    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);
    };

    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);
    };

    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 smooth_pixels_radio = main_widget->find_descendant_of_type_named<GUI::RadioButton>("smooth_pixels_radio");
    auto bilinear_radio = main_widget->find_descendant_of_type_named<GUI::RadioButton>("bilinear_radio");
    auto resize_canvas_radio = main_widget->find_descendant_of_type_named<GUI::RadioButton>("resize_canvas");

    VERIFY(nearest_neighbor_radio);
    VERIFY(smooth_pixels_radio);
    VERIFY(bilinear_radio);
    VERIFY(resize_canvas_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;
    };
    smooth_pixels_radio->on_checked = [this](bool is_checked) {
        if (is_checked)
            m_scaling_mode = Gfx::Painter::ScalingMode::SmoothPixels;
    };
    bilinear_radio->on_checked = [this](bool is_checked) {
        if (is_checked)
            m_scaling_mode = Gfx::Painter::ScalingMode::BilinearBlend;
    };
    resize_canvas_radio->on_checked = [this](bool is_checked) {
        if (is_checked)
            m_scaling_mode = Gfx::Painter::ScalingMode::None;
    };

    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);
    };
    ok_button->set_default(true);

    cancel_button->on_click = [this](auto) {
        done(ExecResult::Cancel);
    };
}

}