Skip to content

Commit 2867d30

Browse files
authored
Merge pull request #305 from endlessm/T35712-drag-drop-resource-file
BlockCanvas: Implement drag & drop the file from resource FileSystem
2 parents 698a549 + 96a7da3 commit 2867d30

File tree

5 files changed

+80
-10
lines changed

5 files changed

+80
-10
lines changed

addons/block_code/code_generation/block_definition.gd

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ extends Resource
33

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

6-
const FORMAT_STRING_PATTERN = "\\[(?<out_parameter>[^\\]]+)\\]|\\{(?<in_parameter>[^}]+)\\}|(?<label>[^\\{\\[]+)"
6+
const FORMAT_STRING_PATTERN = "\\[(?<out_parameter>[^\\]]+)\\]|\\{const (?<const_parameter>[^}]+)\\}|\\{(?!const )(?<in_parameter>[^}]+)\\}|(?<label>[^\\{\\[]+)"
77

88
@export var name: StringName
99

@@ -102,6 +102,9 @@ static func parse_display_template(template_string: String):
102102
elif regex_match.names.has("out_parameter"):
103103
var parameter_string := regex_match.get_string("out_parameter")
104104
items.append({"out_parameter": _parse_parameter_format(parameter_string)})
105+
elif regex_match.names.has("const_parameter"):
106+
var parameter_string := regex_match.get_string("const_parameter")
107+
items.append({"const_parameter": _parse_parameter_format(parameter_string)})
105108
return items
106109

107110

addons/block_code/code_generation/blocks_catalog.gd

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,3 +302,20 @@ static func get_property_setter_block_definition(variable: VariableDefinition) -
302302
var block_def := get_variable_setter_block_definition(variable)
303303
block_def.description = "Set the %s property" % variable.var_name
304304
return block_def
305+
306+
307+
static func get_resource_block_definition(file_path: String) -> BlockDefinition:
308+
var block_def := BlockDefinition.new()
309+
var file_name = file_path.get_file()
310+
311+
# Block Definition's name cannot work with '.'
312+
block_def.name = &"get_resource_file_path"
313+
block_def.description = "The full resource path of '%s'" % file_name
314+
block_def.category = "Variables"
315+
block_def.type = Types.BlockType.VALUE
316+
block_def.variant_type = TYPE_STRING
317+
block_def.display_template = "%s {const file_path: STRING}" % file_name
318+
block_def.code_template = "{file_path}"
319+
block_def.defaults = {"file_path": file_path}
320+
321+
return block_def

addons/block_code/serialization/block_script_serialization.gd

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ func instantiate_block(block_definition: BlockDefinition) -> Block:
7272

7373

7474
func instantiate_block_by_name(block_name: String) -> Block:
75-
var block_definition := get_block_definition(block_name)
75+
var block_definition := get_block_definition(block_name, {})
7676

7777
if block_definition == null:
7878
push_warning("Cannot find a block definition for %s" % block_name)
@@ -81,12 +81,14 @@ func instantiate_block_by_name(block_name: String) -> Block:
8181
return instantiate_block(block_definition)
8282

8383

84-
func get_block_definition(block_name: String) -> BlockDefinition:
84+
func get_block_definition(block_name: String, arguments: Dictionary) -> BlockDefinition:
8585
var split := block_name.split(":", true, 1)
8686
var block_definition: BlockDefinition
8787

8888
if len(split) > 1:
89-
return _get_parameter_block_definition(split[0], split[1])
89+
block_definition = _get_parameter_block_definition(split[0], split[1])
90+
if block_definition:
91+
return block_definition
9092

9193
block_definition = _get_base_block_definition(block_name)
9294
if block_definition != null:
@@ -96,6 +98,11 @@ func get_block_definition(block_name: String) -> BlockDefinition:
9698
if block_definition != null:
9799
return block_definition
98100

101+
var file_path = arguments.get("file_path", "")
102+
block_definition = _get_resource_block_definition(block_name, file_path)
103+
if block_definition != null:
104+
return block_definition
105+
99106
# FIXME: This is a workaround for old-style output block references.
100107
# These were generated ahead of time using a block name that has
101108
# a "_" before the parameter name. Now, these parameter blocks
@@ -182,6 +189,16 @@ func _get_parent_node_property_info(property_name: String) -> Dictionary:
182189
return {}
183190

184191

192+
func _get_resource_block_definition(block_name: String, file_path: String) -> BlockDefinition:
193+
if block_name != "get_resource_file_path":
194+
return null
195+
196+
if file_path.is_empty() or not FileAccess.file_exists(file_path) or not ResourceLoader.exists(file_path):
197+
return null
198+
199+
return BlocksCatalog.get_resource_block_definition(file_path)
200+
201+
185202
func _update_block_definitions():
186203
_available_blocks.clear()
187204
_available_blocks.append_array(_get_inherited_block_definitions())
@@ -251,14 +268,15 @@ func _tree_to_ast(tree: BlockSerializationTree) -> BlockAST:
251268

252269
func _block_to_ast_node(node: BlockSerialization) -> BlockAST.ASTNode:
253270
var ast_node := BlockAST.ASTNode.new()
254-
ast_node.data = get_block_definition(node.name)
255271

256272
for arg_name in node.arguments:
257273
var argument = node.arguments[arg_name]
258274
if argument is ValueBlockSerialization:
259275
argument = _value_to_ast_value(argument)
260276
ast_node.arguments[arg_name] = argument
261277

