mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-01-18 17:19:50 +00:00
Move and resize tags by dragging their edges
This commit is contained in:
parent
5a64dde3e5
commit
e3ee931059
|
@ -67,6 +67,12 @@ func serialize() -> Dictionary:
|
||||||
return dict
|
return dict
|
||||||
|
|
||||||
|
|
||||||
|
func duplicate() -> AnimationTag:
|
||||||
|
var new_tag := AnimationTag.new(name, color, from, to)
|
||||||
|
new_tag.user_data = user_data
|
||||||
|
return new_tag
|
||||||
|
|
||||||
|
|
||||||
func get_size() -> int:
|
func get_size() -> int:
|
||||||
return to - from + 1
|
return to - from + 1
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
extends Control
|
extends Control
|
||||||
|
|
||||||
|
enum Drag { NONE, FROM, TO }
|
||||||
|
|
||||||
var tag: AnimationTag
|
var tag: AnimationTag
|
||||||
|
var dragging_tag: AnimationTag
|
||||||
|
var dragged_initial := 0
|
||||||
|
var is_dragging := Drag.NONE
|
||||||
@onready var tag_properties := Global.control.find_child("TagProperties") as ConfirmationDialog
|
@onready var tag_properties := Global.control.find_child("TagProperties") as ConfirmationDialog
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,9 +18,9 @@ func _ready() -> void:
|
||||||
update_position_and_size()
|
update_position_and_size()
|
||||||
|
|
||||||
|
|
||||||
func update_position_and_size() -> void:
|
func update_position_and_size(from_tag := tag) -> void:
|
||||||
position = tag.get_position()
|
position = from_tag.get_position()
|
||||||
custom_minimum_size.x = tag.get_minimum_size()
|
custom_minimum_size.x = from_tag.get_minimum_size()
|
||||||
size.x = custom_minimum_size.x
|
size.x = custom_minimum_size.x
|
||||||
$Line2D.points[2].x = custom_minimum_size.x
|
$Line2D.points[2].x = custom_minimum_size.x
|
||||||
$Line2D.points[3].x = custom_minimum_size.x
|
$Line2D.points[3].x = custom_minimum_size.x
|
||||||
|
@ -24,3 +29,72 @@ func update_position_and_size() -> void:
|
||||||
func _on_button_pressed() -> void:
|
func _on_button_pressed() -> void:
|
||||||
var tag_id := Global.current_project.animation_tags.find(tag)
|
var tag_id := Global.current_project.animation_tags.find(tag)
|
||||||
tag_properties.show_dialog(Rect2i(), tag_id, true)
|
tag_properties.show_dialog(Rect2i(), tag_id, true)
|
||||||
|
|
||||||
|
|
||||||
|
func _resize_tag(resize: Drag, value: int) -> void:
|
||||||
|
var new_animation_tags: Array[AnimationTag] = []
|
||||||
|
# Loop through the tags to create new classes for them, so that they won't be the same
|
||||||
|
# as Global.current_project.animation_tags's classes. Needed for undo/redo to work properly.
|
||||||
|
for frame_tag in Global.current_project.animation_tags:
|
||||||
|
new_animation_tags.append(frame_tag.duplicate())
|
||||||
|
|
||||||
|
var tag_id := Global.current_project.animation_tags.find(tag)
|
||||||
|
if resize == Drag.FROM:
|
||||||
|
if new_animation_tags[tag_id].from == value:
|
||||||
|
return
|
||||||
|
new_animation_tags[tag_id].from = value
|
||||||
|
elif resize == Drag.TO:
|
||||||
|
if new_animation_tags[tag_id].to == value:
|
||||||
|
return
|
||||||
|
new_animation_tags[tag_id].to = value
|
||||||
|
|
||||||
|
# Handle Undo/Redo
|
||||||
|
Global.current_project.undos += 1
|
||||||
|
Global.current_project.undo_redo.create_action("Resize Frame Tag")
|
||||||
|
Global.current_project.undo_redo.add_do_method(Global.general_redo)
|
||||||
|
Global.current_project.undo_redo.add_undo_method(Global.general_undo)
|
||||||
|
Global.current_project.undo_redo.add_do_property(
|
||||||
|
Global.current_project, &"animation_tags", new_animation_tags
|
||||||
|
)
|
||||||
|
Global.current_project.undo_redo.add_undo_property(
|
||||||
|
Global.current_project, &"animation_tags", Global.current_project.animation_tags
|
||||||
|
)
|
||||||
|
Global.current_project.undo_redo.commit_action()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_resize_from_gui_input(event: InputEvent) -> void:
|
||||||
|
var cel_size: int = Global.animation_timeline.cel_size
|
||||||
|
if event is InputEventMouseButton:
|
||||||
|
if event.pressed:
|
||||||
|
is_dragging = Drag.FROM
|
||||||
|
dragging_tag = tag.duplicate()
|
||||||
|
dragged_initial = global_position.x
|
||||||
|
else:
|
||||||
|
_resize_tag(is_dragging, dragging_tag.from)
|
||||||
|
is_dragging = Drag.NONE
|
||||||
|
dragging_tag = null
|
||||||
|
elif event is InputEventMouseMotion:
|
||||||
|
if is_dragging == Drag.FROM:
|
||||||
|
var dragged_offset := snappedi(event.global_position.x, cel_size)
|
||||||
|
var diff := roundi(float(dragged_offset - dragged_initial) / cel_size)
|
||||||
|
dragging_tag.from = clampi(tag.from + diff, 1, tag.to)
|
||||||
|
update_position_and_size(dragging_tag)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_resize_to_gui_input(event: InputEvent) -> void:
|
||||||
|
var cel_size: int = Global.animation_timeline.cel_size
|
||||||
|
if event is InputEventMouseButton:
|
||||||
|
if event.pressed:
|
||||||
|
is_dragging = Drag.TO
|
||||||
|
dragging_tag = tag.duplicate()
|
||||||
|
dragged_initial = global_position.x + size.x
|
||||||
|
else:
|
||||||
|
_resize_tag(is_dragging, dragging_tag.to)
|
||||||
|
is_dragging = Drag.NONE
|
||||||
|
dragging_tag = null
|
||||||
|
elif event is InputEventMouseMotion:
|
||||||
|
if is_dragging == Drag.TO:
|
||||||
|
var dragged_offset := snappedi(event.global_position.x, cel_size)
|
||||||
|
var diff := roundi(float(dragged_offset - dragged_initial) / cel_size)
|
||||||
|
dragging_tag.to = clampi(tag.to + diff, tag.from, Global.current_project.frames.size())
|
||||||
|
update_position_and_size(dragging_tag)
|
||||||
|
|
|
@ -38,4 +38,30 @@ mouse_default_cursor_shape = 2
|
||||||
text = "Idle"
|
text = "Idle"
|
||||||
flat = true
|
flat = true
|
||||||
|
|
||||||
|
[node name="ResizeFrom" type="Button" parent="."]
|
||||||
|
modulate = Color(1, 1, 1, 0)
|
||||||
|
layout_mode = 0
|
||||||
|
offset_left = -4.0
|
||||||
|
offset_right = 4.0
|
||||||
|
offset_bottom = 32.0
|
||||||
|
mouse_default_cursor_shape = 10
|
||||||
|
keep_pressed_outside = true
|
||||||
|
flat = true
|
||||||
|
|
||||||
|
[node name="ResizeTo" type="Button" parent="."]
|
||||||
|
modulate = Color(1, 1, 1, 0)
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 1
|
||||||
|
anchor_left = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
offset_left = -4.0
|
||||||
|
offset_right = 4.0
|
||||||
|
offset_bottom = 32.0
|
||||||
|
grow_horizontal = 0
|
||||||
|
mouse_default_cursor_shape = 10
|
||||||
|
keep_pressed_outside = true
|
||||||
|
flat = true
|
||||||
|
|
||||||
[connection signal="pressed" from="Button" to="." method="_on_button_pressed"]
|
[connection signal="pressed" from="Button" to="." method="_on_button_pressed"]
|
||||||
|
[connection signal="gui_input" from="ResizeFrom" to="." method="_on_resize_from_gui_input"]
|
||||||
|
[connection signal="gui_input" from="ResizeTo" to="." method="_on_resize_to_gui_input"]
|
||||||
|
|
|
@ -47,9 +47,7 @@ func _on_confirmed() -> void:
|
||||||
# Loop through the tags to create new classes for them, so that they won't be the same
|
# Loop through the tags to create new classes for them, so that they won't be the same
|
||||||
# as Global.current_project.animation_tags's classes. Needed for undo/redo to work properly.
|
# as Global.current_project.animation_tags's classes. Needed for undo/redo to work properly.
|
||||||
for tag in Global.current_project.animation_tags:
|
for tag in Global.current_project.animation_tags:
|
||||||
var new_tag := AnimationTag.new(tag.name, tag.color, tag.from, tag.to)
|
new_animation_tags.append(tag.duplicate())
|
||||||
new_tag.user_data = tag.user_data
|
|
||||||
new_animation_tags.append(new_tag)
|
|
||||||
|
|
||||||
if current_tag_id == Global.current_project.animation_tags.size():
|
if current_tag_id == Global.current_project.animation_tags.size():
|
||||||
var new_tag := AnimationTag.new(tag_name, tag_color, tag_from, tag_to)
|
var new_tag := AnimationTag.new(tag_name, tag_color, tag_from, tag_to)
|
||||||
|
|
Loading…
Reference in a new issue