diff --git a/CHANGELOG.md b/CHANGELOG.md index 157a91059..1c85f9340 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Laurenz Reinthaler (Schweini07), kleonc, Variable-ind ### Added - A new pan tool, used to move around the canvas. ([#399](https://github.com/Orama-Interactive/Pixelorama/pull/399)) - Dragging and dropping individual cels in the timeline to change their position is now possible. +- You can now resize cels in the timeline by holding `Control` and scrolling with the mouse wheel. - Added a new "Performance" tab in the Preferences that exposes options related to the application's FPS to the user. - Added a new pixel grid, which is a grid of size 1px and it appears after a certain zoom level. ([#427](https://github.com/Orama-Interactive/Pixelorama/pull/427)) - Added offset options to the grid. ([#434](https://github.com/Orama-Interactive/Pixelorama/pull/434)) @@ -28,13 +29,16 @@ Laurenz Reinthaler (Schweini07), kleonc, Variable-ind - Frame tags can now be set for frames larger than 100. ([#408](https://github.com/Orama-Interactive/Pixelorama/pull/408)) - The "lock aspect ratio" button in the create new image dialog has been changed to a texture button. - Improved the "Scale Image" dialog. It now automatically sets the size to the current project's size, has a button to lock aspect ratio, and resizing based on percentage. +- Tile mode rects are now cached for a little speedup. ([#443](https://github.com/Orama-Interactive/Pixelorama/pull/443)) ### Fixed - Fixed layer button textures not being updated properly when changing theme. ([#404](https://github.com/Orama-Interactive/Pixelorama/issues/404)) - Keyboard shortcut conflicts between tool shortcuts and other shortcuts that use the "Control" key, like menu shortcuts, have been resolved. ([#407](https://github.com/Orama-Interactive/Pixelorama/pull/407)) - The opacity of a cel and the tile mode opacity are now multiplicative. ([#414](https://github.com/Orama-Interactive/Pixelorama/pull/414)) - Fixed an issue where adding a new layer did not select it, rather it was selecting the above layer of the previously selected layer. ([#424](https://github.com/Orama-Interactive/Pixelorama/pull/424)) -- Fixed cel opacity not being always updated on the UI. ([#420](https://github.com/Orama-Interactive/Pixelorama/pull/420)) +- Fixed cel opacity not always being updated on the UI. ([#420](https://github.com/Orama-Interactive/Pixelorama/pull/420)) +- Loading empty backuped projects no longer result in a crash. ([#445](https://github.com/Orama-Interactive/Pixelorama/issues/445)) +- Fixed potential index out of bounds error when loading backup files. ([#446](https://github.com/Orama-Interactive/Pixelorama/pull/446))

