1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-03-13 06:45:17 +00:00

Ability to select multiple cels and edit them all at once

A rather significant change, so, while I have tested it, it might still be buggy. Implements a part of #306.
This commit is contained in:
Manolis Papadeas 2021-06-12 01:06:13 +03:00
parent 73cce5b740
commit de850ce8a1
14 changed files with 322 additions and 128 deletions

View file

@ -43,42 +43,51 @@ func _about_to_show() -> void:
func _confirmed() -> void: func _confirmed() -> void:
var project := Global.current_project
if affect == CEL: if affect == CEL:
if !Global.current_project.layers[Global.current_project.current_layer].can_layer_get_drawn(): # No changes if the layer is locked or invisible if !project.layers[project.current_layer].can_layer_get_drawn(): # No changes if the layer is locked or invisible
return return
if project.selected_cels.size() == 1:
Global.canvas.handle_undo("Draw") Global.canvas.handle_undo("Draw")
commit_action(current_cel) commit_action(current_cel)
Global.canvas.handle_redo("Draw") Global.canvas.handle_redo("Draw")
else:
Global.canvas.handle_undo("Draw", project, -1, -1)
for cel_index in project.selected_cels:
var cel : Cel = project.frames[cel_index[0]].cels[cel_index[1]]
var cel_image : Image = cel.image
commit_action(cel_image)
Global.canvas.handle_redo("Draw", project, -1, -1)
elif affect == FRAME: elif affect == FRAME:
Global.canvas.handle_undo("Draw", Global.current_project, -1) Global.canvas.handle_undo("Draw", project, -1)
var i := 0 var i := 0
for cel in Global.current_project.frames[Global.current_project.current_frame].cels: for cel in project.frames[project.current_frame].cels:
if Global.current_project.layers[i].can_layer_get_drawn(): if project.layers[i].can_layer_get_drawn():
commit_action(cel.image) commit_action(cel.image)
i += 1 i += 1
Global.canvas.handle_redo("Draw", Global.current_project, -1) Global.canvas.handle_redo("Draw", project, -1)
elif affect == ALL_FRAMES: elif affect == ALL_FRAMES:
Global.canvas.handle_undo("Draw", Global.current_project, -1, -1)
for frame in Global.current_project.frames:
var i := 0
for cel in frame.cels:
if Global.current_project.layers[i].can_layer_get_drawn():
commit_action(cel.image)
i += 1
Global.canvas.handle_redo("Draw", Global.current_project, -1, -1)
elif affect == ALL_PROJECTS:
for project in Global.projects:
Global.canvas.handle_undo("Draw", project, -1, -1) Global.canvas.handle_undo("Draw", project, -1, -1)
for frame in project.frames: for frame in project.frames:
var i := 0 var i := 0
for cel in frame.cels: for cel in frame.cels:
if project.layers[i].can_layer_get_drawn(): if project.layers[i].can_layer_get_drawn():
commit_action(cel.image, project) commit_action(cel.image)
i += 1 i += 1
Global.canvas.handle_redo("Draw", project, -1, -1) Global.canvas.handle_redo("Draw", project, -1, -1)
elif affect == ALL_PROJECTS:
for _project in Global.projects:
Global.canvas.handle_undo("Draw", _project, -1, -1)
for frame in _project.frames:
var i := 0
for cel in frame.cels:
if _project.layers[i].can_layer_get_drawn():
commit_action(cel.image, _project)
i += 1
Global.canvas.handle_redo("Draw", _project, -1, -1)
func commit_action(_cel : Image, _project : Project = Global.current_project) -> void: func commit_action(_cel : Image, _project : Project = Global.current_project) -> void:
pass pass

View file

