Incorporate min and max zoom limits into the EditorZoomWidget
This commit is contained in:
parent
5c43e4c1ef
commit
44d782681c
|
@ -70,12 +70,36 @@ float EditorZoomWidget::get_zoom() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorZoomWidget::set_zoom(float p_zoom) {
|
void EditorZoomWidget::set_zoom(float p_zoom) {
|
||||||
if (p_zoom > 0 && p_zoom != zoom) {
|
float new_zoom = CLAMP(p_zoom, min_zoom, max_zoom);
|
||||||
zoom = p_zoom;
|
if (zoom != new_zoom) {
|
||||||
|
zoom = new_zoom;
|
||||||
_update_zoom_label();
|
_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) {
|
void EditorZoomWidget::set_zoom_by_increments(int p_increment_count, bool p_integer_only) {
|
||||||
// Remove editor scale from the index computation.
|
// Remove editor scale from the index computation.
|
||||||
const float zoom_noscale = zoom / MAX(1, EDSCALE);
|
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 {
|
} else {
|
||||||
if (p_increment_count >= 1) {
|
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);
|
float new_zoom = 1.0 / Math::ceil(1.0 / zoom_noscale - p_increment_count);
|
||||||
if (Math::is_equal_approx(zoom_noscale, new_zoom)) {
|
if (Math::is_equal_approx(zoom_noscale, new_zoom)) {
|
||||||
// New zoom is identical to the old zoom, so try again.
|
// 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));
|
set_zoom(new_zoom * MAX(1, EDSCALE));
|
||||||
} else {
|
} 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);
|
float new_zoom = 1.0 / Math::floor(1.0 / zoom_noscale - p_increment_count);
|
||||||
if (Math::is_equal_approx(zoom_noscale, new_zoom)) {
|
if (Math::is_equal_approx(zoom_noscale, new_zoom)) {
|
||||||
// New zoom is identical to the old zoom, so try again.
|
// 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 {
|
} else {
|
||||||
// Base increment factor defined as the twelveth root of two.
|
// 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.
|
// 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
|
// In order to avoid numerical imprecisions, we compute and edit a zoom index
|
||||||
// with the following relation: zoom = 2 ^ (index / 12)
|
// with the following relation: zoom = 2 ^ (index / 12)
|
||||||
|
|
||||||
|
@ -179,10 +203,11 @@ EditorZoomWidget::EditorZoomWidget() {
|
||||||
|
|
||||||
zoom_reset = memnew(Button);
|
zoom_reset = memnew(Button);
|
||||||
zoom_reset->set_flat(true);
|
zoom_reset->set_flat(true);
|
||||||
zoom_reset->add_theme_style_override("normal", memnew(StyleBoxEmpty));
|
Ref<StyleBoxEmpty> empty_stylebox = memnew(StyleBoxEmpty);
|
||||||
zoom_reset->add_theme_style_override("hover", memnew(StyleBoxEmpty));
|
zoom_reset->add_theme_style_override("normal", empty_stylebox);
|
||||||
zoom_reset->add_theme_style_override("focus", memnew(StyleBoxEmpty));
|
zoom_reset->add_theme_style_override("hover", empty_stylebox);
|
||||||
zoom_reset->add_theme_style_override("pressed", memnew(StyleBoxEmpty));
|
zoom_reset->add_theme_style_override("focus", empty_stylebox);
|
||||||
|
zoom_reset->add_theme_style_override("pressed", empty_stylebox);
|
||||||
add_child(zoom_reset);
|
add_child(zoom_reset);
|
||||||
zoom_reset->add_theme_constant_override("outline_size", Math::ceil(2 * EDSCALE));
|
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));
|
zoom_reset->add_theme_color_override("font_outline_color", Color(0, 0, 0));
|
||||||
|
|
|
@ -42,6 +42,8 @@ class EditorZoomWidget : public HBoxContainer {
|
||||||
Button *zoom_plus = nullptr;
|
Button *zoom_plus = nullptr;
|
||||||
|
|
||||||
float zoom = 1.0;
|
float zoom = 1.0;
|
||||||
|
float min_zoom = 1.0 / 128;
|
||||||
|
float max_zoom = 128.0;
|
||||||
void _update_zoom_label();
|
void _update_zoom_label();
|
||||||
void _button_zoom_minus();
|
void _button_zoom_minus();
|
||||||
void _button_zoom_reset();
|
void _button_zoom_reset();
|
||||||
|
@ -57,6 +59,11 @@ public:
|
||||||
float get_zoom();
|
float get_zoom();
|
||||||
void set_zoom(float p_zoom);
|
void set_zoom(float p_zoom);
|
||||||
void set_zoom_by_increments(int p_increment_count, bool p_integer_only = false);
|
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.
|
// Sets the shortcut context for the zoom buttons. By default their context is this EditorZoomWidget control.
|
||||||
void set_shortcut_context(Node *p_node) const;
|
void set_shortcut_context(Node *p_node) const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -60,11 +60,6 @@
|
||||||
#include "scene/resources/packed_scene.h"
|
#include "scene/resources/packed_scene.h"
|
||||||
#include "scene/resources/style_box_texture.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)
|
#define RULER_WIDTH (15 * EDSCALE)
|
||||||
constexpr real_t SCALE_HANDLE_DISTANCE = 25;
|
constexpr real_t SCALE_HANDLE_DISTANCE = 25;
|
||||||
constexpr real_t MOVE_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) {
|
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) {
|
if (p_zoom == zoom) {
|
||||||
zoom_widget->set_zoom(p_zoom);
|
|
||||||
return;
|
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;
|
view_offset += p_position / prev_zoom - p_position / zoom;
|
||||||
|
|
||||||
// We want to align in-scene pixels to screen pixels, this prevents blurry rendering
|
// 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
|
// 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)
|
// 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);
|
const real_t closest_zoom_factor = Math::round(zoom);
|
||||||
if (Math::is_zero_approx(zoom - closest_zoom_factor)) {
|
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_int = view_offset.floor();
|
||||||
Vector2 view_offset_frac = view_offset - view_offset_int;
|
Vector2 view_offset_frac = view_offset - view_offset_int;
|
||||||
view_offset = view_offset_int + (view_offset_frac * closest_zoom_factor).round() / closest_zoom_factor;
|
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));
|
button_center_view->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback).bind(VIEW_CENTER_TO_SELECTION));
|
||||||
|
|
||||||
zoom_widget = memnew(EditorZoomWidget);
|
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_anchors_and_offsets_preset(Control::PRESET_TOP_LEFT, Control::PRESET_MODE_MINSIZE, 2 * EDSCALE);
|
||||||
zoom_widget->set_shortcut_context(this);
|
zoom_widget->set_shortcut_context(this);
|
||||||
|
controls_hb->add_child(zoom_widget);
|
||||||
zoom_widget->connect("zoom_changed", callable_mp(this, &CanvasItemEditor::_update_zoom));
|
zoom_widget->connect("zoom_changed", callable_mp(this, &CanvasItemEditor::_update_zoom));
|
||||||
|
|
||||||
panner.instantiate();
|
panner.instantiate();
|
||||||
|
|
|
@ -90,8 +90,6 @@ Size2i TileAtlasView::_compute_alternative_tiles_control_size() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileAtlasView::_update_zoom_and_panning(bool p_zoom_on_mouse_pos) {
|
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();
|
float zoom = zoom_widget->get_zoom();
|
||||||
|
|
||||||
// Compute the minimum sizes.
|
// Compute the minimum sizes.
|
||||||
|
|
|
@ -931,6 +931,7 @@ GenericTilePolygonEditor::GenericTilePolygonEditor() {
|
||||||
snap_subdivision->connect("value_changed", callable_mp(this, &GenericTilePolygonEditor::_store_snap_options).unbind(1));
|
snap_subdivision->connect("value_changed", callable_mp(this, &GenericTilePolygonEditor::_store_snap_options).unbind(1));
|
||||||
|
|
||||||
editor_zoom_widget = memnew(EditorZoomWidget);
|
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->set_position(Vector2(5, 5));
|
||||||
editor_zoom_widget->connect("zoom_changed", callable_mp(this, &GenericTilePolygonEditor::_zoom_changed).unbind(1));
|
editor_zoom_widget->connect("zoom_changed", callable_mp(this, &GenericTilePolygonEditor::_zoom_changed).unbind(1));
|
||||||
editor_zoom_widget->set_shortcut_context(this);
|
editor_zoom_widget->set_shortcut_context(this);
|
||||||
|
|
Loading…
Reference in New Issue