Skip to content

Commit 3a57c12

Browse files
committed
Animated highlighted connections
1 parent 2b0fdb1 commit 3a57c12

6 files changed

Lines changed: 143 additions & 26 deletions

File tree

material_maker/nodes/base.gd

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,9 @@ func _draw() -> void:
250250
if control.get("modulate"):
251251
control.modulate.a = opacity
252252

253+
get_parent().get_node("HighlightsOverlay").update_connections()
254+
255+
253256
func draw_portgroup_stylebox(first_port : Vector2, last_port : Vector2) -> void:
254257
var stylebox_position: Vector2 = first_port + Vector2(-0.5,-0.5) * portgroup_width
255258
var stylebox_size: Vector2 = Vector2(portgroup_width, last_port.y - first_port.y + portgroup_width)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[gd_resource type="ShaderMaterial" format=3 uid="uid://cvfcub2mms71a"]
2+
3+
[sub_resource type="Shader" id="Shader_pewh7"]
4+
code = "shader_type canvas_item;
5+
6+
void fragment() {
7+
COLOR = vec4(vec3(0.0), 0.25 * sin(UV.x - TIME * TAU) + 0.25);
8+
}"
9+
10+
[resource]
11+
shader = SubResource("Shader_pewh7")

material_maker/panels/graph_edit/graph_edit.gd

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,18 +1086,6 @@ func _on_ButtonTransmitsSeed_toggled(button_pressed) -> void:
10861086

10871087
# Node selection
10881088

1089-
var highlighting_connections : bool = false
1090-
1091-
func highlight_connections() -> void:
1092-
if highlighting_connections:
1093-
return
1094-
highlighting_connections = true
1095-
while Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
1096-
await get_tree().process_frame
1097-
for c in get_connection_list():
1098-
set_connection_activity(c.from_node, c.from_port, c.to_node, c.to_port, 1.0 if get_node(NodePath(c.from_node)).selected or get_node(NodePath(c.to_node)).selected else 0.0)
1099-
highlighting_connections = false
1100-
11011089
func _on_GraphEdit_node_selected(node : GraphElement) -> void:
11021090
if node is MMGraphComment:
11031091
#print("Selecting enclosed nodes...")
@@ -1108,7 +1096,6 @@ func _on_GraphEdit_node_selected(node : GraphElement) -> void:
11081096
elif node is MMGraphCommentLine:
11091097
pass
11101098
else:
1111-
highlight_connections()
11121099
await get_tree().process_frame
11131100
if current_preview[0] != null:
11141101
for n in get_selected_nodes():
@@ -1127,7 +1114,6 @@ func _on_GraphEdit_node_selected(node : GraphElement) -> void:
11271114
mm_globals.main_window.update_menus()
11281115

11291116
func _on_GraphEdit_node_unselected(_node):
1130-
highlight_connections()
11311117
undoredo_move_node_selection_changed = true
11321118
mm_globals.main_window.update_menus()
11331119

material_maker/panels/graph_edit/graph_edit.tscn

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
[gd_scene load_steps=8 format=3 uid="uid://dy1u50we7gtru"]
1+
[gd_scene format=3 uid="uid://dy1u50we7gtru"]
22

33
[ext_resource type="Script" uid="uid://dkp4w3at1o6cm" path="res://material_maker/panels/graph_edit/graph_edit.gd" id="1"]
44
[ext_resource type="Texture2D" uid="uid://c0j4px4n72di5" path="res://material_maker/icons/icons.tres" id="2"]
55
[ext_resource type="Script" uid="uid://bne3k0g56crmy" path="res://material_maker/tools/undo_redo/undo_redo.gd" id="3"]
66
[ext_resource type="PackedScene" uid="uid://buj231c2gxm4o" path="res://material_maker/widgets/desc_button/desc_button.tscn" id="4"]
7+
[ext_resource type="Script" uid="uid://dlah77kjy12l6" path="res://material_maker/panels/graph_edit/highlights_overlay.gd" id="5_u5byk"]
78

89
[sub_resource type="AtlasTexture" id="3"]
910
atlas = ExtResource("2")
@@ -17,7 +18,7 @@ region = Rect2(15.4016, 47.1451, 16.7512, 17.8319)
1718
atlas = ExtResource("2")
1819
region = Rect2(0, 48, 16, 16)
1920

