1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-01-18 17:19:50 +00:00

Crop Tool (#830)

* Added intial crop tool

* [skip ci] Removed unneeeded LINE_WIDTH constant from CropRect

* Added DimensionsLabel

* Cleaned up CropRect._draw

* Hide the CropRect after switching to a different tool

* Sets the crop values to the entire canvas size on setup

* [skip ci] Added crop tool tooltip

* Made Crop tools synced with eachother by placing the crop settings on CropRect

* Added new modes, refactored, added rule of thirds lines and darkened background

* [skip ci] reset optimization

* Renames

* [skip ci] Tweaked the darkened background

* Fixed bug with top/bottom/left/right sliders after rect refactor

* Changing width/height on locked aspect ratio bug

* Aspect ratio sliders rounding/setting a min of 1 px height/width

* Fixed bugs with drawing the crop rect, especially with locked aspect ratio

* Save the mode to config_cache

* Added size lock and renamed mode

* Added tooltip for size lock. Not sure if I did the translation file right

* removed signal that wasn't used

* Formatting

* Removed old TODO comment from one of my previous PRs that isn't true anymore

* Fixed definition order for linter

* Changed locked size modes moving to offset by @Variable-ind, reordered methods

---------

Co-authored-by: MrTriPie <MrTriPie>
This commit is contained in:
mrtripie 2023-03-16 13:50:45 -04:00 committed by GitHub
parent e008c39286
commit 0ad86816e5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 721 additions and 2 deletions

View file

@ -2158,3 +2158,41 @@ msgstr ""
msgid "Reference Images"
msgstr ""
msgid "Crop"
msgstr ""
msgid "Resize the canvas"
msgstr ""
msgid "Margins"
msgstr ""
msgid "Position + Size"
msgstr ""
msgid "Locked Aspect Ratio"
msgstr ""
msgid "Margins:"
msgstr ""
msgid "Aspect Ratio:"
msgstr ""
msgid "Top:"
msgstr ""
msgid "Bottom:"
msgstr ""
msgid "Left:"
msgstr ""
msgid "Right:"
msgstr ""
msgid "Locked size\n\n"
"When enabled using the tool on the canvas will only move the cropping rectangle.\n\n"
"When disabled using the tool on the canvas will draw the rectangle."
msgstr ""

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 B

View file

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/locked_size.png-05ec97950456a9ee42557d3414337309.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/misc/locked_size.png"
dest_files=[ "res://.import/locked_size.png-05ec97950456a9ee42557d3414337309.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 B

View file

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/unlocked_size.png-bd224f1987da9100f208bda51349ff67.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/misc/unlocked_size.png"
dest_files=[ "res://.import/unlocked_size.png-bd224f1987da9100f208bda51349ff67.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 B

View file

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/crop.png-b117b864c2b96dd1998350bff3c06cf8.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/tools/crop.png"
dest_files=[ "res://.import/crop.png-b117b864c2b96dd1998350bff3c06cf8.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 B

View file

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/crop.png-b1dd939167138aaa21a7eeec94aed6bc.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/tools/cursors/crop.png"
dest_files=[ "res://.import/crop.png-b1dd939167138aaa21a7eeec94aed6bc.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

View file

@ -79,6 +79,11 @@ _global_script_classes=[ {
"language": "GDScript",
"path": "res://src/UI/Nodes/CollapsibleContainer.gd"
}, {
"base": "Node2D",
"class": "CropRect",
"language": "GDScript",
"path": "res://src/UI/Canvas/CropRect.gd"
}, {
"base": "Reference",
"class": "Drawer",
"language": "GDScript",
@ -244,6 +249,7 @@ _global_script_class_icons={
"Brushes": "",
"Canvas": "",
"CollapsibleContainer": "",
"CropRect": "",
"Drawer": "",
"Frame": "",
"GIFAnimationExporter": "",

View file

@ -152,6 +152,12 @@ var onion_skinning_blue_red := false
# Palettes
var palettes := {}
# Crop Options:
var crop_top := 0
var crop_bottom := 0
var crop_left := 0
var crop_right := 0
# Nodes
var pixel_layer_button_node: PackedScene = preload("res://src/UI/Timeline/PixelLayerButton.tscn")
var group_layer_button_node: PackedScene = preload("res://src/UI/Timeline/GroupLayerButton.tscn")

View file

@ -86,6 +86,8 @@ var tools := {
preload("res://src/Tools/ColorPicker.tscn"),
"Select a color from a pixel of the sprite"
),
"Crop":
Tool.new("Crop", "Crop", "crop", preload("res://src/Tools/CropTool.tscn"), "Resize the canvas"),
"Pencil":
Tool.new(
"Pencil",

View file

@ -474,6 +474,7 @@ func _size_changed(value: Vector2) -> void:
tiles.tile_size = value
tiles.reset_mask()
size = value
Global.canvas.crop_rect.reset()
func change_cel(new_frame: int, new_layer := -1) -> void:

210
src/Tools/CropTool.gd Normal file
View file

@ -0,0 +1,210 @@
extends BaseTool
# Crop Tool, allows you to resize the canvas interactively
var _offset = Vector2.ZERO
var _crop: CropRect
var _start_pos: Vector2
var _syncing := false
func _ready() -> void:
_crop = Global.canvas.crop_rect
_crop.connect("updated", self, "_sync_ui")
_crop.tool_count += 1
_sync_ui()
func _exit_tree() -> void:
_crop.tool_count -= 1
func draw_start(position: Vector2) -> void:
.draw_start(position)
_offset = position - _crop.rect.position
_start_pos = position
func draw_move(position: Vector2) -> void:
.draw_move(position)
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
# 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)
_crop.emit_signal("updated")
func _sync_ui() -> void:
_syncing = true
$"%CropMode".selected = _crop.mode
$"%SizeLock".pressed = _crop.locked_size
match _crop.mode:
CropRect.Mode.MARGINS:
$"%MarginsContainer".show()
$"%RatioContainer".hide()
$"%PosSizeContainer".hide()
$"%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()
$"%Top".max_value = Global.current_project.size.y - 1
$"%Bottom".max_value = Global.current_project.size.y
$"%Left".max_value = Global.current_project.size.x - 1
$"%Right".max_value = Global.current_project.size.x
$"%Top".value = _crop.rect.position.y
$"%Bottom".value = _crop.rect.end.y
$"%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
$"%DimensionsLabel".text = str(_crop.rect.size.x, " x ", _crop.rect.size.y)
_syncing = false
# UI Signals:
func _on_CropMode_item_selected(index: int) -> void:
if _syncing:
return
_crop.mode = index
_crop.emit_signal("updated")
func _on_SizeLock_toggled(button_pressed: bool) -> void:
if button_pressed:
$"%SizeLock".icon = preload("res://assets/graphics/misc/locked_size.png")
else:
$"%SizeLock".icon = preload("res://assets/graphics/misc/unlocked_size.png")
if _syncing:
return
_crop.locked_size = button_pressed
_crop.emit_signal("updated")
func _on_Top_value_changed(value: float) -> void:
if _syncing:
return
var difference := value - _crop.rect.position.y
_crop.rect.size.y = max(1, _crop.rect.size.y - difference)
_crop.rect.position.y = value
_crop.emit_signal("updated")
func _on_Bottom_value_changed(value: float) -> void:
if _syncing:
return
_crop.rect.position.y = min(value - 1, _crop.rect.position.y)
_crop.rect.end.y = value
_crop.emit_signal("updated")
func _on_Left_value_changed(value: float) -> void:
if _syncing:
return
var difference := value - _crop.rect.position.x
_crop.rect.size.x = max(1, _crop.rect.size.x - difference)
_crop.rect.position.x = value
_crop.emit_signal("updated")
func _on_Right_value_changed(value: float) -> void:
if _syncing:
return
_crop.rect.position.x = min(value - 1, _crop.rect.position.x)
_crop.rect.end.x = value
_crop.emit_signal("updated")
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
_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
_crop.emit_signal("updated")
func _on_PositionX_value_changed(value: float) -> void:
if _syncing:
return
_crop.rect.position.x = value
_crop.emit_signal("updated")
func _on_PositionY_value_changed(value: float) -> void:
if _syncing:
return
_crop.rect.position.y = 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_Apply_pressed() -> void:
_crop.apply()

214
src/Tools/CropTool.tscn Normal file
View file

@ -0,0 +1,214 @@
[gd_scene load_steps=5 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]
[node name="ToolOptions" instance=ExtResource( 1 )]
script = ExtResource( 3 )
[node name="ModeLabel" type="Label" parent="." index="4"]
margin_top = 26.0
margin_right = 116.0
margin_bottom = 40.0
text = "Mode:"
[node name="HBoxContainer" type="HBoxContainer" parent="." index="5"]
margin_top = 44.0
margin_right = 116.0
margin_bottom = 66.0
[node name="CropMode" type="OptionButton" parent="HBoxContainer" index="0"]
unique_name_in_owner = true
margin_right = 84.0
margin_bottom = 22.0
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 ]
selected = 0
[node name="SizeLock" type="Button" parent="HBoxContainer" index="1"]
unique_name_in_owner = true
margin_left = 88.0
margin_right = 116.0
margin_bottom = 22.0
hint_tooltip = "Locked size
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
toggle_mode = true
icon = ExtResource( 4 )
__meta__ = {
"_editor_description_": ""
}
[node name="MarginsContainer" type="VBoxContainer" parent="." index="6"]
unique_name_in_owner = true
margin_top = 70.0
margin_right = 116.0
margin_bottom = 196.0
[node name="MarginsLabel" type="Label" parent="MarginsContainer" index="0"]
margin_right = 116.0
margin_bottom = 14.0
text = "Margins:"
[node name="Top" parent="MarginsContainer" index="1" instance=ExtResource( 2 )]
unique_name_in_owner = true
margin_top = 18.0
margin_right = 116.0
margin_bottom = 42.0
allow_greater = true
allow_lesser = true
prefix = "Top:"
[node name="Bottom" parent="MarginsContainer" 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 = "Bottom:"
[node name="Left" parent="MarginsContainer" index="3" instance=ExtResource( 2 )]
unique_name_in_owner = true
margin_top = 74.0
margin_right = 116.0
margin_bottom = 98.0
allow_greater = true
allow_lesser = true
prefix = "Left:"
[node name="Right" parent="MarginsContainer" index="4" instance=ExtResource( 2 )]
unique_name_in_owner = true
margin_top = 102.0
margin_right = 116.0
margin_bottom = 126.0
allow_greater = true
allow_lesser = true
prefix = "Right:"
[node name="RatioContainer" type="VBoxContainer" parent="." index="7"]
unique_name_in_owner = true
margin_top = 200.0
margin_right = 116.0
margin_bottom = 242.0
[node name="AspectRatioLabel" type="Label" parent="RatioContainer" index="0"]
margin_right = 116.0
margin_bottom = 14.0
text = "Aspect Ratio:"
[node name="HBoxContainer" type="HBoxContainer" parent="RatioContainer" index="1"]
margin_top = 18.0
margin_right = 116.0
margin_bottom = 42.0
[node name="RatioX" parent="RatioContainer/HBoxContainer" index="0" instance=ExtResource( 2 )]
unique_name_in_owner = true
margin_right = 52.0
min_value = 1.0
value = 1.0
allow_greater = true
[node name="Label" type="Label" parent="RatioContainer/HBoxContainer" index="1"]
margin_left = 56.0
margin_top = 5.0
margin_right = 60.0
margin_bottom = 19.0
text = ":"
[node name="RatioY" parent="RatioContainer/HBoxContainer" index="2" instance=ExtResource( 2 )]
unique_name_in_owner = true
margin_left = 64.0
margin_right = 116.0
min_value = 1.0
value = 1.0
allow_greater = true
[node name="PosSizeContainer" type="VBoxContainer" parent="." index="8"]
unique_name_in_owner = true
margin_top = 246.0
margin_right = 116.0
margin_bottom = 390.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 )]
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"]
margin_top = 74.0
margin_right = 116.0
margin_bottom = 88.0
text = "Size:"
[node name="Width" parent="PosSizeContainer" index="4" instance=ExtResource( 2 )]
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
allow_greater = true
prefix = "H:"
[node name="Apply" type="Button" parent="." index="9"]
margin_top = 394.0
margin_right = 116.0
margin_bottom = 414.0
text = "Apply"
[node name="DimensionsLabel" type="Label" parent="." index="10"]
unique_name_in_owner = true
margin_top = 418.0
margin_right = 116.0
margin_bottom = 432.0
align = 1
[connection signal="item_selected" from="HBoxContainer/CropMode" to="." method="_on_CropMode_item_selected"]
[connection signal="toggled" from="HBoxContainer/SizeLock" to="." method="_on_SizeLock_toggled"]
[connection signal="value_changed" from="MarginsContainer/Top" to="." method="_on_Top_value_changed"]
[connection signal="value_changed" from="MarginsContainer/Bottom" to="." method="_on_Bottom_value_changed"]
[connection signal="value_changed" from="MarginsContainer/Left" to="." method="_on_Left_value_changed"]
[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="pressed" from="Apply" to="." method="_on_Apply_pressed"]

View file

@ -14,6 +14,7 @@ onready var tile_mode = $TileMode
onready var pixel_grid = $PixelGrid
onready var grid = $Grid
onready var selection = $Selection
onready var crop_rect: CropRect = $CropRect
onready var indicators = $Indicators
onready var previews = $Previews
onready var mouse_guide_container = $MouseGuideContainer

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=16 format=2]
[gd_scene load_steps=17 format=2]
[ext_resource path="res://src/UI/Canvas/Canvas.gd" type="Script" id=1]
[ext_resource path="res://src/UI/Canvas/Grid.gd" type="Script" id=2]
@ -12,6 +12,7 @@
[ext_resource path="res://src/Shaders/AutoInvertColors.shader" type="Shader" id=10]
[ext_resource path="res://src/UI/Canvas/MouseGuideContainer.tscn" type="PackedScene" id=11]
[ext_resource path="res://src/UI/Canvas/OnionSkinning.gd" type="Script" id=12]
[ext_resource path="res://src/UI/Canvas/CropRect.gd" type="Script" id=13]
[sub_resource type="CanvasItemMaterial" id=1]
blend_mode = 4
@ -61,6 +62,10 @@ script = ExtResource( 8 )
material = SubResource( 2 )
centered = false
[node name="CropRect" type="Node2D" parent="."]
visible = false
script = ExtResource( 13 )
[node name="Indicators" type="Node2D" parent="."]
script = ExtResource( 3 )

97
src/UI/Canvas/CropRect.gd Normal file
View file

@ -0,0 +1,97 @@
class_name CropRect
extends Node2D
# Draws the rectangle overlay for the crop tool
# Stores the shared settings between left and right crop tools
signal updated
enum Mode { MARGINS, POSITION_SIZE, LOCKED_ASPECT_RATIO }
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 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
func _ready() -> void:
connect("updated", self, "update")
Global.connect("project_changed", self, "reset")
mode = Global.config_cache.get_value("preferences", "crop_mode", 0)
locked_size = Global.config_cache.get_value("preferences", "crop_locked_size", false)
reset()
func _exit_tree():
Global.config_cache.set_value("preferences", "crop_mode", mode)
Global.config_cache.set_value("preferences", "crop_locked_size", locked_size)
func _draw() -> void:
# Darken the background by drawing big rectangles around it (top/bottomm/left/right):
draw_rect(
Rect2(rect.position.x - BIG, rect.position.y - BIG, BIG * 2 + rect.size.x, BIG),
DARKEN_COLOR
)
draw_rect(Rect2(rect.position.x - BIG, rect.end.y, BIG * 2 + rect.size.x, BIG), DARKEN_COLOR)
draw_rect(Rect2(rect.position.x - BIG, rect.position.y, BIG, rect.size.y), DARKEN_COLOR)
draw_rect(Rect2(rect.end.x, rect.position.y, BIG, rect.size.y), DARKEN_COLOR)
# Rect:
draw_rect(rect, LINE_COLOR, false)
# Horizontal rule of thirds lines:
var third: float = rect.position.y + rect.size.y * 0.333
draw_line(Vector2(rect.position.x, third), Vector2(rect.end.x, third), LINE_COLOR)
third = rect.position.y + rect.size.y * 0.667
draw_line(Vector2(rect.position.x, third), Vector2(rect.end.x, third), LINE_COLOR)
# Vertical rule of thirds lines:
third = rect.position.x + rect.size.x * 0.333
draw_line(Vector2(third, rect.position.y), Vector2(third, rect.end.y), LINE_COLOR)
third = rect.position.x + rect.size.x * 0.667
draw_line(Vector2(third, rect.position.y), Vector2(third, rect.end.y), LINE_COLOR)
func apply() -> void:
DrawingAlgos.resize_canvas(rect.size.x, rect.size.y, -rect.position.x, -rect.position.y)
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
func _set_tool_count(value: int) -> void:
if tool_count == 0 and value > 0:
reset() # Reset once 1 tool becomes the crop tool
tool_count = value
visible = tool_count

View file

@ -69,7 +69,6 @@ func _frame_scroll_changed(value: float) -> void:
func _on_LayerVBox_resized() -> void:
# TODO: BUG Layers resizing doesn't update the tags!
frame_scroll_bar.margin_left = frame_scroll_container.rect_position.x
tag_spacer.rect_min_size.x = (
frame_scroll_container.rect_global_position.x