From ab324c1dae86cdaf084b92ca88854cc7a15640eb Mon Sep 17 00:00:00 2001 From: Maciej Date: Tue, 28 Dec 2021 11:52:15 +0100 Subject: [PATCH] ImageViewer: Change how scaling works - Store scale as a (float) factor (not as %) - Make scaling exponential so that matches PixelPaint and another image viewers/editors/etc --- .../Applications/ImageViewer/ViewWidget.cpp | 32 ++++++++----------- .../Applications/ImageViewer/ViewWidget.h | 8 ++--- Userland/Applications/ImageViewer/main.cpp | 10 +++--- 3 files changed, 23 insertions(+), 27 deletions(-) diff --git a/Userland/Applications/ImageViewer/ViewWidget.cpp b/Userland/Applications/ImageViewer/ViewWidget.cpp index 802c4a0e654..434b5bf6694 100644 --- a/Userland/Applications/ImageViewer/ViewWidget.cpp +++ b/Userland/Applications/ImageViewer/ViewWidget.cpp @@ -118,22 +118,21 @@ void ViewWidget::navigate(Directions direction) this->load_from_file(m_files_in_same_dir.at(index)); } -void ViewWidget::set_scale(int scale) +void ViewWidget::set_scale(float scale) { if (m_bitmap.is_null()) return; - if (scale < 10) - scale = 10; - if (scale > 1000) - scale = 1000; + if (scale < 0.1f) + scale = 0.1f; + if (scale > 10.f) + scale = 10.f; m_scale = scale; - float scale_factor = (float)m_scale / 100.0f; Gfx::IntSize new_size; - new_size.set_width(m_bitmap->width() * scale_factor); - new_size.set_height(m_bitmap->height() * scale_factor); + new_size.set_width(m_bitmap->width() * m_scale); + new_size.set_height(m_bitmap->height() * m_scale); m_bitmap_rect.set_size(new_size); if (on_scale_change) @@ -207,19 +206,16 @@ void ViewWidget::mousemove_event(GUI::MouseEvent& event) void ViewWidget::mousewheel_event(GUI::MouseEvent& event) { - int new_scale = m_scale - event.wheel_delta() * 10; - if (new_scale < 10) - new_scale = 10; - if (new_scale > 1000) - new_scale = 1000; + float new_scale = m_scale / AK::exp2(event.wheel_delta() / 8.f); + if (new_scale < 0.1f) + new_scale = 0.1f; + if (new_scale > 10.f) + new_scale = 10.f; if (new_scale == m_scale) { return; } - auto old_scale_factor = (float)m_scale / 100.0f; - auto new_scale_factor = (float)new_scale / 100.0f; - // focus_point is the window position the cursor is pointing to. // The pixel (in image space) the cursor points to is located at // (m_pan_origin + focus_point) / scale_factor. @@ -232,7 +228,7 @@ void ViewWidget::mousewheel_event(GUI::MouseEvent& event) }; // A little algebra shows that new m_pan_origin equals to: - m_pan_origin = (m_pan_origin + focus_point) * (new_scale_factor / old_scale_factor) - focus_point; + m_pan_origin = (m_pan_origin + focus_point) * (new_scale / m_scale) - focus_point; set_scale(new_scale); } @@ -313,7 +309,7 @@ void ViewWidget::resize_window() void ViewWidget::reset_view() { m_pan_origin = { 0, 0 }; - set_scale(100); + set_scale(1.f); } void ViewWidget::set_bitmap(const Gfx::Bitmap* bitmap) diff --git a/Userland/Applications/ImageViewer/ViewWidget.h b/Userland/Applications/ImageViewer/ViewWidget.h index 00ed34df0ee..9579a393257 100644 --- a/Userland/Applications/ImageViewer/ViewWidget.h +++ b/Userland/Applications/ImageViewer/ViewWidget.h @@ -29,8 +29,8 @@ public: const Gfx::Bitmap* bitmap() const { return m_bitmap.ptr(); } const String& path() const { return m_path; } - void set_scale(int); - int scale() { return m_scale; } + void set_scale(float); + float scale() { return m_scale; } void set_toolbar_height(int height) { m_toolbar_height = height; } int toolbar_height() { return m_toolbar_height; } bool scaled_for_first_image() { return m_scaled_for_first_image; } @@ -47,7 +47,7 @@ public: void navigate(Directions); void load_from_file(const String&); - Function on_scale_change; + Function on_scale_change; Function on_doubleclick; Function on_drop; Function on_image_change; @@ -78,7 +78,7 @@ private: size_t m_loops_completed { 0 }; NonnullRefPtr m_timer; - int m_scale { -1 }; + float m_scale { -1 }; int m_toolbar_height { 28 }; bool m_scaled_for_first_image { false }; Gfx::FloatPoint m_pan_origin; diff --git a/Userland/Applications/ImageViewer/main.cpp b/Userland/Applications/ImageViewer/main.cpp index 477b40ea906..9375a643a03 100644 --- a/Userland/Applications/ImageViewer/main.cpp +++ b/Userland/Applications/ImageViewer/main.cpp @@ -67,13 +67,13 @@ ErrorOr serenity_main(Main::Arguments arguments) if (path) { widget.set_path(path); } - widget.on_scale_change = [&](int scale) { + widget.on_scale_change = [&](float scale) { if (!widget.bitmap()) { window->set_title("Image Viewer"); return; } - window->set_title(String::formatted("{} {} {}% - Image Viewer", widget.path(), widget.bitmap()->size().to_string(), scale)); + window->set_title(String::formatted("{} {} {}% - Image Viewer", widget.path(), widget.bitmap()->size().to_string(), (int)(scale * 100))); if (scale == 100 && !widget.scaled_for_first_image()) { widget.set_scaled_for_first_image(true); @@ -200,19 +200,19 @@ ErrorOr serenity_main(Main::Arguments arguments) auto zoom_in_action = GUI::CommonActions::make_zoom_in_action( [&](auto&) { - widget.set_scale(widget.scale() + 10); + widget.set_scale(widget.scale() * 1.44f); }, window); auto reset_zoom_action = GUI::CommonActions::make_reset_zoom_action( [&](auto&) { - widget.set_scale(100); + widget.set_scale(1.f); }, window); auto zoom_out_action = GUI::CommonActions::make_zoom_out_action( [&](auto&) { - widget.set_scale(widget.scale() - 10); + widget.set_scale(widget.scale() / 1.44f); }, window);