@ -12,6 +12,8 @@ var frames := [] setget frames_changed # Array of Frames (that contain Cels)
var layers := [] setget layers_changed # Array of Layers var layers := [] setget layers_changed # Array of Layers
var current_frame := 0 setget frame_changed var current_frame := 0 setget frame_changed
var current_layer := 0 setget layer_changed var current_layer := 0 setget layer_changed
var selected_cels := [[0, 0]] # Array of Arrays of 2 integers (frame & layer)
var animation_tags := [] setget animation_tags_changed # Array of AnimationTags var animation_tags := [] setget animation_tags_changed # Array of AnimationTags
var guides := [] # Array of Guides var guides := [] # Array of Guides
var brushes := [] # Array of Images var brushes := [] # Array of Images
@ -386,6 +388,7 @@ func size_changed(value : Vector2) -> void:
func frames_changed(value : Array) -> void: func frames_changed(value : Array) -> void:
frames = value frames = value
selected_cels.clear()
remove_cel_buttons() remove_cel_buttons()
for frame_id in Global.frame_ids.get_children(): for frame_id in Global.frame_ids.get_children():
@ -419,6 +422,8 @@ func layers_changed(value : Array) -> void:
Global.layers_changed_skip = false Global.layers_changed_skip = false
return return
selected_cels.clear()
for container in Global.layers_container.get_children(): for container in Global.layers_container.get_children():
container.queue_free() container.queue_free()
@ -471,11 +476,16 @@ func frame_changed(value : int) -> void:
if i < layer.frame_container.get_child_count(): if i < layer.frame_container.get_child_count():
layer.frame_container.get_child(i).pressed = false layer.frame_container.get_child(i).pressed = false
if selected_cels.empty():
selected_cels.append([current_frame, current_layer])
# Select the new frame # Select the new frame
if current_frame < Global.frame_ids.get_child_count(): for cel in selected_cels:
Global.frame_ids.get_child(current_frame).add_color_override("font_color", Global.control.theme.get_color("Selected Color", "Label")) var _current_frame : int = cel[0]
if layers and current_frame < layers[current_layer].frame_container.get_child_count(): var _current_layer : int = cel[1]
layers[current_layer].frame_container.get_child(current_frame).pressed = true if _current_frame < Global.frame_ids.get_child_count():
Global.frame_ids.get_child(_current_frame).add_color_override("font_color", Global.control.theme.get_color("Selected Color", "Label"))
if _current_frame < layers[_current_layer].frame_container.get_child_count():
layers[_current_layer].frame_container.get_child(_current_frame).pressed = true
Global.disable_button(Global.remove_frame_button, frames.size() == 1) Global.disable_button(Global.remove_frame_button, frames.size() == 1)
Global.disable_button(Global.move_left_frame_button, frames.size() == 1 or current_frame == 0) Global.disable_button(Global.move_left_frame_button, frames.size() == 1 or current_frame == 0)
@ -493,17 +503,18 @@ func layer_changed(value : int) -> void:
Global.canvas.selection.transform_content_confirm() Global.canvas.selection.transform_content_confirm()
current_layer = value current_layer = value
for container in Global.layers_container.get_children():
container.pressed = false
if current_layer < Global.layers_container.get_child_count():
var layer_button = Global.layers_container.get_child(Global.layers_container.get_child_count() - 1 - current_layer)
layer_button.pressed = true
toggle_layer_buttons_current_layer() toggle_layer_buttons_current_layer()
yield(Global.get_tree().create_timer(0.01), "timeout") yield(Global.get_tree().create_timer(0.01), "timeout")
self.current_frame = current_frame # Call frame_changed to update UI self.current_frame = current_frame # Call frame_changed to update UI
for layer_button in Global.layers_container.get_children():
layer_button.pressed = false
for cel in selected_cels:
var _current_layer : int = cel[1]
if _current_layer < Global.layers_container.get_child_count():
var layer_button = Global.layers_container.get_child(Global.layers_container.get_child_count() - 1 - _current_layer)
layer_button.pressed = true
func toggle_layer_buttons_layers() -> void: func toggle_layer_buttons_layers() -> void:

View file

@ -94,6 +94,15 @@ func _get_draw_image() -> Image:
return project.frames[project.current_frame].cels[project.current_layer].image return project.frames[project.current_frame].cels[project.current_layer].image
func _get_selected_draw_images() -> Array: # Array of Images
var images := []
var project : Project = Global.current_project
for cel_index in project.selected_cels:
var cel : Cel = project.frames[cel_index[0]].cels[cel_index[1]]
images.append(cel.image)
return images
func _flip_rect(rect : Rect2, size : Vector2, horizontal : bool, vertical : bool) -> Rect2: func _flip_rect(rect : Rect2, size : Vector2, horizontal : bool, vertical : bool) -> Rect2:
var result := rect var result := rect
if horizontal: if horizontal:

View file

