From 031efc0cdb47ac9c68c767cd745f6ff5d10700c7 Mon Sep 17 00:00:00 2001 From: Manolis Papadeas <35376950+OverloadedOrama@users.noreply.github.com> Date: Thu, 17 Dec 2020 02:20:47 +0200 Subject: [PATCH] Make FPS project-specific and store it in the pxo files --- CHANGELOG.md | 15 +++++++++++++- src/Autoload/Export.gd | 8 ++++---- src/Classes/Project.gd | 6 +++++- src/UI/Canvas/CanvasPreview.gd | 4 ++-- src/UI/Dialogs/ExportDialog.gd | 10 +++++----- src/UI/Timeline/AnimationTimeline.gd | 11 ++++++---- src/UI/UI.tscn | 30 ++++++++++++++-------------- 7 files changed, 52 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a46a68dea..de9291538 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). All the dates are in YYYY-MM-DD format.

+ +## Unreleased +This update has been brought to you by the contributions of: + +Laurenz Reinthaler (Schweini07) + +### Added +- The FPS of the project animation is now stored in the pxo file. + +### Changed +- CPU usage has been significantly been lowered when Pixelorama is idle. ([#394](https://github.com/Orama-Interactive/Pixelorama/pull/394)) +

+ ## [v0.8.2] - 2020-12-12 This update has been brought to you by the contributions of: -PinyaColada, Rémi Verschelde (akien-mga), dasimonde, gschwind, AbhinavKDev +PinyaColada, Rémi Verschelde (akien-mga), dasimonde, gschwind, AbhinavKDev, Laurenz Reinthaler (Schweini07) ### Added - The lighten/darken tool now has a hue shifting mode. It lets users configure the shift in hue, saturation and value of the new shaded pixels. ([#189](https://github.com/Orama-Interactive/Pixelorama/issues/189)) diff --git a/src/Autoload/Export.gd b/src/Autoload/Export.gd index 539a78c16..515b022b6 100644 --- a/src/Autoload/Export.gd +++ b/src/Autoload/Export.gd @@ -216,16 +216,16 @@ func export_gif(args: Dictionary) -> void: match direction: AnimationDirection.FORWARD: for i in range(processed_images.size()): - write_frame_to_gif(processed_images[i], Global.current_project.frames[i].duration * (1 / Global.animation_timeline.fps), exporter, args["export_dialog"]) + write_frame_to_gif(processed_images[i], Global.current_project.frames[i].duration * (1 / Global.current_project.fps), exporter, args["export_dialog"]) AnimationDirection.BACKWARDS: for i in range(processed_images.size() - 1, -1, -1): - write_frame_to_gif(processed_images[i], Global.current_project.frames[i].duration * (1 / Global.animation_timeline.fps), exporter, args["export_dialog"]) + write_frame_to_gif(processed_images[i], Global.current_project.frames[i].duration * (1 / Global.current_project.fps), exporter, args["export_dialog"]) AnimationDirection.PING_PONG: export_progress_fraction = 100 / (processed_images.size() * 2) for i in range(0, processed_images.size()): - write_frame_to_gif(processed_images[i], Global.current_project.frames[i].duration * (1 / Global.animation_timeline.fps), exporter, args["export_dialog"]) + write_frame_to_gif(processed_images[i], Global.current_project.frames[i].duration * (1 / Global.current_project.fps), exporter, args["export_dialog"]) for i in range(processed_images.size() - 2, 0, -1): - write_frame_to_gif(processed_images[i], Global.current_project.frames[i].duration * (1 / Global.animation_timeline.fps), exporter, args["export_dialog"]) + write_frame_to_gif(processed_images[i], Global.current_project.frames[i].duration * (1 / Global.current_project.fps), exporter, args["export_dialog"]) if OS.get_name() == "HTML5": Html5FileExchange.save_gif(exporter.export_file_data(), args["export_paths"][0]) diff --git a/src/Classes/Project.gd b/src/Classes/Project.gd index b4a85310e..624b41535 100644 --- a/src/Classes/Project.gd +++ b/src/Classes/Project.gd @@ -14,8 +14,8 @@ var current_frame := 0 setget frame_changed var current_layer := 0 setget layer_changed var animation_tags := [] setget animation_tags_changed # Array of AnimationTags var guides := [] # Array of Guides - var brushes := [] # Array of Images +var fps := 6.0 var x_symmetry_point var y_symmetry_point @@ -177,6 +177,7 @@ func change_project() -> void: Global.canvas.grid.isometric_polylines.clear() Global.canvas.grid.update() Global.transparent_checker._ready() + Global.animation_timeline.fps_spinbox.value = fps Global.horizontal_ruler.update() Global.vertical_ruler.update() Global.preview_zoom_slider.value = -Global.camera_preview.zoom.x @@ -282,6 +283,7 @@ func serialize() -> Dictionary: "export_directory_path" : directory_path, "export_file_name" : file_name, "export_file_format" : file_format, + "fps" : fps } return project_data @@ -352,6 +354,8 @@ func deserialize(dict : Dictionary) -> void: file_name = dict.export_file_name if dict.has("export_file_format"): file_format = dict.export_file_format + if dict.has("fps"): + fps = dict.fps func name_changed(value : String) -> void: diff --git a/src/UI/Canvas/CanvasPreview.gd b/src/UI/Canvas/CanvasPreview.gd index c7379d60e..1c2163234 100644 --- a/src/UI/Canvas/CanvasPreview.gd +++ b/src/UI/Canvas/CanvasPreview.gd @@ -9,7 +9,7 @@ func _draw() -> void: if frame >= current_project.frames.size(): frame = current_project.current_frame - $AnimationTimer.wait_time = current_project.frames[frame].duration * (1 / Global.animation_timeline.fps) + $AnimationTimer.wait_time = current_project.frames[frame].duration * (1 / Global.current_project.fps) if animation_timer.is_stopped(): frame = current_project.current_frame @@ -30,6 +30,6 @@ func _on_AnimationTimer_timeout() -> void: frame = 0 $AnimationTimer.set_one_shot(true) - $AnimationTimer.wait_time = Global.current_project.frames[frame].duration * (1 / Global.animation_timeline.fps) + $AnimationTimer.wait_time = Global.current_project.frames[frame].duration * (1 / Global.current_project.fps) $AnimationTimer.start() update() diff --git a/src/UI/Dialogs/ExportDialog.gd b/src/UI/Dialogs/ExportDialog.gd index 20a3e5a11..c54b21158 100644 --- a/src/UI/Dialogs/ExportDialog.gd +++ b/src/UI/Dialogs/ExportDialog.gd @@ -149,7 +149,7 @@ func add_animated_preview() -> void: previews.add_child(container) frame_timer.set_one_shot(true) #The wait_time it can't change correctly if it is playing - frame_timer.wait_time = Global.current_project.frames[animated_preview_current_frame].duration * (1 / Global.animation_timeline.fps) + frame_timer.wait_time = Global.current_project.frames[animated_preview_current_frame].duration * (1 / Global.current_project.fps) frame_timer.start() @@ -363,14 +363,14 @@ func _on_FrameTimer_timeout() -> void: animated_preview_current_frame = 0 else: animated_preview_current_frame += 1 - frame_timer.wait_time = Global.current_project.frames[(animated_preview_current_frame - 1) % (animated_preview_frames.size())].duration * (1 / Global.animation_timeline.fps) + frame_timer.wait_time = Global.current_project.frames[(animated_preview_current_frame - 1) % (animated_preview_frames.size())].duration * (1 / Global.current_project.fps) frame_timer.start() Export.AnimationDirection.BACKWARDS: if animated_preview_current_frame == 0: animated_preview_current_frame = Export.processed_images.size() - 1 else: animated_preview_current_frame -= 1 - frame_timer.wait_time = Global.current_project.frames[(animated_preview_current_frame + 1) % (animated_preview_frames.size())].duration * (1 / Global.animation_timeline.fps) + frame_timer.wait_time = Global.current_project.frames[(animated_preview_current_frame + 1) % (animated_preview_frames.size())].duration * (1 / Global.current_project.fps) frame_timer.start() Export.AnimationDirection.PING_PONG: match pingpong_direction: @@ -382,7 +382,7 @@ func _on_FrameTimer_timeout() -> void: animated_preview_current_frame = 0 else: animated_preview_current_frame += 1 - frame_timer.wait_time = Global.current_project.frames[(animated_preview_current_frame - 1) % (animated_preview_frames.size())].duration * (1 / Global.animation_timeline.fps) + frame_timer.wait_time = Global.current_project.frames[(animated_preview_current_frame - 1) % (animated_preview_frames.size())].duration * (1 / Global.current_project.fps) frame_timer.start() Export.AnimationDirection.BACKWARDS: if animated_preview_current_frame == 0: @@ -392,7 +392,7 @@ func _on_FrameTimer_timeout() -> void: pingpong_direction = Export.AnimationDirection.FORWARD else: animated_preview_current_frame -= 1 - frame_timer.wait_time = Global.current_project.frames[(animated_preview_current_frame + 1) % (animated_preview_frames.size())].duration * (1 / Global.animation_timeline.fps) + frame_timer.wait_time = Global.current_project.frames[(animated_preview_current_frame + 1) % (animated_preview_frames.size())].duration * (1 / Global.current_project.fps) frame_timer.start() diff --git a/src/UI/Timeline/AnimationTimeline.gd b/src/UI/Timeline/AnimationTimeline.gd index b2238e3af..1d7e68984 100644 --- a/src/UI/Timeline/AnimationTimeline.gd +++ b/src/UI/Timeline/AnimationTimeline.gd @@ -1,6 +1,5 @@ extends Panel -var fps := 6.0 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 @@ -8,13 +7,15 @@ var last_frame := 0 var timeline_scroll : ScrollContainer var tag_scroll_container : ScrollContainer +var fps_spinbox : SpinBox func _ready() -> void: timeline_scroll = Global.find_node_by_name(self, "TimelineScroll") tag_scroll_container = Global.find_node_by_name(self, "TagScroll") + fps_spinbox = find_node("FPSValue") timeline_scroll.get_h_scrollbar().connect("value_changed", self, "_h_scroll_changed") - Global.animation_timer.wait_time = 1 / fps + Global.animation_timer.wait_time = 1 / Global.current_project.fps func _h_scroll_changed(value : float) -> void: @@ -230,6 +231,7 @@ func _on_AnimationTimer_timeout() -> void: $AnimationTimer.stop() return + var fps = Global.current_project.fps if animation_forward: if Global.current_project.current_frame < last_frame: Global.current_project.current_frame += 1 @@ -299,6 +301,7 @@ func play_animation(play : bool, forward_dir : bool) -> void: if play: Global.animation_timer.set_one_shot(true) # The wait_time can't change correctly if it is playing var duration : float = Global.current_project.frames[Global.current_project.current_frame].duration + var fps = Global.current_project.fps Global.animation_timer.wait_time = duration * (1 / fps) Global.animation_timer.start() animation_forward = forward_dir @@ -325,8 +328,8 @@ func _on_FirstFrame_pressed() -> void: func _on_FPSValue_value_changed(value : float) -> void: - fps = float(value) - Global.animation_timer.wait_time = 1 / fps + Global.current_project.fps = float(value) + Global.animation_timer.wait_time = 1 / Global.current_project.fps func _on_PastOnionSkinning_value_changed(value : float) -> void: diff --git a/src/UI/UI.tscn b/src/UI/UI.tscn index 4b1102748..63f16610f 100644 --- a/src/UI/UI.tscn +++ b/src/UI/UI.tscn @@ -23,6 +23,17 @@ [ext_resource path="res://assets/graphics/dark_themes/tools/zoom.png" type="Texture" id=21] [ext_resource path="res://src/UI/ViewportContainer.gd" type="Script" id=23] +[sub_resource type="ShaderMaterial" id=1] +shader = ExtResource( 9 ) +shader_param/size = 10.0 +shader_param/color1 = Color( 0.7, 0.7, 0.7, 1 ) +shader_param/color2 = Color( 1, 1, 1, 1 ) +shader_param/offset = Vector2( 0, 0 ) +shader_param/scale = Vector2( 0, 0 ) +shader_param/rect_size = Vector2( 0, 0 ) +shader_param/follow_movement = false +shader_param/follow_scale = false + [sub_resource type="ShaderMaterial" id=2] shader = ExtResource( 9 ) shader_param/size = 10.0 @@ -34,18 +45,7 @@ shader_param/rect_size = Vector2( 0, 0 ) shader_param/follow_movement = false shader_param/follow_scale = false -[sub_resource type="ShaderMaterial" id=3] -shader = ExtResource( 9 ) -shader_param/size = 10.0 -shader_param/color1 = Color( 0.7, 0.7, 0.7, 1 ) -shader_param/color2 = Color( 1, 1, 1, 1 ) -shader_param/offset = Vector2( 0, 0 ) -shader_param/scale = Vector2( 0, 0 ) -shader_param/rect_size = Vector2( 0, 0 ) -shader_param/follow_movement = false -shader_param/follow_scale = false - -[sub_resource type="StyleBoxFlat" id=1] +[sub_resource type="StyleBoxFlat" id=3] bg_color = Color( 0.0627451, 0.0627451, 0.0627451, 1 ) expand_margin_top = 6.0 @@ -299,7 +299,7 @@ usage = 0 render_target_update_mode = 3 [node name="TransparentChecker" parent="CanvasAndTimeline/ViewportAndRulers/HSplitContainer/ViewportandVerticalRuler/ViewportContainer/Viewport" instance=ExtResource( 5 )] -material = SubResource( 2 ) +material = SubResource( 1 ) [node name="Canvas" parent="CanvasAndTimeline/ViewportAndRulers/HSplitContainer/ViewportandVerticalRuler/ViewportContainer/Viewport" instance=ExtResource( 19 )] @@ -331,7 +331,7 @@ handle_input_locally = false render_target_update_mode = 3 [node name="TransparentChecker" parent="CanvasAndTimeline/ViewportAndRulers/HSplitContainer/ViewportContainer2/Viewport" instance=ExtResource( 5 )] -material = SubResource( 3 ) +material = SubResource( 2 ) [node name="CanvasPreview" parent="CanvasAndTimeline/ViewportAndRulers/HSplitContainer/ViewportContainer2/Viewport" instance=ExtResource( 2 )] @@ -343,7 +343,7 @@ script = ExtResource( 7 ) [node name="AnimationTimeline" parent="CanvasAndTimeline" instance=ExtResource( 18 )] margin_top = 492.0 margin_bottom = 692.0 -custom_styles/panel = SubResource( 1 ) +custom_styles/panel = SubResource( 3 ) [node name="RightPanel" type="Panel" parent="."] margin_left = 950.0