Skip to content

Commit 204ca31

Browse files
committed
Added multi-reroute gesture
1 parent 8e437b5 commit 204ca31

File tree

8 files changed

+152
-38
lines changed

8 files changed

+152
-38
lines changed

material_maker/icons/cross.png

281 Bytes
Loading
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
[remap]
2+
3+
importer="texture"
4+
type="CompressedTexture2D"
5+
uid="uid://c6ahvommwwa8t"
6+
path="res://.godot/imported/cross.png-84a7013f3d6c2a917d839be20cc31c25.ctex"
7+
metadata={
8+
"vram_texture": false
9+
}
10+
11+
[deps]
12+
13+
source_file="res://material_maker/icons/cross.png"
14+
dest_files=["res://.godot/imported/cross.png-84a7013f3d6c2a917d839be20cc31c25.ctex"]
15+
16+
[params]
17+
18+
compress/mode=0
19+
compress/high_quality=false
20+
compress/lossy_quality=0.7
21+
compress/uastc_level=0
22+
compress/rdo_quality_loss=0.0
23+
compress/hdr_compression=1
24+
compress/normal_map=0
25+
compress/channel_pack=0
26+
mipmaps/generate=false
27+
mipmaps/limit=-1
28+
roughness/mode=0
29+
roughness/src_normal=""
30+
process/channel_remap/red=0
31+
process/channel_remap/green=1
32+
process/channel_remap/blue=2
33+
process/channel_remap/alpha=3
34+
process/fix_alpha_border=true
35+
process/premult_alpha=false
36+
process/normal_map_invert_y=false
37+
process/hdr_as_srgb=false
38+
process/hdr_clamp_exposure=false
39+
process/size_limit=0
40+
detect_3d/compress_to=1

material_maker/panels/graph_edit/graph_edit.gd

Lines changed: 103 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,12 @@ enum ConnectionStyle {DIRECT, BEZIER, ROUNDED, MANHATTAN, DIAGONAL}
5252
var connection_line_style : int = ConnectionStyle.BEZIER
5353

5454
@onready var drag_cut_cursor = preload("res://material_maker/icons/knife.png")
55-
var connections_to_cut : Array[Dictionary]
56-
var drag_cut_line : PackedVector2Array
57-
var valid_drag_cut_entry: bool = false
58-
const CURSOR_HOT_SPOT : Vector2 = Vector2(1.02, 17.34)
55+
@onready var drag_reroute_cursor = preload("res://material_maker/icons/cross.png")
56+
const DRAG_CUT_CURSOR_HOT_SPOT : Vector2 = Vector2(1.02, 17.34)
57+
58+
var drag_line : PackedVector2Array
59+
enum DragLineGesture {CUT, REROUTE, NONE}
60+
var drag_line_mode : int = DragLineGesture.NONE
5961

6062
var lasso_points : PackedVector2Array
6163

@@ -76,7 +78,7 @@ func _ready() -> void:
7678
for t in range(41):
7779
add_valid_connection_type(t, 42)
7880
add_valid_connection_type(42, t)
79-
node_popup.about_to_popup.connect(func(): valid_drag_cut_entry = false)
81+
node_popup.about_to_popup.connect(func(): drag_line_mode = DragLineGesture.NONE)
8082

8183
func _exit_tree():
8284
remove_crash_recovery_file()
@@ -168,22 +170,45 @@ func _gui_input(event) -> void:
168170
accept_event()
169171
node_popup.position = Vector2i(get_screen_transform()*get_local_mouse_position())
170172
node_popup.show_popup()
171-
elif event.is_action_released("ui_cut_drag"):
172-
var conns : Array[Dictionary]
173-
for p in len(drag_cut_line) - 1:
174-
var rect : Rect2
175-
rect.position = drag_cut_line[p]
176-
rect.end = drag_cut_line[p + 1]
177-
conns = get_connections_intersecting_with_rect(rect.abs())
178-
if conns.size():
179-
connections_to_cut.append_array(conns)
180-
if connections_to_cut.size():
181-
on_cut_connections(connections_to_cut)
182-
connections_to_cut.clear()
183-
Input.set_custom_mouse_cursor(null)
184-
drag_cut_line.clear()
185-
conns.clear()
186-
queue_redraw()
173+
elif event.is_action_released("ui_cut_drag") or event.is_action_released("ui_reroute_drag"):
174+
match drag_line_mode:
175+
DragLineGesture.CUT:
176+
var connections_to_cut : Array[Dictionary]
177+
var links : Array[Dictionary]
178+
for p in len(drag_line) - 1:
179+
var rect : Rect2
180+
rect.position = drag_line[p]
181+
rect.end = drag_line[p + 1]
182+
links = get_connections_intersecting_with_rect(rect.abs())
183+
if links.size():
184+
connections_to_cut.append_array(links)
185+
if connections_to_cut.size():
186+
on_cut_connections(connections_to_cut)
187+
connections_to_cut.clear()
188+
Input.set_custom_mouse_cursor(null)
189+
drag_line.clear()
190+
links.clear()
191+
queue_redraw()
192+
DragLineGesture.REROUTE:
193+
if drag_line.size() >= 2:
194+
var drag_reroute_line := Curve2D.new()
195+
for p : Vector2 in drag_line:
196+
drag_reroute_line.add_point(p)
197+
var points := drag_reroute_line.tessellate_even_length(5, connection_lines_thickness)
198+
var target_connections : Array[Dictionary]
199+
for p : Vector2 in points:
200+
var link := get_closest_connection_at_point(p, connection_lines_thickness)
201+
if not link.is_empty() and target_connections.find_custom(func(d):
202+
return (d.from_node == link.from_node and d.from_port == link.from_port
203+
and d.to_node == link.to_node and d.to_port == link.to_port)) == -1:
204+
link.position = p
205+
target_connections.append(link)
206+
if target_connections.size():
207+
on_reroute_connections(target_connections)
208+
target_connections.clear()
209+
Input.set_custom_mouse_cursor(null)
210+
drag_line.clear()
211+
queue_redraw()
187212
elif event.is_action_released("ui_lasso_select", true):
188213
for node in get_children():
189214
if node is GraphElement:
@@ -224,8 +249,10 @@ func _gui_input(event) -> void:
224249
event.control = true
225250
do_zoom(1.0/1.1)
226251
elif event.button_index == MOUSE_BUTTON_RIGHT and event.is_pressed():
227-
valid_drag_cut_entry = true
228-
if event.is_command_or_control_pressed() and event.shift_pressed:
252+
drag_line_mode = DragLineGesture.CUT
253+
if event.shift_pressed:
254+
add_reroute_under_mouse()
255+
elif event.ctrl_pressed:
229256
create_portals()
230257
elif event.shift_pressed:
231258
add_reroute_under_mouse()
@@ -326,15 +353,24 @@ func _gui_input(event) -> void:
326353
if rect.has_point(get_global_mouse_position()):
327354
mm_globals.set_tip_text("Space/#RMB: Nodes menu, Arrow keys: Pan, Mouse wheel: Zoom", 3)
328355

329-
if ((event.button_mask & MOUSE_BUTTON_MASK_RIGHT) != 0 and valid_drag_cut_entry
330-
and event.relative.length() > 1.0):
331-
if event.ctrl_pressed:
332-
Input.set_custom_mouse_cursor(
333-
drag_cut_cursor, Input.CURSOR_ARROW, CURSOR_HOT_SPOT)
334-
drag_cut_line.append(get_local_mouse_position())
356+
# drag line gesture (cut/reroute)
357+
if (event.button_mask & MOUSE_BUTTON_MASK_RIGHT) != 0 and event.relative.length() > 1.0:
358+
if drag_line_mode != DragLineGesture.NONE:
359+
drag_line.append(get_local_mouse_position())
335360
queue_redraw()
336-
elif drag_cut_line.size():
337-
drag_cut_line.append(get_local_mouse_position())
361+
if event.ctrl_pressed:
362+
drag_line_mode = DragLineGesture.CUT
363+
Input.set_custom_mouse_cursor(drag_cut_cursor,
364+
Input.CURSOR_ARROW, DRAG_CUT_CURSOR_HOT_SPOT)
365+
elif event.shift_pressed:
366+
drag_line_mode = DragLineGesture.REROUTE
367+
Input.set_custom_mouse_cursor(drag_reroute_cursor,
368+
Input.CURSOR_ARROW, drag_reroute_cursor.get_size() * 0.5)
369+
else:
370+
drag_line_mode = DragLineGesture.NONE
371+
Input.set_custom_mouse_cursor(null)
372+
if drag_line.size():
373+
drag_line.clear()
338374
queue_redraw()
339375

340376
# lasso selection
@@ -355,8 +391,8 @@ func get_padded_node_rect(graph_node:GraphNode) -> Rect2:
355391
return Rect2(rect.position, rect.size)
356392

357393
func _draw() -> void:
358-
if drag_cut_line.size() > 1:
359-
draw_polyline(drag_cut_line, get_theme_color("connection_knife", "GraphEdit"), 1.0)
394+
if drag_line.size() > 1:
395+
draw_polyline(drag_line, get_theme_color("line_gesture", "GraphEdit"), 1.0)
360396
if lasso_points.size() > 1:
361397
draw_polyline(lasso_points + PackedVector2Array([lasso_points[0]]),
362398
get_theme_color("lasso_stroke", "GraphEdit"), 1.0)
@@ -479,6 +515,40 @@ func do_disconnect_node(from : String, from_slot : int, to : String, to_slot : i
479515
return true
480516
return false
481517

518+
func on_reroute_connections(target_connections : Array[Dictionary]) -> void:
519+
var prev : Dictionary = generator.serialize()
520+
var grouped_connections : Dictionary[String, Array]
521+
522+
# group connections by their source node/port
523+
for link : Dictionary in target_connections:
524+
var key := "%s_%d" % [link.from_node, link.from_port]
525+
if not grouped_connections.has(key):
526+
grouped_connections[key] = []
527+
grouped_connections[key].append(link)
528+
529+
for group : String in grouped_connections:
530+
# find connection group center
531+
var group_rect := Rect2(grouped_connections[group][0].position, Vector2.ZERO)
532+
for group_link : Dictionary in grouped_connections[group]:
533+
group_rect = group_rect.expand(group_link.position)
534+
var group_center := (group_rect.abs().get_center() + scroll_offset) / zoom
535+
536+
# create reroute node
537+
var reroute : Array = await do_create_nodes({nodes=[{name ="reroute", type="reroute",
538+
node_position={x=group_center.x, y=group_center.y}}], connections=[]})
539+
var group_reroute : GraphNode = reroute[0]
540+
group_reroute.position_offset -= group_reroute.size * 0.5
541+
542+
# reroute connections
543+
for link : Dictionary in grouped_connections[group]:
544+
do_disconnect_node(link.from_node, link.from_port, link.to_node, link.to_port)
545+
do_connect_node(link.from_node, link.from_port, group_reroute.name, 0)
546+
do_connect_node(group_reroute.name, 0, link.to_node, link.to_port)
547+
548+
# undo/redo
549+
var next : Dictionary = generator.serialize()
550+
undoredo_create_step("Reroute multiple connections", generator.get_hier_name(), prev, next)
551+
482552
func on_cut_connections(connections_to_be_cut : Array):
483553
var generator_hier_name : String = generator.get_hier_name()
484554
var conns : Array = []
@@ -495,7 +565,6 @@ func on_cut_connections(connections_to_be_cut : Array):
495565
]
496566
undoredo.add("Cut node connections", undo_actions, redo_actions)
497567

498-
499568
func on_disconnect_node(from : String, from_slot : int, to : String, to_slot : int) -> void:
500569
var from_gen = get_node(from).generator
501570
var to_gen = get_node(to).generator