@ -117,8 +117,9 @@ func draw_end(_position : Vector2) -> void:
func fill_in_color(position : Vector2) -> void: func fill_in_color(position : Vector2) -> void:
var project : Project = Global.current_project var project : Project = Global.current_project
var image := _get_draw_image() var color : Color = _get_draw_image().get_pixelv(position)
var color := image.get_pixelv(position) var images := _get_selected_draw_images()
for image in images:
if _fill_with == 0 or _pattern == null: if _fill_with == 0 or _pattern == null:
if tool_slot.color.is_equal_approx(color): if tool_slot.color.is_equal_approx(color):
return return
@ -157,8 +158,9 @@ func fill_in_area(position : Vector2) -> void:
func _flood_fill(position : Vector2) -> void: func _flood_fill(position : Vector2) -> void:
var project : Project = Global.current_project var project : Project = Global.current_project
var image := _get_draw_image() var images := _get_selected_draw_images()
var color := image.get_pixelv(position) for image in images:
var color : Color = image.get_pixelv(position)
if _fill_with == 0 or _pattern == null: if _fill_with == 0 or _pattern == null:
if tool_slot.color.is_equal_approx(color): if tool_slot.color.is_equal_approx(color):
return return
@ -205,24 +207,30 @@ func _set_pixel(image : Image, x : int, y : int, color : Color) -> void:
func commit_undo(action : String, undo_data : Dictionary) -> void: func commit_undo(action : String, undo_data : Dictionary) -> void:
var redo_data = _get_undo_data() var redo_data := _get_undo_data()
var project : Project = Global.current_project var project : Project = Global.current_project
var image : Image = project.frames[project.current_frame].cels[project.current_layer].image var frame := -1
var layer := -1
if Global.animation_timer.is_stopped() and project.selected_cels.size() == 1:
frame = project.current_frame
layer = project.current_layer
project.undos += 1 project.undos += 1
project.undo_redo.create_action(action) project.undo_redo.create_action(action)
project.undo_redo.add_do_property(image, "data", redo_data["image_data"]) for image in redo_data:
project.undo_redo.add_undo_property(image, "data", undo_data["image_data"]) project.undo_redo.add_do_property(image, "data", redo_data[image])
project.undo_redo.add_do_method(Global, "redo", project.current_frame, project.current_layer) for image in undo_data:
project.undo_redo.add_undo_method(Global, "undo", project.current_frame, project.current_layer) project.undo_redo.add_undo_property(image, "data", undo_data[image])
project.undo_redo.add_do_method(Global, "redo", frame, layer)
project.undo_redo.add_undo_method(Global, "undo", frame, layer)
project.undo_redo.commit_action() project.undo_redo.commit_action()
func _get_undo_data() -> Dictionary: func _get_undo_data() -> Dictionary:
var data = {} var data := {}
var project : Project = Global.current_project var images := _get_selected_draw_images()
var image : Image = project.frames[project.current_frame].cels[project.current_layer].image for image in images:
image.unlock() image.unlock()
data["image_data"] = image.data data[image] = image.data
image.lock() image.lock()
return data return data

View file

@ -130,7 +130,7 @@ func update_mirror_brush() -> void:
func update_mask(can_skip := true) -> void: func update_mask(can_skip := true) -> void:
if can_skip and Global.pressure_sensitivity_mode == Global.PressureSensitivity.NONE: if can_skip and Global.pressure_sensitivity_mode == Global.PressureSensitivity.NONE:
return return
var size := _get_draw_image().get_size() var size : Vector2 = Global.current_project.size
# Faster than zeroing PoolByteArray directly. See: https://github.com/Orama-Interactive/Pixelorama/pull/439 # Faster than zeroing PoolByteArray directly. See: https://github.com/Orama-Interactive/Pixelorama/pull/439
var nulled_array := [] var nulled_array := []
nulled_array.resize(size.x * size.y) nulled_array.resize(size.x * size.y)
@ -155,11 +155,11 @@ func prepare_undo() -> void:
func commit_undo(action : String) -> void: func commit_undo(action : String) -> void:
var redo_data = _get_undo_data() var redo_data := _get_undo_data()
var project : Project = Global.current_project var project : Project = Global.current_project
var frame := -1 var frame := -1
var layer := -1 var layer := -1
if Global.animation_timer.is_stopped(): if Global.animation_timer.is_stopped() and project.selected_cels.size() == 1:
frame = project.current_frame frame = project.current_frame
layer = project.current_layer layer = project.current_layer
@ -347,7 +347,8 @@ func _set_pixel(position : Vector2) -> void:
if !project.can_pixel_get_drawn(position): if !project.can_pixel_get_drawn(position):
return return
var image := _get_draw_image() var images := _get_selected_draw_images()
for image in images:
var i := int(position.x + position.y * image.get_size().x) var i := int(position.x + position.y * image.get_size().x)
if _mask.size() >= i + 1: if _mask.size() >= i + 1:
if _mask[i] < Tools.pen_pressure: if _mask[i] < Tools.pen_pressure:
@ -515,13 +516,18 @@ func _line_angle_constraint(start : Vector2, end : Vector2) -> Dictionary:
func _get_undo_data() -> Dictionary: func _get_undo_data() -> Dictionary:
var data = {} var data := {}
var project : Project = Global.current_project var project : Project = Global.current_project
var frames := project.frames var cels := [] # Array of Cels
if Global.animation_timer.is_stopped(): if Global.animation_timer.is_stopped():
frames = [project.frames[project.current_frame]] for cel_index in project.selected_cels:
for frame in frames: cels.append(project.frames[cel_index[0]].cels[cel_index[1]])
var image : Image = frame.cels[project.current_layer].image else:
for frame in project.frames:
var cel : Cel = frame.cels[project.current_layer]
cels.append(cel)
for cel in cels:
var image : Image = cel.image
image.unlock() image.unlock()
data[image] = image.data data[image] = image.data
image.lock() image.lock()

