2
0
Эх сурвалжийг харах

Merge pull request #50526 from pycbouh/graphedit-adjust-zoom-levels-3.x

[3.x] Make zoom limits and step adjustable in GraphEdit
Rémi Verschelde 4 жил өмнө
parent
commit
c391c2210f

+ 12 - 0
doc/classes/GraphEdit.xml

@@ -191,6 +191,9 @@
 		<member name="scroll_offset" type="Vector2" setter="set_scroll_ofs" getter="get_scroll_ofs" default="Vector2( 0, 0 )">
 			The scroll offset.
 		</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">
 			The snapping distance in pixels.
 		</member>
@@ -200,6 +203,15 @@
 		<member name="zoom" type="float" setter="set_zoom" getter="get_zoom" default="1.0">
 			The current zoom value.
 		</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>
 	<signals>
 		<signal name="_begin_node_move">

+ 108 - 18
scene/gui/graph_edit.cpp

@@ -39,16 +39,6 @@
 #include "editor/editor_scale.h"
 #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_PADDING 5
 
@@ -1323,9 +1313,9 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
 		}
 
 		if (b->get_button_index() == BUTTON_WHEEL_UP && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
-			set_zoom_custom(zoom * ZOOM_SCALE, b->get_position());
+			set_zoom_custom(zoom * zoom_step, b->get_position());
 		} else if (b->get_button_index() == BUTTON_WHEEL_DOWN && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
-			set_zoom_custom(zoom / ZOOM_SCALE, b->get_position());
+			set_zoom_custom(zoom / zoom_step, b->get_position());
 		} else if (b->get_button_index() == 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);
 		} else if (b->get_button_index() == BUTTON_WHEEL_DOWN && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
@@ -1400,19 +1390,19 @@ void GraphEdit::set_zoom(float p_zoom) {
 }
 
 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) {
 		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;
 
 	zoom = p_zoom;
 	top_layer->update();
 
+	zoom_minus->set_disabled(zoom == zoom_min);
+	zoom_plus->set_disabled(zoom == zoom_max);
+
 	_update_scroll();
 	minimap->update();
 	connections_layer->update();
@@ -1423,6 +1413,7 @@ void GraphEdit::set_zoom_custom(float p_zoom, const Vector2 &p_center) {
 		v_scroll->set_value(ofs.y);
 	}
 
+	_update_zoom_label();
 	update();
 }
 
@@ -1430,6 +1421,61 @@ float GraphEdit::get_zoom() const {
 	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) {
 	right_disconnects = p_enable;
 }
@@ -1470,14 +1516,20 @@ Array GraphEdit::_get_connection_list() const {
 }
 
 void GraphEdit::_zoom_minus() {
-	set_zoom(zoom / ZOOM_SCALE);
+	set_zoom(zoom / zoom_step);
 }
 void GraphEdit::_zoom_reset() {
 	set_zoom(1);
 }
 
 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) {
@@ -1599,6 +1651,18 @@ void GraphEdit::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_zoom", "p_zoom"), &GraphEdit::set_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("get_snap"), &GraphEdit::get_snap);
 
@@ -1643,7 +1707,14 @@ void GraphEdit::_bind_methods() {
 	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::BOOL, "use_snap"), "set_use_snap", "is_using_snap");
+
+	ADD_GROUP("Zoom", "");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "zoom"), "set_zoom", "get_zoom");
+	ADD_PROPERTY(PropertyInfo(Variant::REAL, "zoom_min"), "set_zoom_min", "get_zoom_min");
+	ADD_PROPERTY(PropertyInfo(Variant::REAL, "zoom_max"), "set_zoom_max", "get_zoom_max");
+	ADD_PROPERTY(PropertyInfo(Variant::REAL, "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_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");
@@ -1668,6 +1739,13 @@ void GraphEdit::_bind_methods() {
 GraphEdit::GraphEdit() {
 	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));
 	add_child(top_layer);
 	top_layer->set_mouse_filter(MOUSE_FILTER_PASS);
@@ -1704,6 +1782,18 @@ GraphEdit::GraphEdit() {
 	top_layer->add_child(zoom_hb);
 	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(ToolButton);
 	zoom_hb->add_child(zoom_minus);
 	zoom_minus->set_tooltip(RTR("Zoom Out"));

+ 22 - 4
scene/gui/graph_edit.h

@@ -33,6 +33,7 @@
 
 #include "scene/gui/box_container.h"
 #include "scene/gui/graph_node.h"
+#include "scene/gui/label.h"
 #include "scene/gui/scroll_bar.h"
 #include "scene/gui/slider.h"
 #include "scene/gui/spin_box.h"
@@ -105,6 +106,7 @@ public:
 	};
 
 private:
+	Label *zoom_label;
 	ToolButton *zoom_minus;
 	ToolButton *zoom_reset;
 	ToolButton *zoom_plus;
@@ -114,10 +116,6 @@ private:
 
 	Button *minimap_button;
 
-	void _zoom_minus();
-	void _zoom_reset();
-	void _zoom_plus();
-
 	HScrollBar *h_scroll;
 	VScrollBar *v_scroll;
 
@@ -144,6 +142,14 @@ private:
 	Vector2 drag_accum;
 
 	float zoom = 1.0f;
+	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_selection_mode_additive = false;
@@ -244,6 +250,18 @@ public:
 	void set_zoom_custom(float p_zoom, const Vector2 &p_center);
 	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);
 	Vector2 get_minimap_size() const;
 	void set_minimap_opacity(float p_opacity);