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,41 +43,50 @@ func _about_to_show() -> void:
func _confirmed() -> void:
var project := Global.current_project
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
Global.canvas.handle_undo("Draw")
commit_action(current_cel)
Global.canvas.handle_redo("Draw")
if project.selected_cels.size() == 1:
Global.canvas.handle_undo("Draw")
commit_action(current_cel)
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:
Global.canvas.handle_undo("Draw", Global.current_project, -1)
Global.canvas.handle_undo("Draw", project, -1)
var i := 0
for cel in Global.current_project.frames[Global.current_project.current_frame].cels:
if Global.current_project.layers[i].can_layer_get_drawn():
for cel in project.frames[project.current_frame].cels:
if project.layers[i].can_layer_get_drawn():
commit_action(cel.image)
i += 1
Global.canvas.handle_redo("Draw", Global.current_project, -1)
Global.canvas.handle_redo("Draw", project, -1)
elif affect == ALL_FRAMES:
Global.canvas.handle_undo("Draw", Global.current_project, -1, -1)
for frame in Global.current_project.frames:
Global.canvas.handle_undo("Draw", project, -1, -1)
for frame in project.frames:
var i := 0
for cel in frame.cels:
if Global.current_project.layers[i].can_layer_get_drawn():
if project.layers[i].can_layer_get_drawn():
commit_action(cel.image)
i += 1
Global.canvas.handle_redo("Draw", Global.current_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:
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)
if _project.layers[i].can_layer_get_drawn():
commit_action(cel.image, _project)
i += 1
Global.canvas.handle_redo("Draw", project, -1, -1)
Global.canvas.handle_redo("Draw", _project, -1, -1)
func commit_action(_cel : Image, _project : Project = Global.current_project) -> void:

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 current_frame := 0 setget frame_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 guides := [] # Array of Guides
var brushes := [] # Array of Images
@ -386,6 +388,7 @@ func size_changed(value : Vector2) -> void:
func frames_changed(value : Array) -> void:
frames = value
selected_cels.clear()
remove_cel_buttons()
for frame_id in Global.frame_ids.get_children():
@ -419,6 +422,8 @@ func layers_changed(value : Array) -> void:
Global.layers_changed_skip = false
return
selected_cels.clear()
for container in Global.layers_container.get_children():
container.queue_free()
@ -471,11 +476,16 @@ func frame_changed(value : int) -> void:
if i < layer.frame_container.get_child_count():
layer.frame_container.get_child(i).pressed = false
if selected_cels.empty():
selected_cels.append([current_frame, current_layer])
# Select the new frame
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 layers and current_frame < layers[current_layer].frame_container.get_child_count():
layers[current_layer].frame_container.get_child(current_frame).pressed = true
for cel in selected_cels:
var _current_frame : int = cel[0]
var _current_layer : int = cel[1]
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.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()
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()
yield(Global.get_tree().create_timer(0.01), "timeout")
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:

View file

@ -94,6 +94,15 @@ func _get_draw_image() -> 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:
var result := rect
if horizontal:

View file

