From e3eabc9fd771b21ededeaeb1ebb690c634fb2348 Mon Sep 17 00:00:00 2001 From: Daze Date: Wed, 27 Nov 2024 22:16:03 -0300 Subject: [PATCH 1/5] Entry block: Change top of shape to ellipsis To make entry blocks more distinguishable from the parameter blocks. Add another drag area, a rectangle that approximates the added ellipsis part. So the block can also be dragged from it. This drag area has a fixed size and doesn't expand. https://github.com/endlessm/godot-block-coding/issues/278 --- .../ui/blocks/entry_block/entry_block.tscn | 7 ++++++ .../blocks/utilities/background/background.gd | 22 ++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) 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/utilities/background/background.gd b/addons/block_code/ui/blocks/utilities/background/background.gd index 11f79667..182f8862 100644 --- a/addons/block_code/ui/blocks/utilities/background/background.gd +++ b/addons/block_code/ui/blocks/utilities/background/background.gd @@ -77,9 +77,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: From 706e9f91b34cc9c245182b0b96a929af1d7cb32c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= Date: Mon, 2 Dec 2024 17:40:21 -0300 Subject: [PATCH 2/5] Parameter block and input: Use custom shape Previously the parameter block and parameter input had a Panel node. Unlike the other blocks which had a custom shape, provided by the background control. But in the next commit we want to have different shapes for value blocks. So remove the panels and add background control nodes intead. --- .../blocks/parameter_block/parameter_block.gd | 25 +-------- .../parameter_block/parameter_block.tscn | 20 +++---- .../blocks/utilities/background/background.gd | 53 +++++++++++++++++++ .../parameter_input/parameter_input.gd | 17 +++--- .../parameter_input/parameter_input.tscn | 14 ++--- addons/block_code/ui/constants.gd | 1 + 6 files changed, 74 insertions(+), 56 deletions(-) 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..6246125c 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,15 @@ 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() - - _panel_normal = _panel.get_theme_stylebox("panel").duplicate() - _panel_normal.bg_color = color - _panel_normal.border_color = color.darkened(0.2) - - _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) + _background.color = color func _on_drag_drop_area_drag_started(offset: Vector2) -> void: @@ -40,11 +27,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..0e95b299 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,12 @@ 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 [node name="DragDropArea" parent="." instance=ExtResource("2_0eadx")] layout_mode = 2 @@ -36,6 +28,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 182f8862..56475150 100644 --- a/addons/block_code/ui/blocks/utilities/background/background.gd +++ b/addons/block_code/ui/blocks/utilities/background/background.gd @@ -110,6 +110,55 @@ 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) +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)) @@ -151,6 +200,10 @@ func _draw(): var shape = _get_statement_shape() fill_polygon = shape stroke_polygon = shape + Types.BlockType.VALUE: + var 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..a569bf52 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,7 @@ 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] func _update_option_input(current_value: Variant = null): @@ -276,14 +275,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..412a3ad3 100644 --- a/addons/block_code/ui/constants.gd +++ b/addons/block_code/ui/constants.gd @@ -10,6 +10,7 @@ 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) From 9a3ea49995a4e6b4b9c60d968a898bcf5daa239f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= Date: Wed, 4 Dec 2024 15:16:39 -0300 Subject: [PATCH 3/5] Background: Add safety check for parent block Mainly to test the background in isolation in a new Control scene. --- addons/block_code/ui/blocks/utilities/background/background.gd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/block_code/ui/blocks/utilities/background/background.gd b/addons/block_code/ui/blocks/utilities/background/background.gd index 56475150..6c21f85f 100644 --- a/addons/block_code/ui/blocks/utilities/background/background.gd +++ b/addons/block_code/ui/blocks/utilities/background/background.gd @@ -47,7 +47,7 @@ func _ready(): func _get_border_color() -> Color: - if parent_block.has_focus(): + if parent_block and parent_block.has_focus(): return Constants.FOCUS_BORDER_COLOR return outline_color From 8ee8da8db86c53cc97ec2b901203049161f0fa5b Mon Sep 17 00:00:00 2001 From: Daze Date: Wed, 4 Dec 2024 15:49:11 -0300 Subject: [PATCH 4/5] Pointy shape for booleans Use a custom background drawing for parameter blocks and input that are of type boolean. https://github.com/endlessm/godot-block-coding/issues/279 --- .../blocks/parameter_block/parameter_block.gd | 13 +++++++ .../parameter_block/parameter_block.tscn | 1 + .../blocks/utilities/background/background.gd | 35 +++++++++++++++++-- .../parameter_input/parameter_input.gd | 3 +- 4 files changed, 49 insertions(+), 3 deletions(-) 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 6246125c..e81408fd 100644 --- a/addons/block_code/ui/blocks/parameter_block/parameter_block.gd +++ b/addons/block_code/ui/blocks/parameter_block/parameter_block.gd @@ -15,6 +15,19 @@ var spawned_by: ParameterOutput func _ready(): super() _background.color = color + _update_block_shape() + + +func _on_definition_changed(): + super() + _update_block_shape() + + +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: 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 0e95b299..8515b87c 100644 --- a/addons/block_code/ui/blocks/parameter_block/parameter_block.tscn +++ b/addons/block_code/ui/blocks/parameter_block/parameter_block.tscn @@ -20,6 +20,7 @@ layout_mode = 2 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 diff --git a/addons/block_code/ui/blocks/utilities/background/background.gd b/addons/block_code/ui/blocks/utilities/background/background.gd index 6c21f85f..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) @@ -47,7 +56,7 @@ func _ready(): func _get_border_color() -> Color: - if parent_block and parent_block.has_focus(): + if parent_block.has_focus(): return Constants.FOCUS_BORDER_COLOR return outline_color @@ -110,6 +119,24 @@ 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. @@ -201,7 +228,11 @@ func _draw(): fill_polygon = shape stroke_polygon = shape Types.BlockType.VALUE: - var shape = _get_round_value_shape() + 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: 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 a569bf52..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 @@ -223,7 +223,8 @@ func _update_visible_input(): func _switch_input(node: Node): for c in _input_switcher.get_children(): c.visible = c == node - _background.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): From f3c1e45aa1ea0558a00271faee11489925f975d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= Date: Wed, 4 Dec 2024 16:16:56 -0300 Subject: [PATCH 5/5] Fix drag preview shape Previously all blocks had a statement shape as drag preview. Now that we have a good mapping of blocks / shapes, use the corresponding shape. A especial case is the control block which uses the background twice, one for the top part and one for the bottom part. For simplicity, use the statement shape in this case. Also, move drag colors to constants. --- addons/block_code/drag_manager/drag.gd | 12 ++++++++++-- addons/block_code/ui/constants.gd | 2 ++ 2 files changed, 12 insertions(+), 2 deletions(-) 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/constants.gd b/addons/block_code/ui/constants.gd index 412a3ad3..66c8cf1c 100644 --- a/addons/block_code/ui/constants.gd +++ b/addons/block_code/ui/constants.gd @@ -13,6 +13,8 @@ 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