## [v0.8.2] - 2020-12-12 diff --git a/src/Classes/Project.gd b/src/Classes/Project.gd index e723abe66..b313c7d62 100644 --- a/src/Classes/Project.gd +++ b/src/Classes/Project.gd @@ -127,7 +127,7 @@ func change_project() -> void: for j in range(frames.size()): # Create frame ID labels var label := Label.new() - label.rect_min_size.x = 36 + label.rect_min_size.x = Global.animation_timeline.cel_size label.align = Label.ALIGN_CENTER label.text = str(j + 1) if j == current_frame: @@ -383,7 +383,7 @@ func frames_changed(value : Array) -> void: for j in range(frames.size()): var label := Label.new() - label.rect_min_size.x = 36 + label.rect_min_size.x = Global.animation_timeline.cel_size label.align = Label.ALIGN_CENTER label.text = str(j + 1) Global.frame_ids.add_child(label) @@ -532,18 +532,19 @@ func animation_tags_changed(value : Array) -> void: child.queue_free() for tag in animation_tags: - var tag_c : Container = load("res://src/UI/Timeline/AnimationTag.tscn").instance() + var tag_base_size = Global.animation_timeline.cel_size + 3 + var tag_c : Container = load("res://src/UI/Timeline/AnimationTagUI.tscn").instance() Global.tag_container.add_child(tag_c) + tag_c.tag = tag var tag_position : int = Global.tag_container.get_child_count() - 1 Global.tag_container.move_child(tag_c, tag_position) tag_c.get_node("Label").text = tag.name tag_c.get_node("Label").modulate = tag.color tag_c.get_node("Line2D").default_color = tag.color - tag_c.rect_position.x = (tag.from - 1) * 39 + tag.from - + tag_c.rect_position.x = (tag.from - 1) * tag_base_size + tag.from var tag_size : int = tag.to - tag.from - tag_c.rect_min_size.x = (tag_size + 1) * 39 + tag_c.rect_min_size.x = (tag_size + 1) * tag_base_size tag_c.get_node("Line2D").points[2] = Vector2(tag_c.rect_min_size.x, 0) tag_c.get_node("Line2D").points[3] = Vector2(tag_c.rect_min_size.x, 32) diff --git a/src/UI/Timeline/AnimationTagUI.gd b/src/UI/Timeline/AnimationTagUI.gd new file mode 100644 index 000000000..2d18c047a --- /dev/null +++ b/src/UI/Timeline/AnimationTagUI.gd @@ -0,0 +1,4 @@ +extends VBoxContainer + + +var tag : AnimationTag diff --git a/src/UI/Timeline/AnimationTag.tscn b/src/UI/Timeline/AnimationTagUI.tscn similarity index 68% rename from src/UI/Timeline/AnimationTag.tscn rename to src/UI/Timeline/AnimationTagUI.tscn index 8265c8435..b1b1504f4 100644 --- a/src/UI/Timeline/AnimationTag.tscn +++ b/src/UI/Timeline/AnimationTagUI.tscn @@ -1,9 +1,12 @@ -[gd_scene format=2] +[gd_scene load_steps=2 format=2] -[node name="AnimationTag" type="VBoxContainer"] +[ext_resource path="res://src/UI/Timeline/AnimationTagUI.gd" type="Script" id=1] + +[node name="AnimationTagUI" type="VBoxContainer"] margin_right = 39.0 margin_bottom = 32.0 rect_min_size = Vector2( 39, 32 ) +script = ExtResource( 1 ) __meta__ = { "_edit_use_anchors_": false } @@ -11,7 +14,6 @@ __meta__ = { [node name="Line2D" type="Line2D" parent="."] points = PoolVector2Array( 0, 32, 0, 0, 39, 0, 39, 32 ) width = 1.0 -texture_mode = 1313163520 [node name="Label" type="Label" parent="."] margin_left = 7.0 diff --git a/src/UI/Timeline/AnimationTimeline.gd b/src/UI/Timeline/AnimationTimeline.gd index 468f996bc..df064d2d2 100644 --- a/src/UI/Timeline/AnimationTimeline.gd +++ b/src/UI/Timeline/AnimationTimeline.gd @@ -4,6 +4,10 @@ var animation_loop := 1 # 0 is no loop, 1 is cycle loop, 2 is ping-pong loop var animation_forward := true var first_frame := 0 var last_frame := 0 +var is_mouse_hover := false +var cel_size := 36 setget cel_size_changed +var min_cel_size := 36 +var max_cel_size := 144 var timeline_scroll : ScrollContainer var tag_scroll_container : ScrollContainer @@ -20,12 +24,47 @@ func _ready() -> void: fps_spinbox.value = Global.current_project.fps +func _input(event : InputEvent) -> void: + var mouse_pos := get_global_mouse_position() + var timeline_rect := Rect2(rect_global_position, rect_size) + if timeline_rect.has_point(mouse_pos): + if Input.is_key_pressed(KEY_CONTROL): + self.cel_size += (2 * int(event.is_action("zoom_in")) - 2 * int(event.is_action("zoom_out"))) + + func _h_scroll_changed(value : float) -> void: # Let the main timeline ScrollContainer affect the tag ScrollContainer too tag_scroll_container.get_child(0).rect_min_size.x = timeline_scroll.get_child(0).rect_size.x - 212 tag_scroll_container.scroll_horizontal = value +func cel_size_changed(value : int) -> void: + cel_size = clamp(value, min_cel_size, max_cel_size) + for layer_button in Global.layers_container.get_children(): + layer_button.rect_min_size.y = cel_size + layer_button.rect_size.y = cel_size + for layer in Global.current_project.layers: + for cel_button in layer.frame_container.get_children(): + cel_button.rect_min_size.x = cel_size + cel_button.rect_min_size.y = cel_size + cel_button.rect_size.x = cel_size + cel_button.rect_size.y = cel_size + + for frame_id in Global.frame_ids.get_children(): + frame_id.rect_min_size.x = cel_size + frame_id.rect_size.x = cel_size + + for tag_c in Global.tag_container.get_children(): + var tag_base_size = cel_size + 3 + var tag : AnimationTag = tag_c.tag + tag_c.rect_position.x = (tag.from - 1) * tag_base_size + tag.from + var tag_size : int = tag.to - tag.from + tag_c.rect_min_size.x = (tag_size + 1) * tag_base_size + tag_c.rect_size.x = (tag_size + 1) * tag_base_size + tag_c.get_node("Line2D").points[2] = Vector2(tag_c.rect_min_size.x, 0) + tag_c.get_node("Line2D").points[3] = Vector2(tag_c.rect_min_size.x, 32) + + func add_frame() -> void: var frame : Frame = Global.canvas.new_empty_frame() var new_frames : Array = Global.current_project.frames.duplicate() @@ -502,4 +541,3 @@ func _on_OpacitySlider_value_changed(value) -> void: func _on_OnionSkinningSettings_popup_hide() -> void: Global.can_draw = true - diff --git a/src/UI/Timeline/CelButton.gd b/src/UI/Timeline/CelButton.gd index a8373642f..fa2f311bd 100644 --- a/src/UI/Timeline/CelButton.gd +++ b/src/UI/Timeline/CelButton.gd @@ -7,6 +7,9 @@ onready var popup_menu : PopupMenu = $PopupMenu func _ready() -> void: + rect_min_size.x = Global.animation_timeline.cel_size + rect_min_size.y = Global.animation_timeline.cel_size + hint_tooltip = tr("Frame: %s, Layer: %s") % [frame + 1, layer] if Global.current_project.frames[frame] in Global.current_project.layers[layer].linked_cels: get_node("LinkedIndicator").visible = true @@ -22,6 +25,16 @@ func _ready() -> void: checker.rect_size = checker.get_parent().rect_size +func _on_CelButton_resized() -> void: + get_node("CelTexture").rect_min_size.x = rect_min_size.x - 4 + get_node("CelTexture").rect_min_size.y = rect_min_size.y - 4 + + get_node("LinkedIndicator").polygon[1].x = rect_min_size.x + get_node("LinkedIndicator").polygon[2].x = rect_min_size.x + get_node("LinkedIndicator").polygon[2].y = rect_min_size.y + get_node("LinkedIndicator").polygon[3].y = rect_min_size.y + + func _on_CelButton_pressed() -> void: if Input.is_action_just_released("left_mouse"): Global.current_project.current_frame = frame diff --git a/src/UI/Timeline/CelButton.tscn b/src/UI/Timeline/CelButton.tscn index 3ec82579b..996879970 100644 --- a/src/UI/Timeline/CelButton.tscn +++ b/src/UI/Timeline/CelButton.tscn @@ -67,4 +67,5 @@ invert_enable = true invert_border = 1.0 polygon = PoolVector2Array( 0, 0, 36, 0, 36, 36, 0, 36 ) [connection signal="pressed" from="." to="." method="_on_CelButton_pressed"] +[connection signal="resized" from="." to="." method="_on_CelButton_resized"] [connection signal="id_pressed" from="PopupMenu" to="." method="_on_PopupMenu_id_pressed"] diff --git a/src/UI/Timeline/LayerButton.gd b/src/UI/Timeline/LayerButton.gd index 2ef61a905..c8d32e76e 100644 --- a/src/UI/Timeline/LayerButton.gd +++ b/src/UI/Timeline/LayerButton.gd @@ -11,6 +11,7 @@ var line_edit : LineEdit func _ready() -> void: + rect_min_size.y = Global.animation_timeline.cel_size visibility_button = find_node("VisibilityButton") lock_button = find_node("LockButton") linked_button = find_node("LinkButton")