Make zoom limits and step adjustable in GraphEdit

This commit is contained in:
Yuri Sizov 2021-06-16 16:14:25 +03:00
parent badad53438
commit 0a82a669e3
3 changed files with 145 additions and 23 deletions

View File

@ -197,6 +197,9 @@
<member name="scroll_offset" type="Vector2" setter="set_scroll_ofs" getter="get_scroll_ofs" default="Vector2( 0, 0 )"> <member name="scroll_offset" type="Vector2" setter="set_scroll_ofs" getter="get_scroll_ofs" default="Vector2( 0, 0 )">
The scroll offset. The scroll offset.
</member> </member>
<member name="show_zoom_label" type="bool" setter="set_show_zoom_label" getter="is_showing_zoom_label" default="false">
If [code]true[/code], makes a label with the current zoom level visible. The zoom value is displayed in percents.
</member>
<member name="snap_distance" type="int" setter="set_snap" getter="get_snap" default="20"> <member name="snap_distance" type="int" setter="set_snap" getter="get_snap" default="20">
The snapping distance in pixels. The snapping distance in pixels.
</member> </member>
@ -206,6 +209,15 @@
<member name="zoom" type="float" setter="set_zoom" getter="get_zoom" default="1.0"> <member name="zoom" type="float" setter="set_zoom" getter="get_zoom" default="1.0">
The current zoom value. The current zoom value.
</member> </member>
<member name="zoom_max" type="float" setter="set_zoom_max" getter="get_zoom_max" default="2.0736">
The upper zoom limit.
</member>
<member name="zoom_min" type="float" setter="set_zoom_min" getter="get_zoom_min" default="0.232568">
The lower zoom limit.
</member>
<member name="zoom_step" type="float" setter="set_zoom_step" getter="get_zoom_step" default="1.2">
The step of each zoom level.
</member>
</members> </members>
<signals> <signals>
<signal name="begin_node_move"> <signal name="begin_node_move">

View File

