From 5c763e983299edbb7d4fb626b7aab719d3b03c29 Mon Sep 17 00:00:00 2001 From: Mustafa Quraish Date: Fri, 21 Jan 2022 02:53:49 -0500 Subject: [PATCH] LibGUI+PixelPaint: Move fit_image_to_view to AbstractZoomPanWidget We often want to zoom and fit the content of the widget into the visible frame (or some rect within the frame), and it makes sense to move this functionality into the AbstractZoomPanWidget to minimize the amount of coordinate math derived classes need to do. This commit moves the code that implements this functionality from `PixelPaint::ImageEditor` into `AbstractZoomPanWidget` so that we can also use it for other applications (such as ImageViewer!) --- .../Applications/PixelPaint/ImageEditor.cpp | 23 +---------------- .../Applications/PixelPaint/ImageEditor.h | 8 +----- .../Applications/PixelPaint/MainWidget.cpp | 2 +- .../LibGUI/AbstractZoomPanWidget.cpp | 25 +++++++++++++++++++ .../Libraries/LibGUI/AbstractZoomPanWidget.h | 11 ++++++++ 5 files changed, 39 insertions(+), 30 deletions(-) diff --git a/Userland/Applications/PixelPaint/ImageEditor.cpp b/Userland/Applications/PixelPaint/ImageEditor.cpp index f0751723fa..5b2192ff52 100644 --- a/Userland/Applications/PixelPaint/ImageEditor.cpp +++ b/Userland/Applications/PixelPaint/ImageEditor.cpp @@ -529,28 +529,7 @@ void ImageEditor::fit_image_to_view(FitType type) }; } - const float border_ratio = 0.95f; - auto image_size = image().size(); - auto height_ratio = floorf(border_ratio * viewport_rect.height()) / (float)image_size.height(); - auto width_ratio = floorf(border_ratio * viewport_rect.width()) / (float)image_size.width(); - - float new_scale = 1.0f; - switch (type) { - case FitType::Width: - new_scale = width_ratio; - break; - case FitType::Height: - new_scale = height_ratio; - break; - case FitType::Image: - new_scale = min(height_ratio, width_ratio); - break; - } - - float offset = m_show_rulers ? -m_ruler_thickness / (scale() * 2.0f) : 0.0f; - - set_origin(Gfx::FloatPoint(offset, offset)); - set_scale(new_scale); + fit_content_to_rect(viewport_rect, type); } void ImageEditor::image_did_change(Gfx::IntRect const& modified_image_rect) diff --git a/Userland/Applications/PixelPaint/ImageEditor.h b/Userland/Applications/PixelPaint/ImageEditor.h index caa42dd705..9d9cc2fa40 100644 --- a/Userland/Applications/PixelPaint/ImageEditor.h +++ b/Userland/Applications/PixelPaint/ImageEditor.h @@ -63,13 +63,7 @@ public: Layer* layer_at_editor_position(Gfx::IntPoint const&); - enum class FitType { - Width, - Height, - Image - }; - - void fit_image_to_view(FitType type = FitType::Image); + void fit_image_to_view(FitType type = FitType::Both); Color primary_color() const { return m_primary_color; } void set_primary_color(Color); diff --git a/Userland/Applications/PixelPaint/MainWidget.cpp b/Userland/Applications/PixelPaint/MainWidget.cpp index e1c99f85ec..8303b7c0bd 100644 --- a/Userland/Applications/PixelPaint/MainWidget.cpp +++ b/Userland/Applications/PixelPaint/MainWidget.cpp @@ -658,7 +658,7 @@ void MainWidget::initialize_menubar(GUI::Window& window) editor->fit_image_to_view(ImageEditor::FitType::Height); return; case s_zoom_level_fit_image: - editor->fit_image_to_view(ImageEditor::FitType::Image); + editor->fit_image_to_view(ImageEditor::FitType::Both); return; } } diff --git a/Userland/Libraries/LibGUI/AbstractZoomPanWidget.cpp b/Userland/Libraries/LibGUI/AbstractZoomPanWidget.cpp index 43c0add6bc..d4752f1b45 100644 --- a/Userland/Libraries/LibGUI/AbstractZoomPanWidget.cpp +++ b/Userland/Libraries/LibGUI/AbstractZoomPanWidget.cpp @@ -180,4 +180,29 @@ void AbstractZoomPanWidget::set_scale_bounds(float min_scale, float max_scale) m_max_scale = max_scale; } +void AbstractZoomPanWidget::fit_content_to_rect(Gfx::IntRect const& viewport_rect, FitType type) +{ + const float border_ratio = 0.95f; + auto image_size = m_original_rect.size(); + auto height_ratio = floorf(border_ratio * viewport_rect.height()) / (float)image_size.height(); + auto width_ratio = floorf(border_ratio * viewport_rect.width()) / (float)image_size.width(); + + float new_scale = 1.0f; + switch (type) { + case FitType::Width: + new_scale = width_ratio; + break; + case FitType::Height: + new_scale = height_ratio; + break; + case FitType::Both: + new_scale = min(height_ratio, width_ratio); + break; + } + + auto const& offset = rect().center() - viewport_rect.center(); + set_origin(Gfx::FloatPoint(offset.x(), offset.y())); + set_scale(new_scale); +} + } diff --git a/Userland/Libraries/LibGUI/AbstractZoomPanWidget.h b/Userland/Libraries/LibGUI/AbstractZoomPanWidget.h index cb0485203b..612438981a 100644 --- a/Userland/Libraries/LibGUI/AbstractZoomPanWidget.h +++ b/Userland/Libraries/LibGUI/AbstractZoomPanWidget.h @@ -54,6 +54,17 @@ public: Function on_scale_change; + enum class FitType { + Width, + Height, + Both + }; + void fit_content_to_rect(Gfx::IntRect const& rect, FitType = FitType::Both); + void fit_content_to_view(FitType fit_type = FitType::Both) + { + fit_content_to_rect(rect(), fit_type); + } + private: Gfx::IntRect m_original_rect; Gfx::IntRect m_content_rect;