From cc65147250aac04b1e680faf767bc09b064ca421 Mon Sep 17 00:00:00 2001 From: Haoyu Qiu Date: Mon, 7 Mar 2022 13:01:39 +0800 Subject: [PATCH] Update scroll position when zooming TileSet editor --- editor/plugins/tile_set_editor_plugin.cpp | 36 +++++++++++++---------- editor/plugins/tile_set_editor_plugin.h | 1 + 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index 6f74fb62c04..9a5268b1592 100644 --- a/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp @@ -1227,11 +1227,11 @@ void TileSetEditor::_on_scroll_container_input(const Ref &p_event) { // to allow performing this action anywhere, even if the cursor isn't // hovering the texture in the workspace. if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed() && mb->get_control()) { - _zoom_in(); + _zoom_on_position(scale_ratio, mb->get_position()); // Don't scroll up after zooming in. accept_event(); } else if (mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed() && mb->get_control()) { - _zoom_out(); + _zoom_on_position(1 / scale_ratio, mb->get_position()); // Don't scroll down after zooming out. accept_event(); } @@ -2416,29 +2416,33 @@ void TileSetEditor::_undo_tile_removal(int p_id) { } void TileSetEditor::_zoom_in() { - float scale = workspace->get_scale().x; - if (scale < max_scale) { - scale *= scale_ratio; - workspace->set_scale(Vector2(scale, scale)); - workspace_container->set_custom_minimum_size(workspace->get_rect().size * scale); - workspace_overlay->set_custom_minimum_size(workspace->get_rect().size * scale); - } + _zoom_on_position(scale_ratio, Vector2()); } + void TileSetEditor::_zoom_out() { - float scale = workspace->get_scale().x; - if (scale > min_scale) { - scale /= scale_ratio; - workspace->set_scale(Vector2(scale, scale)); - workspace_container->set_custom_minimum_size(workspace->get_rect().size * scale); - workspace_overlay->set_custom_minimum_size(workspace->get_rect().size * scale); - } + _zoom_on_position(1 / scale_ratio, Vector2()); } + void TileSetEditor::_zoom_reset() { workspace->set_scale(Vector2(1, 1)); workspace_container->set_custom_minimum_size(workspace->get_rect().size); workspace_overlay->set_custom_minimum_size(workspace->get_rect().size); } +void TileSetEditor::_zoom_on_position(float p_zoom, const Vector2 &p_position) { + const float old_scale = workspace->get_scale().x; + const float new_scale = CLAMP(old_scale * p_zoom, min_scale, max_scale); + + workspace->set_scale(Vector2(new_scale, new_scale)); + workspace_container->set_custom_minimum_size(workspace->get_rect().size * new_scale); + workspace_overlay->set_custom_minimum_size(workspace->get_rect().size * new_scale); + + Vector2 offset = Vector2(scroll->get_h_scroll(), scroll->get_v_scroll()); + offset = (offset + p_position) / old_scale * new_scale - p_position; + scroll->set_h_scroll(offset.x); + scroll->set_v_scroll(offset.y); +} + void TileSetEditor::draw_highlight_current_tile() { Color shadow_color = Color(0.3, 0.3, 0.3, 0.3); if ((workspace_mode == WORKSPACE_EDIT && get_current_tile() >= 0) || !edited_region.has_no_area()) { diff --git a/editor/plugins/tile_set_editor_plugin.h b/editor/plugins/tile_set_editor_plugin.h index 4e0673259e9..87b4b3e731a 100644 --- a/editor/plugins/tile_set_editor_plugin.h +++ b/editor/plugins/tile_set_editor_plugin.h @@ -230,6 +230,7 @@ private: void _zoom_in(); void _zoom_out(); void _zoom_reset(); + void _zoom_on_position(float p_zoom, const Vector2 &p_position); void draw_highlight_current_tile(); void draw_highlight_subtile(Vector2 coord, const Vector &other_highlighted = Vector());