Skip to content

Commit f6ed144

Browse files
committed
Add TemplateEditor to generate UI based on a block format string
This new component replaces StatementBlock.format_string in favour of a more declarative API. https://phabricator.endlessm.com/T35564
1 parent 72d5ebe commit f6ed144

File tree

9 files changed

+209
-117
lines changed

9 files changed

+209
-117
lines changed

addons/block_code/ui/blocks/parameter_block/parameter_block.gd

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ extends Block
44

55
const Constants = preload("res://addons/block_code/ui/constants.gd")
66
const Util = preload("res://addons/block_code/ui/util.gd")
7+
const ParameterOutput = preload("res://addons/block_code/ui/blocks/utilities/parameter_output/parameter_output.gd")
78

89
@export var block_format: String = ""
910
@export var statement: String = ""
1011
@export var variant_type: Variant.Type
1112
@export var defaults: Dictionary = {}
1213

14+
@onready var _template_editor := %TemplateEditor
1315
@onready var _panel := $Panel
14-
@onready var _hbox := %HBoxContainer
1516

1617
var param_name_input_pairs: Array
1718
var param_input_strings: Dictionary # Only loaded from serialized
@@ -36,7 +37,8 @@ func _ready():
3637
if not Util.node_is_part_of_edited_scene(self):
3738
_panel.add_theme_stylebox_override("panel", _panel_normal)
3839

39-
format()
40+
_template_editor.format_string = block_format
41+
_template_editor.parameter_defaults = defaults
4042

4143
if param_input_strings:
4244
for pair in param_name_input_pairs:
@@ -81,10 +83,6 @@ static func get_scene_path():
8183
return "res://addons/block_code/ui/blocks/parameter_block/parameter_block.tscn"
8284

8385

84-
func format():
85-
param_name_input_pairs = StatementBlock.format_string(self, %HBoxContainer, block_format, defaults)
86-
87-
8886
func _on_focus_entered():
8987
_panel.add_theme_stylebox_override("panel", _panel_focus)
9088

addons/block_code/ui/blocks/parameter_block/parameter_block.tscn

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
[gd_scene load_steps=4 format=3 uid="uid://clipm2dd28jde"]
1+
[gd_scene load_steps=5 format=3 uid="uid://clipm2dd28jde"]
22

33
[ext_resource type="Script" path="res://addons/block_code/ui/blocks/parameter_block/parameter_block.gd" id="1_0hajy"]
44
[ext_resource type="PackedScene" uid="uid://c7puyxpqcq6xo" path="res://addons/block_code/ui/blocks/utilities/drag_drop_area/drag_drop_area.tscn" id="2_gy5co"]
5+
[ext_resource type="PackedScene" uid="uid://b1xvp3u11h41s" path="res://addons/block_code/ui/blocks/utilities/template_editor/template_editor.tscn" id="3_shl1a"]
56

67
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_dbera"]
78
bg_color = Color(1, 1, 1, 1)
@@ -35,17 +36,17 @@ layout_mode = 2
3536

3637
[node name="MarginContainer" type="MarginContainer" parent="."]
3738
layout_mode = 2
38-
size_flags_horizontal = 0
3939
mouse_filter = 2
40+
41+
[node name="TemplateEditor" parent="MarginContainer" instance=ExtResource("3_shl1a")]
42+
unique_name_in_owner = true
43+
layout_mode = 2
44+
size_flags_horizontal = 0
4045
theme_override_constants/margin_left = 10
4146
theme_override_constants/margin_top = 8
4247
theme_override_constants/margin_right = 10
4348
theme_override_constants/margin_bottom = 8
44-
45-
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer"]
46-
unique_name_in_owner = true
47-
layout_mode = 2
48-
mouse_filter = 2
49+
format_string = ""
4950

5051
[connection signal="focus_entered" from="." to="." method="_on_focus_entered"]
5152
[connection signal="focus_exited" from="." to="." method="_on_focus_exited"]

addons/block_code/ui/blocks/statement_block/statement_block.gd

Lines changed: 15 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ extends Block
44

55
const ParameterInput = preload("res://addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.gd")
66
const ParameterInputScene = preload("res://addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.tscn")
7+
const ParameterOutput = preload("res://addons/block_code/ui/blocks/utilities/parameter_output/parameter_output.gd")
8+
const ParameterOutputScene = preload("res://addons/block_code/ui/blocks/utilities/parameter_output/parameter_output.tscn")
79

810
@export var block_format: String = ""
911
@export var statement: String = ""
1012
@export var defaults: Dictionary = {}
1113

14+
@onready var _template_editor := %TemplateEditor
1215
@onready var _background := %Background
13-
@onready var _hbox := %HBoxContainer
1416

