From b1e8bde3ac9d40f5cf35b115bf512e91e562157b Mon Sep 17 00:00:00 2001 From: OverloadedOrama <35376950+OverloadedOrama@users.noreply.github.com> Date: Mon, 11 Nov 2019 04:20:09 +0200 Subject: [PATCH] Import brushes from folder - A new type of custom brush has been added, brushes from files! Basically there's a "Brushes" folder where Pixelorama can get brushes from, and, unlike the previous brushes, these are for all projects and are not saved in .pxo files. These brushes get loaded on the _ready() method of Main.gd, and are ignored by Godot. - There are now 2 containers for the two types of custom brushes. The main pixel brush is with the brushes from files. - Fixed bug where, if you had selected a custom "project" brush and loaded a .pxo file, the brush would still be selected, causing potential problems - Fixed bug where you could save a project brush that was completely transparent - Fixed bug where, if you named a file, some shortcuts would be activated. - export_presets.cfg is now ignored. --- .gitignore | 1 + Brushes/.gdignore | 0 Brushes/circle_9x9.png | Bin 0 -> 109 bytes Brushes/circle_filled_9x9.png | Bin 0 -> 108 bytes Main.tscn | 46 ++++++++++++------ Scripts/Canvas.gd | 6 +-- Scripts/Global.gd | 18 +++++-- Scripts/Main.gd | 86 ++++++++++++++++++++++------------ Scripts/SelectionRectangle.gd | 7 +-- export_presets.cfg | 32 ------------- 10 files changed, 108 insertions(+), 88 deletions(-) create mode 100644 Brushes/.gdignore create mode 100644 Brushes/circle_9x9.png create mode 100644 Brushes/circle_filled_9x9.png delete mode 100644 export_presets.cfg diff --git a/.gitignore b/.gitignore index 23fe2047c..0f14fc402 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # Godot-specific ignores .import/ +export_presets.cfg Scripts/Old/ Assets/Graphics/Tools/ diff --git a/Brushes/.gdignore b/Brushes/.gdignore new file mode 100644 index 000000000..e69de29bb diff --git a/Brushes/circle_9x9.png b/Brushes/circle_9x9.png new file mode 100644 index 0000000000000000000000000000000000000000..31b3119d0dd8fa68541196b5e44630d4b52f0a36 GIT binary patch literal 109 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1|%O$WD@{VCY~;iAre!QQyf_TPrT8?6LFxP zsm6z~q%el-!6zRU5d#nqSlTgRDvK=t^Tq9~*9w>zc>Z$#FVdQ&MBb@ E0BqJB%K!iX literal 0 HcmV?d00001 diff --git a/Brushes/circle_filled_9x9.png b/Brushes/circle_filled_9x9.png new file mode 100644 index 0000000000000000000000000000000000000000..417d77c8f1b0f86ab9c4cfc318b0a53db1a088cb GIT binary patch literal 108 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1|%O$WD@{V#-1*YAre!QQyf_TPrT71!DGUz z@u{amqc)~vO_lHmg@J9nki B9%TRk literal 0 HcmV?d00001 diff --git a/Main.tscn b/Main.tscn index f37c489b8..2a164e7d1 100644 --- a/Main.tscn +++ b/Main.tscn @@ -23,7 +23,6 @@ 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 ) @@ -37,10 +36,11 @@ size_flags_vertical = 3 [node name="MenusAndTools" type="VBoxContainer" parent="UI/ToolPanel/Tools"] margin_right = 230.0 -margin_bottom = 266.0 +margin_bottom = 242.0 size_flags_vertical = 3 [node name="MenuItems" type="HBoxContainer" parent="UI/ToolPanel/Tools/MenusAndTools"] +editor/display_folded = true margin_right = 230.0 margin_bottom = 20.0 @@ -72,6 +72,7 @@ mouse_default_cursor_shape = 2 text = "Help" [node name="PaintToolsContainer" type="HBoxContainer" parent="UI/ToolPanel/Tools/MenusAndTools"] +editor/display_folded = true margin_top = 24.0 margin_right = 230.0 margin_bottom = 44.0 @@ -118,6 +119,7 @@ button_mask = 3 text = "Bucket" [node name="ColorToolsContainer" type="HBoxContainer" parent="UI/ToolPanel/Tools/MenusAndTools"] +editor/display_folded = true margin_top = 48.0 margin_right = 230.0 margin_bottom = 68.0 @@ -144,6 +146,7 @@ button_mask = 3 text = "Lighten/Darken" [node name="SelectionToolsContainer2" type="HBoxContainer" parent="UI/ToolPanel/Tools/MenusAndTools"] +editor/display_folded = true margin_top = 72.0 margin_right = 230.0 margin_bottom = 92.0 @@ -159,22 +162,21 @@ button_mask = 3 text = "RectSelect" [node name="HSeparator" type="HSeparator" parent="UI/ToolPanel/Tools"] -margin_top = 270.0 +margin_top = 246.0 margin_right = 230.0 -margin_bottom = 274.0 +margin_bottom = 250.0 [node name="ToolOptions" type="HBoxContainer" parent="UI/ToolPanel/Tools"] -editor/display_folded = true -margin_top = 278.0 +margin_top = 254.0 margin_right = 230.0 -margin_bottom = 544.0 +margin_bottom = 496.0 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 = 266.0 +margin_bottom = 242.0 size_flags_horizontal = 3 [node name="LeftLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions"] @@ -269,13 +271,13 @@ text = "Vert. Mirror" [node name="VSeparator" type="VSeparator" parent="UI/ToolPanel/Tools/ToolOptions"] margin_left = 113.0 margin_right = 117.0 -margin_bottom = 266.0 +margin_bottom = 242.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 = 266.0 +margin_bottom = 242.0 size_flags_horizontal = 3 [node name="RightLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions"] @@ -367,18 +369,19 @@ margin_bottom = 218.0 text = "Vert. Mirror" [node name="HSeparator2" type="HSeparator" parent="UI/ToolPanel/Tools"] -margin_top = 548.0 +margin_top = 500.0 margin_right = 230.0 -margin_bottom = 552.0 +margin_bottom = 504.0 [node name="BrushesContainer" type="ScrollContainer" parent="UI/ToolPanel/Tools"] -margin_top = 556.0 +margin_top = 508.0 margin_right = 230.0 -margin_bottom = 592.0 +margin_bottom = 544.0 size_flags_horizontal = 3 scroll_vertical_enabled = false [node name="BrushHBoxContainer" type="HBoxContainer" parent="UI/ToolPanel/Tools/BrushesContainer"] +editor/display_folded = true margin_right = 36.0 margin_bottom = 36.0 @@ -397,6 +400,21 @@ centered = false offset = Vector2( 28, 0 ) [node name="HSeparator3" type="HSeparator" parent="UI/ToolPanel/Tools"] +margin_top = 548.0 +margin_right = 230.0 +margin_bottom = 552.0 + +[node name="CustomBrushesContainer" type="ScrollContainer" parent="UI/ToolPanel/Tools"] +margin_top = 556.0 +margin_right = 230.0 +margin_bottom = 592.0 +rect_min_size = Vector2( 0, 36 ) +size_flags_horizontal = 3 +scroll_vertical_enabled = false + +[node name="CustomBrushHBoxContainer" type="HBoxContainer" parent="UI/ToolPanel/Tools/CustomBrushesContainer"] + +[node name="HSeparator4" type="HSeparator" parent="UI/ToolPanel/Tools"] margin_top = 596.0 margin_right = 230.0 margin_bottom = 600.0 diff --git a/Scripts/Canvas.gd b/Scripts/Canvas.gd index 918e80b6a..01e363cd1 100644 --- a/Scripts/Canvas.gd +++ b/Scripts/Canvas.gd @@ -374,7 +374,7 @@ func _draw() -> void: var start_pos_x = mouse_pos.x - (Global.left_brush_size >> 1) var start_pos_y = mouse_pos.y - (Global.left_brush_size >> 1) draw_rect(Rect2(start_pos_x, start_pos_y, Global.left_brush_size, Global.left_brush_size), Color.blue, false) - Global.BRUSH_TYPES.CUSTOM: + Global.BRUSH_TYPES.FILE, Global.BRUSH_TYPES.CUSTOM: var custom_brush_size = Global.custom_left_brush_image.get_size() - Vector2.ONE var dst := rectangle_center(mouse_pos, custom_brush_size) draw_texture(Global.custom_left_brush_texture, dst) @@ -385,7 +385,7 @@ func _draw() -> void: var start_pos_x = mouse_pos.x - (Global.right_brush_size >> 1) var start_pos_y = mouse_pos.y - (Global.right_brush_size >> 1) draw_rect(Rect2(start_pos_x, start_pos_y, Global.right_brush_size, Global.right_brush_size), Color.red, false) - Global.BRUSH_TYPES.CUSTOM: + Global.BRUSH_TYPES.FILE, Global.BRUSH_TYPES.CUSTOM: var custom_brush_size = Global.custom_right_brush_image.get_size() - Vector2.ONE var dst := rectangle_center(mouse_pos, custom_brush_size) draw_texture(Global.custom_right_brush_texture, dst) @@ -505,7 +505,7 @@ func draw_pixel(pos : Vector2, color : Color, current_mouse_button : String) -> layers[current_layer_index][0].set_pixel(mirror_x, mirror_y, color) sprite_changed_this_frame = true - Global.BRUSH_TYPES.CUSTOM: + Global.BRUSH_TYPES.FILE, Global.BRUSH_TYPES.CUSTOM: var custom_brush_size := custom_brush_image.get_size() - Vector2.ONE pos = pos.floor() var dst := rectangle_center(pos, custom_brush_size) diff --git a/Scripts/Global.gd b/Scripts/Global.gd index 2de6c22d0..7931a959e 100644 --- a/Scripts/Global.gd +++ b/Scripts/Global.gd @@ -72,7 +72,7 @@ var current_left_tool := "Pencil" var current_right_tool := "Eraser" #Brushes -enum BRUSH_TYPES {PIXEL, CUSTOM} +enum BRUSH_TYPES {PIXEL, FILE, CUSTOM} # warning-ignore:unused_class_variable var left_brush_size := 1 # warning-ignore:unused_class_variable @@ -89,6 +89,8 @@ var left_vertical_mirror := false var right_horizontal_mirror := false # warning-ignore:unused_class_variable var right_vertical_mirror := false + +var brushes_from_files := 0 # warning-ignore:unused_class_variable var custom_brushes := [] # warning-ignore:unused_class_variable @@ -271,18 +273,24 @@ func frame_changed(value : int) -> void: move_right_frame_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND -func create_brush_button(brush_img : Image) -> void: +func create_brush_button(brush_img : Image, brush_type := BRUSH_TYPES.CUSTOM) -> void: + var hbox_container : HBoxContainer var brush_button = load("res://Prefabs/BrushButton.tscn").instance() - brush_button.brush_type = BRUSH_TYPES.CUSTOM + brush_button.brush_type = brush_type brush_button.custom_brush_index = custom_brushes.size() - 1 + if brush_type == BRUSH_TYPES.FILE: + hbox_container = find_node_by_name(get_tree().get_root(), "BrushHBoxContainer") + else: + hbox_container = find_node_by_name(get_tree().get_root(), "CustomBrushHBoxContainer") var brush_tex := ImageTexture.new() brush_tex.create_from_image(brush_img, 0) brush_button.get_child(0).texture = brush_tex - var hbox_container := find_node_by_name(get_tree().get_root(), "BrushHBoxContainer") hbox_container.add_child(brush_button) func remove_brush_buttons() -> void: - var hbox_container := find_node_by_name(get_tree().get_root(), "BrushHBoxContainer") + current_left_brush_type = BRUSH_TYPES.PIXEL + current_right_brush_type = BRUSH_TYPES.PIXEL + var hbox_container := find_node_by_name(get_tree().get_root(), "CustomBrushHBoxContainer") for child in hbox_container.get_children(): if child.name != "PixelBrushButton": hbox_container.remove_child(child) diff --git a/Scripts/Main.gd b/Scripts/Main.gd index 162fb14e7..81cc8f62e 100644 --- a/Scripts/Main.gd +++ b/Scripts/Main.gd @@ -101,12 +101,33 @@ func _ready() -> void: $ExportSprites.get_vbox().add_child(export_as_single_file) $ExportSprites.get_vbox().add_child(export_vertical_spritesheet) + var path := "Brushes" + var brushes_dir := Directory.new() + if !brushes_dir.dir_exists(path): + brushes_dir.make_dir(path) + + brushes_dir.open(path) + brushes_dir.list_dir_begin(true, true) + var file := brushes_dir.get_next() + while file != "": + if file.get_extension().to_upper() == "PNG": + var image := Image.new() + var err := image.load(path.plus_file(file)) + if err == OK: + image.convert(Image.FORMAT_RGBA8) + Global.custom_brushes.append(image) + Global.create_brush_button(image, Global.BRUSH_TYPES.FILE) + file = brushes_dir.get_next() + brushes_dir.list_dir_end() + Global.brushes_from_files = Global.custom_brushes.size() + func _input(event): - for t in tools: #Handle tool shortcuts - if event.is_action_pressed(t[2]): #Shortcut for right button (with Alt) - _on_Tool_pressed(t[0], false, false) - elif event.is_action_pressed(t[1]): #Shortcut for left button - _on_Tool_pressed(t[0], false, true) + if Global.has_focus: + for t in tools: #Handle tool shortcuts + if event.is_action_pressed(t[2]): #Shortcut for right button (with Alt) + _on_Tool_pressed(t[0], false, false) + elif event.is_action_pressed(t[1]): #Shortcut for left button + _on_Tool_pressed(t[0], false, true) func file_menu_id_pressed(id : int) -> void: match id: @@ -246,6 +267,7 @@ func _on_OpenSprite_file_selected(path) -> void: var err := file.open(path, File.READ) if err != OK: #An error occured file.close() + OS.alert("Can't load file") return var current_version : String = ProjectSettings.get_setting("application/config/Version") @@ -296,7 +318,8 @@ func _on_OpenSprite_file_selected(path) -> void: Global.right_color_picker.get_picker().add_preset(color) #Load custom brushes - Global.custom_brushes.clear() + #Global.custom_brushes.clear() + Global.custom_brushes.resize(Global.brushes_from_files) Global.remove_brush_buttons() var brush_line := file.get_line() @@ -351,7 +374,8 @@ func _on_SaveSprite_file_selected(path) -> void: file.store_var(left_palette) file.store_var(right_palette) #Save custom brushes - for brush in Global.custom_brushes: + for i in range(Global.brushes_from_files, Global.custom_brushes.size()): + var brush = Global.custom_brushes[i] file.store_line("/") file.store_16(brush.get_size().x) file.store_16(brush.get_size().y) @@ -368,31 +392,31 @@ func _on_ImportSprites_files_selected(paths) -> void: var biggest_canvas : Canvas var i := Global.canvases.size() for path in paths: - var image = Image.new() - var err = image.load(path) - if err == OK: - opensprite_file_selected = true - var canvas : Canvas = load("res://Prefabs/Canvas.tscn").instance() - canvas.size = image.get_size() - image.convert(Image.FORMAT_RGBA8) - image.lock() - var tex := ImageTexture.new() - tex.create_from_image(image, 0) - #Store [Image, ImageTexture, Layer Name, Visibity boolean] - canvas.layers.append([image, tex, "Layer 0", true]) - canvas.frame = i - Global.canvas_parent.add_child(canvas) - Global.canvases.append(canvas) - canvas.visible = false - if path == paths[0]: #If it's the first file - max_size = canvas.size - biggest_canvas = canvas - else: - if canvas.size > max_size: - biggest_canvas = canvas - - else: + var image := Image.new() + var err := image.load(path) + if err != OK: #An error occured OS.alert("Can't load file") + continue + + opensprite_file_selected = true + var canvas : Canvas = load("res://Prefabs/Canvas.tscn").instance() + canvas.size = image.get_size() + image.convert(Image.FORMAT_RGBA8) + image.lock() + var tex := ImageTexture.new() + tex.create_from_image(image, 0) + #Store [Image, ImageTexture, Layer Name, Visibity boolean] + canvas.layers.append([image, tex, "Layer 0", true]) + canvas.frame = i + Global.canvas_parent.add_child(canvas) + Global.canvases.append(canvas) + canvas.visible = false + if path == paths[0]: #If it's the first file + max_size = canvas.size + biggest_canvas = canvas + else: + if canvas.size > max_size: + biggest_canvas = canvas i += 1 Global.current_frame = i - 1 diff --git a/Scripts/SelectionRectangle.gd b/Scripts/SelectionRectangle.gd index 17823d20c..0cbe4024b 100644 --- a/Scripts/SelectionRectangle.gd +++ b/Scripts/SelectionRectangle.gd @@ -97,22 +97,23 @@ func _process(delta) -> void: #Handle copy if Input.is_action_just_pressed("copy") && Global.selected_pixels.size() > 0: - Global.image_clipboard = layer.get_rect(Rect2(polygon[0], polygon[2] - polygon[0])) #And save as custom brush var brush_img := Image.new() brush_img = layer.get_rect(Rect2(polygon[0], polygon[2] - polygon[0])) + if brush_img.is_invisible(): + return brush_img = brush_img.get_rect(brush_img.get_used_rect()) #save only the visible pixels Global.custom_brushes.append(brush_img) - Global.create_brush_button(brush_img) + Global.image_clipboard = layer.get_rect(Rect2(polygon[0], polygon[2] - polygon[0])) + #Handle paste if Input.is_action_just_pressed("paste") && Global.selected_pixels.size() > 0 && Global.image_clipboard.get_size() > Vector2.ZERO: Global.canvas.handle_undo("Draw") layer.blend_rect(Global.image_clipboard, Rect2(Vector2.ZERO, polygon[2]-polygon[0]), polygon[0]) layer.lock() Global.canvas.handle_redo("Draw") - #Global.canvas.update_texture(Global.canvas.current_layer_index) func _draw() -> void: if img.get_size() == polygon[2] - polygon[0]: diff --git a/export_presets.cfg b/export_presets.cfg deleted file mode 100644 index 80bac5dfb..000000000 --- a/export_presets.cfg +++ /dev/null @@ -1,32 +0,0 @@ -[preset.0] - -name="Windows Desktop" -platform="Windows Desktop" -runnable=true -custom_features="" -export_filter="all_resources" -include_filter="" -exclude_filter="" -export_path="C:/Users/Overloaded/Dropbox/Orama Interactive/Projects/[Programa Labs]/Pixelorama/Full of bugs/Pixelorama.exe" -patch_list=PoolStringArray( ) -script_export_mode=1 -script_encryption_key="" - -[preset.0.options] - -texture_format/bptc=false -texture_format/s3tc=true -texture_format/etc=false -texture_format/etc2=false -texture_format/no_bptc_fallbacks=true -binary_format/64_bits=true -custom_template/release="" -custom_template/debug="" -application/icon="" -application/file_version="0.3" -application/product_version="0.3" -application/company_name="Orama Interactive" -application/product_name="Pixelorama" -application/file_description="" -application/copyright="Orama Interactive 2019" -application/trademarks=""