1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-01-18 17:19:50 +00:00

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.
This commit is contained in:
OverloadedOrama 2019-11-11 04:20:09 +02:00
parent e825cc03e5
commit b1e8bde3ac
10 changed files with 108 additions and 88 deletions

1
.gitignore vendored
View file

@ -1,5 +1,6 @@
# Godot-specific ignores
.import/
export_presets.cfg
Scripts/Old/
Assets/Graphics/Tools/

0
Brushes/.gdignore Normal file
View file

BIN
Brushes/circle_9x9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 B

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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]:

View file

@ -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=""