From d66c501b5c845effcf0691969ecfa8431232d19c Mon Sep 17 00:00:00 2001 From: OverloadedOrama <35376950+OverloadedOrama@users.noreply.github.com> Date: Wed, 13 Nov 2019 15:45:55 +0200 Subject: [PATCH] v0.4 - Undo/Redo, mirrored drawing, lighten/darken tool and more! In this commit: - Added notification labels that appear when the user does an action (for undoing, redoing and saving) - Fixed symmetry with custom brushes. - In Main.gd, current_save_path and current_export_path get cleared when the user creates a new drawing or opens one. v0.4 of Pixelorama is out! Check https://functionoverload590613498.wordpress.com/2019/11/13/pixelorama-v0-4-is-out/ for the full changelog. --- Main.tscn | 9 +++++++-- Prefabs/NotificationLabel.tscn | 17 +++++++++++++++++ README.md | 20 +++++++++++--------- Scripts/Canvas.gd | 8 ++++++-- Scripts/Global.gd | 19 +++++++++++++++---- Scripts/Main.gd | 7 +++++++ Scripts/NotificationLabel.gd | 15 +++++++++++++++ icon.png | Bin 3433 -> 3427 bytes project.godot | 2 +- 9 files changed, 79 insertions(+), 18 deletions(-) create mode 100644 Prefabs/NotificationLabel.tscn create mode 100644 Scripts/NotificationLabel.gd diff --git a/Main.tscn b/Main.tscn index 695a7f329..4f0e291a3 100644 --- a/Main.tscn +++ b/Main.tscn @@ -23,6 +23,7 @@ size_flags_horizontal = 3 custom_constants/separation = 0 [node name="ToolPanel" type="Panel" parent="UI"] +editor/display_folded = true margin_right = 230.0 margin_bottom = 600.0 rect_min_size = Vector2( 230, 0 ) @@ -36,6 +37,7 @@ size_flags_horizontal = 3 size_flags_vertical = 3 [node name="MenusAndTools" type="VBoxContainer" parent="UI/ToolPanel/Tools"] +editor/display_folded = true margin_right = 230.0 margin_bottom = 224.0 size_flags_vertical = 3 @@ -167,6 +169,7 @@ margin_right = 230.0 margin_bottom = 232.0 [node name="ToolOptions" type="HBoxContainer" parent="UI/ToolPanel/Tools"] +editor/display_folded = true margin_top = 236.0 margin_right = 230.0 margin_bottom = 460.0 @@ -174,7 +177,6 @@ size_flags_vertical = 3 custom_constants/separation = 0 [node name="LeftToolOptions" type="VBoxContainer" parent="UI/ToolPanel/Tools/ToolOptions"] -editor/display_folded = true margin_right = 113.0 margin_bottom = 224.0 size_flags_horizontal = 3 @@ -260,12 +262,14 @@ text = "C" margin_top = 166.0 margin_right = 113.0 margin_bottom = 190.0 +hint_tooltip = "Enable horizontal mirrored drawing for the left tool" text = "Horiz. Mirror" [node name="LeftVerticalMirroring" type="CheckBox" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions"] margin_top = 194.0 margin_right = 113.0 margin_bottom = 218.0 +hint_tooltip = "Enable vertical mirrored drawing for the left tool" text = "Vert. Mirror" [node name="VSeparator" type="VSeparator" parent="UI/ToolPanel/Tools/ToolOptions"] @@ -274,7 +278,6 @@ margin_right = 117.0 margin_bottom = 224.0 [node name="RightToolOptions" type="VBoxContainer" parent="UI/ToolPanel/Tools/ToolOptions"] -editor/display_folded = true margin_left = 117.0 margin_right = 230.0 margin_bottom = 224.0 @@ -360,12 +363,14 @@ text = "C" margin_top = 166.0 margin_right = 113.0 margin_bottom = 190.0 +hint_tooltip = "Enable horizontal mirrored drawing for the right tool" text = "Horiz. Mirror" [node name="RightVerticalMirroring" type="CheckBox" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions"] margin_top = 194.0 margin_right = 113.0 margin_bottom = 218.0 +hint_tooltip = "Enable vertical mirrored drawing for the right tool" text = "Vert. Mirror" [node name="HSeparator2" type="HSeparator" parent="UI/ToolPanel/Tools"] diff --git a/Prefabs/NotificationLabel.tscn b/Prefabs/NotificationLabel.tscn new file mode 100644 index 000000000..fb97a8c32 --- /dev/null +++ b/Prefabs/NotificationLabel.tscn @@ -0,0 +1,17 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://Scripts/NotificationLabel.gd" type="Script" id=1] + +[node name="NotificationLabel" type="Label"] +margin_right = 116.0 +margin_bottom = 14.0 +custom_colors/font_color_shadow = Color( 0, 0, 0, 1 ) +text = "Undo: Notification" +script = ExtResource( 1 ) + +[node name="Tween" type="Tween" parent="."] + +[node name="Timer" type="Timer" parent="."] +one_shot = true +autostart = true +[connection signal="timeout" from="Timer" to="." method="_on_Timer_timeout"] diff --git a/README.md b/README.md index 9d76243ba..e9a6e6823 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,30 @@ # Pixelorama - your free and open-source sprite editor! - A free & open-source 2D sprite editor, made with Godot Engine, using GDScript! + Your free & open-source 2D sprite editor, made in the Godot Engine, using GDScript! - [![Pixelorama's horrible UI](https://functionoverload590613498.files.wordpress.com/2019/10/screenshot_265.png)](https://www.youtube.com/watch?v=L8o8QKB8lPs) + [![Pixelorama's horrible UI](https://functionoverload590613498.files.wordpress.com/2019/11/screenshot_268.png)](https://www.youtube.com/watch?v=h3OJROgAR-A) -Current features as of version v0.3: +Current features as of version v0.4: -- Choosing between 4 tools – pencil, eraser, fill bucket and rectangle select – and mapping them to both of your left and right mouse buttons. That’s, pretty wild, huh? +- Choosing between 6 tools – pencil, eraser, fill bucket, paint same color, lighten/darken and rectangle select – and mapping them to both of your left and right mouse buttons. - Different colors and brush sizes for each of the mouse buttons. -- Custom brush support. +- Support of two types of custom brushes: "From files" and "per project" brushes. Custom brushes from files get loaded from the "Brushes" folder that comes with Pixelorama, and per project brushes get saved with the rectangle select tool. - Creating a new canvas with a size of your choosing. - Are you an animator? Then you've come to the right place! Pixelorama has its own Animation Timeline just for you!​ -- Importing PNG and JPEG images, and edit them inside Pixelorama. If you import multiple files, they will be added as individual animation frames. +- Import images and edit them inside Pixelorama. If you import multiple files, they will be added as individual animation frames. - Export your gorgeous art as PNG files. - Save snd open your projects as Pixelorama's custom file format, .pxo +- Undo/Redo support! +- Horizontal & vertical mirrored drawing! - Tile Mode for pattern creation! - Split screen mode to see your masterpiece twice! - Create straight lines for pencil and eraser by holding down Shift while you draw. - The middle mouse wheel isn’t forgotten, you can use it to pan around the canvas and by scrolling up and down, you can zoom in and out! - Keyboard shortcuts! I’m pretty sure this is a lifesaver for most of you. -- Just like onions, Pixelorama has a multiple layer system! You can add, remove, move up and down, clone and merge as many layers as you like! -- Scale and crop your images! +- Just like onions, Pixelorama has a multiple layer system! You can add, remove, move up and down, clone and merge as many layers as you like! You can also rename them! +- Scale, crop and flip your images! Make sure to read my blog post on Function(Overload) for more information! https://functionoverload590613498.wordpress.com/2019/08/18/i-made-my-own-sprite-editor-in-godot/ Download it as a stand-alone on itch.io: https://orama-interactive.itch.io/pixelorama -And if you like, consider helping me by sponsoring this project! +If you like, consider helping me by sponsoring this project! It would enable me to focus more on Pixelorama, and make more projects in the future! diff --git a/Scripts/Canvas.gd b/Scripts/Canvas.gd index 8bc4590f7..e0346f464 100644 --- a/Scripts/Canvas.gd +++ b/Scripts/Canvas.gd @@ -542,8 +542,12 @@ func draw_pixel(pos : Vector2, color : Color, current_mouse_button : String, cur src_rect.size.y = min(src_rect.size.y, selection_rect.size.y) #Handle mirroring - var mirror_x := east_limit + west_limit - pos.x - (pos.x - dst.x) - 1 - var mirror_y := south_limit + north_limit - pos.y - (pos.y - dst.y) - 1 + var mirror_x := east_limit + west_limit - pos.x - (pos.x - dst.x) + var mirror_y := south_limit + north_limit - pos.y - (pos.y - dst.y) + if int(pos_rect_clipped.size.x) % 2 != 0: + mirror_x -= 1 + if int(pos_rect_clipped.size.y) % 2 != 0: + mirror_y -= 1 if color.a > 0: #If it's the pencil layers[current_layer_index][0].blend_rect(custom_brush_image, src_rect, dst) diff --git a/Scripts/Global.gd b/Scripts/Global.gd index 0d46d1937..254c102f6 100644 --- a/Scripts/Global.gd +++ b/Scripts/Global.gd @@ -20,6 +20,7 @@ var draw_grid := false var canvases := [] # warning-ignore:unused_class_variable var hidden_canvases := [] +var control : Node var canvas : Canvas var canvas_parent : Node var second_viewport : ViewportContainer @@ -109,6 +110,7 @@ var custom_right_brush_texture := ImageTexture.new() func _ready() -> void: undo_redo = UndoRedo.new() var root = get_tree().get_root() + control = find_node_by_name(root, "Control") canvas = find_node_by_name(root, "Canvas") canvases.append(canvas) canvas_parent = canvas.get_parent() @@ -165,6 +167,12 @@ func find_node_by_name(root, node_name) -> Node: return found return null +func notification_label(text : String) -> void: + var notification : Label = load("res://Prefabs/NotificationLabel.tscn").instance() + notification.text = text + notification.rect_position = Vector2(240, OS.window_size.y - 150) + get_tree().get_root().add_child(notification) + func undo(_canvases : Array, layer_index : int = -1) -> void: undos -= 1 var action_name := undo_redo.get_current_action_name() @@ -202,7 +210,8 @@ func undo(_canvases : Array, layer_index : int = -1) -> void: frame_container.move_child(_canvases[0].frame_button, current_frame) canvas_parent.move_child(_canvases[0], current_frame) - print("Undo: ", action_name) + notification_label("Undo: %s" % action_name) + func redo(_canvases : Array, layer_index : int = -1) -> void: if undos < undo_redo.get_version(): #If we did undo and then redo @@ -241,7 +250,8 @@ func redo(_canvases : Array, layer_index : int = -1) -> void: frame_container.move_child(_canvases[0].frame_button, current_frame) canvas_parent.move_child(_canvases[0], current_frame) - print("Redo: ", action_name) + if control.redone: + notification_label("Redo: %s" % action_name) func frame_changed(value : int) -> void: current_frame = value @@ -302,7 +312,7 @@ func undo_custom_brush(_brush_button : Button = null) -> void: hbox_container.add_child(_brush_button) hbox_container.move_child(_brush_button, _brush_button.custom_brush_index - brushes_from_files) _brush_button.get_node("DeleteButton").visible = false - print("Undo: ", action_name) + notification_label("Undo: %s" % action_name) func redo_custom_brush(_brush_button : Button = null) -> void: if undos < undo_redo.get_version(): #If we did undo and then redo @@ -311,7 +321,8 @@ func redo_custom_brush(_brush_button : Button = null) -> void: var hbox_container := find_node_by_name(get_tree().get_root(), "CustomBrushHBoxContainer") if action_name == "Delete Custom Brush": hbox_container.remove_child(_brush_button) - print("Redo: ", action_name) + if control.redone: + notification_label("Redo: %s" % action_name) func update_left_custom_brush() -> void: if custom_left_brush_index > -1: diff --git a/Scripts/Main.gd b/Scripts/Main.gd index 81cc8f62e..1b434a901 100644 --- a/Scripts/Main.gd +++ b/Scripts/Main.gd @@ -9,6 +9,7 @@ var import_as_new_frame : CheckBox var export_all_frames : CheckBox var export_as_single_file : CheckBox var export_vertical_spritesheet : CheckBox +var redone := false var fps := 1.0 var animation_loop := 0 #0 is no loop, 1 is cycle loop, 2 is ping-pong loop var animation_forward := true @@ -168,7 +169,9 @@ func edit_menu_id_pressed(id : int) -> void: 0: #Undo Global.undo_redo.undo() 1: #Redo + redone = true Global.undo_redo.redo() + redone = false 2: #Scale Image $ScaleImage.popup_centered() Global.can_draw = false @@ -382,6 +385,7 @@ func _on_SaveSprite_file_selected(path) -> void: file.store_buffer(brush.get_data()) file.store_line("END_BRUSHES") file.close() + Global.notification_label("File saved") func _on_ImportSprites_files_selected(paths) -> void: if !import_as_new_frame.pressed: #If we're not adding a new frame, delete the previous @@ -442,6 +446,8 @@ func clear_canvases() -> void: if child is Canvas: child.queue_free() Global.canvases.clear() + current_save_path = "" + current_export_path = "" func _on_ExportSprites_file_selected(path : String) -> void: current_export_path = path @@ -461,6 +467,7 @@ func export_project() -> void: save_spritesheet() else: save_sprite(Global.canvas, current_export_path) + Global.notification_label("File exported") func save_sprite(canvas : Canvas, path : String) -> void: var whole_image := Image.new() diff --git a/Scripts/NotificationLabel.gd b/Scripts/NotificationLabel.gd new file mode 100644 index 000000000..7db0c4984 --- /dev/null +++ b/Scripts/NotificationLabel.gd @@ -0,0 +1,15 @@ +extends Label + +# Declare member variables here. Examples: +# var a = 2 +# var b = "text" + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + var tween := $Tween + tween.interpolate_property(self, "rect_position", rect_position, Vector2(rect_position.x, rect_position.y - 100), 1, Tween.TRANS_LINEAR, Tween.EASE_OUT) + tween.interpolate_property(self, "modulate", modulate, Color(modulate.r, modulate.g, modulate.b, 0), 1, Tween.TRANS_LINEAR, Tween.EASE_OUT) + tween.start() + +func _on_Timer_timeout() -> void: + queue_free() diff --git a/icon.png b/icon.png index 2b658158b6a2211b656d83fee35e3941e5ad376a..916277470c3f3337353fbc3d34549f1aec7ce85c 100644 GIT binary patch delta 3424 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 IM6N<$f_A~s(f|Me diff --git a/project.godot b/project.godot index d4c173d9f..ebda5c73e 100644 --- a/project.godot +++ b/project.godot @@ -29,7 +29,7 @@ _global_script_class_icons={ config/name="Pixelorama" run/main_scene="res://Main.tscn" config/icon="res://icon.png" -config/Version="v0.3" +config/Version="v0.4" [autoload]