@ -117,21 +117,22 @@ func draw_end(_position : Vector2) -> void:
func fill_in_color(position : Vector2) -> void:
var project : Project = Global.current_project
var image := _get_draw_image()
var color := image.get_pixelv(position)
if _fill_with == 0 or _pattern == null:
if tool_slot.color.is_equal_approx(color):
return
var color : Color = _get_draw_image().get_pixelv(position)
var images := _get_selected_draw_images()
for image in images:
if _fill_with == 0 or _pattern == null:
if tool_slot.color.is_equal_approx(color):
return
image.lock()
image.lock()
for x in Global.current_project.size.x:
for y in Global.current_project.size.y:
var pos := Vector2(x, y)
if project.has_selection and not project.can_pixel_get_drawn(pos):
continue
if image.get_pixelv(pos).is_equal_approx(color):
_set_pixel(image, x, y, tool_slot.color)
for x in Global.current_project.size.x:
for y in Global.current_project.size.y:
var pos := Vector2(x, y)
if project.has_selection and not project.can_pixel_get_drawn(pos):
continue
if image.get_pixelv(pos).is_equal_approx(color):
_set_pixel(image, x, y, tool_slot.color)
func fill_in_area(position : Vector2) -> void:
@ -157,35 +158,36 @@ func fill_in_area(position : Vector2) -> void:
func _flood_fill(position : Vector2) -> void:
var project : Project = Global.current_project
var image := _get_draw_image()
var color := image.get_pixelv(position)
if _fill_with == 0 or _pattern == null:
if tool_slot.color.is_equal_approx(color):
return
var images := _get_selected_draw_images()
for image in images:
var color : Color = image.get_pixelv(position)
if _fill_with == 0 or _pattern == null:
if tool_slot.color.is_equal_approx(color):
return
image.lock()
var processed := BitMap.new()
processed.create(image.get_size())
var q = [position]
for n in q:
if processed.get_bit(n):
continue
var west : Vector2 = n
var east : Vector2 = n
while west.x >= 0 && image.get_pixelv(west).is_equal_approx(color):
west += Vector2.LEFT
while east.x < project.size.x && image.get_pixelv(east).is_equal_approx(color):
east += Vector2.RIGHT
for px in range(west.x + 1, east.x):
var p := Vector2(px, n.y)
_set_pixel(image, p.x, p.y, tool_slot.color)
processed.set_bit(p, true)
var north := p + Vector2.UP
var south := p + Vector2.DOWN
if north.y >= 0 && image.get_pixelv(north).is_equal_approx(color):
q.append(north)
if south.y < project.size.y && image.get_pixelv(south).is_equal_approx(color):
q.append(south)
image.lock()
var processed := BitMap.new()
processed.create(image.get_size())
var q = [position]
for n in q:
if processed.get_bit(n):
continue
var west : Vector2 = n
var east : Vector2 = n
while west.x >= 0 && image.get_pixelv(west).is_equal_approx(color):
west += Vector2.LEFT
while east.x < project.size.x && image.get_pixelv(east).is_equal_approx(color):
east += Vector2.RIGHT
for px in range(west.x + 1, east.x):
var p := Vector2(px, n.y)
_set_pixel(image, p.x, p.y, tool_slot.color)
processed.set_bit(p, true)
var north := p + Vector2.UP
var south := p + Vector2.DOWN
if north.y >= 0 && image.get_pixelv(north).is_equal_approx(color):
q.append(north)
if south.y < project.size.y && image.get_pixelv(south).is_equal_approx(color):
q.append(south)
func _set_pixel(image : Image, x : int, y : int, color : Color) -> void:
@ -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:
var redo_data = _get_undo_data()
var redo_data := _get_undo_data()
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.undo_redo.create_action(action)
project.undo_redo.add_do_property(image, "data", redo_data["image_data"])
project.undo_redo.add_undo_property(image, "data", undo_data["image_data"])
project.undo_redo.add_do_method(Global, "redo", project.current_frame, project.current_layer)
project.undo_redo.add_undo_method(Global, "undo", project.current_frame, project.current_layer)
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()
func _get_undo_data() -> Dictionary:
var data = {}
var project : Project = Global.current_project
var image : Image = project.frames[project.current_frame].cels[project.current_layer].image
image.unlock()
data["image_data"] = image.data
image.lock()
var data := {}
var images := _get_selected_draw_images()
for image in images:
image.unlock()
data[image] = image.data
image.lock()
return data

View file

@ -130,7 +130,7 @@ func update_mirror_brush() -> void:
func update_mask(can_skip := true) -> void:
if can_skip and Global.pressure_sensitivity_mode == Global.PressureSensitivity.NONE:
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
var nulled_array := []
nulled_array.resize(size.x * size.y)
@ -155,11 +155,11 @@ func prepare_undo() -> 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 frame := -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
layer = project.current_layer
@ -347,14 +347,15 @@ func _set_pixel(position : Vector2) -> void:
if !project.can_pixel_get_drawn(position):
return
var image := _get_draw_image()
var i := int(position.x + position.y * image.get_size().x)
if _mask.size() >= i + 1:
if _mask[i] < Tools.pen_pressure:
_mask[i] = Tools.pen_pressure
var images := _get_selected_draw_images()
for image in images:
var i := int(position.x + position.y * image.get_size().x)
if _mask.size() >= i + 1:
if _mask[i] < Tools.pen_pressure:
_mask[i] = Tools.pen_pressure
_drawer.set_pixel(image, position, tool_slot.color)
else:
_drawer.set_pixel(image, position, tool_slot.color)
else:
_drawer.set_pixel(image, position, tool_slot.color)
func _draw_brush_image(_image : Image, _src_rect: Rect2, _dst: Vector2) -> void:
@ -515,13 +516,18 @@ func _line_angle_constraint(start : Vector2, end : Vector2) -> Dictionary:
func _get_undo_data() -> Dictionary:
var data = {}
var data := {}
var project : Project = Global.current_project
var frames := project.frames
var cels := [] # Array of Cels
if Global.animation_timer.is_stopped():
frames = [project.frames[project.current_frame]]
for frame in frames:
var image : Image = frame.cels[project.current_layer].image
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()

View file