@ -40,16 +40,6 @@
#include "editor/editor_scale.h" #include "editor/editor_scale.h"
#endif #endif
#define ZOOM_SCALE 1.2
// Allow dezooming 8 times from the default zoom level.
// At low zoom levels, text is unreadable due to its small size and poor filtering,
// but this is still useful for previewing purposes.
#define MIN_ZOOM (1 / Math::pow(ZOOM_SCALE, 8))
// Allow zooming 4 times from the default zoom level.
#define MAX_ZOOM (1 * Math::pow(ZOOM_SCALE, 4))
#define MINIMAP_OFFSET 12 #define MINIMAP_OFFSET 12
#define MINIMAP_PADDING 5 #define MINIMAP_PADDING 5
@ -1328,9 +1318,9 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
} }
if (b->get_button_index() == MOUSE_BUTTON_WHEEL_UP && Input::get_singleton()->is_key_pressed(KEY_CTRL)) { if (b->get_button_index() == MOUSE_BUTTON_WHEEL_UP && Input::get_singleton()->is_key_pressed(KEY_CTRL)) {
set_zoom_custom(zoom * ZOOM_SCALE, b->get_position()); set_zoom_custom(zoom * zoom_step, b->get_position());
} else if (b->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && Input::get_singleton()->is_key_pressed(KEY_CTRL)) { } else if (b->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && Input::get_singleton()->is_key_pressed(KEY_CTRL)) {
set_zoom_custom(zoom / ZOOM_SCALE, b->get_position()); set_zoom_custom(zoom / zoom_step, b->get_position());
} else if (b->get_button_index() == MOUSE_BUTTON_WHEEL_UP && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { } else if (b->get_button_index() == MOUSE_BUTTON_WHEEL_UP && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * b->get_factor() / 8); v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * b->get_factor() / 8);
} else if (b->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { } else if (b->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
@ -1397,19 +1387,19 @@ void GraphEdit::set_zoom(float p_zoom) {
} }
void GraphEdit::set_zoom_custom(float p_zoom, const Vector2 &p_center) { void GraphEdit::set_zoom_custom(float p_zoom, const Vector2 &p_center) {
p_zoom = CLAMP(p_zoom, MIN_ZOOM, MAX_ZOOM); p_zoom = CLAMP(p_zoom, zoom_min, zoom_max);
if (zoom == p_zoom) { if (zoom == p_zoom) {
return; return;
} }
zoom_minus->set_disabled(zoom == MIN_ZOOM);
zoom_plus->set_disabled(zoom == MAX_ZOOM);
Vector2 sbofs = (Vector2(h_scroll->get_value(), v_scroll->get_value()) + p_center) / zoom; Vector2 sbofs = (Vector2(h_scroll->get_value(), v_scroll->get_value()) + p_center) / zoom;
zoom = p_zoom; zoom = p_zoom;
top_layer->update(); top_layer->update();
zoom_minus->set_disabled(zoom == zoom_min);
zoom_plus->set_disabled(zoom == zoom_max);
_update_scroll(); _update_scroll();
minimap->update(); minimap->update();
connections_layer->update(); connections_layer->update();
@ -1420,6 +1410,7 @@ void GraphEdit::set_zoom_custom(float p_zoom, const Vector2 &p_center) {
v_scroll->set_value(ofs.y); v_scroll->set_value(ofs.y);
} }
_update_zoom_label();
update(); update();
} }
@ -1427,6 +1418,61 @@ float GraphEdit::get_zoom() const {
return zoom; return zoom;
} }
void GraphEdit::set_zoom_step(float p_zoom_step) {
p_zoom_step = abs(p_zoom_step);
if (zoom_step == p_zoom_step) {
return;
}
zoom_step = p_zoom_step;
}
float GraphEdit::get_zoom_step() const {
return zoom_step;
}
void GraphEdit::set_zoom_min(float p_zoom_min) {
ERR_FAIL_COND_MSG(p_zoom_min > zoom_max, "Cannot set min zoom level greater than max zoom level.");
if (zoom_min == p_zoom_min) {
return;
}
zoom_min = p_zoom_min;
set_zoom(zoom);
}
float GraphEdit::get_zoom_min() const {
return zoom_min;
}
void GraphEdit::set_zoom_max(float p_zoom_max) {
ERR_FAIL_COND_MSG(p_zoom_max < zoom_min, "Cannot set max zoom level lesser than min zoom level.");
if (zoom_max == p_zoom_max) {
return;
}
zoom_max = p_zoom_max;
set_zoom(zoom);
}
float GraphEdit::get_zoom_max() const {
return zoom_max;
}
void GraphEdit::set_show_zoom_label(bool p_enable) {
if (zoom_label->is_visible() == p_enable) {
return;
}
zoom_label->set_visible(p_enable);
}
bool GraphEdit::is_showing_zoom_label() const {
return zoom_label->is_visible();
}
void GraphEdit::set_right_disconnects(bool p_enable) { void GraphEdit::set_right_disconnects(bool p_enable) {
right_disconnects = p_enable; right_disconnects = p_enable;
} }
@ -1467,7 +1513,7 @@ Array GraphEdit::_get_connection_list() const {
} }
void GraphEdit::_zoom_minus() { void GraphEdit::_zoom_minus() {
set_zoom(zoom / ZOOM_SCALE); set_zoom(zoom / zoom_step);
} }
void GraphEdit::_zoom_reset() { void GraphEdit::_zoom_reset() {
@ -1475,7 +1521,13 @@ void GraphEdit::_zoom_reset() {
} }
void GraphEdit::_zoom_plus() { void GraphEdit::_zoom_plus() {
set_zoom(zoom * ZOOM_SCALE); set_zoom(zoom * zoom_step);
}
void GraphEdit::_update_zoom_label() {
int zoom_percent = static_cast<int>(Math::round(zoom * 100));
String zoom_text = itos(zoom_percent) + "%";
zoom_label->set_text(zoom_text);
} }
void GraphEdit::add_valid_connection_type(int p_type, int p_with_type) { void GraphEdit::add_valid_connection_type(int p_type, int p_with_type) {
@ -1616,6 +1668,18 @@ void GraphEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_zoom", "zoom"), &GraphEdit::set_zoom); ClassDB::bind_method(D_METHOD("set_zoom", "zoom"), &GraphEdit::set_zoom);
ClassDB::bind_method(D_METHOD("get_zoom"), &GraphEdit::get_zoom); ClassDB::bind_method(D_METHOD("get_zoom"), &GraphEdit::get_zoom);
ClassDB::bind_method(D_METHOD("set_zoom_min", "zoom_min"), &GraphEdit::set_zoom_min);
ClassDB::bind_method(D_METHOD("get_zoom_min"), &GraphEdit::get_zoom_min);
ClassDB::bind_method(D_METHOD("set_zoom_max", "zoom_max"), &GraphEdit::set_zoom_max);
ClassDB::bind_method(D_METHOD("get_zoom_max"), &GraphEdit::get_zoom_max);
ClassDB::bind_method(D_METHOD("set_zoom_step", "zoom_step"), &GraphEdit::set_zoom_step);
ClassDB::bind_method(D_METHOD("get_zoom_step"), &GraphEdit::get_zoom_step);
ClassDB::bind_method(D_METHOD("set_show_zoom_label", "enable"), &GraphEdit::set_show_zoom_label);
ClassDB::bind_method(D_METHOD("is_showing_zoom_label"), &GraphEdit::is_showing_zoom_label);
ClassDB::bind_method(D_METHOD("set_snap", "pixels"), &GraphEdit::set_snap); ClassDB::bind_method(D_METHOD("set_snap", "pixels"), &GraphEdit::set_snap);
ClassDB::bind_method(D_METHOD("get_snap"), &GraphEdit::get_snap); ClassDB::bind_method(D_METHOD("get_snap"), &GraphEdit::get_snap);
@ -1650,9 +1714,18 @@ void GraphEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scroll_offset"), "set_scroll_ofs", "get_scroll_ofs"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scroll_offset"), "set_scroll_ofs", "get_scroll_ofs");
ADD_PROPERTY(PropertyInfo(Variant::INT, "snap_distance"), "set_snap", "get_snap"); ADD_PROPERTY(PropertyInfo(Variant::INT, "snap_distance"), "set_snap", "get_snap");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_snap"), "set_use_snap", "is_using_snap"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_snap"), "set_use_snap", "is_using_snap");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "zoom"), "set_zoom", "get_zoom");
ADD_GROUP("Connection Lines", "connection_lines");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "connection_lines_thickness"), "set_connection_lines_thickness", "get_connection_lines_thickness"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "connection_lines_thickness"), "set_connection_lines_thickness", "get_connection_lines_thickness");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "connection_lines_antialiased"), "set_connection_lines_antialiased", "is_connection_lines_antialiased"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "connection_lines_antialiased"), "set_connection_lines_antialiased", "is_connection_lines_antialiased");
ADD_GROUP("Zoom", "");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "zoom"), "set_zoom", "get_zoom");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "zoom_min"), "set_zoom_min", "get_zoom_min");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "zoom_max"), "set_zoom_max", "get_zoom_max");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "zoom_step"), "set_zoom_step", "get_zoom_step");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_zoom_label"), "set_show_zoom_label", "is_showing_zoom_label");
ADD_GROUP("Minimap", "minimap"); ADD_GROUP("Minimap", "minimap");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "minimap_enabled"), "set_minimap_enabled", "is_minimap_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "minimap_enabled"), "set_minimap_enabled", "is_minimap_enabled");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "minimap_size"), "set_minimap_size", "get_minimap_size"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "minimap_size"), "set_minimap_size", "get_minimap_size");
@ -1677,6 +1750,13 @@ void GraphEdit::_bind_methods() {
GraphEdit::GraphEdit() { GraphEdit::GraphEdit() {
set_focus_mode(FOCUS_ALL); set_focus_mode(FOCUS_ALL);
// Allow dezooming 8 times from the default zoom level.
// At low zoom levels, text is unreadable due to its small size and poor filtering,
// but this is still useful for previewing purposes.
zoom_min = (1 / Math::pow(zoom_step, 8));
// Allow zooming 4 times from the default zoom level.
zoom_max = (1 * Math::pow(zoom_step, 4));
top_layer = memnew(GraphEditFilter(this)); top_layer = memnew(GraphEditFilter(this));
add_child(top_layer); add_child(top_layer);
top_layer->set_mouse_filter(MOUSE_FILTER_PASS); top_layer->set_mouse_filter(MOUSE_FILTER_PASS);
@ -1713,6 +1793,18 @@ GraphEdit::GraphEdit() {
top_layer->add_child(zoom_hb); top_layer->add_child(zoom_hb);
zoom_hb->set_position(Vector2(10, 10)); zoom_hb->set_position(Vector2(10, 10));
zoom_label = memnew(Label);
zoom_hb->add_child(zoom_label);
zoom_label->set_visible(false);
zoom_label->set_v_size_flags(Control::SIZE_SHRINK_CENTER);
zoom_label->set_align(Label::ALIGN_CENTER);
#ifdef TOOLS_ENABLED
zoom_label->set_custom_minimum_size(Size2(48, 0) * EDSCALE);
#else
zoom_label->set_custom_minimum_size(Size2(48, 0));
#endif
_update_zoom_label();
zoom_minus = memnew(Button); zoom_minus = memnew(Button);
zoom_minus->set_flat(true); zoom_minus->set_flat(true);
zoom_hb->add_child(zoom_minus); zoom_hb->add_child(zoom_minus);

View File

@ -34,6 +34,7 @@
#include "scene/gui/box_container.h" #include "scene/gui/box_container.h"
#include "scene/gui/button.h" #include "scene/gui/button.h"
#include "scene/gui/graph_node.h" #include "scene/gui/graph_node.h"
#include "scene/gui/label.h"
#include "scene/gui/scroll_bar.h" #include "scene/gui/scroll_bar.h"
#include "scene/gui/slider.h" #include "scene/gui/slider.h"
#include "scene/gui/spin_box.h" #include "scene/gui/spin_box.h"
@ -105,6 +106,7 @@ public:
}; };
private: private:
Label *zoom_label;
Button *zoom_minus; Button *zoom_minus;
Button *zoom_reset; Button *zoom_reset;
Button *zoom_plus; Button *zoom_plus;
@ -114,10 +116,6 @@ private:
Button *minimap_button; Button *minimap_button;
void _zoom_minus();
void _zoom_reset();
void _zoom_plus();
HScrollBar *h_scroll; HScrollBar *h_scroll;
VScrollBar *v_scroll; VScrollBar *v_scroll;
@ -144,6 +142,14 @@ private:
Vector2 drag_accum; Vector2 drag_accum;
float zoom = 1.0; float zoom = 1.0;
float zoom_step = 1.2;
float zoom_min;
float zoom_max;
void _zoom_minus();
void _zoom_reset();
void _zoom_plus();
void _update_zoom_label();
bool box_selecting = false; bool box_selecting = false;
bool box_selection_mode_additive = false; bool box_selection_mode_additive = false;
@ -247,6 +253,18 @@ public:
void set_zoom_custom(float p_zoom, const Vector2 &p_center); void set_zoom_custom(float p_zoom, const Vector2 &p_center);
float get_zoom() const; float get_zoom() const;
void set_zoom_min(float p_zoom_min);
float get_zoom_min() const;
void set_zoom_max(float p_zoom_max);
float get_zoom_max() const;
void set_zoom_step(float p_zoom_step);
float get_zoom_step() const;
void set_show_zoom_label(bool p_enable);
bool is_showing_zoom_label() const;
void set_minimap_size(Vector2 p_size); void set_minimap_size(Vector2 p_size);
Vector2 get_minimap_size() const; Vector2 get_minimap_size() const;
void set_minimap_opacity(float p_opacity); void set_minimap_opacity(float p_opacity);