View file

@ -73,4 +73,7 @@ func _draw_brush_image(_image : Image, src_rect: Rect2, dst: Vector2) -> void:
var size := _image.get_size() var size := _image.get_size()
if _clear_image.get_size() != size: if _clear_image.get_size() != size:
_clear_image.resize(size.x, size.y, Image.INTERPOLATE_NEAREST) _clear_image.resize(size.x, size.y, Image.INTERPOLATE_NEAREST)
_get_draw_image().blit_rect_mask(_clear_image, _image, src_rect, dst)
var images := _get_selected_draw_images()
for draw_image in images:
draw_image.blit_rect_mask(_clear_image, _image, src_rect, dst)

View file

@ -1,6 +1,7 @@
extends BaseTool extends BaseTool
var _undo_data := {}
var _start_pos : Vector2 var _start_pos : Vector2
var _offset : Vector2 var _offset : Vector2
@ -29,6 +30,7 @@ func _input(event : InputEvent) -> void:
func draw_start(position : Vector2) -> void: func draw_start(position : Vector2) -> void:
_start_pos = position _start_pos = position
_offset = position _offset = position
_undo_data = _get_undo_data()
if Global.current_project.has_selection: if Global.current_project.has_selection:
selection_node.transform_content_start() selection_node.transform_content_start()
_content_transformation_check = selection_node.is_moving_content _content_transformation_check = selection_node.is_moving_content
@ -72,19 +74,60 @@ func draw_end(position : Vector2) -> void:
var pixel_diff : Vector2 = position - _start_pos var pixel_diff : Vector2 = position - _start_pos
var project : Project = Global.current_project var project : Project = Global.current_project
var image : Image = _get_draw_image()
if project.has_selection: if project.has_selection:
selection_node.move_borders_end() selection_node.move_borders_end()
else: else:
Global.canvas.move_preview_location = Vector2.ZERO Global.canvas.move_preview_location = Vector2.ZERO
var images := _get_selected_draw_images()
for image in images:
var image_copy := Image.new() var image_copy := Image.new()
image_copy.copy_from(image) image_copy.copy_from(image)
Global.canvas.handle_undo("Draw")
image.fill(Color(0, 0, 0, 0)) image.fill(Color(0, 0, 0, 0))
image.blit_rect(image_copy, Rect2(Vector2.ZERO, project.size), pixel_diff) image.blit_rect(image_copy, Rect2(Vector2.ZERO, project.size), pixel_diff)
Global.canvas.handle_redo("Draw") commit_undo("Draw")
_start_pos = Vector2.INF _start_pos = Vector2.INF
_snap_to_grid = false _snap_to_grid = false
func commit_undo(action : String) -> void:
var redo_data := _get_undo_data()
var project : Project = Global.current_project
var frame := -1
var layer := -1
if Global.animation_timer.is_stopped() and project.selected_cels.size() == 1:
frame = project.current_frame
layer = project.current_layer
project.undos += 1
project.undo_redo.create_action(action)
for image in redo_data:
project.undo_redo.add_do_property(image, "data", redo_data[image])
for image in _undo_data:
project.undo_redo.add_undo_property(image, "data", _undo_data[image])
project.undo_redo.add_do_method(Global, "redo", frame, layer)
project.undo_redo.add_undo_method(Global, "undo", frame, layer)
project.undo_redo.commit_action()
_undo_data.clear()
func _get_undo_data() -> Dictionary:
var data := {}
var project : Project = Global.current_project
var cels := [] # Array of Cels
if Global.animation_timer.is_stopped():
for cel_index in project.selected_cels:
cels.append(project.frames[cel_index[0]].cels[cel_index[1]])
else:
for frame in project.frames:
var cel : Cel = frame.cels[project.current_layer]
cels.append(cel)
for cel in cels:
var image : Image = cel.image
image.unlock()
data[image] = image.data
image.lock()
return data

View file

