mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-10 10:01:13 +09:00
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
This commit is contained in:
parent
1c3a82d59e
commit
ab324c1dae
Notes:
sideshowbarker
2024-07-17 22:02:14 +09:00
Author: https://github.com/sppmacd
Commit: ab324c1dae
Pull-request: https://github.com/SerenityOS/serenity/pull/11463
3 changed files with 23 additions and 27 deletions
|
@ -118,22 +118,21 @@ void ViewWidget::navigate(Directions direction)
|
||||||
this->load_from_file(m_files_in_same_dir.at(index));
|
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())
|
if (m_bitmap.is_null())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (scale < 10)
|
if (scale < 0.1f)
|
||||||
scale = 10;
|
scale = 0.1f;
|
||||||
if (scale > 1000)
|
if (scale > 10.f)
|
||||||
scale = 1000;
|
scale = 10.f;
|
||||||
|
|
||||||
m_scale = scale;
|
m_scale = scale;
|
||||||
float scale_factor = (float)m_scale / 100.0f;
|
|
||||||
|
|
||||||
Gfx::IntSize new_size;
|
Gfx::IntSize new_size;
|
||||||
new_size.set_width(m_bitmap->width() * scale_factor);
|
new_size.set_width(m_bitmap->width() * m_scale);
|
||||||
new_size.set_height(m_bitmap->height() * scale_factor);
|
new_size.set_height(m_bitmap->height() * m_scale);
|
||||||
m_bitmap_rect.set_size(new_size);
|
m_bitmap_rect.set_size(new_size);
|
||||||
|
|
||||||
if (on_scale_change)
|
if (on_scale_change)
|
||||||
|
@ -207,19 +206,16 @@ void ViewWidget::mousemove_event(GUI::MouseEvent& event)
|
||||||
|
|
||||||
void ViewWidget::mousewheel_event(GUI::MouseEvent& event)
|
void ViewWidget::mousewheel_event(GUI::MouseEvent& event)
|
||||||
{
|
{
|
||||||
int new_scale = m_scale - event.wheel_delta() * 10;
|
float new_scale = m_scale / AK::exp2(event.wheel_delta() / 8.f);
|
||||||
if (new_scale < 10)
|
if (new_scale < 0.1f)
|
||||||
new_scale = 10;
|
new_scale = 0.1f;
|
||||||
if (new_scale > 1000)
|
if (new_scale > 10.f)
|
||||||
new_scale = 1000;
|
new_scale = 10.f;
|
||||||
|
|
||||||
if (new_scale == m_scale) {
|
if (new_scale == m_scale) {
|
||||||
return;
|
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.
|
// focus_point is the window position the cursor is pointing to.
|
||||||
// The pixel (in image space) the cursor points to is located at
|
// The pixel (in image space) the cursor points to is located at
|
||||||
// (m_pan_origin + focus_point) / scale_factor.
|
// (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:
|
// 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);
|
set_scale(new_scale);
|
||||||
}
|
}
|
||||||
|
@ -313,7 +309,7 @@ void ViewWidget::resize_window()
|
||||||
void ViewWidget::reset_view()
|
void ViewWidget::reset_view()
|
||||||
{
|
{
|
||||||
m_pan_origin = { 0, 0 };
|
m_pan_origin = { 0, 0 };
|
||||||
set_scale(100);
|
set_scale(1.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewWidget::set_bitmap(const Gfx::Bitmap* bitmap)
|
void ViewWidget::set_bitmap(const Gfx::Bitmap* bitmap)
|
||||||
|
|
|
@ -29,8 +29,8 @@ public:
|
||||||
|
|
||||||
const Gfx::Bitmap* bitmap() const { return m_bitmap.ptr(); }
|
const Gfx::Bitmap* bitmap() const { return m_bitmap.ptr(); }
|
||||||
const String& path() const { return m_path; }
|
const String& path() const { return m_path; }
|
||||||
void set_scale(int);
|
void set_scale(float);
|
||||||
int scale() { return m_scale; }
|
float scale() { return m_scale; }
|
||||||
void set_toolbar_height(int height) { m_toolbar_height = height; }
|
void set_toolbar_height(int height) { m_toolbar_height = height; }
|
||||||
int toolbar_height() { return m_toolbar_height; }
|
int toolbar_height() { return m_toolbar_height; }
|
||||||
bool scaled_for_first_image() { return m_scaled_for_first_image; }
|
bool scaled_for_first_image() { return m_scaled_for_first_image; }
|
||||||
|
@ -47,7 +47,7 @@ public:
|
||||||
void navigate(Directions);
|
void navigate(Directions);
|
||||||
void load_from_file(const String&);
|
void load_from_file(const String&);
|
||||||
|
|
||||||
Function<void(int)> on_scale_change;
|
Function<void(float)> on_scale_change;
|
||||||
Function<void()> on_doubleclick;
|
Function<void()> on_doubleclick;
|
||||||
Function<void(const GUI::DropEvent&)> on_drop;
|
Function<void(const GUI::DropEvent&)> on_drop;
|
||||||
Function<void(const Gfx::Bitmap*)> on_image_change;
|
Function<void(const Gfx::Bitmap*)> on_image_change;
|
||||||
|
@ -78,7 +78,7 @@ private:
|
||||||
size_t m_loops_completed { 0 };
|
size_t m_loops_completed { 0 };
|
||||||
NonnullRefPtr<Core::Timer> m_timer;
|
NonnullRefPtr<Core::Timer> m_timer;
|
||||||
|
|
||||||
int m_scale { -1 };
|
float m_scale { -1 };
|
||||||
int m_toolbar_height { 28 };
|
int m_toolbar_height { 28 };
|
||||||
bool m_scaled_for_first_image { false };
|
bool m_scaled_for_first_image { false };
|
||||||
Gfx::FloatPoint m_pan_origin;
|
Gfx::FloatPoint m_pan_origin;
|
||||||
|
|
|
@ -67,13 +67,13 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
if (path) {
|
if (path) {
|
||||||
widget.set_path(path);
|
widget.set_path(path);
|
||||||
}
|
}
|
||||||
widget.on_scale_change = [&](int scale) {
|
widget.on_scale_change = [&](float scale) {
|
||||||
if (!widget.bitmap()) {
|
if (!widget.bitmap()) {
|
||||||
window->set_title("Image Viewer");
|
window->set_title("Image Viewer");
|
||||||
return;
|
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()) {
|
if (scale == 100 && !widget.scaled_for_first_image()) {
|
||||||
widget.set_scaled_for_first_image(true);
|
widget.set_scaled_for_first_image(true);
|
||||||
|
@ -200,19 +200,19 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
|
|
||||||
auto zoom_in_action = GUI::CommonActions::make_zoom_in_action(
|
auto zoom_in_action = GUI::CommonActions::make_zoom_in_action(
|
||||||
[&](auto&) {
|
[&](auto&) {
|
||||||
widget.set_scale(widget.scale() + 10);
|
widget.set_scale(widget.scale() * 1.44f);
|
||||||
},
|
},
|
||||||
window);
|
window);
|
||||||
|
|
||||||
auto reset_zoom_action = GUI::CommonActions::make_reset_zoom_action(
|
auto reset_zoom_action = GUI::CommonActions::make_reset_zoom_action(
|
||||||
[&](auto&) {
|
[&](auto&) {
|
||||||
widget.set_scale(100);
|
widget.set_scale(1.f);
|
||||||
},
|
},
|
||||||
window);
|
window);
|
||||||
|
|
||||||
auto zoom_out_action = GUI::CommonActions::make_zoom_out_action(
|
auto zoom_out_action = GUI::CommonActions::make_zoom_out_action(
|
||||||
[&](auto&) {
|
[&](auto&) {
|
||||||
widget.set_scale(widget.scale() - 10);
|
widget.set_scale(widget.scale() / 1.44f);
|
||||||
},
|
},
|
||||||
window);
|
window);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue