@@ -41,6 +41,12 @@ var undoredo_move_node_selection_changed : bool = true
41
41
enum ConnectionStyle {DIRECT , BEZIER , ROUNDED , MANHATTAN , DIAGONAL }
42
42
var connection_line_style : int = ConnectionStyle .BEZIER
43
43
44
+ @onready var drag_cut_cursor = preload ("res://material_maker/icons/knife.png" )
45
+ var connections_to_cut : Array [Dictionary ]
46
+ var drag_cut_line : Line2D = Line2D .new ()
47
+ var valid_drag_cut_entry : bool = false
48
+ const CURSOR_HOT_SPOT : Vector2 = Vector2 (2.0 , 27.22 )
49
+
44
50
signal save_path_changed
45
51
signal graph_changed
46
52
signal view_updated
@@ -53,6 +59,7 @@ func _ready() -> void:
53
59
for t in range (41 ):
54
60
add_valid_connection_type (t , 42 )
55
61
add_valid_connection_type (42 , t )
62
+ node_popup .about_to_popup .connect (func (): valid_drag_cut_entry = false )
56
63
57
64
func _exit_tree ():
58
65
remove_crash_recovery_file ()
@@ -121,6 +128,22 @@ func _gui_input(event) -> void:
121
128
accept_event ()
122
129
node_popup .position = Vector2i (get_screen_transform ()* get_local_mouse_position ())
123
130
node_popup .show_popup ()
131
+ elif event .is_action_released ("ui_cut_drag" ):
132
+ var conns : Array [Dictionary ]
133
+ for p in len (drag_cut_line .points ) - 1 :
134
+ var rect : Rect2
135
+ rect .position = drag_cut_line .points [p ]
136
+ rect .end = drag_cut_line .points [p + 1 ]
137
+ conns = get_connections_intersecting_with_rect (rect .abs ())
138
+ if conns .size ():
139
+ connections_to_cut .append_array (conns )
140
+ if connections_to_cut .size ():
141
+ on_cut_connections (connections_to_cut )
142
+ connections_to_cut .clear ()
143
+ Input .set_custom_mouse_cursor (null )
144
+ drag_cut_line .clear_points ()
145
+ conns .clear ()
146
+ queue_redraw ()
124
147
elif event .is_action_pressed ("ui_hierarchy_up" ):
125
148
on_ButtonUp_pressed ()
126
149
elif event .is_action_pressed ("ui_hierarchy_down" ):
@@ -142,6 +165,7 @@ func _gui_input(event) -> void:
142
165
event .control = true
143
166
do_zoom (1.0 / 1.1 )
144
167
elif event .button_index == MOUSE_BUTTON_RIGHT and event .is_pressed ():
168
+ valid_drag_cut_entry = true
145
169
for c in get_children ():
146
170
if ! c is GraphNode :
147
171
continue
@@ -161,10 +185,11 @@ func _gui_input(event) -> void:
161
185
if c .has_method ("on_clicked_output" ):
162
186
c .on_clicked_output (slot .index , Input .is_key_pressed (KEY_SHIFT ))
163
187
return
164
- # Only popup the UI library if Ctrl is not pressed to avoid conflicting
165
- # with the Ctrl + Space shortcut.
166
- node_popup .position = Vector2i (get_screen_transform ()* get_local_mouse_position ())
167
- node_popup .show_popup ()
188
+ # Only show add node popup if Ctrl is not pressed to
189
+ # avoid conflicting with drag-cut shortcut (Ctrl + RMB)
190
+ if ! event .ctrl_pressed :
191
+ node_popup .position = Vector2i (get_screen_transform ()* get_local_mouse_position ())
192
+ node_popup .show_popup ()
168
193
else :
169
194
if event .button_index == MOUSE_BUTTON_LEFT :
170
195
if event .double_click :
@@ -219,13 +244,27 @@ func _gui_input(event) -> void:
219
244
if rect .has_point (get_global_mouse_position ()):
220
245
mm_globals .set_tip_text ("Space/#RMB: Nodes menu, Arrow keys: Pan, Mouse wheel: Zoom" , 3 )
221
246
247
+ if (event .button_mask & MOUSE_BUTTON_MASK_RIGHT ) != 0 and valid_drag_cut_entry :
248
+ if event .ctrl_pressed :
249
+ Input .set_custom_mouse_cursor (
250
+ drag_cut_cursor , Input .CURSOR_ARROW , CURSOR_HOT_SPOT )
251
+ drag_cut_line .add_point (get_local_mouse_position ())
252
+ queue_redraw ()
253
+ elif drag_cut_line .points .size ():
254
+ drag_cut_line .add_point (get_local_mouse_position ())
255
+ queue_redraw ()
256
+
222
257
func get_padded_node_rect (graph_node :GraphNode ) -> Rect2 :
223
258
var rect : Rect2 = graph_node .get_global_rect ()
224
259
var padding := 8 * graph_node .get_global_transform ().get_scale ().x
225
260
rect .position .x -= padding
226
261
rect .size .x += padding * 2
227
262
return Rect2 (rect .position , rect .size )
228
263
264
+ func _draw () -> void :
265
+ if drag_cut_line .points .size () > 1 :
266
+ draw_polyline (drag_cut_line .points , Color .WHITE , 0.5 )
267
+
229
268
230
269
# Misc. useful functions
231
270
func get_source (node , port ) -> Dictionary :
@@ -306,6 +345,23 @@ func do_disconnect_node(from : String, from_slot : int, to : String, to_slot : i
306
345
return true
307
346
return false
308
347
348
+ func on_cut_connections (connections : Array ):
349
+ var generator_hier_name : String = generator .get_hier_name ()
350
+ var conns : Array = []
351
+ for c in connections :
352
+ var from_gen = get_node (str (c .from_node )).generator
353
+ var to_gen = get_node (str (c .to_node )).generator
354
+ if do_disconnect_node (c .from_node , c .from_port , c .to_node , c .to_port ):
355
+ conns .append ({from = from_gen .name ,from_port = c .from_port , to = to_gen .name , to_port = c .to_port })
356
+ var undo_actions = [
357
+ { type = "add_to_graph" , parent = generator_hier_name , generators = [], connections = conns }
358
+ ]
359
+ var redo_actions = [
360
+ { type = "remove_connections" , parent = generator_hier_name , connections = conns }
361
+ ]
362
+ undoredo .add ("Cut node connections" , undo_actions , redo_actions )
363
+
364
+
309
365
func on_disconnect_node (from : String , from_slot : int , to : String , to_slot : int ) -> void :
310
366
var from_gen = get_node (from ).generator
311
367
var to_gen = get_node (to ).generator
0 commit comments