1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-02-20 12:33:14 +00:00

Replace the Locked Aspect Ratio mode in the crop tool with a lock button next to the size sliders

This commit is contained in:
Emmanouil Papadeas 2023-03-24 01:17:30 +02:00
parent 2ad1391ca1
commit acb32844a1
3 changed files with 72 additions and 126 deletions

View file

@ -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:

View file

@ -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"]

View file

@ -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