From 0b7384621e2f5e94621c6fcb301b88786ad12d2e Mon Sep 17 00:00:00 2001 From: Yuri Roubinsky Date: Sat, 4 Jul 2020 08:00:17 +0300 Subject: [PATCH 1/6] Prevents incorrect connection attempt on port clicking in GraphEdit, cherry-picked for 3.x --- scene/gui/graph_edit.cpp | 115 +++++++++++++++++++-------------------- scene/gui/graph_edit.h | 2 + 2 files changed, 57 insertions(+), 60 deletions(-) diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index a49e54e9986..73ca838e596 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -567,9 +567,9 @@ void GraphEdit::_top_layer_input(const Ref &p_ev) { Ref mb = p_ev; if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) { - + connecting_valid = false; Ref port = get_icon("port", "GraphNode"); - Vector2 mpos(mb->get_position().x, mb->get_position().y); + click_pos = mb->get_position(); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to(get_child(i)); @@ -579,8 +579,7 @@ void GraphEdit::_top_layer_input(const Ref &p_ev) { for (int j = 0; j < gn->get_connection_output_count(); j++) { Vector2 pos = gn->get_connection_output_position(j) + gn->get_position(); - if (is_in_hot_zone(pos, mpos)) { - + if (is_in_hot_zone(pos, click_pos)) { if (valid_left_disconnect_types.has(gn->get_connection_output_type(j))) { //check disconnect for (List::Element *E = connections.front(); E; E = E->next()) { @@ -626,8 +625,7 @@ void GraphEdit::_top_layer_input(const Ref &p_ev) { for (int j = 0; j < gn->get_connection_input_count(); j++) { Vector2 pos = gn->get_connection_input_position(j) + gn->get_position(); - if (is_in_hot_zone(pos, mpos)) { - + if (is_in_hot_zone(pos, click_pos)) { if (right_disconnects || valid_right_disconnect_types.has(gn->get_connection_input_type(j))) { //check disconnect for (List::Element *E = connections.front(); E; E = E->next()) { @@ -679,42 +677,40 @@ void GraphEdit::_top_layer_input(const Ref &p_ev) { connecting_to = mm->get_position(); connecting_target = false; top_layer->update(); - minimap->update(); + connecting_valid = click_pos.distance_to(connecting_to) > 20.0 * zoom; - Ref port = get_icon("port", "GraphNode"); - Vector2 mpos = mm->get_position(); - for (int i = get_child_count() - 1; i >= 0; i--) { - - GraphNode *gn = Object::cast_to(get_child(i)); - if (!gn) - continue; - - if (!connecting_out) { - for (int j = 0; j < gn->get_connection_output_count(); j++) { - - Vector2 pos = gn->get_connection_output_position(j) + gn->get_position(); - int type = gn->get_connection_output_type(j); - if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos, mpos)) { - - connecting_target = true; - connecting_to = pos; - connecting_target_to = gn->get_name(); - connecting_target_index = j; - return; - } + if (connecting_valid) { + Ref port = get_icon("port", "GraphNode"); + Vector2 mpos = mm->get_position(); + for (int i = get_child_count() - 1; i >= 0; i--) { + GraphNode *gn = Object::cast_to(get_child(i)); + if (!gn) { + continue; } - } else { - for (int j = 0; j < gn->get_connection_input_count(); j++) { - - Vector2 pos = gn->get_connection_input_position(j) + gn->get_position(); - int type = gn->get_connection_input_type(j); - if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos, mpos)) { - connecting_target = true; - connecting_to = pos; - connecting_target_to = gn->get_name(); - connecting_target_index = j; - return; + if (!connecting_out) { + for (int j = 0; j < gn->get_connection_output_count(); j++) { + Vector2 pos = gn->get_connection_output_position(j) + gn->get_position(); + int type = gn->get_connection_output_type(j); + if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos, mpos)) { + connecting_target = true; + connecting_to = pos; + connecting_target_to = gn->get_name(); + connecting_target_index = j; + return; + } + } + } else { + for (int j = 0; j < gn->get_connection_input_count(); j++) { + Vector2 pos = gn->get_connection_input_position(j) + gn->get_position(); + int type = gn->get_connection_input_type(j); + if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos, mpos)) { + connecting_target = true; + connecting_to = pos; + connecting_target_to = gn->get_name(); + connecting_target_index = j; + return; + } } } } @@ -722,30 +718,29 @@ void GraphEdit::_top_layer_input(const Ref &p_ev) { } if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && !mb->is_pressed()) { + if (connecting_valid) { + if (connecting && connecting_target) { + String from = connecting_from; + int from_slot = connecting_index; + String to = connecting_target_to; + int to_slot = connecting_target_index; - if (connecting && connecting_target) { + if (!connecting_out) { + SWAP(from, to); + SWAP(from_slot, to_slot); + } + emit_signal("connection_request", from, from_slot, to, to_slot); - String from = connecting_from; - int from_slot = connecting_index; - String to = connecting_target_to; - int to_slot = connecting_target_index; + } else if (!just_disconnected) { + String from = connecting_from; + int from_slot = connecting_index; + Vector2 ofs = Vector2(mb->get_position().x, mb->get_position().y); - if (!connecting_out) { - SWAP(from, to); - SWAP(from_slot, to_slot); - } - emit_signal("connection_request", from, from_slot, to, to_slot); - - } else if (!just_disconnected) { - - String from = connecting_from; - int from_slot = connecting_index; - Vector2 ofs = Vector2(mb->get_position().x, mb->get_position().y); - - if (!connecting_out) { - emit_signal("connection_from_empty", from, from_slot, ofs); - } else { - emit_signal("connection_to_empty", from, from_slot, ofs); + if (!connecting_out) { + emit_signal("connection_from_empty", from, from_slot, ofs); + } else { + emit_signal("connection_to_empty", from, from_slot, ofs); + } } } diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index 155e390fb37..3be65224f8b 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -137,6 +137,8 @@ private: String connecting_target_to; int connecting_target_index; bool just_disconnected; + bool connecting_valid; + Vector2 click_pos; bool dragging; bool just_selected; From 3ad676cbbe1db53177b8ec75f0b9dc9517d90639 Mon Sep 17 00:00:00 2001 From: Yuri Roubinsky Date: Sun, 5 Jul 2020 09:47:58 +0300 Subject: [PATCH 2/6] Fix GraphEdit reconnecting to disconnected port, cherry-picked for 3.x --- scene/gui/graph_edit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 73ca838e596..03d7972eb23 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -677,7 +677,7 @@ void GraphEdit::_top_layer_input(const Ref &p_ev) { connecting_to = mm->get_position(); connecting_target = false; top_layer->update(); - connecting_valid = click_pos.distance_to(connecting_to) > 20.0 * zoom; + connecting_valid = just_disconnected || click_pos.distance_to(connecting_to) > 20.0 * zoom; if (connecting_valid) { Ref port = get_icon("port", "GraphNode"); From 70cd4c5958abe197a936409edc69f67866bb5429 Mon Sep 17 00:00:00 2001 From: Yuri Roubinsky Date: Fri, 26 Feb 2021 10:31:39 +0300 Subject: [PATCH 3/6] Fix GraphEdit connects when graph is zoomed/unzoomed, cherry-picked for 3.x --- scene/gui/graph_edit.cpp | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 03d7972eb23..7068719c31e 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -547,14 +547,15 @@ bool GraphEdit::_filter_input(const Point2 &p_point) { for (int j = 0; j < gn->get_connection_output_count(); j++) { Vector2 pos = gn->get_connection_output_position(j) + gn->get_position(); - if (is_in_hot_zone(pos, p_point)) + if (is_in_hot_zone(pos / zoom, p_point / zoom)) { return true; + } } for (int j = 0; j < gn->get_connection_input_count(); j++) { Vector2 pos = gn->get_connection_input_position(j) + gn->get_position(); - if (is_in_hot_zone(pos, p_point)) { + if (is_in_hot_zone(pos / zoom, p_point / zoom)) { return true; } } @@ -569,7 +570,7 @@ void GraphEdit::_top_layer_input(const Ref &p_ev) { if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) { connecting_valid = false; Ref port = get_icon("port", "GraphNode"); - click_pos = mb->get_position(); + click_pos = mb->get_position() / zoom; for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to(get_child(i)); @@ -579,7 +580,7 @@ void GraphEdit::_top_layer_input(const Ref &p_ev) { for (int j = 0; j < gn->get_connection_output_count(); j++) { Vector2 pos = gn->get_connection_output_position(j) + gn->get_position(); - if (is_in_hot_zone(pos, click_pos)) { + if (is_in_hot_zone(pos / zoom, click_pos)) { if (valid_left_disconnect_types.has(gn->get_connection_output_type(j))) { //check disconnect for (List::Element *E = connections.front(); E; E = E->next()) { @@ -625,7 +626,7 @@ void GraphEdit::_top_layer_input(const Ref &p_ev) { for (int j = 0; j < gn->get_connection_input_count(); j++) { Vector2 pos = gn->get_connection_input_position(j) + gn->get_position(); - if (is_in_hot_zone(pos, click_pos)) { + if (is_in_hot_zone(pos / zoom, click_pos)) { if (right_disconnects || valid_right_disconnect_types.has(gn->get_connection_input_type(j))) { //check disconnect for (List::Element *E = connections.front(); E; E = E->next()) { @@ -677,11 +678,12 @@ void GraphEdit::_top_layer_input(const Ref &p_ev) { connecting_to = mm->get_position(); connecting_target = false; top_layer->update(); - connecting_valid = just_disconnected || click_pos.distance_to(connecting_to) > 20.0 * zoom; + minimap->update(); + connecting_valid = just_disconnected || click_pos.distance_to(connecting_to / zoom) > 20.0 * zoom; if (connecting_valid) { Ref port = get_icon("port", "GraphNode"); - Vector2 mpos = mm->get_position(); + Vector2 mpos = mm->get_position() / zoom; for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to(get_child(i)); if (!gn) { @@ -692,7 +694,7 @@ void GraphEdit::_top_layer_input(const Ref &p_ev) { for (int j = 0; j < gn->get_connection_output_count(); j++) { Vector2 pos = gn->get_connection_output_position(j) + gn->get_position(); int type = gn->get_connection_output_type(j); - if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos, mpos)) { + if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos / zoom, mpos)) { connecting_target = true; connecting_to = pos; connecting_target_to = gn->get_name(); @@ -704,7 +706,7 @@ void GraphEdit::_top_layer_input(const Ref &p_ev) { for (int j = 0; j < gn->get_connection_input_count(); j++) { Vector2 pos = gn->get_connection_input_position(j) + gn->get_position(); int type = gn->get_connection_input_type(j); - if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos, mpos)) { + if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos / zoom, mpos)) { connecting_target = true; connecting_to = pos; connecting_target_to = gn->get_name(); @@ -783,6 +785,11 @@ bool GraphEdit::is_in_hot_zone(const Vector2 &pos, const Vector2 &p_mouse_pos) { if (!child) continue; Rect2 rect = child->get_rect(); + + // To prevent intersections with other nodes. + rect.position *= zoom; + rect.size *= zoom; + if (rect.has_point(p_mouse_pos)) { //check sub-controls @@ -1242,7 +1249,7 @@ void GraphEdit::_gui_input(const Ref &p_ev) { if (gn_selected->is_resizing()) continue; - if (gn_selected->has_point(b->get_position() - gn_selected->get_position())) { + if (gn_selected->has_point((b->get_position() - gn_selected->get_position()) / zoom)) { gn = gn_selected; break; } From 72c54c10eb40bc7c4903c42b05bc6bccc7e92124 Mon Sep 17 00:00:00 2001 From: Lightning_A Date: Thu, 18 Mar 2021 18:27:19 -0600 Subject: [PATCH 4/6] Enable zooming graph_edit with scrollwheel, cherry-picked for 3.x --- scene/gui/graph_edit.cpp | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 7068719c31e..5150ab1970a 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -1343,25 +1343,17 @@ void GraphEdit::_gui_input(const Ref &p_ev) { minimap->update(); } - if (b->get_button_index() == BUTTON_WHEEL_UP && b->is_pressed()) { - //too difficult to get right - //set_zoom(zoom*ZOOM_SCALE); - } - - if (b->get_button_index() == BUTTON_WHEEL_DOWN && b->is_pressed()) { - //too difficult to get right - //set_zoom(zoom/ZOOM_SCALE); - } - if (b->get_button_index() == BUTTON_WHEEL_UP && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { + if (b->get_button_index() == BUTTON_WHEEL_UP && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { + set_zoom(zoom * ZOOM_SCALE); + } else if (b->get_button_index() == BUTTON_WHEEL_DOWN && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { + set_zoom(zoom / ZOOM_SCALE); + } 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); - } - if (b->get_button_index() == BUTTON_WHEEL_DOWN && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { + } else if (b->get_button_index() == BUTTON_WHEEL_DOWN && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * b->get_factor() / 8); - } - if (b->get_button_index() == BUTTON_WHEEL_RIGHT || (b->get_button_index() == BUTTON_WHEEL_DOWN && Input::get_singleton()->is_key_pressed(KEY_SHIFT))) { + } else if (b->get_button_index() == BUTTON_WHEEL_RIGHT || (b->get_button_index() == BUTTON_WHEEL_DOWN && Input::get_singleton()->is_key_pressed(KEY_SHIFT))) { h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() * b->get_factor() / 8); - } - if (b->get_button_index() == BUTTON_WHEEL_LEFT || (b->get_button_index() == BUTTON_WHEEL_UP && Input::get_singleton()->is_key_pressed(KEY_SHIFT))) { + } else if (b->get_button_index() == BUTTON_WHEEL_LEFT || (b->get_button_index() == BUTTON_WHEEL_UP && Input::get_singleton()->is_key_pressed(KEY_SHIFT))) { h_scroll->set_value(h_scroll->get_value() - h_scroll->get_page() * b->get_factor() / 8); } } From 77cf07c013db47c91d59bcbd083a10e18f48c98d Mon Sep 17 00:00:00 2001 From: Lightning_A Date: Mon, 5 Apr 2021 23:00:56 -0600 Subject: [PATCH 5/6] Make scrollwheel zoom based on mouse position, cherry-picked for 3.x --- scene/gui/graph_edit.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 5150ab1970a..4567f8de27b 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -1344,9 +1344,9 @@ void GraphEdit::_gui_input(const Ref &p_ev) { } if (b->get_button_index() == BUTTON_WHEEL_UP && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { - set_zoom(zoom * ZOOM_SCALE); + set_zoom_custom(zoom * ZOOM_SCALE, b->get_position()); } else if (b->get_button_index() == BUTTON_WHEEL_DOWN && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { - set_zoom(zoom / ZOOM_SCALE); + set_zoom_custom(zoom / ZOOM_SCALE, 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)) { From 827f6739a2e1977385c91cba282f394abdf5913b Mon Sep 17 00:00:00 2001 From: Lightning_A Date: Mon, 26 Apr 2021 09:22:28 -0600 Subject: [PATCH 6/6] Initialize some graphedit values in the header --- scene/gui/graph_edit.cpp | 13 ------------- scene/gui/graph_edit.h | 30 +++++++++++++++--------------- 2 files changed, 15 insertions(+), 28 deletions(-) diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 4567f8de27b..347fec8b19d 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -1717,8 +1717,6 @@ void GraphEdit::_bind_methods() { GraphEdit::GraphEdit() { set_focus_mode(FOCUS_ALL); - awaiting_scroll_offset_update = false; - top_layer = NULL; top_layer = memnew(GraphEditFilter(this)); add_child(top_layer); top_layer->set_mouse_filter(MOUSE_FILTER_PASS); @@ -1741,13 +1739,6 @@ GraphEdit::GraphEdit() { v_scroll->set_name("_v_scroll"); top_layer->add_child(v_scroll); - updating = false; - connecting = false; - right_disconnects = false; - - box_selecting = false; - dragging = false; - //set large minmax so it can scroll even if not resized yet h_scroll->set_min(-10000); h_scroll->set_max(10000); @@ -1758,8 +1749,6 @@ GraphEdit::GraphEdit() { h_scroll->connect("value_changed", this, "_scroll_moved"); v_scroll->connect("value_changed", this, "_scroll_moved"); - zoom = 1; - zoom_hb = memnew(HBoxContainer); top_layer->add_child(zoom_hb); zoom_hb->set_position(Vector2(10, 10)); @@ -1824,7 +1813,5 @@ GraphEdit::GraphEdit() { minimap->set_margin(Margin::MARGIN_BOTTOM, -MINIMAP_OFFSET); minimap->connect("draw", this, "_minimap_draw"); - setting_scroll_ofs = false; - just_disconnected = false; set_clip_contents(true); } diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index 3be65224f8b..e6668aff27b 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -126,38 +126,38 @@ private: float port_grab_distance_horizontal; float port_grab_distance_vertical; - bool connecting; + bool connecting = false; String connecting_from; - bool connecting_out; + bool connecting_out = false; int connecting_index; int connecting_type; Color connecting_color; - bool connecting_target; + bool connecting_target = false; Vector2 connecting_to; String connecting_target_to; int connecting_target_index; - bool just_disconnected; - bool connecting_valid; + bool just_disconnected = false; + bool connecting_valid = false; Vector2 click_pos; - bool dragging; - bool just_selected; - bool moving_selection; + bool dragging = false; + bool just_selected = false; + bool moving_selection = false; Vector2 drag_accum; - float zoom; + float zoom = 1.0f; - bool box_selecting; - bool box_selection_mode_additive; + bool box_selecting = false; + bool box_selection_mode_additive = false; Point2 box_selecting_from; Point2 box_selecting_to; Rect2 box_selecting_rect; List previus_selected; - bool setting_scroll_ofs; - bool right_disconnects; - bool updating; - bool awaiting_scroll_offset_update; + bool setting_scroll_ofs = false; + bool right_disconnects = false; + bool updating = false; + bool awaiting_scroll_offset_update = false; List connections; void _bake_segment2d(Vector &points, Vector &colors, float p_begin, float p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_min_depth, int p_max_depth, float p_tol, const Color &p_color, const Color &p_to_color, int &lines) const;