mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 13:32:45 +00: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
					
				
					 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
	
	 Maciej
						Maciej