diff --git a/addons/block_code/drag_manager/drag.gd b/addons/block_code/drag_manager/drag.gd index 589c5a0d..102b38c0 100644 --- a/addons/block_code/drag_manager/drag.gd +++ b/addons/block_code/drag_manager/drag.gd @@ -179,7 +179,7 @@ func _get_distance_to_snap_point(snap_point: SnapPoint) -> float: func _update_action_hint(): match action: DragAction.REMOVE: - _block.modulate = Color(1.0, 1.0, 1.0, 0.5) + _block.modulate = Constants.DRAG_REMOVE_COLOR _: _block.modulate = Color.WHITE @@ -193,7 +193,15 @@ func _update_preview(): # Make preview block _preview_block = Background.new() - _preview_block.color = Color(1, 1, 1, 0.5) + _preview_block.color = Constants.DRAG_PREVIEW_COLOR + if _block.definition.type == Types.BlockType.CONTROL: + # Especial case for control block, use statement shape as preview: + _preview_block.block_type = Types.BlockType.STATEMENT + else: + _preview_block.block_type = _block.definition.type + if _block.definition.type == Types.BlockType.VALUE and _block.definition.variant_type == TYPE_BOOL: + _preview_block.is_pointy_value = true + _preview_block.custom_minimum_size = _block.get_global_rect().size / scale _preview_block.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN _preview_block.size_flags_vertical = Control.SIZE_SHRINK_BEGIN diff --git a/addons/block_code/ui/blocks/entry_block/entry_block.tscn b/addons/block_code/ui/blocks/entry_block/entry_block.tscn index 8e031c01..5201e4c3 100644 --- a/addons/block_code/ui/blocks/entry_block/entry_block.tscn +++ b/addons/block_code/ui/blocks/entry_block/entry_block.tscn @@ -19,6 +19,12 @@ layout_mode = 2 mouse_filter = 2 theme_override_constants/separation = 0 +[node name="DragDropArea" parent="VBoxContainer" instance=ExtResource("3_swkpp")] +custom_minimum_size = Vector2(80, 16) +layout_mode = 2 +size_flags_horizontal = 0 +mouse_default_cursor_shape = 2 + [node name="TopMarginContainer" type="MarginContainer" parent="VBoxContainer"] custom_minimum_size = Vector2(0, 30) layout_mode = 2 @@ -56,4 +62,5 @@ layout_mode = 2 [node name="SnapPoint" parent="VBoxContainer" instance=ExtResource("4_yj206")] layout_mode = 2 +[connection signal="drag_started" from="VBoxContainer/DragDropArea" to="." method="_on_drag_drop_area_drag_started"] [connection signal="drag_started" from="VBoxContainer/TopMarginContainer/DragDropArea" to="." method="_on_drag_drop_area_drag_started"] diff --git a/addons/block_code/ui/blocks/parameter_block/parameter_block.gd b/addons/block_code/ui/blocks/parameter_block/parameter_block.gd index f12ebf1b..e81408fd 100644 --- a/addons/block_code/ui/blocks/parameter_block/parameter_block.gd +++ b/addons/block_code/ui/blocks/parameter_block/parameter_block.gd @@ -6,28 +6,28 @@ const Constants = preload("res://addons/block_code/ui/constants.gd") const Util = preload("res://addons/block_code/ui/util.gd") const ParameterOutput = preload("res://addons/block_code/ui/blocks/utilities/parameter_output/parameter_output.gd") -@onready var _panel := $Panel +@onready var _background := %Background var args_to_add_after_format: Dictionary # Only used when loading var spawned_by: ParameterOutput -var _panel_normal: StyleBox -var _panel_focus: StyleBox - func _ready(): super() + _background.color = color + _update_block_shape() + - _panel_normal = _panel.get_theme_stylebox("panel").duplicate() - _panel_normal.bg_color = color - _panel_normal.border_color = color.darkened(0.2) +func _on_definition_changed(): + super() + _update_block_shape() - _panel_focus = _panel.get_theme_stylebox("panel").duplicate() - _panel_focus.bg_color = color - _panel_focus.border_color = Constants.FOCUS_BORDER_COLOR - if not Util.node_is_part_of_edited_scene(self): - _panel.add_theme_stylebox_override("panel", _panel_normal) +func _update_block_shape(): + if not definition: + return + await ready + _background.is_pointy_value = definition.variant_type == TYPE_BOOL func _on_drag_drop_area_drag_started(offset: Vector2) -> void: @@ -40,11 +40,3 @@ static func get_block_class(): static func get_scene_path(): return "res://addons/block_code/ui/blocks/parameter_block/parameter_block.tscn" - - -func _on_focus_entered(): - _panel.add_theme_stylebox_override("panel", _panel_focus) - - -func _on_focus_exited(): - _panel.add_theme_stylebox_override("panel", _panel_normal) diff --git a/addons/block_code/ui/blocks/parameter_block/parameter_block.tscn b/addons/block_code/ui/blocks/parameter_block/parameter_block.tscn index 4109d0c8..8515b87c 100644 --- a/addons/block_code/ui/blocks/parameter_block/parameter_block.tscn +++ b/addons/block_code/ui/blocks/parameter_block/parameter_block.tscn @@ -2,19 +2,9 @@ [ext_resource type="Script" path="res://addons/block_code/ui/blocks/parameter_block/parameter_block.gd" id="1_0hajy"] [ext_resource type="PackedScene" uid="uid://c7puyxpqcq6xo" path="res://addons/block_code/ui/blocks/utilities/drag_drop_area/drag_drop_area.tscn" id="2_0eadx"] +[ext_resource type="Script" path="res://addons/block_code/ui/blocks/utilities/background/background.gd" id="2_oimwh"] [ext_resource type="PackedScene" uid="uid://b1xvp3u11h41s" path="res://addons/block_code/ui/blocks/utilities/template_editor/template_editor.tscn" id="3_shl1a"] -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_dbera"] -bg_color = Color(1, 1, 1, 1) -border_width_left = 3 -border_width_top = 3 -border_width_right = 3 -border_width_bottom = 3 -corner_radius_top_left = 16 -corner_radius_top_right = 16 -corner_radius_bottom_right = 16 -corner_radius_bottom_left = 16 - [node name="ParameterBlock" type="MarginContainer" node_paths=PackedStringArray("template_editor")] offset_right = 16.0 offset_bottom = 8.0 @@ -24,10 +14,13 @@ mouse_filter = 2 script = ExtResource("1_0hajy") template_editor = NodePath("MarginContainer/TemplateEditor") -[node name="Panel" type="Panel" parent="."] +[node name="Background" type="Control" parent="."] unique_name_in_owner = true layout_mode = 2 -theme_override_styles/panel = SubResource("StyleBoxFlat_dbera") +script = ExtResource("2_oimwh") +color = Color(1, 1, 1, 1) +block_type = 3 +is_pointy_value = null [node name="DragDropArea" parent="." instance=ExtResource("2_0eadx")] layout_mode = 2 @@ -36,6 +29,8 @@ mouse_default_cursor_shape = 2 [node name="MarginContainer" type="MarginContainer" parent="."] layout_mode = 2 mouse_filter = 2 +theme_override_constants/margin_left = 10 +theme_override_constants/margin_right = 10 [node name="TemplateEditor" parent="MarginContainer" instance=ExtResource("3_shl1a")] unique_name_in_owner = true diff --git a/addons/block_code/ui/blocks/utilities/background/background.gd b/addons/block_code/ui/blocks/utilities/background/background.gd index 11f79667..769185b9 100644 --- a/addons/block_code/ui/blocks/utilities/background/background.gd +++ b/addons/block_code/ui/blocks/utilities/background/background.gd @@ -23,6 +23,10 @@ var parent_block: Block @export var control_part: ControlPart = ControlPart.TOP: set = _set_control_part +## Only relevant if block_type is VALUE. +@export var is_pointy_value: bool = false: + set = _set_is_pointy_value + func _set_color(new_color): color = new_color @@ -40,6 +44,11 @@ func _set_control_part(new_control_part): queue_redraw() +func _set_is_pointy_value(new_is_pointy_value): + is_pointy_value = new_is_pointy_value + queue_redraw() + + func _ready(): parent_block = BlockTreeUtil.get_parent_block(self) parent_block.focus_entered.connect(queue_redraw) @@ -77,9 +86,29 @@ func _get_knob_shape(displacement: Vector2 = Vector2.ZERO) -> PackedVector2Array func _get_entry_shape() -> PackedVector2Array: var box_shape = _get_box_shape(size) + var ellipsis = PackedVector2Array( + [ + Vector2(5, -4.012612), + Vector2(10, -7.240165), + Vector2(15, -9.822201), + Vector2(20, -11.84718), + Vector2(25, -13.37339), + Vector2(30, -14.43944), + Vector2(35, -15.06994), + Vector2(40, -15.27864), + Vector2(45, -15.06994), + Vector2(50, -14.43944), + Vector2(55, -13.37339), + Vector2(60, -11.84718), + Vector2(65, -9.822201), + Vector2(70, -7.240165), + Vector2(75, -4.012612), + Vector2(80, 0), + ] + ) var bottom_knob_shape = _get_knob_shape(Vector2(Constants.KNOB_X, size.y)) bottom_knob_shape.reverse() - return box_shape.slice(0, 3) + bottom_knob_shape + box_shape.slice(3) + return box_shape.slice(0, 1) + ellipsis + box_shape.slice(1, 3) + bottom_knob_shape + box_shape.slice(3) func _get_statement_shape() -> PackedVector2Array: @@ -90,6 +119,73 @@ func _get_statement_shape() -> PackedVector2Array: return box_shape.slice(0, 1) + top_knob_shape + box_shape.slice(1, 3) + bottom_knob_shape + box_shape.slice(3) +# Note: This is a especial case of _get_round_value_shape() with resolution = 2, +# but it's easier this way. +func _get_pointy_value_shape() -> PackedVector2Array: + var radius_x = min(size.x, size.y) / 2 + var radius_y = max(radius_x, size.y / 2) + return PackedVector2Array( + [ + Vector2(radius_x, 0), + Vector2(size.x - radius_x, 0), + Vector2(size.x, radius_y), + Vector2(size.x - radius_x, size.y), + Vector2(radius_x, size.y), + Vector2(0, radius_y), + Vector2(radius_x, 0), + ] + ) + + +func _get_round_value_shape() -> PackedVector2Array: + # Normally radius_y will be equal to radius_x. But if the block is more vertical + # than horizontal, we'll have to deform the arc shapes. + var radius_x = min(size.x, size.y) / 2 + var radius_y = max(radius_x, size.y / 2) + + var right_arc = [] + for i in range(Constants.ROUND_RESOLUTION): + var angle = -PI / 2 + PI * i / Constants.ROUND_RESOLUTION + ( + right_arc + . append( + Vector2( + cos(angle) * radius_x + size.x - radius_x, + (sin(angle) + 1) * radius_y, + ) + ) + ) + var left_arc = [] + for i in range(Constants.ROUND_RESOLUTION): + var angle = PI / 2 + PI * i / Constants.ROUND_RESOLUTION + ( + left_arc + . append( + Vector2( + (cos(angle) + 1) * radius_x, + (sin(angle) + 1) * radius_y, + ) + ) + ) + return PackedVector2Array( + ( + [ + Vector2(radius_x, 0), + Vector2(size.x - radius_x, 0), + ] + + right_arc + + [ + Vector2(size.x - radius_x, size.y), + Vector2(radius_x, size.y), + ] + + left_arc + + [ + Vector2(radius_x, 0), + ] + ) + ) + + func _get_control_top_fill_shape() -> PackedVector2Array: var box_shape = _get_box_shape(size) var top_knob_shape = _get_knob_shape(Vector2(Constants.KNOB_X, 0.0)) @@ -131,6 +227,14 @@ func _draw(): var shape = _get_statement_shape() fill_polygon = shape stroke_polygon = shape + Types.BlockType.VALUE: + var shape + if is_pointy_value: + shape = _get_pointy_value_shape() + else: + shape = _get_round_value_shape() + fill_polygon = shape + stroke_polygon = shape Types.BlockType.CONTROL: if control_part == ControlPart.TOP: fill_polygon = _get_control_top_fill_shape() 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 29db8b1c..4c9d9d41 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 @@ -21,7 +21,7 @@ var default_value: Variant var _drag_start: Vector2 = Vector2.INF -@onready var _panel := %Panel +@onready var _background := %Background @onready var snap_point := %SnapPoint @onready var _input_switcher := %InputSwitcher @@ -68,7 +68,7 @@ func set_raw_input(raw_input: Variant): match variant_type: TYPE_COLOR: _color_input.color = raw_input - _update_panel_bg_color(raw_input) + _update_background_color(raw_input) TYPE_VECTOR2: # Rounding because floats are doubles by default but Vector2s have single components _x_line_edit.text = ("%.4f" % raw_input.x).rstrip("0").rstrip(".") if raw_input != null else "" @@ -140,8 +140,7 @@ func _set_placeholder(new_placeholder: String) -> void: func _ready(): - var stylebox = _panel.get_theme_stylebox("panel") - stylebox.bg_color = Color.WHITE + _background.color = Color.WHITE _set_placeholder(placeholder) _set_option_data(option_data) @@ -224,7 +223,8 @@ func _update_visible_input(): func _switch_input(node: Node): for c in _input_switcher.get_children(): c.visible = c == node - _panel.visible = node not in [_option_input] + _background.visible = node not in [_option_input, null] + _background.is_pointy_value = node == _bool_input func _update_option_input(current_value: Variant = null): @@ -276,14 +276,12 @@ func _update_option_input(current_value: Variant = null): func _on_color_input_color_changed(color): - _update_panel_bg_color(color) + _update_background_color(color) modified.emit() -func _update_panel_bg_color(new_color): - var stylebox = _panel.get_theme_stylebox("panel").duplicate() - stylebox.bg_color = new_color - _panel.add_theme_stylebox_override("panel", stylebox) +func _update_background_color(new_color): + _background.color = new_color func _on_option_input_item_selected(index): diff --git a/addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.tscn b/addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.tscn index a243ac9a..c4949f7b 100644 --- a/addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.tscn +++ b/addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.tscn @@ -3,13 +3,7 @@ [ext_resource type="Script" path="res://addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.gd" id="1_rgmxn"] [ext_resource type="PackedScene" uid="uid://c7puyxpqcq6xo" path="res://addons/block_code/ui/blocks/utilities/drag_drop_area/drag_drop_area.tscn" id="2_05gck"] [ext_resource type="PackedScene" uid="uid://b1oge52xhjqnu" path="res://addons/block_code/ui/blocks/utilities/snap_point/snap_point.tscn" id="2_6esp3"] - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_tn6h4"] -bg_color = Color(1, 1, 1, 1) -corner_radius_top_left = 40 -corner_radius_top_right = 40 -corner_radius_bottom_right = 40 -corner_radius_bottom_left = 40 +[ext_resource type="Script" path="res://addons/block_code/ui/blocks/utilities/background/background.gd" id="2_68spp"] [sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_afyv2"] @@ -41,11 +35,11 @@ grow_vertical = 2 mouse_filter = 2 script = ExtResource("1_rgmxn") -[node name="Panel" type="Panel" parent="."] +[node name="Background" type="Control" parent="."] unique_name_in_owner = true layout_mode = 2 -mouse_filter = 2 -theme_override_styles/panel = SubResource("StyleBoxFlat_tn6h4") +script = ExtResource("2_68spp") +block_type = 3 [node name="InputSwitcher" type="MarginContainer" parent="."] unique_name_in_owner = true diff --git a/addons/block_code/ui/constants.gd b/addons/block_code/ui/constants.gd index edfb077a..66c8cf1c 100644 --- a/addons/block_code/ui/constants.gd +++ b/addons/block_code/ui/constants.gd @@ -10,8 +10,11 @@ const CONTROL_MARGIN = 20.0 const OUTLINE_WIDTH = 3.0 const MINIMUM_SNAP_DISTANCE = 80.0 const MINIMUM_DRAG_THRESHOLD = 25 +const ROUND_RESOLUTION = 10 const FOCUS_BORDER_COLOR = Color(225, 242, 0) +const DRAG_REMOVE_COLOR = Color(1, 1, 1, 0.5) +const DRAG_PREVIEW_COLOR = Color(225, 242, 0, 0.3) ## Properties for builtin categories. Order starts at 10 for the first ## category and then are separated by 10 to allow custom categories to