1517
var param_name_input_pairs: Array
1618
var param_input_strings: Dictionary # Only loaded from serialized
@@ -23,7 +25,8 @@ func _ready():
2325
_background.show_top = false
2426
_background.color = color
2527

26-
format()
28+
_template_editor.format_string = block_format
29+
_template_editor.parameter_defaults = defaults
2730

2831
if param_input_strings:
2932
for pair in param_name_input_pairs:
@@ -82,80 +85,16 @@ func get_instruction_node() -> InstructionTree.TreeNode:
8285

8386

8487
func format():
85-
param_name_input_pairs = format_string(self, %HBoxContainer, block_format, defaults)
88+
print("AAAAAH")
8689

8790

8891
static func format_string(parent_block: Block, attach_to: Node, string: String, _defaults: Dictionary) -> Array:
89-
var _param_name_input_pairs = []
90-
var regex = RegEx.new()
91-
regex.compile("\\[([^\\]]+)\\]|\\{([^}]+)\\}") # Capture things of format {test} or [test]
92-
var results := regex.search_all(string)
93-
94-
var start: int = 0
95-
for result in results:
96-
var label_text := string.substr(start, result.get_start() - start)
97-
if label_text != "":
98-
var label = Label.new()
99-
label.add_theme_color_override("font_color", Color.WHITE)
100-
label.text = label_text
101-
attach_to.add_child(label)
102-
103-
var param := result.get_string()
104-
var copy_block: bool = param[0] == "["
105-
param = param.substr(1, param.length() - 2)
106-
107-
var split := param.split(": ")
108-
var param_name := split[0]
109-
var param_type_str := split[1]
110-
111-
var param_type = null
112-
var option := false
113-
if param_type_str == "OPTION": # Easy way to specify dropdown option
114-
option = true
115-
else:
116-
param_type = Types.STRING_TO_VARIANT_TYPE[param_type_str]
117-
118-
var param_default = null
119-
if _defaults.has(param_name):
120-
param_default = _defaults[param_name]
121-
122-
var param_node: Node
123-
124-
if copy_block:
125-
var parameter_output: ParameterOutput = preload("res://addons/block_code/ui/blocks/utilities/parameter_output/parameter_output.tscn").instantiate()
126-
parameter_output.name = "ParameterOutput%d" % start # Unique path
127-
parameter_output.block_params = {
128-
"block_format": param_name,
129-
"statement": param_name,
130-
"variant_type": param_type,
131-
"color": parent_block.color,
132-
"scope": parent_block.get_entry_statement() if parent_block is EntryBlock else ""
133-
}
134-
parameter_output.block = parent_block
135-
attach_to.add_child(parameter_output)
136-
else:
137-
var parameter_input: ParameterInput = ParameterInputScene.instantiate()
138-
parameter_input.name = "ParameterInput%d" % start # Unique path
139-
parameter_input.placeholder = param_name
140-
if param_type != null:
141-
parameter_input.variant_type = param_type
142-
elif option:
143-
parameter_input.option = true
144-
parameter_input.modified.connect(func(): parent_block.modified.emit())
145-
146-
attach_to.add_child(parameter_input)
147-
if param_default:
148-
parameter_input.set_raw_input(param_default)
149-
150-
_param_name_input_pairs.append([param_name, parameter_input])
151-
152-
start = result.get_end()
153-
154-
var label_text := string.substr(start)
155-
if label_text != "":
156-
var label = Label.new()
157-
label.add_theme_color_override("font_color", Color.WHITE)
158-
label.text = label_text
159-
attach_to.add_child(label)
160-
161-
return _param_name_input_pairs
92+
# FIXME: This is ridiculous. Just rewrite this mess.
93+
# We need the default value to be figured out at the end of it all,
94+
# and not serialized. Only a value the user explicitly sets should
95+
# be serialized. A list of options should not be serialized. It
96+
# populates ParameterInput, but it is not the same thing as its
97+
# value.
98+
99+
print("NOOOOO")
100+
return []

addons/block_code/ui/blocks/statement_block/statement_block.tscn

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
[gd_scene load_steps=5 format=3 uid="uid://c84vmg3odrtxt"]
1+
[gd_scene load_steps=6 format=3 uid="uid://c84vmg3odrtxt"]
22