@ -103,17 +103,14 @@ func draw_end(_position : Vector2) -> void:
if _fill_inside: if _fill_inside:
_draw_points.append(_position) _draw_points.append(_position)
if _draw_points.size() > 3: if _draw_points.size() > 3:
var image = _get_draw_image()
var v = Vector2() var v = Vector2()
var image_size = image.get_size() var image_size = Global.current_project.size
for x in image_size.x: for x in image_size.x:
v.x = x v.x = x
for y in image_size.y: for y in image_size.y:
v.y = y v.y = y
if Geometry.is_point_in_polygon(v, _draw_points): if Geometry.is_point_in_polygon(v, _draw_points):
image.lock()
draw_tool(v) draw_tool(v)
image.unlock()
if _changed or _drawer.color_op.changed: if _changed or _drawer.color_op.changed:
commit_undo("Draw") commit_undo("Draw")
cursor_text = "" cursor_text = ""
@ -122,9 +119,10 @@ func draw_end(_position : Vector2) -> void:
func _draw_brush_image(image : Image, src_rect: Rect2, dst: Vector2) -> void: func _draw_brush_image(image : Image, src_rect: Rect2, dst: Vector2) -> void:
_changed = true _changed = true
var images := _get_selected_draw_images()
if _overwrite: if _overwrite:
_get_draw_image().blit_rect(image, src_rect, dst) for draw_image in images:
draw_image.blit_rect(image, src_rect, dst)
else: else:
_get_draw_image().blend_rect(image, src_rect, dst) for draw_image in images:
draw_image.blend_rect(image, src_rect, dst)

View file

