@@ -4,13 +4,16 @@ extends MarginContainer
4
4
5
5
const EXTEND_MARGIN : float = 800
6
6
const BLOCK_AUTO_PLACE_MARGIN : Vector2 = Vector2 (16 , 8 )
7
+ const ZOOM_FACTOR : float = 1.1
7
8
8
9
@onready var _window : Control = % Window
9
- @onready var _window_scroll : ScrollContainer = % WindowScroll
10
+ @onready var _mouse_override : Control = % MouseOverride
11
+ @onready var _zoom_label : Label = % ZoomLabel
10
12
@onready var _choose_block_code_label : Label = % ChooseBlockCodeLabel
11
13
@onready var _create_block_code_label : Label = % CreateBlockCodeLabel
12
14
13
15
var _block_scenes_by_class = {}
16
+ var _panning := false
14
17
15
18
signal reconnect_block (block : Block )
16
19
@@ -30,10 +33,8 @@ func _populate_block_scenes_by_class():
30
33
31
34
32
35
func add_block (block : Block , position : Vector2 = Vector2 .ZERO ) -> void :
33
- block .position = position
34
- block .position .y += _window_scroll .scroll_vertical
36
+ block .position = canvas_to_window (position )
35
37
_window .add_child (block )
36
- _window .custom_minimum_size .y = max (block .position .y + EXTEND_MARGIN , _window .custom_minimum_size .y )
37
38
38
39
39
40
func get_blocks () -> Array [Block ]:
@@ -59,14 +60,20 @@ func set_child(n: Node):
59
60
func bsd_selected (bsd : BlockScriptData ):
60
61
clear_canvas ()
61
62
63
+ _window .position = Vector2 (0 , 0 )
64
+ _window .scale = Vector2 (1 , 1 )
65
+
66
+ _zoom_label .visible = true
62
67
_choose_block_code_label .visible = false
63
68
_create_block_code_label .visible = false
64
69
65
70
if not bsd and scene_has_bsd_nodes ():
66
71
_choose_block_code_label .visible = true
72
+ _zoom_label .visible = false
67
73
return
68
74
elif not bsd and not scene_has_bsd_nodes ():
69
75
_create_block_code_label .visible = true
76
+ _zoom_label .visible = false
70
77
return
71
78
72
79
for tree in bsd .block_trees .array :
@@ -151,3 +158,51 @@ func set_scope(scope: String):
151
158
func release_scope ():
152
159
for block in _window .get_children ():
153
160
block .modulate = Color .WHITE
161
+
162
+
163
+ func _input (event ):
164
+ if event is InputEventKey :
165
+ if event .keycode == KEY_SHIFT :
166
+ if event .pressed :
167
+ _mouse_override .mouse_filter = Control .MOUSE_FILTER_PASS
168
+ _mouse_override .mouse_default_cursor_shape = Control .CURSOR_MOVE
169
+ else :
170
+ _mouse_override .mouse_filter = Control .MOUSE_FILTER_IGNORE
171
+ _mouse_override .mouse_default_cursor_shape = Control .CURSOR_ARROW
172
+
173
+ if event is InputEventMouseButton :
174
+ if event .button_index == MOUSE_BUTTON_LEFT :
175
+ if event .pressed and is_mouse_over ():
176
+ _panning = true
177
+ else :
178
+ _panning = false
179
+
180
+ var relative_mouse_pos := get_global_mouse_position () - get_global_rect ().position
181
+
182
+ if is_mouse_over ():
183
+ var old_mouse_window_pos := canvas_to_window (relative_mouse_pos )
184
+
185
+ if event .button_index == MOUSE_BUTTON_WHEEL_UP and _window .scale .x < 2 :
186
+ _window .scale *= ZOOM_FACTOR
187
+ if event .button_index == MOUSE_BUTTON_WHEEL_DOWN and _window .scale .x > 0.2 :
188
+ _window .scale /= ZOOM_FACTOR
189
+
190
+ _zoom_label .text = "%.1f x" % _window .scale .x
191
+
192
+ _window .position -= (old_mouse_window_pos - canvas_to_window (relative_mouse_pos )) * _window .scale .x
193
+
194
+ if event is InputEventMouseMotion :
195
+ if Input .is_key_pressed (KEY_SHIFT ) and _panning :
196
+ _window .position += event .relative
197
+
198
+
199
+ func canvas_to_window (v : Vector2 ) -> Vector2 :
200
+ return _window .get_transform ().affine_inverse () * v
201
+
202
+
203
+ func window_to_canvas (v : Vector2 ) -> Vector2 :
204
+ return _window .get_transform () * v
205
+
206
+
207
+ func is_mouse_over () -> bool :
208
+ return get_global_rect ().has_point (get_global_mouse_position ())
0 commit comments