Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorporate min and max zoom limits into the EditorZoomWidget #81812

Merged
merged 1 commit into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 35 additions & 10 deletions editor/gui/editor_zoom_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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.
Expand All @@ -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.
Expand All @@ -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)

Expand Down Expand Up @@ -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<StyleBoxEmpty> 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));
Expand Down
7 changes: 7 additions & 0 deletions editor/gui/editor_zoom_widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -57,6 +59,11 @@ class EditorZoomWidget : public HBoxContainer {
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;
};
Expand Down
14 changes: 4 additions & 10 deletions editor/plugins/canvas_item_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
Expand Down Expand Up @@ -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();
Expand Down
2 changes: 0 additions & 2 deletions editor/plugins/tiles/tile_atlas_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions editor/plugins/tiles/tile_data_editors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading