Skip to content

Commit ebe008a

Browse files
authored
Merge pull request #98 from endlessm/scratch-like-categories
Scratch-like category UI
2 parents 563efb2 + fe1b59b commit ebe008a

9 files changed

+211
-85
lines changed

addons/block_code/block_code_plugin.gd

+2-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ const DISABLED_CLASSES := [
4141
"Picker",
4242
"TitleBar",
4343
"MainPanel",
44-
"BlockCodePlugin"
44+
"BlockCodePlugin",
45+
"BlockCategoryButton"
4546
]
4647

4748

addons/block_code/ui/main_panel.gd

+25
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,17 @@ var eia: EditorInterfaceAccess
99
@onready var _drag_manager: DragManager = %DragManager
1010
@onready var _title_bar: TitleBar = %TitleBar
1111
@onready var _editor_inspector: EditorInspector = EditorInterface.get_inspector()
12+
@onready var _picker_split: HSplitContainer = %PickerSplit
13+
@onready var _collapse_button: Button = %CollapseButton
14+
15+
@onready var _icon_collapse := EditorInterface.get_editor_theme().get_icon("Back", "EditorIcons")
16+
@onready var _icon_expand := EditorInterface.get_editor_theme().get_icon("Forward", "EditorIcons")
1217

1318
var block_code_tab: Button
1419
var _current_block_code_node: BlockCode
1520
var _scene_root: Node
1621
var _block_code_nodes: Array
22+
var _collapsed: bool = false
1723

1824
var undo_redo: EditorUndoRedoManager
1925

@@ -30,6 +36,8 @@ func _ready():
3036
block_code_tab = eia.Utils.find_child_by_name(eia.context_switcher, "Block Code")
3137
undo_redo.version_changed.connect(_on_undo_redo_version_changed)
3238

39+
_collapse_button.icon = _icon_collapse
40+
3341

3442
func _on_undo_redo_version_changed():
3543
if _current_block_code_node == null:
@@ -92,6 +100,11 @@ func _input(event):
92100
else:
93101
_drag_manager.drag_ended()
94102

103+
if event is InputEventKey:
104+
if Input.is_key_pressed(KEY_CTRL) and event.pressed and event.keycode == KEY_BACKSLASH:
105+
_collapse_button.button_pressed = not _collapse_button.button_pressed
106+
toggle_collapse()
107+
95108

96109
func _print_generated_script():
97110
if _current_block_code_node == null:
@@ -100,3 +113,15 @@ func _print_generated_script():
100113
var script: String = _block_canvas.generate_script_from_current_window(block_script.script_inherits)
101114
print(script)
102115
print("Debug script! (not saved)")
116+
117+
118+
func toggle_collapse():
119+
_collapsed = not _collapsed
120+
121+
_collapse_button.icon = _icon_expand if _collapsed else _icon_collapse
122+
_picker.set_collapsed(_collapsed)
123+
_picker_split.collapsed = _collapsed
124+
125+
126+
func _on_collapse_button_pressed():
127+
toggle_collapse()

addons/block_code/ui/main_panel.tscn

+27-5
Original file line numberDiff line numberDiff line change
@@ -45,24 +45,46 @@ text = "Print Generated Script"
4545
layout_mode = 2
4646
size_flags_vertical = 3
4747

48-
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/HBoxContainer/ScriptVBox/MarginContainer"]
48+
[node name="PickerSplit" type="HSplitContainer" parent="MarginContainer/HBoxContainer/ScriptVBox/MarginContainer"]
49+
unique_name_in_owner = true
4950
layout_mode = 2
5051
size_flags_horizontal = 3
5152
size_flags_vertical = 3
5253

53-
[node name="Picker" parent="MarginContainer/HBoxContainer/ScriptVBox/MarginContainer/HBoxContainer" instance=ExtResource("2_hv5f3")]
54+
[node name="Picker" parent="MarginContainer/HBoxContainer/ScriptVBox/MarginContainer/PickerSplit" instance=ExtResource("2_hv5f3")]
55+
unique_name_in_owner = true
56+
layout_mode = 2
57+
58+
[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/HBoxContainer/ScriptVBox/MarginContainer/PickerSplit"]
59+
layout_mode = 2
60+
theme_override_constants/margin_bottom = 4
61+
62+
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/HBoxContainer/ScriptVBox/MarginContainer/PickerSplit/MarginContainer"]
63+
layout_mode = 2
64+
65+
[node name="NodeBlockCanvas" parent="MarginContainer/HBoxContainer/ScriptVBox/MarginContainer/PickerSplit/MarginContainer/VBoxContainer" instance=ExtResource("3_ml5y3")]
5466
unique_name_in_owner = true
5567
layout_mode = 2
5668

57-
[node name="NodeBlockCanvas" parent="MarginContainer/HBoxContainer/ScriptVBox/MarginContainer/HBoxContainer" instance=ExtResource("3_ml5y3")]
69+
[node name="BottomBar" type="HBoxContainer" parent="MarginContainer/HBoxContainer/ScriptVBox/MarginContainer/PickerSplit/MarginContainer/VBoxContainer"]
70+
layout_mode = 2
71+
72+
[node name="CollapseButton" type="Button" parent="MarginContainer/HBoxContainer/ScriptVBox/MarginContainer/PickerSplit/MarginContainer/VBoxContainer/BottomBar"]
5873
unique_name_in_owner = true
5974
layout_mode = 2
75+
size_flags_horizontal = 8
76+
tooltip_text = "Collapse the picker toolbar. Shortcut (Ctrl-Space)"
77+
flat = true
78+
79+
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/HBoxContainer/ScriptVBox/MarginContainer/PickerSplit/MarginContainer/VBoxContainer/BottomBar"]
80+
layout_mode = 2
6081

6182
[node name="DragManager" parent="MarginContainer/HBoxContainer/ScriptVBox/MarginContainer" instance=ExtResource("4_yijtu")]
6283
unique_name_in_owner = true
6384
layout_mode = 2
6485
mouse_filter = 2
65-
picker_path = NodePath("../HBoxContainer/Picker")
66-
block_canvas_path = NodePath("../HBoxContainer/NodeBlockCanvas")
86+
picker_path = NodePath("../PickerSplit/Picker")
87+
block_canvas_path = NodePath("../PickerSplit/MarginContainer/VBoxContainer/NodeBlockCanvas")
6788

6889
[connection signal="pressed" from="MarginContainer/HBoxContainer/ScriptVBox/HBoxContainer/Button" to="." method="_on_button_pressed"]
90+
[connection signal="pressed" from="MarginContainer/HBoxContainer/ScriptVBox/MarginContainer/PickerSplit/MarginContainer/VBoxContainer/BottomBar/CollapseButton" to="." method="_on_collapse_button_pressed"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
@tool
2+
class_name BlockCategoryButton
3+
extends MarginContainer
4+
5+
signal selected
6+
7+
var category: BlockCategory
8+
9+
@onready var _panel := %Panel
10+
@onready var _label := %Label
11+
12+
13+
func _ready():
14+
if not category:
15+
category = BlockCategory.new("Example", Color.RED)
16+
17+
var new_stylebox: StyleBoxFlat = _panel.get_theme_stylebox("panel").duplicate()
18+
new_stylebox.bg_color = category.color
19+
20+
_panel.add_theme_stylebox_override("panel", new_stylebox)
21+
22+
_label.text = category.name
23+
24+
25+
func _on_button_pressed():
26+
selected.emit(category)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
[gd_scene load_steps=7 format=3 uid="uid://bdtetj0gs45hv"]
2+
3+
[ext_resource type="Script" path="res://addons/block_code/ui/picker/categories/block_category_button.gd" id="1_pxxnl"]
4+
5+
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_eogpc"]
6+
bg_color = Color(1, 0, 0, 1)
7+
corner_radius_top_left = 100
8+
corner_radius_top_right = 100
9+
corner_radius_bottom_right = 100
10+
corner_radius_bottom_left = 100
11+
12+
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_ousiv"]
13+
14+
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_fyk0j"]
15+
bg_color = Color(1, 1, 1, 0.196078)
16+
17+
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ha83k"]
18+
bg_color = Color(1, 1, 1, 0.392157)
19+
20+
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_dgecf"]
21+
22+
[node name="BlockCategoryButton" type="MarginContainer"]
23+
custom_minimum_size = Vector2(150, 0)
24+
offset_right = 148.0
25+
offset_bottom = 32.0
26+
script = ExtResource("1_pxxnl")
27+
28+
[node name="HBoxContainer" type="HBoxContainer" parent="."]
29+
layout_mode = 2
30+
31+
[node name="MarginContainer" type="MarginContainer" parent="HBoxContainer"]
32+
custom_minimum_size = Vector2(40, 40)
33+
layout_mode = 2
34+
theme_override_constants/margin_left = 8
35+
theme_override_constants/margin_top = 8
36+
theme_override_constants/margin_right = 8
37+
theme_override_constants/margin_bottom = 8
38+
39+
[node name="Panel" type="Panel" parent="HBoxContainer/MarginContainer"]
40+
unique_name_in_owner = true
41+
layout_mode = 2
42+
theme_override_styles/panel = SubResource("StyleBoxFlat_eogpc")
43+
44+
[node name="Label" type="Label" parent="HBoxContainer"]
45+
unique_name_in_owner = true
46+
layout_mode = 2
47+
text = "Example"
48+
49+
[node name="Button" type="Button" parent="."]
50+
layout_mode = 2
51+
mouse_default_cursor_shape = 2
52+
theme_override_styles/normal = SubResource("StyleBoxEmpty_ousiv")
53+
theme_override_styles/hover = SubResource("StyleBoxFlat_fyk0j")
54+
theme_override_styles/pressed = SubResource("StyleBoxFlat_ha83k")
55+
theme_override_styles/focus = SubResource("StyleBoxEmpty_dgecf")
56+
57+
[connection signal="pressed" from="Button" to="." method="_on_button_pressed"]

addons/block_code/ui/picker/categories/block_category_display.gd

+2-37
Original file line numberDiff line numberDiff line change
@@ -2,53 +2,18 @@
22
class_name BlockCategoryDisplay
33
extends MarginContainer
44

5-
signal category_expanded(value: bool)
6-
75
var category: BlockCategory
86

9-
@onready var _button := %Button
10-
@onready var _blocks_container := %BlocksContainer
7+
@onready var _label := %Label
118
@onready var _blocks := %Blocks
12-
@onready var _background := %Background
13-
14-
@onready var _icon_collapsed := EditorInterface.get_editor_theme().get_icon("GuiTreeArrowRight", "EditorIcons")
15-
@onready var _icon_expanded := EditorInterface.get_editor_theme().get_icon("GuiTreeArrowDown", "EditorIcons")
16-
17-
var expanded: bool:
18-
set = _set_expanded
19-
20-
21-
func _set_expanded(value: bool):
22-
expanded = value
23-
24-
_blocks_container.visible = expanded
25-
if expanded:
26-
_button.icon = _icon_expanded
27-
_background.color = category.color.darkened(0.5)
28-
_background.color.a = 0.3
29-
else:
30-
_button.icon = _icon_collapsed
31-
_background.color = category.color.darkened(0.2)
32-
_background.color.a = 0.3
33-
34-
category_expanded.emit(expanded)
359

3610

3711
func _ready():
38-
if not category:
39-
category = BlockCategory.new()
40-
41-
_button.text = category.name
12+
_label.text = category.name
4213

4314
for _block in category.block_list:
4415
var block: Block = _block as Block
4516

4617
block.color = category.color
4718

4819
_blocks.add_child(block)
49-
50-
expanded = false
51-
52-
53-
func _on_button_toggled(toggled_on):
54-
expanded = toggled_on

addons/block_code/ui/picker/categories/block_category_display.tscn

+9-37
Original file line numberDiff line numberDiff line change
@@ -10,53 +10,25 @@ offset_right = -918.0
1010
offset_bottom = -246.0
1111
grow_horizontal = 2
1212
grow_vertical = 2
13+
theme_override_constants/margin_left = 4
14+
theme_override_constants/margin_bottom = 40
1315
script = ExtResource("1_wkdht")
1416

15-
[node name="Background" type="ColorRect" parent="."]
16-
unique_name_in_owner = true
17+
[node name="VBoxContainer" type="VBoxContainer" parent="."]
1718
layout_mode = 2
1819

19-
[node name="MarginContainer" type="MarginContainer" parent="."]
20+
[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer"]
2021
layout_mode = 2
21-
theme_override_constants/margin_left = 10
22-
theme_override_constants/margin_top = 4
23-
theme_override_constants/margin_right = 10
2422
theme_override_constants/margin_bottom = 4
2523

26-
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"]
27-
custom_minimum_size = Vector2(400, 0)
28-
layout_mode = 2
29-
30-
[node name="Spacer" type="Control" parent="MarginContainer/VBoxContainer"]
31-
custom_minimum_size = Vector2(0, 4)
32-
layout_mode = 2
33-
34-
[node name="Button" type="Button" parent="MarginContainer/VBoxContainer"]
24+
[node name="Label" type="Label" parent="VBoxContainer/MarginContainer"]
3525
unique_name_in_owner = true
3626
layout_mode = 2
37-
theme_override_font_sizes/font_size = 16
38-
toggle_mode = true
39-
text = "Category"
40-
flat = true
41-
alignment = 0
42-
icon_alignment = 2
27+
theme_override_font_sizes/font_size = 18
28+
text = "Example Category
29+
"
4330

44-
[node name="BlocksContainer" type="VBoxContainer" parent="MarginContainer/VBoxContainer"]
45-
unique_name_in_owner = true
46-
visible = false
47-
layout_mode = 2
48-
49-
[node name="Spacer2" type="Control" parent="MarginContainer/VBoxContainer/BlocksContainer"]
50-
custom_minimum_size = Vector2(0, 4)
51-
layout_mode = 2
52-
53-
[node name="Blocks" type="VBoxContainer" parent="MarginContainer/VBoxContainer/BlocksContainer"]
31+
[node name="Blocks" type="VBoxContainer" parent="VBoxContainer"]
5432
unique_name_in_owner = true
5533
layout_mode = 2
5634
theme_override_constants/separation = 14
57-
58-
[node name="Spacer3" type="Control" parent="MarginContainer/VBoxContainer/BlocksContainer"]
59-
custom_minimum_size = Vector2(0, 50)
60-
layout_mode = 2
61-
62-
[connection signal="toggled" from="MarginContainer/VBoxContainer/Button" to="." method="_on_button_toggled"]

addons/block_code/ui/picker/picker.gd

+25
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ extends MarginContainer
55
signal block_picked(block: Block)
66

77
@onready var _block_list := %BlockList
8+
@onready var _block_scroll := %BlockScroll
9+
@onready var _category_list := %CategoryList
10+
@onready var _widget_container := %WidgetContainer
811

912

1013
func bsd_selected(bsd: BlockScriptData):
@@ -33,6 +36,9 @@ func bsd_selected(bsd: BlockScriptData):
3336

3437

3538
func reset_picker():
39+
for c in _category_list.get_children():
40+
c.queue_free()
41+
3642
for c in _block_list.get_children():
3743
c.queue_free()
3844

@@ -46,6 +52,12 @@ func init_picker(extra_blocks: Array[Block] = [], extra_categories: Array[BlockC
4652
for _category in block_categories:
4753
var category: BlockCategory = _category as BlockCategory
4854

55+
var block_category_button: BlockCategoryButton = preload("res://addons/block_code/ui/picker/categories/block_category_button.tscn").instantiate()
56+
block_category_button.category = category
57+
block_category_button.selected.connect(_category_selected)
58+
59+
_category_list.add_child(block_category_button)
60+
4961
var block_category_display := preload("res://addons/block_code/ui/picker/categories/block_category_display.tscn").instantiate()
5062
block_category_display.category = category
5163

@@ -55,6 +67,19 @@ func init_picker(extra_blocks: Array[Block] = [], extra_categories: Array[BlockC
5567
var block: Block = _block as Block
5668
block.drag_started.connect(_block_picked)
5769

70+
_block_scroll.scroll_vertical = 0
71+
5872

5973
func _block_picked(block: Block):
6074
block_picked.emit(block)
75+
76+
77+
func _category_selected(category: BlockCategory):
78+
for block_category_display in _block_list.get_children():
79+
if block_category_display.category.name == category.name:
80+
_block_scroll.scroll_vertical = block_category_display.position.y
81+
break
82+
83+
84+
func set_collapsed(collapsed: bool):
85+
_widget_container.visible = not collapsed

0 commit comments

Comments
 (0)