@ -78,8 +78,6 @@ func _input(event : InputEvent) -> void:
sprite_changed_this_frame = false sprite_changed_this_frame = false
var current_project : Project = Global.current_project
if Global.has_focus: if Global.has_focus:
if !cursor_image_has_changed: if !cursor_image_has_changed:
cursor_image_has_changed = true cursor_image_has_changed = true
@ -96,7 +94,7 @@ func _input(event : InputEvent) -> void:
Tools.handle_draw(current_pixel.floor(), event) Tools.handle_draw(current_pixel.floor(), event)
if sprite_changed_this_frame: if sprite_changed_this_frame:
update_texture(current_project.current_layer) update_selected_cels_textures()
func camera_zoom() -> void: func camera_zoom() -> void:
@ -231,6 +229,20 @@ func update_texture(layer_index : int, frame_index := -1, project : Project = Gl
frame_texture_rect.texture = current_cel.image_texture frame_texture_rect.texture = current_cel.image_texture
func update_selected_cels_textures(project : Project = Global.current_project) -> void:
for cel_index in project.selected_cels:
var frame_index : int = cel_index[0]
var layer_index : int = cel_index[1]
if frame_index < project.frames.size() and layer_index < project.layers.size():
var current_cel : Cel = project.frames[frame_index].cels[layer_index]
current_cel.image_texture.create_from_image(current_cel.image, 0)
if project == Global.current_project:
var frame_texture_rect : TextureRect
frame_texture_rect = Global.find_node_by_name(project.layers[layer_index].frame_container.get_child(frame_index), "CelTexture")
frame_texture_rect.texture = current_cel.image_texture
func onion_skinning() -> void: func onion_skinning() -> void:
# Past # Past
if Global.onion_skinning_past_rate > 0: if Global.onion_skinning_past_rate > 0:

View file

@ -193,10 +193,6 @@ func _on_CopyFrame_pressed(frame := -1) -> void:
Global.current_project.undo_redo.add_do_property(Global.current_project, "frames", new_frames) Global.current_project.undo_redo.add_do_property(Global.current_project, "frames", new_frames)
Global.current_project.undo_redo.add_do_property(Global.current_project, "current_frame", frame + 1) Global.current_project.undo_redo.add_do_property(Global.current_project, "current_frame", frame + 1)
Global.current_project.undo_redo.add_do_property(Global.current_project, "animation_tags", new_animation_tags) Global.current_project.undo_redo.add_do_property(Global.current_project, "animation_tags", new_animation_tags)
for i in range(Global.current_project.layers.size()):
for child in Global.current_project.layers[i].frame_container.get_children():
Global.current_project.undo_redo.add_do_property(child, "pressed", false)
Global.current_project.undo_redo.add_undo_property(child, "pressed", child.pressed)
Global.current_project.undo_redo.add_undo_property(Global.current_project, "frames", Global.current_project.frames) Global.current_project.undo_redo.add_undo_property(Global.current_project, "frames", Global.current_project.frames)
Global.current_project.undo_redo.add_undo_property(Global.current_project, "current_frame", frame) Global.current_project.undo_redo.add_undo_property(Global.current_project, "current_frame", frame)
@ -279,6 +275,7 @@ func _on_AnimationTimer_timeout() -> void:
var fps = Global.current_project.fps var fps = Global.current_project.fps
if animation_forward: if animation_forward:
if Global.current_project.current_frame < last_frame: if Global.current_project.current_frame < last_frame:
Global.current_project.selected_cels.clear()
Global.current_project.current_frame += 1 Global.current_project.current_frame += 1
Global.animation_timer.wait_time = Global.current_project.frames[Global.current_project.current_frame].duration * (1/fps) Global.animation_timer.wait_time = Global.current_project.frames[Global.current_project.current_frame].duration * (1/fps)
Global.animation_timer.start() # Change the frame, change the wait time and start a cycle, this is the best way to do it Global.animation_timer.start() # Change the frame, change the wait time and start a cycle, this is the best way to do it
@ -289,6 +286,7 @@ func _on_AnimationTimer_timeout() -> void:
Global.play_backwards.pressed = false Global.play_backwards.pressed = false
Global.animation_timer.stop() Global.animation_timer.stop()
1: # Cycle loop 1: # Cycle loop
Global.current_project.selected_cels.clear()
Global.current_project.current_frame = first_frame Global.current_project.current_frame = first_frame
Global.animation_timer.wait_time = Global.current_project.frames[Global.current_project.current_frame].duration * (1/fps) Global.animation_timer.wait_time = Global.current_project.frames[Global.current_project.current_frame].duration * (1/fps)
Global.animation_timer.start() Global.animation_timer.start()
@ -298,6 +296,7 @@ func _on_AnimationTimer_timeout() -> void:
else: else:
if Global.current_project.current_frame > first_frame: if Global.current_project.current_frame > first_frame:
Global.current_project.selected_cels.clear()
Global.current_project.current_frame -= 1 Global.current_project.current_frame -= 1
Global.animation_timer.wait_time = Global.current_project.frames[Global.current_project.current_frame].duration * (1/fps) Global.animation_timer.wait_time = Global.current_project.frames[Global.current_project.current_frame].duration * (1/fps)
Global.animation_timer.start() Global.animation_timer.start()
@ -308,6 +307,7 @@ func _on_AnimationTimer_timeout() -> void:
Global.play_forward.pressed = false Global.play_forward.pressed = false
Global.animation_timer.stop() Global.animation_timer.stop()
1: # Cycle loop 1: # Cycle loop
Global.current_project.selected_cels.clear()
Global.current_project.current_frame = last_frame Global.current_project.current_frame = last_frame
Global.animation_timer.wait_time = Global.current_project.frames[Global.current_project.current_frame].duration * (1/fps) Global.animation_timer.wait_time = Global.current_project.frames[Global.current_project.current_frame].duration * (1/fps)
Global.animation_timer.start() Global.animation_timer.start()
@ -355,20 +355,24 @@ func play_animation(play : bool, forward_dir : bool) -> void:
func _on_NextFrame_pressed() -> void: func _on_NextFrame_pressed() -> void:
Global.current_project.selected_cels.clear()
if Global.current_project.current_frame < Global.current_project.frames.size() - 1: if Global.current_project.current_frame < Global.current_project.frames.size() - 1:
Global.current_project.current_frame += 1 Global.current_project.current_frame += 1
func _on_PreviousFrame_pressed() -> void: func _on_PreviousFrame_pressed() -> void:
Global.current_project.selected_cels.clear()
if Global.current_project.current_frame > 0: if Global.current_project.current_frame > 0:
Global.current_project.current_frame -= 1 Global.current_project.current_frame -= 1
func _on_LastFrame_pressed() -> void: func _on_LastFrame_pressed() -> void:
Global.current_project.selected_cels.clear()
Global.current_project.current_frame = Global.current_project.frames.size() - 1 Global.current_project.current_frame = Global.current_project.frames.size() - 1
func _on_FirstFrame_pressed() -> void: func _on_FirstFrame_pressed() -> void:
Global.current_project.selected_cels.clear()
Global.current_project.current_frame = 0 Global.current_project.current_frame = 0

View file

@ -43,13 +43,50 @@ func _on_CelButton_resized() -> void:
func _on_CelButton_pressed() -> void: func _on_CelButton_pressed() -> void:
var project := Global.current_project
if Input.is_action_just_released("left_mouse"): if Input.is_action_just_released("left_mouse"):
Global.current_project.current_frame = frame var change_cel := true
Global.current_project.current_layer = layer var prev_curr_frame : int = project.current_frame
var prev_curr_layer : int = project.current_layer
if Input.is_action_pressed("shift"):
var frame_diff_sign = sign(frame - prev_curr_frame)
if frame_diff_sign == 0:
frame_diff_sign = 1
var layer_diff_sign = sign(layer - prev_curr_layer)
if layer_diff_sign == 0:
layer_diff_sign = 1
for i in range(prev_curr_frame, frame + frame_diff_sign, frame_diff_sign):
for j in range(prev_curr_layer, layer + layer_diff_sign, layer_diff_sign):
var frame_layer := [i, j]
if !project.selected_cels.has(frame_layer):
project.selected_cels.append(frame_layer)
elif Input.is_action_pressed("ctrl"):
var frame_layer := [frame, layer]
if project.selected_cels.has(frame_layer):
if project.selected_cels.size() > 1:
project.selected_cels.erase(frame_layer)
change_cel = false
else:
project.selected_cels.append(frame_layer)
else: # If the button is pressed without Shift or Control
project.selected_cels.clear()
var frame_layer := [frame, layer]
if !project.selected_cels.has(frame_layer):
project.selected_cels.append(frame_layer)
if change_cel:
project.current_frame = frame
project.current_layer = layer
else:
project.current_frame = project.selected_cels[0][0]
project.current_layer = project.selected_cels[0][1]
release_focus()
elif Input.is_action_just_released("right_mouse"): elif Input.is_action_just_released("right_mouse"):
popup_menu.popup(Rect2(get_global_mouse_position(), Vector2.ONE)) popup_menu.popup(Rect2(get_global_mouse_position(), Vector2.ONE))
pressed = !pressed pressed = !pressed
elif Input.is_action_just_released("middle_mouse"): # Middle mouse click elif Input.is_action_just_released("middle_mouse"):
pressed = !pressed pressed = !pressed
delete_cel_contents() delete_cel_contents()
else: # An example of this would be Space else: # An example of this would be Space
@ -147,6 +184,8 @@ func can_drop_data(_pos, data) -> bool:
func drop_data(_pos, data) -> void: func drop_data(_pos, data) -> void:
var new_frame = data[1] var new_frame = data[1]
var new_layer = data[2] var new_layer = data[2]
if new_frame == frame and new_layer == layer:
return
var this_frame_new_cels = Global.current_project.frames[frame].cels.duplicate() var this_frame_new_cels = Global.current_project.frames[frame].cels.duplicate()
var new_frame_new_cels var new_frame_new_cels
@ -161,6 +200,9 @@ func drop_data(_pos, data) -> void:
Global.current_project.undo_redo.create_action("Move Cels") Global.current_project.undo_redo.create_action("Move Cels")
Global.current_project.undo_redo.add_do_property(Global.current_project.frames[frame], "cels", this_frame_new_cels) Global.current_project.undo_redo.add_do_property(Global.current_project.frames[frame], "cels", this_frame_new_cels)
Global.current_project.undo_redo.add_do_property(Global.current_project, "current_layer", layer)
Global.current_project.undo_redo.add_undo_property(Global.current_project, "current_layer", Global.current_project.current_layer)
if frame != new_frame: # If the cel moved to a different frame if frame != new_frame: # If the cel moved to a different frame
Global.current_project.undo_redo.add_do_property(Global.current_project.frames[new_frame], "cels", new_frame_new_cels) Global.current_project.undo_redo.add_do_property(Global.current_project.frames[new_frame], "cels", new_frame_new_cels)

View file

@ -12,7 +12,29 @@ func _ready() -> void:
func _button_pressed() -> void: func _button_pressed() -> void:
if Input.is_action_just_released("left_mouse"): if Input.is_action_just_released("left_mouse"):
var prev_curr_frame : int = Global.current_project.current_frame
if Input.is_action_pressed("shift"):
var frame_diff_sign = sign(frame - prev_curr_frame)
if frame_diff_sign == 0:
frame_diff_sign = 1
for i in range(prev_curr_frame, frame + frame_diff_sign, frame_diff_sign):
for j in range(0, Global.current_project.layers.size()):
var frame_layer := [i, j]
if !Global.current_project.selected_cels.has(frame_layer):
Global.current_project.selected_cels.append(frame_layer)
elif Input.is_action_pressed("ctrl"):
for j in range(0, Global.current_project.layers.size()):
var frame_layer := [frame, j]
if !Global.current_project.selected_cels.has(frame_layer):
Global.current_project.selected_cels.append(frame_layer)
else: # If the button is pressed without Shift or Control
Global.current_project.selected_cels.clear()
var frame_layer := [frame, Global.current_project.current_layer]
if !Global.current_project.selected_cels.has(frame_layer):
Global.current_project.selected_cels.append(frame_layer)
Global.current_project.current_frame = frame Global.current_project.current_frame = frame
elif Input.is_action_just_released("right_mouse"): elif Input.is_action_just_released("right_mouse"):
if Global.current_project.frames.size() == 1: if Global.current_project.frames.size() == 1:
popup_menu.set_item_disabled(0, true) popup_menu.set_item_disabled(0, true)
@ -26,7 +48,7 @@ func _button_pressed() -> void:
popup_menu.set_item_disabled(3, false) popup_menu.set_item_disabled(3, false)
popup_menu.popup(Rect2(get_global_mouse_position(), Vector2.ONE)) popup_menu.popup(Rect2(get_global_mouse_position(), Vector2.ONE))
pressed = !pressed pressed = !pressed
elif Input.is_action_just_released("middle_mouse"): # Middle mouse click elif Input.is_action_just_released("middle_mouse"):
pressed = !pressed pressed = !pressed
Global.animation_timeline._on_DeleteFrame_pressed(frame) Global.animation_timeline._on_DeleteFrame_pressed(frame)
else: # An example of this would be Space else: # An example of this would be Space
@ -59,12 +81,14 @@ func change_frame_order(rate : int) -> void:
Global.current_project.undo_redo.create_action("Change Frame Order") Global.current_project.undo_redo.create_action("Change Frame Order")
Global.current_project.undo_redo.add_do_property(Global.current_project, "frames", new_frames) Global.current_project.undo_redo.add_do_property(Global.current_project, "frames", new_frames)
Global.current_project.undo_redo.add_undo_property(Global.current_project, "frames", Global.current_project.frames)
if Global.current_project.current_frame == frame: if Global.current_project.current_frame == frame:
Global.current_project.undo_redo.add_do_property(Global.current_project, "current_frame", change) Global.current_project.undo_redo.add_do_property(Global.current_project, "current_frame", change)
Global.current_project.undo_redo.add_undo_property(Global.current_project, "current_frame", Global.current_project.current_frame) else:
Global.current_project.undo_redo.add_do_property(Global.current_project, "current_frame", Global.current_project.current_frame)
Global.current_project.undo_redo.add_undo_property(Global.current_project, "frames", Global.current_project.frames) Global.current_project.undo_redo.add_undo_property(Global.current_project, "current_frame", Global.current_project.current_frame)
Global.current_project.undo_redo.add_undo_method(Global, "undo") Global.current_project.undo_redo.add_undo_method(Global, "undo")
Global.current_project.undo_redo.add_do_method(Global, "redo") Global.current_project.undo_redo.add_do_method(Global, "redo")

View file

@ -45,9 +45,33 @@ func _input(event : InputEvent) -> void:
save_layer_name(line_edit.text) save_layer_name(line_edit.text)
func _on_LayerContainer_gui_input(event : InputEvent): func _on_LayerContainer_gui_input(event : InputEvent) -> void:
var project := Global.current_project
if event is InputEventMouseButton: if event is InputEventMouseButton:
Global.current_project.current_layer = layer var prev_curr_layer : int = project.current_layer
if Input.is_action_pressed("shift"):
var layer_diff_sign = sign(layer - prev_curr_layer)
if layer_diff_sign == 0:
layer_diff_sign = 1
for i in range(0, project.frames.size()):
for j in range(prev_curr_layer, layer + layer_diff_sign, layer_diff_sign):
var frame_layer := [i, j]
if !project.selected_cels.has(frame_layer):
project.selected_cels.append(frame_layer)
elif Input.is_action_pressed("ctrl"):
for i in range(0, project.frames.size()):
var frame_layer := [i, layer]
if !project.selected_cels.has(frame_layer):
project.selected_cels.append(frame_layer)
else: # If the button is pressed without Shift or Control
project.selected_cels.clear()
var frame_layer := [project.current_frame, layer]
if !project.selected_cels.has(frame_layer):
project.selected_cels.append(frame_layer)
project.current_layer = layer
if event.doubleclick: if event.doubleclick:
label.visible = false label.visible = false
line_edit.visible = true line_edit.visible = true

View file

@ -9,6 +9,7 @@
margin_right = 210.0 margin_right = 210.0
margin_bottom = 36.0 margin_bottom = 36.0
rect_min_size = Vector2( 212, 36 ) rect_min_size = Vector2( 212, 36 )
mouse_default_cursor_shape = 2
size_flags_horizontal = 0 size_flags_horizontal = 0
toggle_mode = true toggle_mode = true
action_mode = 0 action_mode = 0