mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-26 06:18:59 +00:00
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!)
84 lines
2.6 KiB
C++
84 lines
2.6 KiB
C++
/*
|
|
* Copyright (c) 2022, Mustafa Quraish <mustafa@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <LibGUI/Frame.h>
|
|
#include <LibGfx/Point.h>
|
|
#include <LibGfx/Rect.h>
|
|
|
|
namespace GUI {
|
|
|
|
class AbstractZoomPanWidget : public GUI::Frame {
|
|
C_OBJECT(AbstractZoomPanWidget);
|
|
|
|
public:
|
|
void set_scale(float scale);
|
|
float scale() const { return m_scale; }
|
|
void set_scale_bounds(float min_scale, float max_scale);
|
|
|
|
void scale_by(float amount);
|
|
void scale_centered(float new_scale, Gfx::IntPoint const& center);
|
|
|
|
bool is_panning() const { return m_is_panning; }
|
|
void start_panning(Gfx::IntPoint const& position);
|
|
void stop_panning();
|
|
|
|
void pan_to(Gfx::IntPoint const& position);
|
|
|
|
// Should be overridden by derived classes if they want updates.
|
|
virtual void handle_relayout(Gfx::IntRect const&) { update(); }
|
|
void relayout();
|
|
|
|
Gfx::FloatPoint frame_to_content_position(Gfx::IntPoint const& frame_position) const;
|
|
Gfx::FloatRect frame_to_content_rect(Gfx::IntRect const& frame_rect) const;
|
|
Gfx::FloatPoint content_to_frame_position(Gfx::IntPoint const& content_position) const;
|
|
Gfx::FloatRect content_to_frame_rect(Gfx::IntRect const& content_rect) const;
|
|
|
|
virtual void mousewheel_event(GUI::MouseEvent& event) override;
|
|
virtual void mousedown_event(GUI::MouseEvent& event) override;
|
|
virtual void resize_event(GUI::ResizeEvent& event) override;
|
|
virtual void mousemove_event(GUI::MouseEvent& event) override;
|
|
virtual void mouseup_event(GUI::MouseEvent& event) override;
|
|
|
|
void set_original_rect(Gfx::IntRect const& rect) { m_original_rect = rect; }
|
|
void set_content_rect(Gfx::IntRect const& content_rect);
|
|
void set_origin(Gfx::FloatPoint const& origin) { m_origin = origin; }
|
|
|
|
void reset_view();
|
|
|
|
Gfx::IntRect content_rect() const { return m_content_rect; }
|
|
|
|
Function<void(float)> 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;
|
|
|
|
Gfx::IntPoint m_pan_mouse_pos;
|
|
Gfx::FloatPoint m_origin;
|
|
Gfx::FloatPoint m_pan_start;
|
|
bool m_is_panning { false };
|
|
|
|
float m_min_scale { 0.1f };
|
|
float m_max_scale { 10.0f };
|
|
float m_scale { 1.0f };
|
|
|
|
AK::Variant<Gfx::StandardCursor, NonnullRefPtr<Gfx::Bitmap>> m_saved_cursor { Gfx::StandardCursor::None };
|
|
};
|
|
|
|
}
|