20-
[node name="GraphEdit" type="GraphEdit" groups=["mm_graphedit"]]
21+
[node name="GraphEdit" type="GraphEdit" unique_id=175822157 groups=["mm_graphedit"]]
2122
anchors_preset = 15
2223
anchor_right = 1.0
2324
anchor_bottom = 1.0
@@ -34,11 +35,11 @@ show_menu = false
3435
show_zoom_label = true
3536
script = ExtResource("1")
3637

37-
[node name="Timer" type="Timer" parent="."]
38+
[node name="Timer" type="Timer" parent="." unique_id=654752788]
3839
wait_time = 0.2
3940
one_shot = true
4041

41-
[node name="GraphUI" type="HBoxContainer" parent="."]
42+
[node name="GraphUI" type="HBoxContainer" parent="." unique_id=45635343]
4243
top_level = true
4344
custom_minimum_size = Vector2(0, 25)
4445
layout_mode = 1
@@ -51,43 +52,47 @@ offset_bottom = 31.0
5152
grow_horizontal = 0
5253
alignment = 2
5354

54-
[node name="SubGraphUI" type="HBoxContainer" parent="GraphUI"]
55+
[node name="SubGraphUI" type="HBoxContainer" parent="GraphUI" unique_id=1847281688]
5556
layout_mode = 2
5657
size_flags_horizontal = 9
5758

58-
[node name="Label" type="LineEdit" parent="GraphUI/SubGraphUI"]
59+
[node name="Label" type="LineEdit" parent="GraphUI/SubGraphUI" unique_id=1166036264]
5960
custom_minimum_size = Vector2(150, 0)
6061
layout_mode = 2
6162
size_flags_horizontal = 9
6263

63-
[node name="Description" parent="GraphUI/SubGraphUI" instance=ExtResource("4")]
64+
[node name="Description" parent="GraphUI/SubGraphUI" unique_id=610946558 instance=ExtResource("4")]
6465
layout_mode = 2
6566

66-
[node name="ButtonTransmitsSeed" type="Button" parent="GraphUI/SubGraphUI"]
67+
[node name="ButtonTransmitsSeed" type="Button" parent="GraphUI/SubGraphUI" unique_id=1858333769]
6768
layout_mode = 2
6869
size_flags_horizontal = 9
6970
tooltip_text = "Affect children seeds"
7071
toggle_mode = true
7172
icon = SubResource("3")
7273

73-
[node name="ButtonUp" type="Button" parent="GraphUI/SubGraphUI"]
74+
[node name="ButtonUp" type="Button" parent="GraphUI/SubGraphUI" unique_id=1608742490]
7475
layout_mode = 2
7576
size_flags_horizontal = 9
7677
tooltip_text = "Back to parent"
7778
icon = SubResource("4")
7879

79-
[node name="ButtonShowTree" type="Button" parent="GraphUI"]
80+
[node name="ButtonShowTree" type="Button" parent="GraphUI" unique_id=1663795300]
8081
layout_mode = 2
8182
tooltip_text = "Show hierarchy"
8283
icon = SubResource("5")
8384

84-
[node name="Control" type="Control" parent="GraphUI"]
85+
[node name="Control" type="Control" parent="GraphUI" unique_id=265307966]
8586
custom_minimum_size = Vector2(14, 0)
8687
layout_mode = 2
8788

88-
[node name="UndoRedo" type="Node" parent="."]
89+
[node name="UndoRedo" type="Node" parent="." unique_id=476880472]
8990
script = ExtResource("3")
9091

