diff --git a/Userland/Applications/PixelPaint/MainWidget.cpp b/Userland/Applications/PixelPaint/MainWidget.cpp index 80a7bcba4f..07c6238cef 100644 --- a/Userland/Applications/PixelPaint/MainWidget.cpp +++ b/Userland/Applications/PixelPaint/MainWidget.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -83,9 +84,17 @@ MainWidget::MainWidget() image_editor.set_active_tool(active_tool); m_show_guides_action->set_checked(image_editor.guide_visibility()); m_show_rulers_action->set_checked(image_editor.ruler_visibility()); + image_editor.on_scale_changed(image_editor.scale()); }; } +// Note: Update these together! v +static const Vector s_suggested_zoom_levels { "25%", "50%", "100%", "200%", "300%", "400%", "800%", "1600%", "Fit to width", "Fit to height", "Fit entire image" }; +static constexpr int s_zoom_level_fit_width = 8; +static constexpr int s_zoom_level_fit_height = 9; +static constexpr int s_zoom_level_fit_image = 10; +// Note: Update these together! ^ + void MainWidget::initialize_menubar(GUI::Window& window) { auto& file_menu = window.add_menu("&File"); @@ -729,6 +738,44 @@ void MainWidget::initialize_menubar(GUI::Window& window) toolbar.add_action(*m_zoom_in_action); toolbar.add_action(*m_zoom_out_action); toolbar.add_action(*m_reset_zoom_action); + m_zoom_combobox = toolbar.add(); + m_zoom_combobox->set_max_width(75); + m_zoom_combobox->set_model(*GUI::ItemListModel::create(s_suggested_zoom_levels)); + m_zoom_combobox->on_change = [this](String const& value, GUI::ModelIndex const& index) { + auto* editor = current_image_editor(); + if (editor == nullptr) + return; + + if (index.is_valid()) { + switch (index.row()) { + case s_zoom_level_fit_width: + editor->fit_image_to_view(ImageEditor::FitType::Width); + return; + case s_zoom_level_fit_height: + editor->fit_image_to_view(ImageEditor::FitType::Height); + return; + case s_zoom_level_fit_image: + editor->fit_image_to_view(ImageEditor::FitType::Image); + return; + } + } + + auto zoom_level_optional = value.view().trim("%"sv, TrimMode::Right).to_int(); + if (!zoom_level_optional.has_value()) { + // Indicate that a parse-error occurred by resetting the text to the current state. + editor->on_scale_changed(editor->scale()); + return; + } + + editor->set_absolute_scale(zoom_level_optional.value() * 1.0f / 100); + // If the selected zoom level got clamped, or a "fit to …" level was selected, + // there is a chance that the new scale is identical to the old scale. + // In these cases, we need to manually reset the text: + editor->on_scale_changed(editor->scale()); + }; + m_zoom_combobox->on_return_pressed = [this]() { + m_zoom_combobox->on_change(m_zoom_combobox->text(), GUI::ModelIndex()); + }; } void MainWidget::open_image_fd(int fd, String const& path) @@ -824,6 +871,10 @@ ImageEditor& MainWidget::create_new_editor(NonnullRefPtr image) // NOTE: We invoke the above hook directly here to make sure the tab title is set up. image_editor.on_image_title_change(image->title()); + image_editor.on_scale_changed = [this](float scale) { + m_zoom_combobox->set_text(String::formatted("{}%", roundf(scale * 100))); + }; + if (image->layer_count()) image_editor.set_active_layer(&image->layer(0)); diff --git a/Userland/Applications/PixelPaint/MainWidget.h b/Userland/Applications/PixelPaint/MainWidget.h index 23d57f9c5d..8e2118aa62 100644 --- a/Userland/Applications/PixelPaint/MainWidget.h +++ b/Userland/Applications/PixelPaint/MainWidget.h @@ -18,6 +18,7 @@ #include "ToolboxWidget.h" #include "Tools/Tool.h" #include +#include #include #include #include @@ -54,6 +55,7 @@ private: RefPtr m_tool_properties_widget; RefPtr m_tab_widget; RefPtr m_statusbar; + RefPtr m_zoom_combobox; RefPtr m_new_image_action; RefPtr m_open_image_action;