Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework GraphEdit connections (drawing, API, optimizations) #86158

Merged
merged 1 commit into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
YuriSizov marked this conversation as resolved.
Show resolved Hide resolved
};

// 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 @@ -1367,6 +1367,10 @@ void EditorThemeManager::_populate_standard_styles(const Ref<Theme> &p_theme, Th
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
Geometror marked this conversation as resolved.
Show resolved Hide resolved
--------
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
Loading