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:
parent
73cce5b740
commit
de850ce8a1
14 changed files with 322 additions and 128 deletions
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue