From 8eb01c0b11463382f14fcef0c9b6cb869e8f5718 Mon Sep 17 00:00:00 2001 From: Luke Wilde Date: Wed, 29 Dec 2021 15:37:04 +0000 Subject: [PATCH] ImageViewer: Allow choice between nearest neighbor and bilinear scaling Currently, ImageViewer always uses nearest neighbor scaling. This allows the user to choose whether to use nearest neighbor or bilinear scaling. It current defaults to nearest neighbor. --- .../Applications/ImageViewer/ViewWidget.cpp | 9 ++++++-- .../Applications/ImageViewer/ViewWidget.h | 3 +++ Userland/Applications/ImageViewer/main.cpp | 23 +++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/Userland/Applications/ImageViewer/ViewWidget.cpp b/Userland/Applications/ImageViewer/ViewWidget.cpp index 434b5bf669..b728ee4b44 100644 --- a/Userland/Applications/ImageViewer/ViewWidget.cpp +++ b/Userland/Applications/ImageViewer/ViewWidget.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -178,7 +177,7 @@ void ViewWidget::paint_event(GUI::PaintEvent& event) Gfx::StylePainter::paint_transparency_grid(painter, frame_inner_rect(), palette()); if (!m_bitmap.is_null()) - painter.draw_scaled_bitmap(m_bitmap_rect, *m_bitmap, m_bitmap->rect()); + painter.draw_scaled_bitmap(m_bitmap_rect, *m_bitmap, m_bitmap->rect(), 1.0f, m_scaling_mode); } void ViewWidget::mousedown_event(GUI::MouseEvent& event) @@ -343,4 +342,10 @@ void ViewWidget::animate() } } +void ViewWidget::set_scaling_mode(Gfx::Painter::ScalingMode scaling_mode) +{ + m_scaling_mode = scaling_mode; + update(); +} + } diff --git a/Userland/Applications/ImageViewer/ViewWidget.h b/Userland/Applications/ImageViewer/ViewWidget.h index 9579a39325..49770fb446 100644 --- a/Userland/Applications/ImageViewer/ViewWidget.h +++ b/Userland/Applications/ImageViewer/ViewWidget.h @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -37,6 +38,7 @@ public: void set_scaled_for_first_image(bool val) { m_scaled_for_first_image = val; } void set_path(const String& path); void resize_window(); + void set_scaling_mode(Gfx::Painter::ScalingMode); bool is_next_available() const; bool is_previous_available() const; @@ -86,6 +88,7 @@ private: Gfx::FloatPoint m_saved_pan_origin; Vector m_files_in_same_dir; Optional m_current_index; + Gfx::Painter::ScalingMode m_scaling_mode { Gfx::Painter::ScalingMode::NearestNeighbor }; }; } diff --git a/Userland/Applications/ImageViewer/main.cpp b/Userland/Applications/ImageViewer/main.cpp index 9375a643a0..a3027f8908 100644 --- a/Userland/Applications/ImageViewer/main.cpp +++ b/Userland/Applications/ImageViewer/main.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -225,6 +226,16 @@ ErrorOr serenity_main(Main::Arguments arguments) if (widget.bitmap()) GUI::Clipboard::the().set_bitmap(*widget.bitmap()); }); + + auto nearest_neighbor_action = GUI::Action::create_checkable("&Nearest Neighbor", [&](auto&) { + widget.set_scaling_mode(Gfx::Painter::ScalingMode::NearestNeighbor); + }); + nearest_neighbor_action->set_checked(true); + + auto bilinear_action = GUI::Action::create_checkable("&Bilinear", [&](auto&) { + widget.set_scaling_mode(Gfx::Painter::ScalingMode::BilinearBlend); + }); + widget.on_image_change = [&](const Gfx::Bitmap* bitmap) { bool should_enable_image_actions = (bitmap != nullptr); bool should_enable_forward_actions = (widget.is_next_available() && should_enable_image_actions); @@ -287,6 +298,18 @@ ErrorOr serenity_main(Main::Arguments arguments) view_menu.add_action(zoom_in_action); view_menu.add_action(reset_zoom_action); view_menu.add_action(zoom_out_action); + view_menu.add_separator(); + + auto& scaling_mode_menu = view_menu.add_submenu("&Scaling Mode"); + + auto scaling_mode_group = make(); + scaling_mode_group->set_exclusive(true); + scaling_mode_group->add_action(*nearest_neighbor_action); + scaling_mode_group->add_action(*bilinear_action); + + scaling_mode_menu.add_action(nearest_neighbor_action); + scaling_mode_menu.add_action(bilinear_action); + view_menu.add_separator(); view_menu.add_action(hide_show_toolbar_action);