material_maker/theme/classic_base.tres

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -981,10 +981,10 @@ CodeEdit/colors/symbol_color = Color(1, 1, 1, 1)
981981
CodeEdit/colors/type_color = Color(1, 1, 0.878431, 1)
982982
CodeEdit/styles/normal = SubResource("StyleBoxFlat_meah8")
983983
FileDialog/styles/panel = SubResource("StyleBoxFlat_7b2nb")
984-
GraphEdit/colors/connection_knife = Color(1, 1, 1, 1)
985984
GraphEdit/colors/grid_major = Color(0.321569, 0.337255, 0.384314, 1)
986985
GraphEdit/colors/grid_minor = Color(0.321569, 0.337255, 0.384314, 1)
987986
GraphEdit/colors/lasso_stroke = Color(1, 1, 1, 1)
987+
GraphEdit/colors/line_gesture = Color(1, 1, 1, 1)
988988
GraphEdit/constants/port_hotzone_inner_extent = 8
989989
GraphEdit/constants/port_hotzone_outer_extent = 50
990990
GraphEdit/icons/grid_toggle = SubResource("AtlasTexture_m1w7u")

material_maker/theme/default dark.tres

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ metadata/_custom_type_script = "uid://3ga2k3abkk0d"
205205

206206
[sub_resource type="Resource" id="Resource_0m7hk"]
207207
script = ExtResource("4_0efyb")
208-
name = "GraphEditConnectionKnife"
208+
name = "GraphEditLineGesture"
209209
orig = Color(0.99215686, 0.9843137, 1, 1)
210210
target = Color(1, 1, 1, 1)
211211
metadata/_custom_type_script = "uid://3ga2k3abkk0d"

material_maker/theme/default light.tres

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ metadata/_custom_type_script = "uid://3ga2k3abkk0d"
346346

347347
[sub_resource type="Resource" id="Resource_qqxbn"]
348348
script = ExtResource("4_rhf2q")
349-
name = "GraphEditConnectionKnife"
349+
name = "GraphEditLineGesture"
350350
orig = Color(0.99215686, 0.9843137, 1, 1)
351351
target = Color(1, 1, 1, 1)
352352
metadata/_custom_type_script = "uid://3ga2k3abkk0d"

material_maker/theme/default.tres

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1252,10 +1252,10 @@ FileDialog/colors/file_disabled_color = Color(0.301961, 0.305882, 0.309804, 1)
12521252
FileDialog/colors/file_icon_color = Color(0.698039, 0.698039, 0.698039, 1)
12531253
FileDialog/colors/folder_icon_color = Color(0.698039, 0.698039, 0.698039, 1)
12541254
FileDialog/styles/panel = SubResource("StyleBoxFlat_ck0hb")
1255-
GraphEdit/colors/connection_knife = Color(0.99215686, 0.9843137, 1, 1)
12561255
GraphEdit/colors/grid_major = Color(0.137255, 0.141176, 0.152941, 1)
12571256
GraphEdit/colors/grid_minor = Color(0.137255, 0.141176, 0.152941, 1)
12581257
GraphEdit/colors/lasso_stroke = Color(0.9882353, 0.9882353, 0.9882353, 1)
1258+
GraphEdit/colors/line_gesture = Color(0.9882353, 0.9882353, 0.9882353, 1)
12591259
GraphEdit/constants/port_hotzone_inner_extent = 8
12601260
GraphEdit/constants/port_hotzone_outer_extent = 50
12611261
GraphEdit/icons/grid_toggle = SubResource("AtlasTexture_m1w7u")

project.godot

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,11 @@ left_click={
132132
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(80, 13),"global_position":Vector2(89, 61),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null)
133133
]
134134
}
135+
ui_reroute_drag={
136+
"deadzone": 0.5,
137+
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":true,"ctrl_pressed":false,"meta_pressed":false,"button_mask":2,"position":Vector2(812, 27),"global_position":Vector2(828, 108),"factor":1.0,"button_index":2,"canceled":false,"pressed":true,"double_click":false,"script":null)
138+
]
139+
}
135140

136141
[locale]
137142

0 commit comments

Comments
 (0)