From b02713067eaea3888a6e0f25c4a1c6e08893993d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= Date: Wed, 24 Jul 2024 10:43:06 -0300 Subject: [PATCH 1/4] ParameterInput: Validate text input before submit For float, int, and Vector2 types. If the text is not valid, reset to the last submitted text and don't emit the midified signal. --- .../parameter_input/parameter_input.gd | 50 +++++++++++-------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.gd b/addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.gd index 7d28fcc9..8e603475 100644 --- a/addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.gd +++ b/addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.gd @@ -33,9 +33,11 @@ var option: bool = false @onready var _bool_input_option := %BoolInputOption # Used to submit the text when losing focus: -var _last_lineedit_submitted_text: String -var _last_x_lineedit_submitted_text: String -var _last_y_lineedit_submitted_text: String +@onready var _last_submitted_text = { + _line_edit: _line_edit.text, + _x_line_edit: _x_line_edit.text, + _y_line_edit: _y_line_edit.text, +} func set_raw_input(raw_input): @@ -99,10 +101,6 @@ func _ready(): snap_point.block_type = block_type snap_point.variant_type = variant_type - _last_lineedit_submitted_text = _line_edit.text - _last_x_lineedit_submitted_text = _x_line_edit.text - _last_y_lineedit_submitted_text = _y_line_edit.text - _update_visible_input() @@ -136,34 +134,44 @@ func get_string() -> String: return "%s" % input -func _on_line_edit_text_submitted(new_text): - _last_lineedit_submitted_text = new_text +func _validate_and_submit_edit_text(line_edit: Node, type: Variant.Type): + if _last_submitted_text[line_edit] == line_edit.text: + return + match type: + TYPE_FLOAT: + if not line_edit.text.is_valid_float(): + line_edit.text = _last_submitted_text[line_edit] + return + TYPE_INT: + if not line_edit.text.is_valid_int(): + line_edit.text = _last_submitted_text[line_edit] + return + _last_submitted_text[line_edit] = line_edit.text modified.emit() +func _on_line_edit_text_submitted(_new_text): + _validate_and_submit_edit_text(_line_edit, variant_type) + + func _on_line_edit_focus_exited(): - if _last_lineedit_submitted_text != _line_edit.text: - modified.emit() + _validate_and_submit_edit_text(_line_edit, variant_type) -func _on_x_line_edit_text_submitted(new_text): - _last_x_lineedit_submitted_text = new_text - modified.emit() +func _on_x_line_edit_text_submitted(_new_text): + _validate_and_submit_edit_text(_x_line_edit, TYPE_FLOAT) func _on_x_line_edit_focus_exited(): - if _last_x_lineedit_submitted_text != _x_line_edit.text: - modified.emit() + _validate_and_submit_edit_text(_x_line_edit, TYPE_FLOAT) -func _on_y_line_edit_text_submitted(new_text): - _last_y_lineedit_submitted_text = new_text - modified.emit() +func _on_y_line_edit_text_submitted(_new_text): + _validate_and_submit_edit_text(_y_line_edit, TYPE_FLOAT) func _on_y_line_edit_focus_exited(): - if _last_y_lineedit_submitted_text != _y_line_edit.text: - modified.emit() + _validate_and_submit_edit_text(_y_line_edit, TYPE_FLOAT) func _update_visible_input(): From e9ffc17f8ad8f4daf8c2f3333f921ded10657496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= Date: Wed, 24 Jul 2024 10:47:10 -0300 Subject: [PATCH 2/4] ParameterInput: Improve _switch_input function --- .../ui/blocks/utilities/parameter_input/parameter_input.gd | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.gd b/addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.gd index 8e603475..95073a0e 100644 --- a/addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.gd +++ b/addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.gd @@ -193,15 +193,11 @@ func _update_visible_input(): func _switch_input(node: Node): for c in _input_switcher.get_children(): - c.visible = false - - if node: - node.visible = true + c.visible = c == node func _on_color_input_color_changed(color): _update_panel_bg_color(color) - modified.emit() From 98fa3b3f840dd48ea5b821ce58241391c76c92f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= Date: Wed, 24 Jul 2024 11:17:19 -0300 Subject: [PATCH 3/4] CategoryFactory: Use degrees for rotation We are not exposing PI or TAU constants. It's simpler to have a single way to set/change rotation as degrees. The Godot UI also has a degrees slider for Node2D rotation. rotation_degrees is a property, so remove the custom setter. --- .../block_code/ui/picker/categories/category_factory.gd | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/addons/block_code/ui/picker/categories/category_factory.gd b/addons/block_code/ui/picker/categories/category_factory.gd index 2e07279f..021d04b2 100644 --- a/addons/block_code/ui/picker/categories/category_factory.gd +++ b/addons/block_code/ui/picker/categories/category_factory.gd @@ -593,16 +593,9 @@ static func get_built_in_blocks(_class_name: String) -> Array[Block]: match _class_name: "Node2D": - var b = BLOCKS["statement_block"].instantiate() - b.block_name = "node2d_rotation" - b.block_format = "Set Rotation Degrees {angle: FLOAT}" - b.statement = "rotation_degrees = {angle}" - b.category = "Transform | Rotation" - block_list.append(b) - props = { "position": "Transform | Position", - "rotation": "Transform | Rotation", + "rotation_degrees": "Transform | Rotation", "scale": "Transform | Scale", } From ce6f0a1be3eb2a9424c35dabe57d23252ffdba4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= Date: Wed, 24 Jul 2024 12:02:04 -0300 Subject: [PATCH 4/4] CategoryFactory: Add defaults to all blocks All possible blocks gain default values. So they can be used directly without having to type a value. And most importantly, so the script is not generated with syntax errors. The defaults are opinionated, they have to be. Eg. set scale to double size, change position so the node2d moves to the right-bottom. Also: remove "change by" block for modulate and visible properties. They don't make sense. https://phabricator.endlessm.com/T35562 --- .../ui/picker/categories/category_factory.gd | 90 +++++++++++++++---- 1 file changed, 71 insertions(+), 19 deletions(-) diff --git a/addons/block_code/ui/picker/categories/category_factory.gd b/addons/block_code/ui/picker/categories/category_factory.gd index 021d04b2..f4386b31 100644 --- a/addons/block_code/ui/picker/categories/category_factory.gd +++ b/addons/block_code/ui/picker/categories/category_factory.gd @@ -362,6 +362,7 @@ static func get_general_blocks() -> Array[Block]: b.variant_type = TYPE_VECTOR2 b.block_format = "Vector2 x: {x: FLOAT} y: {y: FLOAT}" b.statement = "Vector2({x}, {y})" + b.defaults = {"x": "0", "y": "0"} b.category = "Variables" block_list.append(b) @@ -373,6 +374,7 @@ static func get_general_blocks() -> Array[Block]: b.variant_type = TYPE_INT b.block_format = "{a: INT} + {b: INT}" b.statement = "({a} + {b})" + b.defaults = {"a": "1", "b": "1"} b.category = "Math" block_list.append(b) @@ -381,6 +383,7 @@ static func get_general_blocks() -> Array[Block]: b.variant_type = TYPE_INT b.block_format = "{a: INT} - {b: INT}" b.statement = "({a} - {b})" + b.defaults = {"a": "1", "b": "1"} b.category = "Math" block_list.append(b) @@ -389,6 +392,7 @@ static func get_general_blocks() -> Array[Block]: b.variant_type = TYPE_INT b.block_format = "{a: INT} * {b: INT}" b.statement = "({a} * {b})" + b.defaults = {"a": "1", "b": "1"} b.category = "Math" block_list.append(b) @@ -397,6 +401,7 @@ static func get_general_blocks() -> Array[Block]: b.variant_type = TYPE_INT b.block_format = "{a: INT} / {b: INT}" b.statement = "({a} / {b})" + b.defaults = {"a": "1", "b": "1"} b.category = "Math" block_list.append(b) @@ -405,6 +410,7 @@ static func get_general_blocks() -> Array[Block]: b.variant_type = TYPE_INT b.block_format = "{base: INT} ^ {exp: INT}" b.statement = "(pow({base}, {exp}))" + b.defaults = {"base": "1", "exp": "1"} b.category = "Math" block_list.append(b) @@ -413,14 +419,14 @@ static func get_general_blocks() -> Array[Block]: b = BLOCKS["control_block"].instantiate() b.block_name = "if" - b.block_formats = ["if {condition: BOOL}"] + b.block_formats = ["if {condition: BOOL}"] b.statements = ["if {condition}:"] b.category = "Logic | Conditionals" block_list.append(b) b = BLOCKS["control_block"].instantiate() b.block_name = "if_else" - b.block_formats = ["if {condition: BOOL}", "else"] + b.block_formats = ["if {condition: BOOL}", "else"] b.statements = ["if {condition}:", "else:"] b.category = "Logic | Conditionals" block_list.append(b) @@ -430,7 +436,11 @@ static func get_general_blocks() -> Array[Block]: b.variant_type = TYPE_BOOL b.block_format = "{int1: INT} {op: OPTION} {int2: INT}" b.statement = "({int1} {op} {int2})" - b.defaults = {"op": OptionData.new(["==", ">", "<", ">=", "<=", "!="])} + b.defaults = { + "op": OptionData.new(["==", ">", "<", ">=", "<=", "!="]), + "int1": "1", + "int2": "1", + } b.category = "Logic | Comparison" block_list.append(b) @@ -529,6 +539,20 @@ static func property_to_blocklist(property: Dictionary) -> Array[Block]: var variant_type = property.type + const FALLBACK_SET_FOR_TYPE = { + TYPE_INT: "0", + TYPE_FLOAT: "0", + TYPE_VECTOR2: "0, 0", + TYPE_COLOR: "DARK_ORANGE", + } + + const FALLBACK_CHANGE_FOR_TYPE = { + TYPE_INT: "1", + TYPE_FLOAT: "1", + TYPE_VECTOR2: "1, 1", + TYPE_COLOR: "DARK_ORANGE", + } + if variant_type: var type_string: String = Types.VARIANT_TYPE_TO_STRING[variant_type] @@ -536,15 +560,20 @@ static func property_to_blocklist(property: Dictionary) -> Array[Block]: b.block_name = "set_prop_%s" % property.name b.block_format = "Set %s to {value: %s}" % [property.name.capitalize(), type_string] b.statement = "%s = {value}" % property.name + var default_set = property.get("default_set", FALLBACK_SET_FOR_TYPE.get(variant_type, "")) + b.defaults = {"value": default_set} b.category = property.category block_list.append(b) - b = BLOCKS["statement_block"].instantiate() - b.block_name = "change_prop_%s" % property.name - b.block_format = "Change %s by {value: %s}" % [property.name.capitalize(), type_string] - b.statement = "%s += {value}" % property.name - b.category = property.category - block_list.append(b) + if property.get("has_change", true): + b = BLOCKS["statement_block"].instantiate() + b.block_name = "change_prop_%s" % property.name + b.block_format = "Change %s by {value: %s}" % [property.name.capitalize(), type_string] + b.statement = "%s += {value}" % property.name + var default_change = property.get("default_change", FALLBACK_CHANGE_FOR_TYPE[variant_type]) + b.defaults = {"value": default_change} + b.category = property.category + block_list.append(b) b = BLOCKS["parameter_block"].instantiate() b.block_name = "get_prop_%s" % property.name @@ -565,7 +594,7 @@ static func blocks_from_property_list(property_list: Array, selected_props: Dict for prop in property_list: if selected_property == prop.name: found_prop = prop - found_prop.category = selected_props[selected_property] + found_prop.merge(selected_props[selected_property]) break if found_prop: block_list.append_array(property_to_blocklist(found_prop)) @@ -594,15 +623,38 @@ static func get_built_in_blocks(_class_name: String) -> Array[Block]: match _class_name: "Node2D": props = { - "position": "Transform | Position", - "rotation_degrees": "Transform | Rotation", - "scale": "Transform | Scale", + "position": + { + "category": "Transform | Position", + "default_set": "100, 100", + "default_change": "1, 1", + }, + "rotation_degrees": + { + "category": "Transform | Rotation", + "default_set": "45", + "default_change": "1", + }, + "scale": + { + "category": "Transform | Scale", + "default_set": "2, 2", + "default_change": "0.1, 0.1", + }, } "CanvasItem": props = { - "modulate": "Graphics | Modulate", - "visible": "Graphics | Visibility", + "modulate": + { + "category": "Graphics | Modulate", + "has_change": false, + }, + "visible": + { + "category": "Graphics | Visibility", + "has_change": false, + }, } "RigidBody2D": @@ -643,9 +695,9 @@ static func get_built_in_blocks(_class_name: String) -> Array[Block]: block_list.append(b) props = { - "mass": "Physics | Mass", - "linear_velocity": "Physics | Velocity", - "angular_velocity": "Physics | Velocity", + "mass": {"category": "Physics | Mass"}, + "linear_velocity": {"category": "Physics | Velocity"}, + "angular_velocity": {"category": "Physics | Velocity"}, } "AnimationPlayer": @@ -747,7 +799,7 @@ static func get_built_in_blocks(_class_name: String) -> Array[Block]: block_list.append(b) props = { - "velocity": "Physics | Velocity", + "velocity": {"category": "Physics | Velocity"}, } var prop_list = ClassDB.class_get_property_list(_class_name, true)