@@ -5,195 +5,15 @@ extends Control
55signal block_dropped
66signal block_modified
77
8+ const Drag = preload ("res://addons/block_code/drag_manager/drag.gd" )
9+
810@export var picker_path : NodePath
911@export var block_canvas_path : NodePath
1012
1113const Constants = preload ("res://addons/block_code/ui/constants.gd" )
1214
1315enum DragAction { NONE , PLACE , REMOVE }
1416
15-
16- class Drag :
17- extends Control
18- var _block : Block
19- var _block_scope : String
20- var _block_canvas : BlockCanvas
21- var _preview_block : Control
22- var _snap_points : Array [Node ]
23- var _delete_areas : Array [Rect2 ]
24- var action : DragAction :
25- get :
26- return action
27- set (value ):
28- if action != value :
29- action = value
30- _update_action_hint ()
31-
32- var target_snap_point : SnapPoint :
33- get :
34- return target_snap_point
35- set (value ):
36- if target_snap_point != value :
37- target_snap_point = value
38- _update_preview ()
39-
40- var snap_block : Block :
41- get :
42- return target_snap_point .get_parent_block () if target_snap_point else null
43-
44- func _init (block : Block , block_scope : String , offset : Vector2 , block_canvas : BlockCanvas ):
45- assert (block .get_parent () == null )
46-
47- add_child (block )
48- block .position = - offset
49-
50- _block = block
51- _block_scope = block_scope
52- _block_canvas = block_canvas
53-
54- func set_snap_points (snap_points : Array [Node ]):
55- _snap_points = snap_points .filter (_snaps_to )
56-
57- func add_delete_area (delete_area : Rect2 ):
58- _delete_areas .append (delete_area )
59-
60- func update_drag_state ():
61- global_position = get_global_mouse_position ()
62-
63- if _block_canvas .is_mouse_over ():
64- scale = Vector2 (_block_canvas .zoom , _block_canvas .zoom )
65- else :
66- scale = Vector2 (1 , 1 )
67-
68- for rect in _delete_areas :
69- if rect .has_point (get_global_mouse_position ()):
70- action = DragAction .REMOVE
71- target_snap_point = null
72- return
73-
74- action = DragAction .PLACE
75-
76- target_snap_point = _find_closest_snap_point ()
77-
78- func apply_drag () -> Block :
79- update_drag_state ()
80-
81- if action == DragAction .PLACE :
82- _place_block ()
83- return _block
84- elif action == DragAction .REMOVE :
85- _remove_block ()
86- return null
87- else :
88- return null
89-
90- func _remove_block ():
91- target_snap_point = null
92- _block .queue_free ()
93-
94- func _place_block ():
95- var canvas_rect : Rect2 = _block_canvas .get_global_rect ()
96-
97- var position = _block .global_position - canvas_rect .position
98-
99- remove_child (_block )
100-
101- if target_snap_point :
102- # Snap the block to the point
103- var orphaned_block = target_snap_point .insert_snapped_block (_block )
104- if orphaned_block :
105- # Place the orphan block somewhere outside the snap point
106- _block_canvas .arrange_block (orphaned_block , snap_block )
107- else :
108- # Block goes on screen somewhere
109- _block_canvas .add_block (_block , position )
110-
111- target_snap_point = null
112-
113- func _snaps_to (node : Node ) -> bool :
114- var _snap_point : SnapPoint = node as SnapPoint
115-
116- if not _snap_point :
117- push_error ("Warning: node %s is not of class SnapPoint." % node )
118- return false
119-
120- if not _block_canvas .is_ancestor_of (_snap_point ):
121- # We only snap to blocks on the canvas:
122- return false
123-
124- if _block .block_type != _snap_point .block_type :
125- # We only snap to the same block type:
126- return false
127-
128- if _block .block_type == Types .BlockType .VALUE and not Types .can_cast (_block .variant_type , _snap_point .variant_type ):
129- # We only snap Value blocks to snaps that can cast to same variant:
130- return false
131-
132- # Check if any parent node is this node
133- if _snap_point .is_ancestor_of (_block ):
134- return false
135-
136- var top_block = _get_top_block_for_node (_snap_point )
137-
138- # Check if scope is valid
139- if _block_scope != "" :
140- if top_block is EntryBlock :
141- if _block_scope != top_block .get_entry_statement ():
142- return false
143- elif top_block :
144- var tree_scope := DragManager .get_tree_scope (top_block )
145- if tree_scope != "" and _block_scope != tree_scope :
146- return false
147-
148- return true
149-
150- func _find_closest_snap_point () -> Node :
151- var closest_snap_point : SnapPoint = null
152- var closest_distance : int
153- for snap_point in _snap_points :
154- var distance = _get_distance_to_snap_point (snap_point )
155- if distance > Constants .MINIMUM_SNAP_DISTANCE * _block_canvas .zoom :
156- continue
157- elif closest_snap_point == null or distance < closest_distance :
158- closest_snap_point = snap_point
159- closest_distance = distance
160- return closest_snap_point
161-
162- func _get_top_block_for_node (node : Node ) -> Block :
163- for top_block in _block_canvas .get_blocks ():
164- if top_block .is_ancestor_of (node ):
165- return top_block
166- return null
167-
168- func _get_distance_to_snap_point (snap_point : SnapPoint ) -> float :
169- var from_global : Vector2 = _block .global_position
170- return from_global .distance_to (snap_point .global_position )
171-
172- func _update_action_hint ():
173- match action :
174- DragAction .REMOVE :
175- _block .modulate = Color (1.0 , 1.0 , 1.0 , 0.5 )
176- _ :
177- _block .modulate = Color .WHITE
178-
179- func _update_preview ():
180- if _preview_block :
181- _preview_block .queue_free ()
182- _preview_block = null
183-
184- if target_snap_point :
185- # Make preview block
186- _preview_block = Control .new ()
187- _preview_block .set_script (preload ("res://addons/block_code/ui/blocks/utilities/background/background.gd" ))
188-
189- _preview_block .color = Color (1 , 1 , 1 , 0.5 )
190- _preview_block .custom_minimum_size = _block .get_global_rect ().size
191- _preview_block .size_flags_horizontal = Control .SIZE_SHRINK_BEGIN
192- _preview_block .size_flags_vertical = Control .SIZE_SHRINK_BEGIN
193-
194- target_snap_point .add_child (_preview_block )
195-
196-
19717var _picker : Picker
19818var _block_canvas : BlockCanvas
19919
0 commit comments