From 7dcd95a35a36301a3cb5769464f2717d930c17e2 Mon Sep 17 00:00:00 2001 From: j30 <46060104+joaquin30@users.noreply.github.com> Date: Mon, 16 Dec 2024 22:58:08 -0500 Subject: [PATCH] Added collapse/expand blocks to hide advanced settings. This commit modifies the display_template parsing of .tres block definitions, adding a separator using the | character. All labels and parameters after this separator are added to a new CollapsableSettings container that has collapse/expand buttons, with the goal of hiding advanced settings from users. To do this, a new hidden key with a boolean value is added to the results of the parse_display_template method. Additionally, CollapsableSettings is implemented using an HBoxContainer and changing the visibility of child nodes when changing collapse/expand states. Fixes https://github.com/endlessm/godot-block-coding/issues/288. --- .../block_code/blocks/sounds/play_sound.tres | 2 +- .../code_generation/block_definition.gd | 38 ++++++++++++------ .../template_editor/collapsable_settings.gd | 34 ++++++++++++++++ .../template_editor/collapsable_settings.tscn | 25 ++++++++++++ .../utilities/template_editor/minus.png | Bin 0 -> 197 bytes .../template_editor/minus.png.import | 34 ++++++++++++++++ .../blocks/utilities/template_editor/plus.png | Bin 0 -> 206 bytes .../utilities/template_editor/plus.png.import | 34 ++++++++++++++++ .../template_editor/template_editor.gd | 37 +++++++++++------ 9 files changed, 177 insertions(+), 27 deletions(-) create mode 100644 addons/block_code/ui/blocks/utilities/template_editor/collapsable_settings.gd create mode 100644 addons/block_code/ui/blocks/utilities/template_editor/collapsable_settings.tscn create mode 100644 addons/block_code/ui/blocks/utilities/template_editor/minus.png create mode 100644 addons/block_code/ui/blocks/utilities/template_editor/minus.png.import create mode 100644 addons/block_code/ui/blocks/utilities/template_editor/plus.png create mode 100644 addons/block_code/ui/blocks/utilities/template_editor/plus.png.import diff --git a/addons/block_code/blocks/sounds/play_sound.tres b/addons/block_code/blocks/sounds/play_sound.tres index 72840769..06d6a34a 100644 --- a/addons/block_code/blocks/sounds/play_sound.tres +++ b/addons/block_code/blocks/sounds/play_sound.tres @@ -10,7 +10,7 @@ description = "Play the audio stream with volume and pitch" category = "Sounds" type = 2 variant_type = 0 -display_template = "play the sound {name: STRING} with volume {db: FLOAT} dB and pitch scale {pitch: FLOAT}" +display_template = "play the sound {name: STRING} | with volume {db: FLOAT} dB and pitch scale {pitch: FLOAT}" code_template = "var __sound_node = get_node({name}) __sound_node.volume_db = {db} __sound_node.pitch_scale = {pitch} diff --git a/addons/block_code/code_generation/block_definition.gd b/addons/block_code/code_generation/block_definition.gd index b9a72e82..eba8a483 100644 --- a/addons/block_code/code_generation/block_definition.gd +++ b/addons/block_code/code_generation/block_definition.gd @@ -92,19 +92,31 @@ func get_output_parameters() -> Dictionary: static func parse_display_template(template_string: String): var items: Array[Dictionary] - for regex_match in _display_template_regex.search_all(template_string): - if regex_match.names.has("label"): - var label_string := regex_match.get_string("label") - items.append({"label": label_string}) - elif regex_match.names.has("in_parameter"): - var parameter_string := regex_match.get_string("in_parameter") - items.append({"in_parameter": _parse_parameter_format(parameter_string)}) - elif regex_match.names.has("out_parameter"): - var parameter_string := regex_match.get_string("out_parameter") - items.append({"out_parameter": _parse_parameter_format(parameter_string)}) - elif regex_match.names.has("const_parameter"): - var parameter_string := regex_match.get_string("const_parameter") - items.append({"const_parameter": _parse_parameter_format(parameter_string)}) + # Parse the template string. + var parse_template_string = func(template_string: String, hidden: bool): + for regex_match in _display_template_regex.search_all(template_string): + if regex_match.names.has("label"): + var label_string := regex_match.get_string("label") + items.append({"label": label_string, "hidden": hidden}) + elif regex_match.names.has("in_parameter"): + var parameter_string := regex_match.get_string("in_parameter") + items.append({"in_parameter": _parse_parameter_format(parameter_string), "hidden": hidden}) + elif regex_match.names.has("out_parameter"): + var parameter_string := regex_match.get_string("out_parameter") + items.append({"out_parameter": _parse_parameter_format(parameter_string), "hidden": hidden}) + elif regex_match.names.has("const_parameter"): + var parameter_string := regex_match.get_string("const_parameter") + items.append({"const_parameter": _parse_parameter_format(parameter_string), "hidden": hidden}) + # This splits in two the template string in the first "|" character + # to separate normal and hidden parameters. + var sep: int = template_string.find("|") + if sep == -1: + parse_template_string.call(template_string, false) + else: + var template_string_normal := template_string.substr(0, sep).trim_suffix(" ") + var template_string_advanced := template_string.substr(sep + 1) + parse_template_string.call(template_string_normal, false) + parse_template_string.call(template_string_advanced, true) return items diff --git a/addons/block_code/ui/blocks/utilities/template_editor/collapsable_settings.gd b/addons/block_code/ui/blocks/utilities/template_editor/collapsable_settings.gd new file mode 100644 index 00000000..8ea99334 --- /dev/null +++ b/addons/block_code/ui/blocks/utilities/template_editor/collapsable_settings.gd @@ -0,0 +1,34 @@ +@tool +class_name CollapsableSettings +extends HBoxContainer + +@onready var _expand_button: Button = %ExpandSettingsButton +@onready var _collapse_button: Button = %CollapseSettingsButton +var _collapsed := false + + +func _ready() -> void: + _collapse() + move_child(_expand_button, 0) + move_child(_collapse_button, -1) + _expand_button.connect("button_up", _expand) + _collapse_button.connect("button_up", _collapse) + + +func _expand() -> void: + if not _collapsed: + return + for child in get_children(true): + child.visible = true + _expand_button.visible = false + _collapse_button.visible = true + _collapsed = false + + +func _collapse() -> void: + if _collapsed: + return + for child in get_children(true): + child.visible = false + _expand_button.visible = true + _collapsed = true diff --git a/addons/block_code/ui/blocks/utilities/template_editor/collapsable_settings.tscn b/addons/block_code/ui/blocks/utilities/template_editor/collapsable_settings.tscn new file mode 100644 index 00000000..653cc063 --- /dev/null +++ b/addons/block_code/ui/blocks/utilities/template_editor/collapsable_settings.tscn @@ -0,0 +1,25 @@ +[gd_scene load_steps=4 format=3 uid="uid://1xfpd777g8pf"] + +[ext_resource type="Script" path="res://addons/block_code/ui/blocks/utilities/template_editor/collapsable_settings.gd" id="1_f0ssn"] +[ext_resource type="Texture2D" uid="uid://br7yvjjtbuups" path="res://addons/block_code/ui/blocks/utilities/template_editor/plus.png" id="2_8s057"] +[ext_resource type="Texture2D" uid="uid://di3ona3fudjkx" path="res://addons/block_code/ui/blocks/utilities/template_editor/minus.png" id="3_6qcv3"] + +[node name="CollapsableSettings" type="HBoxContainer"] +offset_right = 36.0 +offset_bottom = 31.0 +script = ExtResource("1_f0ssn") + +[node name="ExpandSettingsButton" type="Button" parent="."] +unique_name_in_owner = true +layout_mode = 2 +icon = ExtResource("2_8s057") +flat = true +icon_alignment = 1 + +[node name="CollapseSettingsButton" type="Button" parent="."] +unique_name_in_owner = true +custom_minimum_size = Vector2(20, 20) +layout_mode = 2 +icon = ExtResource("3_6qcv3") +flat = true +icon_alignment = 1 diff --git a/addons/block_code/ui/blocks/utilities/template_editor/minus.png b/addons/block_code/ui/blocks/utilities/template_editor/minus.png new file mode 100644 index 0000000000000000000000000000000000000000..88af774e3a3fa486d8e33ef4c5e3eb913dfc6371 GIT binary patch literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE;AkEe@ch(+((5Ko~43LM!p{{27w zlG9zcdy!?5kW$YhPKQZhvJ5u8l@BD>O7OFu&JatLsW|c?O7Q<#p~`@JIXYn*nZ8c& z+U22aeo50~lj@o!o44#=`sHqzZ&gRAP2=nhR!!4Bq*(3^^P6VK%+Mwo7Box$shih# v-R$Fc&o7irU-Ieu)=Re8&!p0hU9_-MXo}EVvDq~b=q?6NS3j3^P65c!FX08ZbTnJkGg4KIjGYSw1;d!_4Hox()NSZV3Y@B}V`v>Vtv=Mn$5>xVo9kUh zRYv={f2TaeABvak`>6Eh9N)?7cGDj1PBmm(pi!aZ^@39^GF_+pLyG0TF#lGJ$mvP#qScY25&`aOmufDuD%Z*q2agL0=hd_qrk`3BSKnF5-y85}Sb4q9e E0MH9ci~s-t literal 0 HcmV?d00001 diff --git a/addons/block_code/ui/blocks/utilities/template_editor/plus.png.import b/addons/block_code/ui/blocks/utilities/template_editor/plus.png.import new file mode 100644 index 00000000..446a2f83 --- /dev/null +++ b/addons/block_code/ui/blocks/utilities/template_editor/plus.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://br7yvjjtbuups" +path="res://.godot/imported/plus.png-415014510d01c9db50069dbfc9e6ab6f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/block_code/ui/blocks/utilities/template_editor/plus.png" +dest_files=["res://.godot/imported/plus.png-415014510d01c9db50069dbfc9e6ab6f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/block_code/ui/blocks/utilities/template_editor/template_editor.gd b/addons/block_code/ui/blocks/utilities/template_editor/template_editor.gd index 1d22c7bd..6a17ca2f 100644 --- a/addons/block_code/ui/blocks/utilities/template_editor/template_editor.gd +++ b/addons/block_code/ui/blocks/utilities/template_editor/template_editor.gd @@ -12,6 +12,7 @@ const ParameterInput = preload("res://addons/block_code/ui/blocks/utilities/para const ParameterInputScene = preload("res://addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.tscn") const ParameterOutput = preload("res://addons/block_code/ui/blocks/utilities/parameter_output/parameter_output.gd") const ParameterOutputScene = preload("res://addons/block_code/ui/blocks/utilities/parameter_output/parameter_output.tscn") +const CollapsableSettingsScene = preload("res://addons/block_code/ui/blocks/utilities/template_editor/collapsable_settings.tscn") ## A string describing a block's display format. For example: ## [br] @@ -86,27 +87,37 @@ func _update_from_format_string(): _container.remove_child(child) child.queue_free() - var match_id = 0 + var match_id: int = 0 + var is_collapsable := false + var collapsable: CollapsableSettings = CollapsableSettingsScene.instantiate() for item in BlockDefinition.parse_display_template(format_string): + var hidden: bool = item.get("hidden", false) + var container: Container = collapsable if hidden else _container + if hidden: + is_collapsable = true if item.has("label"): - _append_label(item.get("label")) + _append_label(container, item.get("label")) elif item.has("in_parameter"): - _append_input_parameter(item.get("in_parameter"), match_id) + _append_input_parameter(container, item.get("in_parameter"), match_id) elif item.has("out_parameter"): - _append_output_parameter(item.get("out_parameter"), match_id) + _append_output_parameter(container, item.get("out_parameter"), match_id) elif item.has("const_parameter"): - _append_const_parameter(item.get("const_parameter"), match_id) + _append_const_parameter(container, item.get("const_parameter"), match_id) match_id += 1 + if is_collapsable: + _container.add_child(collapsable) + else: + collapsable.queue_free() -func _append_label(label_format: String): +func _append_label(container: Container, label_format: String): var label = Label.new() label.add_theme_color_override("font_color", Color.WHITE) label.text = label_format.strip_edges() - _container.add_child(label) + container.add_child(label) -func _append_input_parameter(parameter: Dictionary, id: int) -> ParameterInput: +func _append_input_parameter(container: Container, parameter: Dictionary, id: int) -> ParameterInput: var default_value = parameter_defaults.get(parameter["name"]) var parameter_input: ParameterInput = ParameterInputScene.instantiate() @@ -125,26 +136,26 @@ func _append_input_parameter(parameter: Dictionary, id: int) -> ParameterInput: parameter_input.modified.connect(func(): modified.emit()) - _container.add_child(parameter_input) + container.add_child(parameter_input) _parameter_inputs_by_name[parameter["name"]] = parameter_input return parameter_input -func _append_output_parameter(parameter: Dictionary, id: int): +func _append_output_parameter(container: Container, parameter: Dictionary, id: int): var parameter_output: ParameterOutput parameter_output = ParameterOutputScene.instantiate() parameter_output.name = "ParameterOutput%d" % id parameter_output.block = parent_block parameter_output.parameter_name = parameter["name"] - _container.add_child(parameter_output) + container.add_child(parameter_output) -func _append_const_parameter(parameter: Dictionary, id: int): +func _append_const_parameter(container: Container, parameter: Dictionary, id: int): # const_parameter is a kind of in_parameter with default value, but never # changes value. - var parameter_const := _append_input_parameter(parameter, id) + var parameter_const := _append_input_parameter(container, parameter, id) parameter_const.visible = false