278+
ast_node.data = get_block_definition(node.name, ast_node.arguments)
279+
262280
var children: Array[BlockAST.ASTNode]
263281
for c in node.children:
264282
children.append(_block_to_ast_node(c))
@@ -269,14 +287,15 @@ func _block_to_ast_node(node: BlockSerialization) -> BlockAST.ASTNode:
269287

270288
func _value_to_ast_value(value_node: ValueBlockSerialization) -> BlockAST.ASTValueNode:
271289
var ast_value_node := BlockAST.ASTValueNode.new()
272-
ast_value_node.data = get_block_definition(value_node.name)
273290

274291
for arg_name in value_node.arguments:
275292
var argument = value_node.arguments[arg_name]
276293
if argument is ValueBlockSerialization:
277294
argument = _value_to_ast_value(argument)
278295
ast_value_node.arguments[arg_name] = argument
279296

297+
ast_value_node.data = get_block_definition(value_node.name, ast_value_node.arguments)
298+
280299
return ast_value_node
281300

282301

addons/block_code/ui/block_canvas/block_canvas.gd

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ func _can_drop_data(at_position: Vector2, data: Variant) -> bool:
8787
return false
8888
return true
8989

90+
# Allow dropping resource file
91+
if data.get("type", "") == "files":
92+
return true
93+
9094
var nodes: Array = data.get("nodes", [])
9195
if nodes.size() != 1:
9296
return false
@@ -108,6 +112,8 @@ func _drop_data(at_position: Vector2, data: Variant) -> void:
108112
_drop_node(at_position, data)
109113
elif data["type"] == "obj_property":
110114
_drop_obj_property(at_position, data)
115+
elif data["type"] == "files":
116+
_drop_files(at_position, data)
111117

112118

113119
func _drop_node(at_position: Vector2, data: Variant) -> void:
@@ -148,6 +154,23 @@ func _drop_obj_property(at_position: Vector2, data: Variant) -> void:
148154
reconnect_block.emit(block)
149155

150156

157+
func _drop_files(at_position: Vector2, data: Variant) -> void:
158+
var resource_files = data["files"]
159+
var next_position = at_position
160+
const bias = 20
161+
162+
for file_path in resource_files:
163+
# Prepare a Variable block getting the file's resource path.
164+
var block_definition = BlocksCatalog.get_resource_block_definition(file_path)
165+
var block = _context.block_script.instantiate_block(block_definition)
166+
add_block(block, next_position)
167+
reconnect_block.emit(block)
168+
169+
# Shift next block's position a little bit to avoid overlap totally.
170+
next_position.x += bias
171+
next_position.y += bias
172+
173+
151174
func add_block(block: Block, position: Vector2 = Vector2.ZERO) -> void:
152175
if block is EntryBlock:
153176
block.position = canvas_to_window(position).snapped(SNAP_GRID)

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

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ const ParameterInputScene = preload("res://addons/block_code/ui/blocks/utilities
1313
const ParameterOutput = preload("res://addons/block_code/ui/blocks/utilities/parameter_output/parameter_output.gd")
1414
const ParameterOutputScene = preload("res://addons/block_code/ui/blocks/utilities/parameter_output/parameter_output.tscn")
1515

16-
const FORMAT_STRING_PATTERN = "\\[(?<out_parameter>[^\\]]+)\\]|\\{(?<in_parameter>[^}]+)\\}|(?<label>[^\\{\\[]+)"
17-
1816
## A string describing a block's display format. For example:
1917
## [br]
2018
## [code]
@@ -41,7 +39,6 @@ var parent_block: Block
4139
var _parameter_inputs_by_name: Dictionary
4240

4341
@onready var _container := %Container
44-
@onready var _regex := RegEx.create_from_string(FORMAT_STRING_PATTERN)
4542

4643

4744
func _ready() -> void:
@@ -97,6 +94,8 @@ func _update_from_format_string():
9794
_append_input_parameter(item.get("in_parameter"), match_id)
9895
elif item.has("out_parameter"):
9996
_append_output_parameter(item.get("out_parameter"), match_id)
97+
elif item.has("const_parameter"):
98+
_append_const_parameter(item.get("const_parameter"), match_id)
10099
match_id += 1
101100

102101

@@ -107,7 +106,7 @@ func _append_label(label_format: String):
107106
_container.add_child(label)
108107

109108

110-
func _append_input_parameter(parameter: Dictionary, id: int):
109+
func _append_input_parameter(parameter: Dictionary, id: int) -> ParameterInput:
111110
var default_value = parameter_defaults.get(parameter["name"])
112111

113112
var parameter_input: ParameterInput = ParameterInputScene.instantiate()
@@ -129,6 +128,8 @@ func _append_input_parameter(parameter: Dictionary, id: int):
129128
_container.add_child(parameter_input)
130129
_parameter_inputs_by_name[parameter["name"]] = parameter_input
131130

131+
return parameter_input
132+
132133

133134
func _append_output_parameter(parameter: Dictionary, id: int):
134135
var parameter_output: ParameterOutput
@@ -140,5 +141,12 @@ func _append_output_parameter(parameter: Dictionary, id: int):
140141
_container.add_child(parameter_output)
141142

142143

144+
func _append_const_parameter(parameter: Dictionary, id: int):
145+
# const_parameter is a kind of in_parameter with default value, but never
146+
# changes value.
147+
var parameter_const := _append_input_parameter(parameter, id)
148+
parameter_const.visible = false
149+
150+
143151
func _on_parameter_input_drag_started(offset: Vector2):
144152
drag_started.emit(offset)

0 commit comments

Comments
 (0)