From 44d782681c553e4f248fc58825d90d7272c53e5f Mon Sep 17 00:00:00 2001 From: MewPurPur Date: Sun, 17 Sep 2023 18:33:02 +0300 Subject: [PATCH] Incorporate min and max zoom limits into the EditorZoomWidget --- editor/gui/editor_zoom_widget.cpp | 45 +++++++++++++++----- editor/gui/editor_zoom_widget.h | 7 +++ editor/plugins/canvas_item_editor_plugin.cpp | 14 ++---- editor/plugins/tiles/tile_atlas_view.cpp | 2 - editor/plugins/tiles/tile_data_editors.cpp | 1 + 5 files changed, 47 insertions(+), 22 deletions(-) diff --git a/editor/gui/editor_zoom_widget.cpp b/editor/gui/editor_zoom_widget.cpp index e292dc99ac2..5c936a75f2a 100644 --- a/editor/gui/editor_zoom_widget.cpp +++ b/editor/gui/editor_zoom_widget.cpp @@ -70,12 +70,36 @@ float EditorZoomWidget::get_zoom() { } void EditorZoomWidget::set_zoom(float p_zoom) { - if (p_zoom > 0 && p_zoom != zoom) { - zoom = p_zoom; + float new_zoom = CLAMP(p_zoom, min_zoom, max_zoom); + if (zoom != new_zoom) { + zoom = new_zoom; _update_zoom_label(); } } +float EditorZoomWidget::get_min_zoom() { + return min_zoom; +} + +float EditorZoomWidget::get_max_zoom() { + return max_zoom; +} + +void EditorZoomWidget::setup_zoom_limits(float p_min, float p_max) { + ERR_FAIL_COND(p_min < 0 || p_min > p_max); + + min_zoom = p_min; + max_zoom = p_max; + + if (zoom > max_zoom) { + set_zoom(max_zoom); + emit_signal(SNAME("zoom_changed"), zoom); + } else if (zoom < min_zoom) { + set_zoom(min_zoom); + emit_signal(SNAME("zoom_changed"), zoom); + } +} + void EditorZoomWidget::set_zoom_by_increments(int p_increment_count, bool p_integer_only) { // Remove editor scale from the index computation. const float zoom_noscale = zoom / MAX(1, EDSCALE); @@ -97,7 +121,7 @@ void EditorZoomWidget::set_zoom_by_increments(int p_increment_count, bool p_inte } } else { if (p_increment_count >= 1) { - // Zooming. Convert the current zoom into a denominator. + // Zooming in. Convert the current zoom into a denominator. float new_zoom = 1.0 / Math::ceil(1.0 / zoom_noscale - p_increment_count); if (Math::is_equal_approx(zoom_noscale, new_zoom)) { // New zoom is identical to the old zoom, so try again. @@ -106,7 +130,7 @@ void EditorZoomWidget::set_zoom_by_increments(int p_increment_count, bool p_inte } set_zoom(new_zoom * MAX(1, EDSCALE)); } else { - // Dezooming. Convert the current zoom into a denominator. + // Zooming out. Convert the current zoom into a denominator. float new_zoom = 1.0 / Math::floor(1.0 / zoom_noscale - p_increment_count); if (Math::is_equal_approx(zoom_noscale, new_zoom)) { // New zoom is identical to the old zoom, so try again. @@ -118,9 +142,9 @@ void EditorZoomWidget::set_zoom_by_increments(int p_increment_count, bool p_inte } } else { // Base increment factor defined as the twelveth root of two. - // This allow a smooth geometric evolution of the zoom, with the advantage of + // This allows for a smooth geometric evolution of the zoom, with the advantage of // visiting all integer power of two scale factors. - // note: this is analogous to the 'semitones' interval in the music world + // Note: this is analogous to the 'semitone' interval in the music world // In order to avoid numerical imprecisions, we compute and edit a zoom index // with the following relation: zoom = 2 ^ (index / 12) @@ -179,10 +203,11 @@ EditorZoomWidget::EditorZoomWidget() { zoom_reset = memnew(Button); zoom_reset->set_flat(true); - zoom_reset->add_theme_style_override("normal", memnew(StyleBoxEmpty)); - zoom_reset->add_theme_style_override("hover", memnew(StyleBoxEmpty)); - zoom_reset->add_theme_style_override("focus", memnew(StyleBoxEmpty)); - zoom_reset->add_theme_style_override("pressed", memnew(StyleBoxEmpty)); + Ref empty_stylebox = memnew(StyleBoxEmpty); + zoom_reset->add_theme_style_override("normal", empty_stylebox); + zoom_reset->add_theme_style_override("hover", empty_stylebox); + zoom_reset->add_theme_style_override("focus", empty_stylebox); + zoom_reset->add_theme_style_override("pressed", empty_stylebox); add_child(zoom_reset); zoom_reset->add_theme_constant_override("outline_size", Math::ceil(2 * EDSCALE)); zoom_reset->add_theme_color_override("font_outline_color", Color(0, 0, 0)); diff --git a/editor/gui/editor_zoom_widget.h b/editor/gui/editor_zoom_widget.h index be54043d937..6b2fe4d3e98 100644 --- a/editor/gui/editor_zoom_widget.h +++ b/editor/gui/editor_zoom_widget.h @@ -42,6 +42,8 @@ class EditorZoomWidget : public HBoxContainer { Button *zoom_plus = nullptr; float zoom = 1.0; + float min_zoom = 1.0 / 128; + float max_zoom = 128.0; void _update_zoom_label(); void _button_zoom_minus(); void _button_zoom_reset(); @@ -57,6 +59,11 @@ public: float get_zoom(); void set_zoom(float p_zoom); void set_zoom_by_increments(int p_increment_count, bool p_integer_only = false); + + float get_min_zoom(); + float get_max_zoom(); + // It's best to setup simultaneously, so min < max can be checked easily. + void setup_zoom_limits(float p_min, float p_max); // Sets the shortcut context for the zoom buttons. By default their context is this EditorZoomWidget control. void set_shortcut_context(Node *p_node) const; }; diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 703cd7ef81f..c7d6cf32448 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -60,11 +60,6 @@ #include "scene/resources/packed_scene.h" #include "scene/resources/style_box_texture.h" -// Min and Max are power of two in order to play nicely with successive increment. -// That way, we can naturally reach a 100% zoom from boundaries. -constexpr real_t MIN_ZOOM = 1. / 128; -constexpr real_t MAX_ZOOM = 128; - #define RULER_WIDTH (15 * EDSCALE) constexpr real_t SCALE_HANDLE_DISTANCE = 25; constexpr real_t MOVE_HANDLE_DISTANCE = 25; @@ -4100,10 +4095,9 @@ void CanvasItemEditor::_update_scroll(real_t) { } void CanvasItemEditor::_zoom_on_position(real_t p_zoom, Point2 p_position) { - p_zoom = CLAMP(p_zoom, MIN_ZOOM, MAX_ZOOM); + p_zoom = CLAMP(p_zoom, zoom_widget->get_min_zoom(), zoom_widget->get_max_zoom()); if (p_zoom == zoom) { - zoom_widget->set_zoom(p_zoom); return; } @@ -4113,12 +4107,12 @@ void CanvasItemEditor::_zoom_on_position(real_t p_zoom, Point2 p_position) { view_offset += p_position / prev_zoom - p_position / zoom; // We want to align in-scene pixels to screen pixels, this prevents blurry rendering - // in small details (texts, lines). + // of small details (texts, lines). // This correction adds a jitter movement when zooming, so we correct only when the // zoom factor is an integer. (in the other cases, all pixels won't be aligned anyway) const real_t closest_zoom_factor = Math::round(zoom); if (Math::is_zero_approx(zoom - closest_zoom_factor)) { - // make sure scene pixel at view_offset is aligned on a screen pixel + // Make sure scene pixel at view_offset is aligned on a screen pixel. Vector2 view_offset_int = view_offset.floor(); Vector2 view_offset_frac = view_offset - view_offset_int; view_offset = view_offset_int + (view_offset_frac * closest_zoom_factor).round() / closest_zoom_factor; @@ -5077,9 +5071,9 @@ CanvasItemEditor::CanvasItemEditor() { button_center_view->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback).bind(VIEW_CENTER_TO_SELECTION)); zoom_widget = memnew(EditorZoomWidget); - controls_hb->add_child(zoom_widget); zoom_widget->set_anchors_and_offsets_preset(Control::PRESET_TOP_LEFT, Control::PRESET_MODE_MINSIZE, 2 * EDSCALE); zoom_widget->set_shortcut_context(this); + controls_hb->add_child(zoom_widget); zoom_widget->connect("zoom_changed", callable_mp(this, &CanvasItemEditor::_update_zoom)); panner.instantiate(); diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp index b55be8b3f89..039213e5452 100644 --- a/editor/plugins/tiles/tile_atlas_view.cpp +++ b/editor/plugins/tiles/tile_atlas_view.cpp @@ -90,8 +90,6 @@ Size2i TileAtlasView::_compute_alternative_tiles_control_size() { } void TileAtlasView::_update_zoom_and_panning(bool p_zoom_on_mouse_pos) { - // Don't allow zoom to go below 1% or above 10000% - zoom_widget->set_zoom(CLAMP(zoom_widget->get_zoom(), 0.01f, 100.f)); float zoom = zoom_widget->get_zoom(); // Compute the minimum sizes. diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp index 26487e8dfd7..f0f3ed84492 100644 --- a/editor/plugins/tiles/tile_data_editors.cpp +++ b/editor/plugins/tiles/tile_data_editors.cpp @@ -931,6 +931,7 @@ GenericTilePolygonEditor::GenericTilePolygonEditor() { snap_subdivision->connect("value_changed", callable_mp(this, &GenericTilePolygonEditor::_store_snap_options).unbind(1)); editor_zoom_widget = memnew(EditorZoomWidget); + editor_zoom_widget->setup_zoom_limits(0.125, 128.0); editor_zoom_widget->set_position(Vector2(5, 5)); editor_zoom_widget->connect("zoom_changed", callable_mp(this, &GenericTilePolygonEditor::_zoom_changed).unbind(1)); editor_zoom_widget->set_shortcut_context(this);