@ -73,4 +73,7 @@ func _draw_brush_image(_image : Image, src_rect: Rect2, dst: Vector2) -> void:
var size := _image.get_size()
if _clear_image.get_size() != size:
_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
var _undo_data := {}
var _start_pos : Vector2
var _offset : Vector2
@ -29,6 +30,7 @@ func _input(event : InputEvent) -> void:
func draw_start(position : Vector2) -> void:
_start_pos = position
_offset = position
_undo_data = _get_undo_data()
if Global.current_project.has_selection:
selection_node.transform_content_start()
_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 project : Project = Global.current_project
var image : Image = _get_draw_image()
if project.has_selection:
selection_node.move_borders_end()
else:
Global.canvas.move_preview_location = Vector2.ZERO
var image_copy := Image.new()
image_copy.copy_from(image)
Global.canvas.handle_undo("Draw")
image.fill(Color(0, 0, 0, 0))
image.blit_rect(image_copy, Rect2(Vector2.ZERO, project.size), pixel_diff)
var images := _get_selected_draw_images()
for image in images:
var image_copy := Image.new()
image_copy.copy_from(image)
image.fill(Color(0, 0, 0, 0))
image.blit_rect(image_copy, Rect2(Vector2.ZERO, project.size), pixel_diff)
Global.canvas.handle_redo("Draw")
commit_undo("Draw")
_start_pos = Vector2.INF
_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:
_draw_points.append(_position)
if _draw_points.size() > 3:
var image = _get_draw_image()
var v = Vector2()
var image_size = image.get_size()
var image_size = Global.current_project.size
for x in image_size.x:
v.x = x
for y in image_size.y:
v.y = y
if Geometry.is_point_in_polygon(v, _draw_points):
image.lock()
draw_tool(v)
image.unlock()
if _changed or _drawer.color_op.changed:
commit_undo("Draw")
cursor_text = ""
@ -122,9 +119,10 @@ func draw_end(_position : Vector2) -> void:
func _draw_brush_image(image : Image, src_rect: Rect2, dst: Vector2) -> void:
_changed = true
var images := _get_selected_draw_images()
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:
_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
var current_project : Project = Global.current_project
if Global.has_focus:
if !cursor_image_has_changed:
cursor_image_has_changed = true
@ -96,7 +94,7 @@ func _input(event : InputEvent) -> void:
Tools.handle_draw(current_pixel.floor(), event)
if sprite_changed_this_frame:
update_texture(current_project.current_layer)
update_selected_cels_textures()
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
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:
# Past
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, "current_frame", frame + 1)
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, "current_frame", frame)
@ -279,6 +275,7 @@ func _on_AnimationTimer_timeout() -> void:
var fps = Global.current_project.fps
if animation_forward:
if Global.current_project.current_frame < last_frame:
Global.current_project.selected_cels.clear()
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.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.animation_timer.stop()
1: # Cycle loop
Global.current_project.selected_cels.clear()
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.start()
@ -298,6 +296,7 @@ func _on_AnimationTimer_timeout() -> void:
else:
if Global.current_project.current_frame > first_frame:
Global.current_project.selected_cels.clear()
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.start()
@ -308,6 +307,7 @@ func _on_AnimationTimer_timeout() -> void:
Global.play_forward.pressed = false
Global.animation_timer.stop()
1: # Cycle loop
Global.current_project.selected_cels.clear()
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.start()
@ -355,20 +355,24 @@ func play_animation(play : bool, forward_dir : bool) -> void:
func _on_NextFrame_pressed() -> void:
Global.current_project.selected_cels.clear()
if Global.current_project.current_frame < Global.current_project.frames.size() - 1:
Global.current_project.current_frame += 1
func _on_PreviousFrame_pressed() -> void:
Global.current_project.selected_cels.clear()
if Global.current_project.current_frame > 0:
Global.current_project.current_frame -= 1
func _on_LastFrame_pressed() -> void:
Global.current_project.selected_cels.clear()
Global.current_project.current_frame = Global.current_project.frames.size() - 1
func _on_FirstFrame_pressed() -> void:
Global.current_project.selected_cels.clear()
Global.current_project.current_frame = 0

View file

@ -43,13 +43,50 @@ func _on_CelButton_resized() -> void:
func _on_CelButton_pressed() -> void:
var project := Global.current_project
if Input.is_action_just_released("left_mouse"):
Global.current_project.current_frame = frame
Global.current_project.current_layer = layer
var change_cel := true
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"):
popup_menu.popup(Rect2(get_global_mouse_position(), Vector2.ONE))
pressed = !pressed
elif Input.is_action_just_released("middle_mouse"): # Middle mouse click
elif Input.is_action_just_released("middle_mouse"):
pressed = !pressed
delete_cel_contents()
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:
var new_frame = data[1]
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 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.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
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:
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
elif Input.is_action_just_released("right_mouse"):
if Global.current_project.frames.size() == 1:
popup_menu.set_item_disabled(0, true)
@ -26,7 +48,7 @@ func _button_pressed() -> void:
popup_menu.set_item_disabled(3, false)
popup_menu.popup(Rect2(get_global_mouse_position(), Vector2.ONE))
pressed = !pressed
elif Input.is_action_just_released("middle_mouse"): # Middle mouse click
elif Input.is_action_just_released("middle_mouse"):
pressed = !pressed
Global.animation_timeline._on_DeleteFrame_pressed(frame)
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.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:
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_do_method(Global, "redo")

View file

@ -45,9 +45,33 @@ func _input(event : InputEvent) -> void:
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:
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:
label.visible = false
line_edit.visible = true

View file

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