3-
[ext_resource type="Script" path="res://addons/block_code/ui/blocks/statement_block/statement_block.gd" id="1_6wvlf"]
4-
[ext_resource type="Script" path="res://addons/block_code/ui/blocks/utilities/background/background.gd" id="2_lctqt"]
5-
[ext_resource type="PackedScene" uid="uid://c7puyxpqcq6xo" path="res://addons/block_code/ui/blocks/utilities/drag_drop_area/drag_drop_area.tscn" id="2_owgdx"]
6-
[ext_resource type="PackedScene" uid="uid://b1oge52xhjqnu" path="res://addons/block_code/ui/blocks/utilities/snap_point/snap_point.tscn" id="3_5vaov"]
3+
[ext_resource type="Script" path="res://addons/block_code/ui/blocks/statement_block/statement_block.gd" id="1_1vvoi"]
4+
[ext_resource type="Script" path="res://addons/block_code/ui/blocks/utilities/background/background.gd" id="2_xnyfs"]
5+
[ext_resource type="PackedScene" uid="uid://c7puyxpqcq6xo" path="res://addons/block_code/ui/blocks/utilities/drag_drop_area/drag_drop_area.tscn" id="3_m80p6"]
6+
[ext_resource type="PackedScene" uid="uid://b1xvp3u11h41s" path="res://addons/block_code/ui/blocks/utilities/template_editor/template_editor.tscn" id="4_fupjs"]
7+
[ext_resource type="PackedScene" uid="uid://b1oge52xhjqnu" path="res://addons/block_code/ui/blocks/utilities/snap_point/snap_point.tscn" id="5_l3h04"]
78

89
[node name="StatementBlock" type="MarginContainer"]
910
size_flags_horizontal = 0
1011
focus_mode = 2
1112
mouse_filter = 2
12-
script = ExtResource("1_6wvlf")
13+
script = ExtResource("1_1vvoi")
1314
block_name = &"statement_block"
1415
label = "StatementBlock"
1516
bottom_snap_path = NodePath("VBoxContainer/SnapPoint")
@@ -33,10 +34,10 @@ theme_override_constants/margin_bottom = 0
3334
unique_name_in_owner = true
3435
layout_mode = 2
3536
mouse_filter = 1
36-
script = ExtResource("2_lctqt")
37+
script = ExtResource("2_xnyfs")
3738
color = Color(1, 1, 1, 1)
3839

39-
[node name="DragDropArea" parent="VBoxContainer/TopMarginContainer" instance=ExtResource("2_owgdx")]
40+
[node name="DragDropArea" parent="VBoxContainer/TopMarginContainer" instance=ExtResource("3_m80p6")]
4041
layout_mode = 2
4142

