mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-01-19 09:39:48 +00:00
Merge branch 'Orama-Interactive:master' into Achievements
This commit is contained in:
commit
a3ab62d53a
|
@ -12,10 +12,12 @@ Built using Godot 4.2.2
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- Added tolerance to the bucket tool's "similar area" mode and to the magic wand tool.
|
- Added tolerance to the bucket tool's "similar area" mode and to the magic wand tool.
|
||||||
|
- It is now possible to move all selected cels between different frames, but they all have to be on the same layer.
|
||||||
- Cel properties of group and 3D cels can now be edited.
|
- Cel properties of group and 3D cels can now be edited.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Renamed the "similarity" slider of the select by color tool and the bucket tool's "similar colors" mode to "tolerance", and made it work the inverse way to make it consistent with other art software.
|
- Renamed the "similarity" slider of the select by color tool and the bucket tool's "similar colors" mode to "tolerance", and made it work the inverse way to make it consistent with other art software.
|
||||||
|
- It is now possible to change the blend modes of multiple selected layers from the timeline's option button.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Scaling with cleanEdge and OmniScale is now working again. [#1074](https://github.com/Orama-Interactive/Pixelorama/issues/1074)
|
- Scaling with cleanEdge and OmniScale is now working again. [#1074](https://github.com/Orama-Interactive/Pixelorama/issues/1074)
|
||||||
|
@ -24,6 +26,7 @@ Built using Godot 4.2.2
|
||||||
- Fixed crashes when attempting to export specific layers or tags that have been deleted.
|
- Fixed crashes when attempting to export specific layers or tags that have been deleted.
|
||||||
- Fixed crashes when importing brushes and palettes.
|
- Fixed crashes when importing brushes and palettes.
|
||||||
- Fixed an issue with the bucket tool filling with the wrong color.
|
- Fixed an issue with the bucket tool filling with the wrong color.
|
||||||
|
- Fixed bug where some buttons on the interface were not affected by the custom icon color on startup.
|
||||||
- Fixed issue with the cursor blinking at the edge of the canvas on some devices. [#1075](https://github.com/Orama-Interactive/Pixelorama/pull/1075)
|
- Fixed issue with the cursor blinking at the edge of the canvas on some devices. [#1075](https://github.com/Orama-Interactive/Pixelorama/pull/1075)
|
||||||
- Fixed wrong rendering of the isometric grid. [#1069](https://github.com/Orama-Interactive/Pixelorama/pull/1069)
|
- Fixed wrong rendering of the isometric grid. [#1069](https://github.com/Orama-Interactive/Pixelorama/pull/1069)
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
## Keychain
|
## Keychain
|
||||||
|
|
||||||
- Upstream: https://github.com/Orama-Interactive/Keychain
|
- Upstream: https://github.com/Orama-Interactive/Keychain
|
||||||
- Version: [7b02c8f31635dda73016bbc8d63a95025b157ce3](https://github.com/Orama-Interactive/Keychain/commit/7b02c8f31635dda73016bbc8d63a95025b157ce3)
|
- Version: [0ddeb6fd4f40438d09551ada475668b91ce23dea](https://github.com/Orama-Interactive/Keychain/commit/0ddeb6fd4f40438d09551ada475668b91ce23dea)
|
||||||
- License: [MIT](https://github.com/Orama-Interactive/Keychain/blob/main/LICENSE)
|
- License: [MIT](https://github.com/Orama-Interactive/Keychain/blob/main/LICENSE)
|
||||||
|
|
||||||
## gdgifexporter
|
## gdgifexporter
|
||||||
|
|
|
@ -10,8 +10,8 @@ const MOUSE_BUTTON_NAMES: PackedStringArray = [
|
||||||
"Wheel Down Button",
|
"Wheel Down Button",
|
||||||
"Wheel Left Button",
|
"Wheel Left Button",
|
||||||
"Wheel Right Button",
|
"Wheel Right Button",
|
||||||
"X Button 1",
|
"Mouse Thumb Button 1",
|
||||||
"X Button 2",
|
"Mouse Thumb Button 2",
|
||||||
]
|
]
|
||||||
|
|
||||||
const JOY_BUTTON_NAMES: PackedStringArray = [
|
const JOY_BUTTON_NAMES: PackedStringArray = [
|
||||||
|
|
|
@ -103,10 +103,10 @@ msgstr ""
|
||||||
msgid "Wheel Right Button"
|
msgid "Wheel Right Button"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "X Button 1"
|
msgid "Mouse Thumb Button 1"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "X Button 2"
|
msgid "Mouse Thumb Button 2"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "DualShock Cross, Xbox A, Nintendo B"
|
msgid "DualShock Cross, Xbox A, Nintendo B"
|
||||||
|
|
|
@ -109,11 +109,11 @@ msgstr "Τρόχος αριστερά"
|
||||||
msgid "Wheel Right Button"
|
msgid "Wheel Right Button"
|
||||||
msgstr "Τρόχος δεξιά"
|
msgstr "Τρόχος δεξιά"
|
||||||
|
|
||||||
msgid "X Button 1"
|
msgid "Mouse Thumb Button 1"
|
||||||
msgstr "Κουμπί X 1"
|
msgstr "Κουμπί αντίχειρα ποντικού 1"
|
||||||
|
|
||||||
msgid "X Button 2"
|
msgid "Mouse Thumb Button 2"
|
||||||
msgstr "Κουμπί X 2"
|
msgstr "Κουμπί αντίχειρα ποντικιού 2"
|
||||||
|
|
||||||
msgid "DualShock Cross, Xbox A, Nintendo B"
|
msgid "DualShock Cross, Xbox A, Nintendo B"
|
||||||
msgstr "DualShock Σταυρός, Xbox A, Nintendo B"
|
msgstr "DualShock Σταυρός, Xbox A, Nintendo B"
|
||||||
|
|
|
@ -752,19 +752,34 @@ func swap_layers(a: Dictionary, b: Dictionary) -> void:
|
||||||
_update_layer_ui()
|
_update_layer_ui()
|
||||||
|
|
||||||
|
|
||||||
func move_cel(from_frame: int, to_frame: int, layer: int) -> void:
|
## Moves multiple cels between different frames, but on the same layer.
|
||||||
|
## TODO: Perhaps figure out a way to optimize this. Right now it copies all of the cels of
|
||||||
|
## a layer into a temporary array, sorts it and then copies it into each frame's `cels` array
|
||||||
|
## on that layer. This was done in order to replicate the code from [method move_frames].
|
||||||
|
## TODO: Make a method like this, but for moving cels between different layers, on the same frame.
|
||||||
|
func move_cels_same_layer(
|
||||||
|
from_indices: PackedInt32Array, to_indices: PackedInt32Array, layer: int
|
||||||
|
) -> void:
|
||||||
Global.canvas.selection.transform_content_confirm()
|
Global.canvas.selection.transform_content_confirm()
|
||||||
selected_cels.clear()
|
selected_cels.clear()
|
||||||
var cel: BaseCel = frames[from_frame].cels[layer]
|
var cels: Array[BaseCel] = []
|
||||||
if from_frame < to_frame:
|
for frame in frames:
|
||||||
for f in range(from_frame, to_frame): # Forward range
|
cels.append(frame.cels[layer])
|
||||||
frames[f].cels[layer] = frames[f + 1].cels[layer] # Move left
|
var removed_cels: Array[BaseCel] = []
|
||||||
else:
|
for i in from_indices.size():
|
||||||
for f in range(from_frame, to_frame, -1): # Backward range
|
# With each removed index, future indices need to be lowered, so subtract by i
|
||||||
frames[f].cels[layer] = frames[f - 1].cels[layer] # Move right
|
removed_cels.append(cels.pop_at(from_indices[i] - i))
|
||||||
frames[to_frame].cels[layer] = cel
|
for i in to_indices.size():
|
||||||
Global.animation_timeline.project_cel_removed(from_frame, layer)
|
cels.insert(to_indices[i], removed_cels[i])
|
||||||
Global.animation_timeline.project_cel_added(to_frame, layer)
|
for i in frames.size():
|
||||||
|
var new_cel := cels[i]
|
||||||
|
frames[i].cels[layer] = new_cel
|
||||||
|
|
||||||
|
for i in from_indices.size():
|
||||||
|
# With each removed index, future indices need to be lowered, so subtract by i
|
||||||
|
Global.animation_timeline.project_cel_removed(from_indices[i] - i, layer)
|
||||||
|
for i in to_indices.size():
|
||||||
|
Global.animation_timeline.project_cel_added(to_indices[i], layer)
|
||||||
|
|
||||||
# Update the cel buttons for this layer:
|
# Update the cel buttons for this layer:
|
||||||
var cel_hbox: HBoxContainer = Global.cel_vbox.get_child(layers.size() - 1 - layer)
|
var cel_hbox: HBoxContainer = Global.cel_vbox.get_child(layers.size() - 1 - layer)
|
||||||
|
|
|
@ -260,26 +260,53 @@ func _get_drag_data(_position: Vector2) -> Variant:
|
||||||
texture_rect.texture = cel_texture.texture
|
texture_rect.texture = cel_texture.texture
|
||||||
button.add_child(texture_rect)
|
button.add_child(texture_rect)
|
||||||
set_drag_preview(button)
|
set_drag_preview(button)
|
||||||
|
return ["Cel", _get_cel_indices()]
|
||||||
return ["Cel", frame, layer]
|
|
||||||
|
|
||||||
|
|
||||||
func _can_drop_data(_pos: Vector2, data) -> bool:
|
func _can_drop_data(_pos: Vector2, data) -> bool:
|
||||||
var project := Global.current_project
|
var project := Global.current_project
|
||||||
if typeof(data) == TYPE_ARRAY and data[0] == "Cel":
|
if typeof(data) != TYPE_ARRAY:
|
||||||
var drag_frame = data[1]
|
Global.animation_timeline.drag_highlight.visible = false
|
||||||
var drag_layer = data[2]
|
return false
|
||||||
if project.layers[drag_layer].get_script() == project.layers[layer].get_script():
|
if data[0] != "Cel":
|
||||||
|
Global.animation_timeline.drag_highlight.visible = false
|
||||||
|
return false
|
||||||
|
var drop_cels: Array = data[1]
|
||||||
|
drop_cels.sort_custom(_sort_cel_indices_by_frame)
|
||||||
|
var drop_frames: PackedInt32Array = []
|
||||||
|
var drop_layers: PackedInt32Array = []
|
||||||
|
for cel_idx in drop_cels:
|
||||||
|
drop_frames.append(cel_idx[0])
|
||||||
|
drop_layers.append(cel_idx[1])
|
||||||
|
# Can't move to the same cel
|
||||||
|
for drop_frame in drop_frames:
|
||||||
|
if drop_frame == frame and drop_layers[-1] == layer:
|
||||||
|
Global.animation_timeline.drag_highlight.visible = false
|
||||||
|
return false
|
||||||
|
# Can't move different types of layers between them
|
||||||
|
for drop_layer in drop_layers:
|
||||||
|
if project.layers[drop_layer].get_script() != project.layers[layer].get_script():
|
||||||
|
Global.animation_timeline.drag_highlight.visible = false
|
||||||
|
return false
|
||||||
|
|
||||||
|
var drop_layer := drop_layers[0]
|
||||||
|
# Check if all dropped cels are on the same layer
|
||||||
|
var different_layers := false
|
||||||
|
for l in drop_layers:
|
||||||
|
if l != layer:
|
||||||
|
different_layers = true
|
||||||
|
# Check if any of the dropped cels are linked
|
||||||
|
var are_dropped_cels_linked := false
|
||||||
|
for f in drop_frames:
|
||||||
|
if project.frames[f].cels[drop_layer].link_set != null:
|
||||||
|
are_dropped_cels_linked = true
|
||||||
|
|
||||||
if ( # If both cels are on the same layer, or both are not linked
|
if ( # If both cels are on the same layer, or both are not linked
|
||||||
drag_layer == layer
|
drop_layer == layer
|
||||||
or (
|
or (project.frames[frame].cels[layer].link_set == null and not are_dropped_cels_linked)
|
||||||
project.frames[frame].cels[layer].link_set == null
|
|
||||||
and project.frames[drag_frame].cels[drag_layer].link_set == null
|
|
||||||
)
|
|
||||||
):
|
):
|
||||||
if not (drag_frame == frame and drag_layer == layer):
|
|
||||||
var region: Rect2
|
var region: Rect2
|
||||||
if Input.is_action_pressed("ctrl") or layer != drag_layer: # Swap cels
|
if Input.is_action_pressed("ctrl") or different_layers: # Swap cels
|
||||||
region = get_global_rect()
|
region = get_global_rect()
|
||||||
else: # Move cels
|
else: # Move cels
|
||||||
if _get_region_rect(0, 0.5).has_point(get_global_mouse_position()): # Left
|
if _get_region_rect(0, 0.5).has_point(get_global_mouse_position()): # Left
|
||||||
|
@ -298,15 +325,27 @@ func _can_drop_data(_pos: Vector2, data) -> bool:
|
||||||
|
|
||||||
|
|
||||||
func _drop_data(_pos: Vector2, data) -> void:
|
func _drop_data(_pos: Vector2, data) -> void:
|
||||||
var drop_frame: int = data[1]
|
var drop_cels: Array = data[1]
|
||||||
var drop_layer: int = data[2]
|
drop_cels.sort_custom(_sort_cel_indices_by_frame)
|
||||||
var project := Global.current_project
|
var drop_frames: PackedInt32Array = []
|
||||||
|
var drop_layers: PackedInt32Array = []
|
||||||
|
for cel_idx in drop_cels:
|
||||||
|
drop_frames.append(cel_idx[0])
|
||||||
|
drop_layers.append(cel_idx[1])
|
||||||
|
var drop_layer := drop_layers[0]
|
||||||
|
var different_layers := false
|
||||||
|
for l in drop_layers:
|
||||||
|
if l != layer:
|
||||||
|
different_layers = true
|
||||||
|
|
||||||
|
var project := Global.current_project
|
||||||
project.undo_redo.create_action("Move Cels")
|
project.undo_redo.create_action("Move Cels")
|
||||||
if Input.is_action_pressed("ctrl") or layer != drop_layer: # Swap cels
|
if Input.is_action_pressed("ctrl") or different_layers: # Swap cels
|
||||||
project.undo_redo.add_do_method(project.swap_cel.bind(frame, layer, drop_frame, drop_layer))
|
project.undo_redo.add_do_method(
|
||||||
|
project.swap_cel.bind(frame, layer, drop_frames[0], drop_layer)
|
||||||
|
)
|
||||||
project.undo_redo.add_undo_method(
|
project.undo_redo.add_undo_method(
|
||||||
project.swap_cel.bind(frame, layer, drop_frame, drop_layer)
|
project.swap_cel.bind(frame, layer, drop_frames[0], drop_layer)
|
||||||
)
|
)
|
||||||
else: # Move cels
|
else: # Move cels
|
||||||
var to_frame: int
|
var to_frame: int
|
||||||
|
@ -314,10 +353,16 @@ func _drop_data(_pos: Vector2, data) -> void:
|
||||||
to_frame = frame
|
to_frame = frame
|
||||||
else: # Right
|
else: # Right
|
||||||
to_frame = frame + 1
|
to_frame = frame + 1
|
||||||
|
for drop_frame in drop_frames:
|
||||||
if drop_frame < frame:
|
if drop_frame < frame:
|
||||||
to_frame -= 1
|
to_frame -= 1
|
||||||
project.undo_redo.add_do_method(project.move_cel.bind(drop_frame, to_frame, layer))
|
var to_frames := range(to_frame, to_frame + drop_frames.size())
|
||||||
project.undo_redo.add_undo_method(project.move_cel.bind(to_frame, drop_frame, layer))
|
project.undo_redo.add_do_method(
|
||||||
|
project.move_cels_same_layer.bind(drop_frames, to_frames, layer)
|
||||||
|
)
|
||||||
|
project.undo_redo.add_undo_method(
|
||||||
|
project.move_cels_same_layer.bind(to_frames, drop_frames, layer)
|
||||||
|
)
|
||||||
|
|
||||||
project.undo_redo.add_do_method(project.change_cel.bind(frame, layer))
|
project.undo_redo.add_do_method(project.change_cel.bind(frame, layer))
|
||||||
project.undo_redo.add_undo_method(
|
project.undo_redo.add_undo_method(
|
||||||
|
@ -343,3 +388,11 @@ func _get_cel_indices(add_current_cel := false) -> Array:
|
||||||
else:
|
else:
|
||||||
indices = [[frame, layer]]
|
indices = [[frame, layer]]
|
||||||
return indices
|
return indices
|
||||||
|
|
||||||
|
|
||||||
|
func _sort_cel_indices_by_frame(a: Array, b: Array) -> bool:
|
||||||
|
var frame_a: int = a[0]
|
||||||
|
var frame_b: int = b[0]
|
||||||
|
if frame_a < frame_b:
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
Loading…
Reference in a new issue