diff --git a/src/Tools/CropTool.gd b/src/Tools/CropTool.gd index 758fbd3d7..ea245cb7e 100644 --- a/src/Tools/CropTool.gd +++ b/src/Tools/CropTool.gd @@ -1,10 +1,11 @@ extends BaseTool # Crop Tool, allows you to resize the canvas interactively -var _offset = Vector2.ZERO +var _offset := Vector2.ZERO var _crop: CropRect var _start_pos: Vector2 var _syncing := false +var _locked_ratio := false func _ready() -> void: @@ -29,28 +30,24 @@ func draw_move(position: Vector2) -> void: if _crop.locked_size: _crop.rect.position = position - _offset else: - match _crop.mode: - CropRect.Mode.MARGINS, CropRect.Mode.POSITION_SIZE: - _crop.rect.position.x = min(_start_pos.x, position.x) - _crop.rect.position.y = min(_start_pos.y, position.y) - _crop.rect.end.x = max(_start_pos.x, position.x) - _crop.rect.end.y = max(_start_pos.y, position.y) - CropRect.Mode.LOCKED_ASPECT_RATIO: - var distance = abs(_start_pos.x - position.x) + abs(_start_pos.y - position.y) - _crop.rect.size.x = round( - distance * _crop.ratio.x / (_crop.ratio.x + _crop.ratio.y) - ) - _crop.rect.size.y = round( - distance * _crop.ratio.y / (_crop.ratio.x + _crop.ratio.y) - ) - if _start_pos.x < position.x: - _crop.rect.position.x = _start_pos.x - else: - _crop.rect.position.x = _start_pos.x - _crop.rect.size.x - if _start_pos.y < position.y: - _crop.rect.position.y = _start_pos.y - else: - _crop.rect.position.y = _start_pos.y - _crop.rect.size.y + if _crop.mode == CropRect.Mode.POSITION_SIZE and _locked_ratio: + var ratio: Vector2 = $"%Size".ratio + var distance := abs(_start_pos.x - position.x) + abs(_start_pos.y - position.y) + _crop.rect.size.x = round(distance * ratio.x / (ratio.x + ratio.y)) + _crop.rect.size.y = round(distance * ratio.y / (ratio.x + ratio.y)) + if _start_pos.x < position.x: + _crop.rect.position.x = _start_pos.x + else: + _crop.rect.position.x = _start_pos.x - _crop.rect.size.x + if _start_pos.y < position.y: + _crop.rect.position.y = _start_pos.y + else: + _crop.rect.position.y = _start_pos.y - _crop.rect.size.y + else: + _crop.rect.position.x = min(_start_pos.x, position.x) + _crop.rect.position.y = min(_start_pos.y, position.y) + _crop.rect.end.x = max(_start_pos.x, position.x) + _crop.rect.end.y = max(_start_pos.y, position.y) # Ensure that the size is at least 1: _crop.rect.size.x = max(1, _crop.rect.size.x) _crop.rect.size.y = max(1, _crop.rect.size.y) @@ -69,12 +66,6 @@ func _sync_ui() -> void: $"%DimensionsLabel".show() CropRect.Mode.POSITION_SIZE: $"%MarginsContainer".hide() - $"%RatioContainer".hide() - $"%PosSizeContainer".show() - $"%DimensionsLabel".hide() - CropRect.Mode.LOCKED_ASPECT_RATIO: - $"%MarginsContainer".hide() - $"%RatioContainer".show() $"%PosSizeContainer".show() $"%DimensionsLabel".hide() @@ -87,17 +78,10 @@ func _sync_ui() -> void: $"%Left".value = _crop.rect.position.x $"%Right".value = _crop.rect.end.x - $"%RatioX".value = _crop.ratio.x - $"%RatioY".value = _crop.ratio.y - - $"%PositionX".max_value = Global.current_project.size.x - 1 - $"%PositionY".max_value = Global.current_project.size.y - 1 - $"%Width".max_value = Global.current_project.size.x - $"%Height".max_value = Global.current_project.size.y - $"%PositionX".value = _crop.rect.position.x - $"%PositionY".value = _crop.rect.position.y - $"%Width".value = _crop.rect.size.x - $"%Height".value = _crop.rect.size.y + $"%Position".max_value = Global.current_project.size - Vector2.ONE + $"%Size".max_value = Global.current_project.size + $"%Position".value = _crop.rect.position + $"%Size".value = _crop.rect.size $"%DimensionsLabel".text = str(_crop.rect.size.x, " x ", _crop.rect.size.y) _syncing = false @@ -161,49 +145,40 @@ func _on_Right_value_changed(value: float) -> void: func _on_RatioX_value_changed(value: float) -> void: if _syncing: return - _crop.rect.size.x = round(max(1, _crop.rect.size.y / _crop.ratio.y * value)) - _crop.ratio.x = value + var prev_ratio: Vector2 = $"%Size".ratio + $"%Size".ratio.x = value + _crop.rect.size.x = round(max(1, _crop.rect.size.y / prev_ratio.y * value)) _crop.emit_signal("updated") func _on_RatioY_value_changed(value: float) -> void: if _syncing: return - _crop.rect.size.y = round(max(1, _crop.rect.size.x / _crop.ratio.x * value)) - _crop.ratio.y = value + var prev_ratio: Vector2 = $"%Size".ratio + $"%Size".ratio.y = value + _crop.rect.size.y = round(max(1, _crop.rect.size.x / prev_ratio.x * value)) _crop.emit_signal("updated") -func _on_PositionX_value_changed(value: float) -> void: +func _on_Position_value_changed(value: Vector2) -> void: if _syncing: return - _crop.rect.position.x = value + _crop.rect.position = value _crop.emit_signal("updated") -func _on_PositionY_value_changed(value: float) -> void: +func _on_Size_value_changed(value: Vector2) -> void: if _syncing: return - _crop.rect.position.y = value + _crop.rect.size = value _crop.emit_signal("updated") -func _on_Width_value_changed(value: float) -> void: - if _syncing: - return - if _crop.mode == CropRect.Mode.LOCKED_ASPECT_RATIO: - _crop.rect.size.y = round(max(1, (value / _crop.ratio.x) * _crop.ratio.y)) - _crop.rect.size.x = value - _crop.emit_signal("updated") - - -func _on_Height_value_changed(value: float) -> void: - if _syncing: - return - if _crop.mode == CropRect.Mode.LOCKED_ASPECT_RATIO: - _crop.rect.size.x = round(max(1, (value / _crop.ratio.y) * _crop.ratio.x)) - _crop.rect.size.y = value - _crop.emit_signal("updated") +func _on_Size_ratio_toggled(button_pressed: bool) -> void: + $"%RatioX".value = $"%Size".ratio.x + $"%RatioY".value = $"%Size".ratio.y + $"%RatioContainer".visible = button_pressed + _locked_ratio = button_pressed func _on_Apply_pressed() -> void: diff --git a/src/Tools/CropTool.tscn b/src/Tools/CropTool.tscn index a343c6bc4..06762bfa4 100644 --- a/src/Tools/CropTool.tscn +++ b/src/Tools/CropTool.tscn @@ -1,20 +1,21 @@ -[gd_scene load_steps=5 format=2] +[gd_scene load_steps=6 format=2] [ext_resource path="res://src/Tools/BaseTool.tscn" type="PackedScene" id=1] [ext_resource path="res://src/UI/Nodes/ValueSlider.tscn" type="PackedScene" id=2] [ext_resource path="res://src/Tools/CropTool.gd" type="Script" id=3] [ext_resource path="res://assets/graphics/misc/unlocked_size.png" type="Texture" id=4] +[ext_resource path="res://src/UI/Nodes/ValueSliderV2.tscn" type="PackedScene" id=5] [node name="ToolOptions" instance=ExtResource( 1 )] script = ExtResource( 3 ) -[node name="ModeLabel" type="Label" parent="." index="4"] +[node name="ModeLabel" type="Label" parent="." index="2"] margin_top = 26.0 margin_right = 116.0 margin_bottom = 40.0 text = "Mode:" -[node name="HBoxContainer" type="HBoxContainer" parent="." index="5"] +[node name="HBoxContainer" type="HBoxContainer" parent="." index="3"] margin_top = 44.0 margin_right = 116.0 margin_bottom = 66.0 @@ -23,10 +24,11 @@ margin_bottom = 66.0 unique_name_in_owner = true margin_right = 84.0 margin_bottom = 22.0 +mouse_default_cursor_shape = 2 size_flags_horizontal = 3 text = "Margins" clip_text = true -items = [ "Margins", null, false, 0, null, "Position + Size", null, false, 1, null, "Locked Aspect Ratio", null, false, 3, null ] +items = [ "Margins", null, false, 0, null, "Position + Size", null, false, 1, null ] selected = 0 [node name="SizeLock" type="Button" parent="HBoxContainer" index="1"] @@ -40,13 +42,14 @@ When enabled using the tool on the canvas will only move the cropping rectangle. When disabled using the tool on the canvas will draw the rectangle." focus_mode = 0 +mouse_default_cursor_shape = 2 toggle_mode = true icon = ExtResource( 4 ) __meta__ = { "_editor_description_": "" } -[node name="MarginsContainer" type="VBoxContainer" parent="." index="6"] +[node name="MarginsContainer" type="VBoxContainer" parent="." index="4"] unique_name_in_owner = true margin_top = 70.0 margin_right = 116.0 @@ -93,8 +96,9 @@ allow_greater = true allow_lesser = true prefix = "Right:" -[node name="RatioContainer" type="VBoxContainer" parent="." index="7"] +[node name="RatioContainer" type="VBoxContainer" parent="." index="5"] unique_name_in_owner = true +visible = false margin_top = 200.0 margin_right = 116.0 margin_bottom = 242.0 @@ -131,72 +135,55 @@ min_value = 1.0 value = 1.0 allow_greater = true -[node name="PosSizeContainer" type="VBoxContainer" parent="." index="8"] +[node name="PosSizeContainer" type="VBoxContainer" parent="." index="6"] unique_name_in_owner = true -margin_top = 246.0 +margin_top = 200.0 margin_right = 116.0 -margin_bottom = 390.0 +margin_bottom = 344.0 [node name="PositionLabel" type="Label" parent="PosSizeContainer" index="0"] margin_right = 116.0 margin_bottom = 14.0 text = "Position:" -[node name="PositionX" parent="PosSizeContainer" index="1" instance=ExtResource( 2 )] +[node name="Position" parent="PosSizeContainer" index="1" instance=ExtResource( 5 )] unique_name_in_owner = true margin_top = 18.0 margin_right = 116.0 -margin_bottom = 42.0 -allow_greater = true -allow_lesser = true -prefix = "X:" - -[node name="PositionY" parent="PosSizeContainer" index="2" instance=ExtResource( 2 )] -unique_name_in_owner = true -margin_top = 46.0 -margin_right = 116.0 margin_bottom = 70.0 allow_greater = true allow_lesser = true -prefix = "Y:" -[node name="SizeLabel" type="Label" parent="PosSizeContainer" index="3"] +[node name="SizeLabel" type="Label" parent="PosSizeContainer" index="2"] margin_top = 74.0 margin_right = 116.0 margin_bottom = 88.0 text = "Size:" -[node name="Width" parent="PosSizeContainer" index="4" instance=ExtResource( 2 )] +[node name="Size" parent="PosSizeContainer" index="3" instance=ExtResource( 5 )] unique_name_in_owner = true margin_top = 92.0 margin_right = 116.0 -margin_bottom = 116.0 -min_value = 1.0 -value = 1.0 -allow_greater = true -prefix = "W:" - -[node name="Height" parent="PosSizeContainer" index="5" instance=ExtResource( 2 )] -unique_name_in_owner = true -margin_top = 120.0 -margin_right = 116.0 margin_bottom = 144.0 -min_value = 1.0 -value = 1.0 +value = Vector2( 1, 1 ) +min_value = Vector2( 1, 1 ) allow_greater = true -prefix = "H:" +show_ratio = true +prefix_x = "Width:" +prefix_y = "Height:" -[node name="Apply" type="Button" parent="." index="9"] -margin_top = 394.0 +[node name="Apply" type="Button" parent="." index="7"] +margin_top = 348.0 margin_right = 116.0 -margin_bottom = 414.0 +margin_bottom = 368.0 +mouse_default_cursor_shape = 2 text = "Apply" -[node name="DimensionsLabel" type="Label" parent="." index="10"] +[node name="DimensionsLabel" type="Label" parent="." index="8"] unique_name_in_owner = true -margin_top = 418.0 +margin_top = 372.0 margin_right = 116.0 -margin_bottom = 432.0 +margin_bottom = 386.0 align = 1 [connection signal="item_selected" from="HBoxContainer/CropMode" to="." method="_on_CropMode_item_selected"] @@ -207,8 +194,7 @@ align = 1 [connection signal="value_changed" from="MarginsContainer/Right" to="." method="_on_Right_value_changed"] [connection signal="value_changed" from="RatioContainer/HBoxContainer/RatioX" to="." method="_on_RatioX_value_changed"] [connection signal="value_changed" from="RatioContainer/HBoxContainer/RatioY" to="." method="_on_RatioY_value_changed"] -[connection signal="value_changed" from="PosSizeContainer/PositionX" to="." method="_on_PositionX_value_changed"] -[connection signal="value_changed" from="PosSizeContainer/PositionY" to="." method="_on_PositionY_value_changed"] -[connection signal="value_changed" from="PosSizeContainer/Width" to="." method="_on_Width_value_changed"] -[connection signal="value_changed" from="PosSizeContainer/Height" to="." method="_on_Height_value_changed"] +[connection signal="value_changed" from="PosSizeContainer/Position" to="." method="_on_Position_value_changed"] +[connection signal="ratio_toggled" from="PosSizeContainer/Size" to="." method="_on_Size_ratio_toggled"] +[connection signal="value_changed" from="PosSizeContainer/Size" to="." method="_on_Size_value_changed"] [connection signal="pressed" from="Apply" to="." method="_on_Apply_pressed"] diff --git a/src/UI/Canvas/CropRect.gd b/src/UI/Canvas/CropRect.gd index fc9447f76..ef8954b22 100644 --- a/src/UI/Canvas/CropRect.gd +++ b/src/UI/Canvas/CropRect.gd @@ -5,16 +5,15 @@ extends Node2D signal updated -enum Mode { MARGINS, POSITION_SIZE, LOCKED_ASPECT_RATIO } +enum Mode { MARGINS, POSITION_SIZE } const BIG = 100000 # Size of big rectangles used to darken background. const DARKEN_COLOR = Color(0, 0, 0, 0.5) const LINE_COLOR = Color.white -var mode := 0 setget _set_mode +var mode: int = Mode.MARGINS setget _set_mode var locked_size := false var rect := Rect2(0, 0, 1, 1) -var ratio := Vector2.ONE # How many crop tools are active (0-2), setter makes this visible if not 0 var tool_count := 0 setget _set_tool_count @@ -66,27 +65,13 @@ func apply() -> void: func reset() -> void: rect.position = Vector2.ZERO rect.size = Global.current_project.size - if mode == Mode.LOCKED_ASPECT_RATIO: - _auto_ratio_from_resolution() emit_signal("updated") -func _auto_ratio_from_resolution() -> void: - var divisor := _gcd(rect.size.x, rect.size.y) - ratio = rect.size / divisor - - -# Greatest common divisor -func _gcd(a: int, b: int) -> int: - return a if b == 0 else _gcd(b, a % b) - - # Setters func _set_mode(value: int) -> void: - if value == Mode.LOCKED_ASPECT_RATIO and mode != Mode.LOCKED_ASPECT_RATIO: - _auto_ratio_from_resolution() mode = value