From 6daa3ca4f369a44d81146c471b7f58833cce9b70 Mon Sep 17 00:00:00 2001 From: Dylan McCall Date: Wed, 25 Sep 2024 15:56:08 -0700 Subject: [PATCH] ParameterInput: Detect click & drag gestures If the user clicks and drags inside ParameterInput, start dragging the parent block. This makes it easier to manipulate blocks which contain a large number of parameter input widgets. --- addons/block_code/ui/blocks/block/block.gd | 6 ++++ .../parameter_input/parameter_input.gd | 35 +++++++++++++++++++ .../parameter_input/parameter_input.tscn | 2 ++ .../template_editor/template_editor.gd | 6 ++++ addons/block_code/ui/constants.gd | 1 + 5 files changed, 50 insertions(+) diff --git a/addons/block_code/ui/blocks/block/block.gd b/addons/block_code/ui/blocks/block/block.gd index 4cc09f0d..2902f330 100644 --- a/addons/block_code/ui/blocks/block/block.gd +++ b/addons/block_code/ui/blocks/block/block.gd @@ -78,12 +78,18 @@ func _update_template_editor(): template_editor.parameter_defaults = _get_parameter_defaults() if not template_editor.modified.is_connected(_on_template_editor_modified): template_editor.modified.connect(_on_template_editor_modified) + if not template_editor.drag_started.is_connected(_on_template_editor_drag_started): + template_editor.drag_started.connect(_on_template_editor_drag_started) func _on_template_editor_modified(): modified.emit() +func _on_template_editor_drag_started(): + _drag_started() + + func _get_format_string() -> String: if not definition: return "" 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 11004dde..9ef24f36 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 @@ -1,6 +1,9 @@ @tool extends MarginContainer +signal drag_started + +const Constants = preload("res://addons/block_code/ui/constants.gd") const OptionData = preload("res://addons/block_code/code_generation/option_data.gd") const Types = preload("res://addons/block_code/types/types.gd") @@ -16,6 +19,9 @@ signal modified var default_value: Variant +var _drag_start: Vector2 = Vector2.INF +var _is_dragging: bool = false + @onready var _panel := %Panel @onready var snap_point := %SnapPoint @onready var _input_switcher := %InputSwitcher @@ -283,3 +289,32 @@ func _on_option_input_item_selected(index): func _on_snap_point_snapped_block_changed(block): _update_visible_input() + + +func _input(event: InputEvent) -> void: + if snap_point.has_snapped_block(): + return + + if event is InputEventMouseButton: + var button_event: InputEventMouseButton = event as InputEventMouseButton + + if button_event.button_index != MOUSE_BUTTON_LEFT: + return + + if button_event.double_click: + # Double click event (with the mouse released) has both pressed=true + # and double_click=true, so ignore it as a special case. + pass + elif button_event.pressed and get_global_rect().has_point(button_event.global_position): + # Keep track of where the mouse click originated, but allow this + # event to propagate to other nodes. + _drag_start = event.global_position + else: + _drag_start = Vector2.INF + elif _drag_start != Vector2.INF and event is InputEventMouseMotion: + var motion_event: InputEventMouseMotion = event as InputEventMouseMotion + + if not get_global_rect().has_point(event.global_position) and _drag_start.distance_to(event.global_position) > Constants.MINIMUM_DRAG_THRESHOLD: + get_viewport().set_input_as_handled() + drag_started.emit() + _drag_start = Vector2.INF 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 5ed2066e..747d8cea 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 @@ -87,6 +87,7 @@ custom_minimum_size = Vector2(40, 0) layout_mode = 2 tooltip_text = "Parameter" theme_override_styles/normal = SubResource("StyleBoxEmpty_fjquj") +action_mode = 1 fit_to_longest_item = false [node name="Vector2Input" type="MarginContainer" parent="InputSwitcher"] @@ -171,6 +172,7 @@ theme_override_colors/font_focus_color = Color(0, 0, 0, 1) theme_override_colors/font_color = Color(0, 0, 0, 1) theme_override_styles/focus = SubResource("StyleBoxEmpty_e7f0k") theme_override_styles/normal = SubResource("StyleBoxEmpty_fjquj") +action_mode = 1 selected = 0 item_count = 2 popup/item_0/text = "False" 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 ff8e2ec0..a4863f74 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 @@ -2,6 +2,7 @@ class_name TemplateEditor extends Container +signal drag_started signal modified const BlockDefinition = preload("res://addons/block_code/code_generation/block_definition.gd") @@ -113,6 +114,7 @@ func _append_input_parameter(parameter: Dictionary, id: int): parameter_input.name = "ParameterInput%d" % id parameter_input.placeholder = parameter["name"] parameter_input.variant_type = parameter["type"] + parameter_input.drag_started.connect(_on_parameter_input_drag_started) if default_value is OptionData: var option_data := default_value as OptionData @@ -136,3 +138,7 @@ func _append_output_parameter(parameter: Dictionary, id: int): parameter_output.block = parent_block parameter_output.parameter_name = parameter["name"] _container.add_child(parameter_output) + + +func _on_parameter_input_drag_started(): + drag_started.emit() diff --git a/addons/block_code/ui/constants.gd b/addons/block_code/ui/constants.gd index 04e86325..ca8e95b5 100644 --- a/addons/block_code/ui/constants.gd +++ b/addons/block_code/ui/constants.gd @@ -9,6 +9,7 @@ const KNOB_Z = 5.0 const CONTROL_MARGIN = 20.0 const OUTLINE_WIDTH = 3.0 const MINIMUM_SNAP_DISTANCE = 80.0 +const MINIMUM_DRAG_THRESHOLD = 25 const FOCUS_BORDER_COLOR = Color(225, 242, 0)