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:
parent
e825cc03e5
commit
b1e8bde3ac
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,5 +1,6 @@
|
|||
# Godot-specific ignores
|
||||
.import/
|
||||
export_presets.cfg
|
||||
|
||||
Scripts/Old/
|
||||
Assets/Graphics/Tools/
|
||||
|
|
0
Brushes/.gdignore
Normal file
0
Brushes/.gdignore
Normal file
BIN
Brushes/circle_9x9.png
Normal file
BIN
Brushes/circle_9x9.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 109 B |
BIN
Brushes/circle_filled_9x9.png
Normal file
BIN
Brushes/circle_filled_9x9.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 108 B |
46
Main.tscn
46
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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -101,7 +101,28 @@ 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):
|
||||
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)
|
||||
|
@ -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,9 +392,12 @@ 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:
|
||||
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()
|
||||
|
@ -391,9 +418,6 @@ func _on_ImportSprites_files_selected(paths) -> void:
|
|||
if canvas.size > max_size:
|
||||
biggest_canvas = canvas
|
||||
|
||||
else:
|
||||
OS.alert("Can't load file")
|
||||
|
||||
i += 1
|
||||
Global.current_frame = i - 1
|
||||
Global.canvas = Global.canvases[Global.canvases.size() - 1]
|
||||
|
|
|
@ -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]:
|
||||
|
|
|
@ -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=""
|
Loading…
Reference in a new issue