92+
[node name="HighlightsOverlay" type="Control" parent="." unique_id=2128156926]
93+
anchors_preset = 0
94+
script = ExtResource("5_u5byk")
95+
9196
[connection signal="connection_drag_ended" from="." to="." method="_on_connection_drag_ended"]
9297
[connection signal="connection_drag_started" from="." to="." method="_on_connection_drag_started"]
9398
[connection signal="connection_from_empty" from="." to="." method="request_popup" binds= [true]]
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
class_name HighlightsOverlay
2+
extends Control
3+
4+
5+
class AnimatedConnection extends Line2D:
6+
var connection : Dictionary
7+
8+
@onready var graph : MMGraphEdit = owner
9+
10+
var active_connections : Array[Dictionary]
11+
var is_updating_connections := false
12+
13+
const LINE_MATERIAL := preload("res://material_maker/panels/graph_edit/animated_connection.tres")
14+
15+
func _ready() -> void:
16+
graph.child_order_changed.connect(_move_above_connections.call_deferred)
17+
graph.get_node("_connection_layer").draw.connect(queue_redraw)
18+
graph.get_node("_connection_layer").child_order_changed.connect(update_connections)
19+
graph.connection_drag_started.connect(update_connections.bind(1).unbind(3))
20+
graph.node_selected.connect(update_connections.unbind(1))
21+
graph.node_deselected.connect(update_connections.unbind(1))
22+
graph.gui_input.connect(_graph_gui_input)
23+
24+
func _draw() -> void:
25+
if get_children().is_empty():
26+
return
27+
28+
for line : AnimatedConnection in get_children():
29+
var conn : Dictionary = line.connection
30+
var positions := get_connection_positions(conn)
31+
if positions.is_empty():
32+
continue
33+
34+
line.visible = get_viewport_rect().intersects(
35+
Rect2(positions.from, positions.to - positions.from).abs())
36+
37+
line.points = graph._get_connection_line(positions.from, positions.to)
38+
line.width = graph.connection_lines_thickness
39+
40+
func _move_above_connections() -> void:
41+
graph.move_child(self, graph.get_node("_connection_layer").get_index() + 1)
42+
43+
func _graph_gui_input(e : InputEvent) -> void:
44+
if e is InputEventKey:
45+
update_connections(true)
46+
47+
func update_connections(should_hide_when_updating : bool = false) -> void:
48+
if is_updating_connections:
49+
return
50+
is_updating_connections = true
51+
52+
if should_hide_when_updating:
53+
hide()
54+
55+
while Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
56+
await get_tree().process_frame
57+
58+
active_connections.clear()
59+
for c in graph.get_connection_list():
60+
if (graph.get_node(NodePath(c.from_node)).selected
61+
or graph.get_node(NodePath(c.to_node)).selected):
62+
active_connections.append(c)
63+
await get_tree().process_frame
64+
create_animated_connections()
65+
66+
# Remove inactive/invalid animated conections
67+
if get_children().size():
68+
for anim_line : AnimatedConnection in get_children():
69+
if (anim_line.connection not in active_connections
70+
or get_connection_positions(anim_line.connection).is_empty()):
71+
remove_child(anim_line)
72+
anim_line.free()
73+
74+
queue_redraw()
75+
is_updating_connections = false
76+
show.call_deferred()
77+
78+
func create_animated_connections() -> void:
79+
if active_connections.size():
80+
for active_connection in active_connections:
81+
var positions := get_connection_positions(active_connection)
82+
if positions.is_empty():
83+
continue
84+
85+
var has_existing_connection : bool = false
86+
for c in get_children():
87+
if c.connection == active_connection:
88+
has_existing_connection = true
89+
break
90+
91+
if not has_existing_connection:
92+
var ac := AnimatedConnection.new()
93+
ac.connection = active_connection
94+
ac.texture_mode = Line2D.LINE_TEXTURE_TILE
95+
ac.material = LINE_MATERIAL
96+
ac.points = graph._get_connection_line(positions.from, positions.to)
97+
ac.width = graph.connection_lines_thickness
98+
add_child(ac)
99+
100+
func get_connection_positions(from_connection : Dictionary) -> Dictionary:
101+
var c := from_connection
102+
var positions : Dictionary
103+
if graph.has_node(NodePath(c.from_node)) and graph.has_node(NodePath(c.to_node)):
104+
var from_node : GraphNode = graph.get_node(NodePath(c.from_node))
105+
var to_node : GraphNode = graph.get_node(NodePath(c.to_node))
106+
if from_node and to_node:
107+
var from_pos := from_node.get_output_port_position(c.from_port)
108+
var to_pos := to_node.get_input_port_position(c.to_port)
109+
positions.from = from_pos * graph.zoom + from_node.position
110+
positions.to = to_pos * graph.zoom + to_node.position
111+
return positions
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://dlah77kjy12l6

0 commit comments

Comments
 (0)