Skip to content

Commit 4478548

Browse files
committed
Add zoom and pan to block canvas
1 parent b7cbac1 commit 4478548

File tree

2 files changed

+96
-7
lines changed

2 files changed

+96
-7
lines changed

addons/block_code/ui/block_canvas/block_canvas.gd

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@ extends MarginContainer
44

55
const EXTEND_MARGIN: float = 800
66
const BLOCK_AUTO_PLACE_MARGIN: Vector2 = Vector2(16, 8)
7+
const ZOOM_FACTOR: float = 1.1
78

89
@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
1012
@onready var _choose_block_code_label: Label = %ChooseBlockCodeLabel
1113
@onready var _create_block_code_label: Label = %CreateBlockCodeLabel
1214

1315
var _block_scenes_by_class = {}
16+
var _panning := false
1417

1518
signal reconnect_block(block: Block)
1619

@@ -30,10 +33,8 @@ func _populate_block_scenes_by_class():
3033

3134

3235
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)
3537
_window.add_child(block)
36-
_window.custom_minimum_size.y = max(block.position.y + EXTEND_MARGIN, _window.custom_minimum_size.y)
3738

3839

3940
func get_blocks() -> Array[Block]:
@@ -59,14 +60,20 @@ func set_child(n: Node):
5960
func bsd_selected(bsd: BlockScriptData):
6061
clear_canvas()
6162

63+
_window.position = Vector2(0, 0)
64+
_window.scale = Vector2(1, 1)
65+
66+
_zoom_label.visible = true
6267
_choose_block_code_label.visible = false
6368
_create_block_code_label.visible = false
6469

6570
if not bsd and scene_has_bsd_nodes():
6671
_choose_block_code_label.visible = true
72+
_zoom_label.visible = false
6773
return
6874
elif not bsd and not scene_has_bsd_nodes():
6975
_create_block_code_label.visible = true
76+
_zoom_label.visible = false
7077
return
7178

7279
for tree in bsd.block_trees.array:
@@ -151,3 +158,51 @@ func set_scope(scope: String):
151158
func release_scope():
152159
for block in _window.get_children():
153160
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 = "%.1fx" % _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())

addons/block_code/ui/block_canvas/block_canvas.tscn

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,50 @@ script = ExtResource("1_tk8h2")
1515
[node name="Panel" type="Panel" parent="."]
1616
layout_mode = 2
1717

18-
[node name="WindowScroll" type="ScrollContainer" parent="."]
19-
unique_name_in_owner = true
18+
[node name="WindowContainer" type="MarginContainer" parent="."]
19+
clip_contents = true
2020
layout_mode = 2
2121

22-
[node name="Window" type="Control" parent="WindowScroll"]
22+
[node name="Window" type="Control" parent="WindowContainer"]
2323
unique_name_in_owner = true
2424
layout_mode = 2
2525
size_flags_horizontal = 3
2626
mouse_filter = 1
2727

28+
[node name="Overlay" type="Control" parent="WindowContainer"]
29+
layout_mode = 2
30+
mouse_filter = 2
31+
32+
[node name="MarginContainer" type="MarginContainer" parent="WindowContainer/Overlay"]
33+
layout_mode = 1
34+
anchors_preset = 3
35+
anchor_left = 1.0
36+
anchor_top = 1.0
37+
anchor_right = 1.0
38+
anchor_bottom = 1.0
39+
offset_left = -40.0
40+
offset_top = -40.0
41+
grow_horizontal = 0
42+
grow_vertical = 0
43+
mouse_filter = 2
44+
theme_override_constants/margin_left = 4
45+
theme_override_constants/margin_top = 4
46+
theme_override_constants/margin_right = 4
47+
theme_override_constants/margin_bottom = 4
48+
49+
[node name="ZoomLabel" type="Label" parent="WindowContainer/Overlay/MarginContainer"]
50+
unique_name_in_owner = true
51+
layout_mode = 2
52+
theme_override_colors/font_color = Color(1, 1, 1, 0.196078)
53+
theme_override_font_sizes/font_size = 24
54+
text = "1x"
55+
horizontal_alignment = 2
56+
57+
[node name="MouseOverride" type="MarginContainer" parent="."]
58+
unique_name_in_owner = true
59+
layout_mode = 2
60+
mouse_filter = 2
61+
2862
[node name="ChooseBlockCodeLabel" type="Label" parent="."]
2963
unique_name_in_owner = true
3064
visible = false

0 commit comments

Comments
 (0)