Skip to content

Commit

Permalink
Merge pull request #86158 from Geometror/ge-connection-rework
Browse files Browse the repository at this point in the history
Rework `GraphEdit` connections (drawing, API, optimizations)
  • Loading branch information
YuriSizov committed Jan 18, 2024
2 parents de95a3e + 9d7c297 commit 66b0bd9
Show file tree
Hide file tree
Showing 10 changed files with 693 additions and 252 deletions.
26 changes: 26 additions & 0 deletions core/math/geometry_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ class Geometry2D {
}
}

static real_t get_distance_to_segment(const Vector2 &p_point, const Vector2 *p_segment) {
return p_point.distance_to(get_closest_point_to_segment(p_point, p_segment));
}

static bool is_point_in_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) {
Vector2 an = a - s;
Vector2 bn = b - s;
Expand Down Expand Up @@ -249,6 +253,28 @@ class Geometry2D {
return -1;
}

static bool segment_intersects_rect(const Vector2 &p_from, const Vector2 &p_to, const Rect2 &p_rect) {
if (p_rect.has_point(p_from) || p_rect.has_point(p_to)) {
return true;
}

const Vector2 rect_points[4] = {
p_rect.position,
p_rect.position + Vector2(p_rect.size.x, 0),
p_rect.position + p_rect.size,
p_rect.position + Vector2(0, p_rect.size.y)
};

// Check if any of the rect's edges intersect the segment.
for (int i = 0; i < 4; i++) {
if (segment_intersects_segment(p_from, p_to, rect_points[i], rect_points[(i + 1) % 4], nullptr)) {
return true;
}
}

return false;
}

enum PolyBooleanOperation {
OPERATION_UNION,
OPERATION_DIFFERENCE,
Expand Down
39 changes: 35 additions & 4 deletions doc/classes/GraphEdit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,22 @@
[b]Note:[/b] This method suppresses any other connection request signals apart from [signal connection_drag_ended].
</description>
</method>
<method name="get_connection_line">
<method name="get_closest_connection_at_point" qualifiers="const">
<return type="Dictionary" />
<param index="0" name="point" type="Vector2" />
<param index="1" name="max_distance" type="float" default="4.0" />
<description>
Returns the closest connection to the given point in screen space. If no connection is found within [param max_distance] pixels, an empty [Dictionary] is returned.
A connection consists in a structure of the form [code]{ from_port: 0, from_node: "GraphNode name 0", to_port: 1, to_node: "GraphNode name 1" }[/code].
For example, getting a connection at a given mouse position can be achieved like this:
[codeblocks]
[gdscript]
var connection = get_closest_connection_at_point(mouse_event.get_position())
[/gdscript]
[/codeblocks]
</description>
</method>
<method name="get_connection_line" qualifiers="const">
<return type="PackedVector2Array" />
<param index="0" name="from_node" type="Vector2" />
<param index="1" name="to_node" type="Vector2" />
Expand All @@ -154,7 +169,14 @@
<method name="get_connection_list" qualifiers="const">
<return type="Dictionary[]" />
<description>
Returns an Array containing the list of connections. A connection consists in a structure of the form [code]{ from_port: 0, from_node: "GraphNode name 0", to_port: 1, to_node: "GraphNode name 1" }[/code].
Returns an [Array] containing the list of connections. A connection consists in a structure of the form [code]{ from_port: 0, from_node: "GraphNode name 0", to_port: 1, to_node: "GraphNode name 1" }[/code].
</description>
</method>
<method name="get_connections_intersecting_with_rect" qualifiers="const">
<return type="Dictionary[]" />
<param index="0" name="rect" type="Rect2" />
<description>
Returns an [Array] containing the list of connections that intersect with the given [Rect2]. A connection consists in a structure of the form [code]{ from_port: 0, from_node: "GraphNode name 0", to_port: 1, to_node: "GraphNode name 1" }[/code].
</description>
</method>
<method name="get_menu_hbox">
Expand Down Expand Up @@ -233,7 +255,7 @@
<member name="connection_lines_curvature" type="float" setter="set_connection_lines_curvature" getter="get_connection_lines_curvature" default="0.5">
The curvature of the lines between the nodes. 0 results in straight lines.
</member>
<member name="connection_lines_thickness" type="float" setter="set_connection_lines_thickness" getter="get_connection_lines_thickness" default="2.0">
<member name="connection_lines_thickness" type="float" setter="set_connection_lines_thickness" getter="get_connection_lines_thickness" default="4.0">
The thickness of the lines between the nodes.
</member>
<member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" overrides="Control" enum="Control.FocusMode" default="2" />
Expand Down Expand Up @@ -417,7 +439,16 @@
</constants>
<theme_items>
<theme_item name="activity" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
Color of the connection's activity (see [method set_connection_activity]).
Color the connection line is interpolated to based on the activity value of a connection (see [method set_connection_activity]).
</theme_item>
<theme_item name="connection_hover_tint_color" data_type="color" type="Color" default="Color(0, 0, 0, 0.3)">
Color which is blended with the connection line when the mouse is hovering over it.
</theme_item>
<theme_item name="connection_rim_color" data_type="color" type="Color" default="Color(0.1, 0.1, 0.1, 0.6)">
Color of the rim around each connection line used for making intersecting lines more distinguishable.
</theme_item>
<theme_item name="connection_valid_target_tint_color" data_type="color" type="Color" default="Color(1, 1, 1, 0.4)">
Color which is blended with the connection line when the currently dragged connection is hovering over a valid target port.
</theme_item>
<theme_item name="grid_major" data_type="color" type="Color" default="Color(1, 1, 1, 0.2)">
Color of major grid lines/dots.
Expand Down
4 changes: 4 additions & 0 deletions editor/themes/editor_theme_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1442,6 +1442,10 @@ void EditorThemeManager::_populate_standard_styles(const Ref<EditorTheme> &p_the
p_theme->set_color("selection_stroke", "GraphEdit", p_theme->get_color(SNAME("box_selection_stroke_color"), EditorStringName(Editor)));
p_theme->set_color("activity", "GraphEdit", p_config.accent_color);

p_theme->set_color("connection_hover_tint_color", "GraphEdit", p_config.dark_theme ? Color(0, 0, 0, 0.3) : Color(1, 1, 1, 0.3));
p_theme->set_color("connection_valid_target_tint_color", "GraphEdit", p_config.dark_theme ? Color(1, 1, 1, 0.4) : Color(0, 0, 0, 0.4));
p_theme->set_color("connection_rim_color", "GraphEdit", p_config.tree_panel_style->get_bg_color());

p_theme->set_icon("zoom_out", "GraphEdit", p_theme->get_icon(SNAME("ZoomLess"), EditorStringName(EditorIcons)));
p_theme->set_icon("zoom_in", "GraphEdit", p_theme->get_icon(SNAME("ZoomMore"), EditorStringName(EditorIcons)));
p_theme->set_icon("zoom_reset", "GraphEdit", p_theme->get_icon(SNAME("ZoomReset"), EditorStringName(EditorIcons)));
Expand Down
7 changes: 7 additions & 0 deletions misc/extension_api_validation/4.2-stable.expected
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,10 @@ Validate extension JSON: Error: Field 'classes/TileMap/methods/get_collision_vis
Validate extension JSON: Error: Field 'classes/TileMap/methods/get_navigation_visibility_mode': is_const changed value in new API, from false to true.

Two TileMap getters were made const. No adjustments should be necessary.


GH-86158
--------
Validate extension JSON: Error: Field 'classes/GraphEdit/methods/get_connection_line': is_const changed value in new API, from false to true.

get_connection_line was made const.
5 changes: 5 additions & 0 deletions scene/gui/graph_edit.compat.inc
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,14 @@ void GraphEdit::_set_arrange_nodes_button_hidden_bind_compat_81582(bool p_enable
set_show_arrange_button(!p_enable);
}

PackedVector2Array GraphEdit::_get_connection_line_bind_compat_86158(const Vector2 &p_from, const Vector2 &p_to) {
return get_connection_line(p_from, p_to);
}

void GraphEdit::_bind_compatibility_methods() {
ClassDB::bind_compatibility_method(D_METHOD("is_arrange_nodes_button_hidden"), &GraphEdit::_is_arrange_nodes_button_hidden_bind_compat_81582);
ClassDB::bind_compatibility_method(D_METHOD("set_arrange_nodes_button_hidden", "enable"), &GraphEdit::_set_arrange_nodes_button_hidden_bind_compat_81582);
ClassDB::bind_compatibility_method(D_METHOD("get_connection_line", "from_node", "to_node"), &GraphEdit::_get_connection_line_bind_compat_86158);
}

#endif
Loading

0 comments on commit 66b0bd9

Please sign in to comment.