4243
[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer/TopMarginContainer"]
@@ -47,14 +48,12 @@ theme_override_constants/margin_top = 6
4748
theme_override_constants/margin_right = 12
4849
theme_override_constants/margin_bottom = 6
4950

50-
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/TopMarginContainer/MarginContainer"]
51+
[node name="TemplateEditor" parent="VBoxContainer/TopMarginContainer/MarginContainer" instance=ExtResource("4_fupjs")]
5152
unique_name_in_owner = true
52-
custom_minimum_size = Vector2(50, 0)
5353
layout_mode = 2
54-
mouse_filter = 2
55-
theme_override_constants/separation = 0
54+
format_string = ""
5655

57-
[node name="SnapPoint" parent="VBoxContainer" instance=ExtResource("3_5vaov")]
56+
[node name="SnapPoint" parent="VBoxContainer" instance=ExtResource("5_l3h04")]
5857
layout_mode = 2
5958

6059
[connection signal="mouse_down" from="VBoxContainer/TopMarginContainer/DragDropArea" to="." method="_on_drag_drop_area_mouse_down"]

addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.gd

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ signal modified
1111
@export var variant_type: Variant.Type = TYPE_STRING
1212
@export var block_type: Types.BlockType = Types.BlockType.VALUE
1313
var option: bool = false
14+
var default_value: Variant
1415

1516
@onready var _panel := %Panel
1617
@onready var snap_point := %SnapPoint
@@ -98,6 +99,7 @@ func _set_placeholder(new_placeholder: String) -> void:
9899
return
99100

100101
_line_edit.placeholder_text = placeholder
102+
_input_switcher.tooltip_text = placeholder
101103

102104

103105
func _ready():
@@ -111,6 +113,9 @@ func _ready():
111113

112114
_update_visible_input()
113115

116+
if default_value:
117+
set_raw_input(default_value)
118+
114119

115120
func get_snapped_block() -> Block:
116121
return snap_point.get_snapped_block()

addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.tscn

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ corner_radius_top_right = 40
1010
corner_radius_bottom_right = 40
1111
corner_radius_bottom_left = 40
1212

13-
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_6oowp"]
14-
1513
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_afyv2"]
1614

1715
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_3r4mt"]
1816

17+
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_6oowp"]
18+
1919
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_5hq7f"]
2020

2121
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_fjquj"]
@@ -60,13 +60,13 @@ theme_override_constants/margin_bottom = 4
6060
unique_name_in_owner = true
6161
layout_mode = 2
6262
mouse_filter = 1
63-
theme_override_colors/font_color = Color(0.118581, 0.118581, 0.118581, 1)
64-
theme_override_colors/font_uneditable_color = Color(0.117647, 0.117647, 0.117647, 1)
6563
theme_override_colors/font_placeholder_color = Color(0.76662, 0.76662, 0.76662, 1)
64+
theme_override_colors/font_uneditable_color = Color(0.117647, 0.117647, 0.117647, 1)
65+
theme_override_colors/font_color = Color(0.118581, 0.118581, 0.118581, 1)
6666
theme_override_constants/minimum_character_width = 0
67-
theme_override_styles/normal = SubResource("StyleBoxEmpty_6oowp")
6867
theme_override_styles/focus = SubResource("StyleBoxEmpty_afyv2")
6968
theme_override_styles/read_only = SubResource("StyleBoxEmpty_3r4mt")
69+
theme_override_styles/normal = SubResource("StyleBoxEmpty_6oowp")
7070
placeholder_text = "Parameter"
7171
expand_to_text_length = true
7272

@@ -106,13 +106,13 @@ size_flags_horizontal = 3
106106
unique_name_in_owner = true
107107
layout_mode = 2
108108
mouse_filter = 1
109-
theme_override_colors/font_color = Color(0.118581, 0.118581, 0.118581, 1)
110-
theme_override_colors/font_uneditable_color = Color(0.117647, 0.117647, 0.117647, 1)
111109
theme_override_colors/font_placeholder_color = Color(0.76662, 0.76662, 0.76662, 1)
110+
theme_override_colors/font_uneditable_color = Color(0.117647, 0.117647, 0.117647, 1)
111+
theme_override_colors/font_color = Color(0.118581, 0.118581, 0.118581, 1)
112112
theme_override_constants/minimum_character_width = 0
113-
theme_override_styles/normal = SubResource("StyleBoxEmpty_6oowp")
114113
theme_override_styles/focus = SubResource("StyleBoxEmpty_afyv2")
115114
theme_override_styles/read_only = SubResource("StyleBoxEmpty_3r4mt")
115+
theme_override_styles/normal = SubResource("StyleBoxEmpty_6oowp")
116116
placeholder_text = "x"
117117
alignment = 1
118118
expand_to_text_length = true
@@ -139,13 +139,13 @@ size_flags_horizontal = 3
139139
unique_name_in_owner = true
140140
layout_mode = 2
141141
mouse_filter = 1
142-
theme_override_colors/font_color = Color(0.118581, 0.118581, 0.118581, 1)
143-
theme_override_colors/font_uneditable_color = Color(0.117647, 0.117647, 0.117647, 1)
144142
theme_override_colors/font_placeholder_color = Color(0.76662, 0.76662, 0.76662, 1)
143+
theme_override_colors/font_uneditable_color = Color(0.117647, 0.117647, 0.117647, 1)
144+
theme_override_colors/font_color = Color(0.118581, 0.118581, 0.118581, 1)
145145
theme_override_constants/minimum_character_width = 0
146-
theme_override_styles/normal = SubResource("StyleBoxEmpty_6oowp")
147146
theme_override_styles/focus = SubResource("StyleBoxEmpty_afyv2")
148147
theme_override_styles/read_only = SubResource("StyleBoxEmpty_3r4mt")
148+
theme_override_styles/normal = SubResource("StyleBoxEmpty_6oowp")
149149
placeholder_text = "y"
150150
alignment = 1
151151
expand_to_text_length = true
@@ -164,14 +164,13 @@ theme_override_constants/margin_left = 8
164164
unique_name_in_owner = true
165165
custom_minimum_size = Vector2(60, 0)
166166
layout_mode = 2
167-
theme_override_colors/font_color = Color(0, 0, 0, 1)
168167
theme_override_colors/font_focus_color = Color(0, 0, 0, 1)
168+
theme_override_colors/font_color = Color(0, 0, 0, 1)
169169
theme_override_styles/focus = SubResource("StyleBoxEmpty_e7f0k")
170170
theme_override_styles/normal = SubResource("StyleBoxEmpty_fjquj")
171-
item_count = 2
172171
selected = 0
172+
item_count = 2
173173
popup/item_0/text = "False"
174-
popup/item_0/id = 0
175174
popup/item_1/text = "True"
176175
popup/item_1/id = 1
177176

addons/block_code/ui/blocks/utilities/parameter_output/parameter_output.gd

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
@tool
2-
class_name ParameterOutput
32
extends MarginContainer
43

54
const Types = preload("res://addons/block_code/types/types.gd")

0 commit comments

Comments
 (0)