From 4e7d5d34cfc6286c3fa27321787c9da1d862dde8 Mon Sep 17 00:00:00 2001 From: Emmanouil Papadeas Date: Tue, 21 Mar 2023 16:36:25 +0200 Subject: [PATCH] Keep aspect ratio when resizing a selection with gizmos, if the button is pressed next to the ValueSliders Also fixes a bug with the inconsistent behavior caused by resizing a selection with gizmos without pressing Shift, while the keep ratio button was pressed. --- src/Tools/SelectionTools/SelectionTool.gd | 18 ++++++++++++++++-- src/Tools/SelectionTools/SelectionTool.tscn | 1 + src/UI/Canvas/Selection.gd | 3 ++- src/UI/Nodes/ValueSliderV2.gd | 8 +++++++- src/UI/Nodes/ValueSliderV2.tscn | 1 + 5 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/Tools/SelectionTools/SelectionTool.gd b/src/Tools/SelectionTools/SelectionTool.gd index 2a97b1744..148524b72 100644 --- a/src/Tools/SelectionTools/SelectionTool.gd +++ b/src/Tools/SelectionTools/SelectionTool.gd @@ -20,6 +20,7 @@ var _intersect := false # Shift + Ctrl + Mouse Click # Used to check if the state of content transformation has been changed # while draw_move() is being called. For example, pressing Enter while still moving content var _content_transformation_check := false +var _skip_slider_logic := false onready var selection_node: Node2D = Global.canvas.selection onready var position_sliders := $Position as ValueSliderV2 @@ -58,11 +59,16 @@ func update_config() -> void: func set_spinbox_values() -> void: + _skip_slider_logic = true var select_rect: Rect2 = selection_node.big_bounding_rectangle - position_sliders.editable = !select_rect.has_no_area() + var has_selection := not select_rect.has_no_area() + if not has_selection: + size_sliders.press_ratio_button(false) + position_sliders.editable = has_selection position_sliders.value = select_rect.position - size_sliders.editable = position_sliders.editable + size_sliders.editable = has_selection size_sliders.value = select_rect.size + _skip_slider_logic = false func draw_start(position: Vector2) -> void: @@ -222,6 +228,8 @@ func _set_cursor_text(rect: Rect2) -> void: func _on_Position_value_changed(value: Vector2) -> void: + if _skip_slider_logic: + return var project: Project = Global.current_project if !project.has_selection: return @@ -239,6 +247,8 @@ func _on_Position_value_changed(value: Vector2) -> void: func _on_Size_value_changed(value: Vector2) -> void: + if _skip_slider_logic: + return if !Global.current_project.has_selection: return @@ -249,6 +259,10 @@ func _on_Size_value_changed(value: Vector2) -> void: selection_node.resize_selection() +func _on_Size_ratio_toggled(button_pressed: bool) -> void: + selection_node.resize_keep_ratio = button_pressed + + func _on_Timer_timeout() -> void: if !selection_node.is_moving_content: selection_node.commit_undo("Move Selection", undo_data) diff --git a/src/Tools/SelectionTools/SelectionTool.tscn b/src/Tools/SelectionTools/SelectionTool.tscn index 49379f365..8972b8bf3 100644 --- a/src/Tools/SelectionTools/SelectionTool.tscn +++ b/src/Tools/SelectionTools/SelectionTool.tscn @@ -56,5 +56,6 @@ one_shot = true [connection signal="item_selected" from="Modes" to="." method="_on_Modes_item_selected"] [connection signal="value_changed" from="Position" to="." method="_on_Position_value_changed"] +[connection signal="ratio_toggled" from="Size" to="." method="_on_Size_ratio_toggled"] [connection signal="value_changed" from="Size" to="." method="_on_Size_value_changed"] [connection signal="timeout" from="Timer" to="." method="_on_Timer_timeout"] diff --git a/src/UI/Canvas/Selection.gd b/src/UI/Canvas/Selection.gd index 5aa2b1d31..c2f15b5f1 100644 --- a/src/UI/Canvas/Selection.gd +++ b/src/UI/Canvas/Selection.gd @@ -27,6 +27,7 @@ var gizmos := [] # Array of Gizmos var dragged_gizmo: Gizmo = null var prev_angle := 0 var mouse_pos_on_gizmo_drag := Vector2.ZERO +var resize_keep_ratio := false onready var canvas: Canvas = get_parent() onready var marching_ants_outline: Sprite = $MarchingAntsOutline @@ -310,7 +311,7 @@ func _gizmo_resize() -> void: else: _resize_rect(canvas.current_pixel, dir) - if Input.is_action_pressed("shape_perfect"): # Maintain aspect ratio + if Input.is_action_pressed("shape_perfect") or resize_keep_ratio: # Maintain aspect ratio var end_y := temp_rect.end.y if dir == Vector2(1, -1) or dir.x == 0: # Top right corner, center top and center bottom var size := temp_rect.size.y diff --git a/src/UI/Nodes/ValueSliderV2.gd b/src/UI/Nodes/ValueSliderV2.gd index 055690b0d..da483296e 100644 --- a/src/UI/Nodes/ValueSliderV2.gd +++ b/src/UI/Nodes/ValueSliderV2.gd @@ -3,6 +3,7 @@ class_name ValueSliderV2 extends HBoxContainer signal value_changed(value) +signal ratio_toggled(button_pressed) export var editable := true setget _set_editable export var value := Vector2.ZERO setget _set_value @@ -35,6 +36,10 @@ func get_sliders() -> Array: return [$GridContainer/X, $GridContainer/Y] +func press_ratio_button(pressed: bool) -> void: + $"%RatioButton".pressed = pressed + + # Greatest common divisor func _gcd(a: int, b: int) -> int: return a if b == 0 else _gcd(b, a % b) @@ -63,6 +68,7 @@ func _on_RatioButton_toggled(button_pressed: bool) -> void: ratio = Vector2.ONE else: ratio = value / divisor + emit_signal("ratio_toggled", button_pressed) # Setters @@ -72,7 +78,7 @@ func _set_editable(val: bool) -> void: editable = val for slider in get_sliders(): slider.editable = val - $Ratio/RatioButton.disabled = not val + $"%RatioButton".disabled = not val func _set_value(val: Vector2) -> void: diff --git a/src/UI/Nodes/ValueSliderV2.tscn b/src/UI/Nodes/ValueSliderV2.tscn index 817770bdf..c84d8f6de 100644 --- a/src/UI/Nodes/ValueSliderV2.tscn +++ b/src/UI/Nodes/ValueSliderV2.tscn @@ -64,6 +64,7 @@ patch_margin_top = 15 patch_margin_bottom = 13 [node name="RatioButton" type="TextureButton" parent="Ratio" groups=["UIButtons"]] +unique_name_in_owner = true anchor_left = 0.5 anchor_top = 0.5 anchor_right = 0.5