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

Initial commit

This commit is contained in:
OverloadedOrama 2019-08-18 12:28:38 +03:00
commit f647a42752
71 changed files with 1548 additions and 0 deletions

2
.gitattributes vendored Normal file
View file

@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

1
.github/FUNDING.yml vendored Normal file
View file

@ -0,0 +1 @@
custom: https://www.paypal.me/OverloadedOrama

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
Scripts/Old/

View file

@ -0,0 +1,3 @@
source_md5="b8469a8d2b9b7f33cde9c50c882514d3"
dest_md5="611bf34048e600d74fb53c849097c026"

View file

@ -0,0 +1,3 @@
source_md5="3f3e12abce4c2177df141c708b02c3cc"
dest_md5="5bb71e82d18a6514c7bec6e2f2996585"

View file

@ -0,0 +1,3 @@
source_md5="90f1e764a9d0303186411784568ef237"
dest_md5="b40997122ed6d10d1612023e114c7315"

View file

@ -0,0 +1,3 @@
source_md5="90f1e764a9d0303186411784568ef237"
dest_md5="5d2507d2ac9dd6d7f8b781cd64e5e4b6"

View file

@ -0,0 +1,3 @@
source_md5="4c6be4fbf792fca422d20d3708852deb"
dest_md5="3f5ec639e0b1538d10f32d07e82950fc"

View file

@ -0,0 +1,3 @@
source_md5="6861c2574df688e89c30a4d2c3ff0512"
dest_md5="5eaa4f1834b413cd6fba1a5e73afdea5"

View file

@ -0,0 +1,3 @@
source_md5="6942d1787a239574517fad8cb24f6443"
dest_md5="5bff2bbc2ec94087f5589b982b0b041d"

View file

@ -0,0 +1,3 @@
source_md5="12b72e84ba20c6659f35eb14d15e384f"
dest_md5="58d1bf2a5d6f24f60937a609877419e1"

View file

@ -0,0 +1,3 @@
source_md5="8cf2e7f9a33f51edd3c13d15baef18e3"
dest_md5="f4ac734b475a905875624c9103984093"

Binary file not shown.

View file

@ -0,0 +1,3 @@
source_md5="327bd47a99785cc67d3b563e11e15386"
dest_md5="f762a141beffeb685bedf56872c571fc"

View file

@ -0,0 +1,3 @@
source_md5="8dd9ff1eebf38898a54579d8c01b0a88"
dest_md5="da70afec3c66d4e872db67f808e12edb"

Binary file not shown.

View file

@ -0,0 +1,3 @@
source_md5="afb486d3e8d644a5cef52b79404018c8"
dest_md5="9c8d35cdd51018124a515cca005b90c8"

Binary file not shown.

View file

@ -0,0 +1,3 @@
source_md5="3b9968d48bb94408d74340e812e4a715"
dest_md5="2d008139a38b2c0df1d773b0eb202d2f"

View file

@ -0,0 +1,3 @@
source_md5="d0ec0d56b87c9a8c60688d6af9d226a0"
dest_md5="605f5c73c93dc2a072713c6f3fcd0563"

View file

@ -0,0 +1,3 @@
source_md5="1afa25ff3984b4aa5d235e151ea745f2"
dest_md5="3331184ae61337c572353772eeedb37b"

View file

@ -0,0 +1,3 @@
source_md5="8cc6a8f03f20c923403c7d96eb234a23"
dest_md5="b99e77f302c757ba661cafd4fec3bab0"

View file

@ -0,0 +1,3 @@
source_md5="2d305c9c1574dd800cd89ab58219d34e"
dest_md5="24117996741ddae3a5250c04b3b71e04"

View file

@ -0,0 +1,3 @@
source_md5="bcdb748e2ada0c3dbc28698c89b242ea"
dest_md5="2bd02d97a5efa3e07380fe97a40d14e8"

View file

@ -0,0 +1,3 @@
source_md5="c0a02d16fd2d93552cb4f1b3bd38e1ba"
dest_md5="c20e14e5d1164cacc78d8d9dad66d3a3"

View file

@ -0,0 +1,3 @@
source_md5="16bf0d760b5c4ff30efd2a7ddb10c5a7"
dest_md5="c9a9e4d828f496f7c9371c42dd41c332"

View file

@ -0,0 +1,3 @@
source_md5="702bfdd94a8185490af255dd080e549d"
dest_md5="0944e37fba7b57fbcd1c1b699eddb31f"

View file

@ -0,0 +1,8 @@
[gd_resource type="DynamicFont" load_steps=2 format=2]
[ext_resource path="res://Assets/Fonts/Roboto-Regular.ttf" type="DynamicFontData" id=1]
[resource]
use_mipmaps = true
use_filter = true
font_data = ExtResource( 1 )

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/eraser.png-63c5caed334f555f34b58013167136d1.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Assets/Graphics/Tools/eraser.png"
dest_files=[ "res://.import/eraser.png-63c5caed334f555f34b58013167136d1.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/fill bucket.png-52b75bf5bbdd3ccd544de66c0c6f7825.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Assets/Graphics/Tools/fill bucket.png"
dest_files=[ "res://.import/fill bucket.png-52b75bf5bbdd3ccd544de66c0c6f7825.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/pencil.png-f45fc5ea6bc3e16a40ce7f3bc56fc30d.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Assets/Graphics/Tools/pencil.png"
dest_files=[ "res://.import/pencil.png-f45fc5ea6bc3e16a40ce7f3bc56fc30d.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

View file

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="792px" height="792px" viewBox="0 0 792 792" style="enable-background:new 0 0 792 792;" xml:space="preserve">
<g>
<g>
<path d="M587.812,235.125h-2.475c-16.385-46.122-54.858-81.725-102.713-94.112V68.062c0-10.247-8.316-18.562-18.562-18.562
h-37.125c-10.246,0-18.562,8.316-18.562,18.562v72.951c-47.854,12.387-86.328,47.99-102.712,94.112h-1.238
c-40.949,0-69.3,27.114-69.3,68.062V722.7c0,40.948,28.351,69.3,69.3,69.3h283.388c40.949,0,68.062-28.352,68.062-69.3V303.188
C655.875,262.239,628.762,235.125,587.812,235.125z M445.5,185.625c36.543,0,68.459,19.961,85.61,49.5H359.89
C377.042,205.586,408.957,185.625,445.5,185.625z M304.425,284.625H346.5h198h37.125h6.188c13.612,0,18.562,4.95,18.562,18.562
v30.938h-321.75v-30.938C284.625,289.575,290.812,284.625,304.425,284.625z M606.375,383.625V643.5h-321.75V383.625H606.375z
M587.812,742.5H304.425c-13.612,0-19.8-6.188-19.8-19.8V693h321.75v29.7C606.375,736.312,601.425,742.5,587.812,742.5z"/>
<circle cx="346.5" cy="86.625" r="24.75"/>
<circle cx="235.125" cy="86.625" r="24.75"/>
<circle cx="297" cy="148.5" r="24.75"/>
<circle cx="297" cy="24.75" r="24.75"/>
<circle cx="160.875" cy="148.5" r="24.75"/>
<circle cx="160.875" cy="24.75" r="24.75"/>
</g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/spraying-bottle-outline.svg-1ab842341f40f026a62a13ccf7ff4577.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Assets/Graphics/Tools/spraying-bottle-outline.svg"
dest_files=[ "res://.import/spraying-bottle-outline.svg-1ab842341f40f026a62a13ccf7ff4577.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

BIN
Assets/Graphics/grid.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 B

View file

@ -0,0 +1,13 @@
[remap]
importer="image"
type="Image"
path="res://.import/grid.png-643b5c8878aaf0c84a360796789dae22.image"
[deps]
source_file="res://Assets/Graphics/grid.png"
dest_files=[ "res://.import/grid.png-643b5c8878aaf0c84a360796789dae22.image" ]
[params]

BIN
Assets/Graphics/left.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/left.png-a0857f5581a7224bc4706f5b5b072c04.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Assets/Graphics/left.png"
dest_files=[ "res://.import/left.png-a0857f5581a7224bc4706f5b5b072c04.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

BIN
Assets/Graphics/right.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/right.png-e081bdade321da1277a90c4dc43840cc.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Assets/Graphics/right.png"
dest_files=[ "res://.import/right.png-e081bdade321da1277a90c4dc43840cc.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

12
Canvas.tscn Normal file
View file

@ -0,0 +1,12 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://Scripts/Canvas.gd" type="Script" id=1]
[node name="Canvas" type="Node2D"]
script = ExtResource( 1 )
[node name="Timer" type="Timer" parent="."]
wait_time = 0.2
one_shot = true
autostart = true
[connection signal="timeout" from="Timer" to="." method="_on_Timer_timeout"]

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 OverloadedOrama
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

38
LayerContainer.tscn Normal file
View file

@ -0,0 +1,38 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://Scripts/LayerContainer.gd" type="Script" id=1]
[node name="LayerContainer" type="PanelContainer"]
margin_top = 42.0
margin_right = 159.0
margin_bottom = 88.0
script = ExtResource( 1 )
[node name="HBoxContainer" type="HBoxContainer" parent="."]
margin_left = 7.0
margin_top = 7.0
margin_right = 152.0
margin_bottom = 39.0
[node name="VisibilityButton" type="Button" parent="HBoxContainer"]
margin_right = 20.0
margin_bottom = 32.0
text = "V"
[node name="TextureRect" type="TextureRect" parent="HBoxContainer"]
margin_left = 24.0
margin_right = 56.0
margin_bottom = 32.0
rect_min_size = Vector2( 32, 32 )
expand = true
[node name="Label" type="Label" parent="HBoxContainer"]
margin_left = 60.0
margin_top = 9.0
margin_right = 106.0
margin_bottom = 23.0
text = "Layer 0"
align = 1
[connection signal="button_down" from="HBoxContainer/VisibilityButton" to="." method="_on_VisibilityButton_button_down"]
[connection signal="button_up" from="HBoxContainer/VisibilityButton" to="." method="_on_VisibilityButton_button_up"]
[connection signal="pressed" from="HBoxContainer/VisibilityButton" to="." method="_on_VisibilityButton_pressed"]

7
Main Theme.tres Normal file
View file

@ -0,0 +1,7 @@
[gd_resource type="Theme" load_steps=2 format=2]
[sub_resource type="StyleBoxFlat" id=1]
bg_color = Color( 0.239216, 0.231373, 0.270588, 1 )
[resource]
PanelContainer/styles/panel = SubResource( 1 )

335
Main.tscn Normal file
View file

@ -0,0 +1,335 @@
[gd_scene load_steps=7 format=2]
[ext_resource path="res://Scripts/Main.gd" type="Script" id=1]
[ext_resource path="res://Main Theme.tres" type="Theme" id=2]
[ext_resource path="res://Assets/Graphics/left.png" type="Texture" id=3]
[ext_resource path="res://Assets/Graphics/right.png" type="Texture" id=4]
[ext_resource path="res://Canvas.tscn" type="PackedScene" id=5]
[ext_resource path="res://Scripts/CameraMovement.gd" type="Script" id=6]
[node name="Control" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 1 )
[node name="UI" type="HBoxContainer" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
size_flags_horizontal = 3
[node name="ToolPanel" type="Panel" parent="UI"]
margin_right = 320.0
margin_bottom = 600.0
rect_min_size = Vector2( 320, 0 )
[node name="VBoxContainer" type="VBoxContainer" parent="UI/ToolPanel"]
margin_right = 40.0
margin_bottom = 44.0
[node name="MenuItems" type="HBoxContainer" parent="UI/ToolPanel/VBoxContainer"]
margin_right = 166.0
margin_bottom = 20.0
[node name="FileMenu" type="MenuButton" parent="UI/ToolPanel/VBoxContainer/MenuItems"]
margin_right = 35.0
margin_bottom = 20.0
theme = ExtResource( 2 )
text = "File"
[node name="EditMenu" type="MenuButton" parent="UI/ToolPanel/VBoxContainer/MenuItems"]
margin_left = 39.0
margin_right = 75.0
margin_bottom = 20.0
theme = ExtResource( 2 )
text = "Edit"
[node name="ToolsContainer" type="HBoxContainer" parent="UI/ToolPanel/VBoxContainer"]
margin_top = 24.0
margin_right = 166.0
margin_bottom = 44.0
[node name="Pencil" type="Button" parent="UI/ToolPanel/VBoxContainer/ToolsContainer"]
margin_right = 51.0
margin_bottom = 20.0
button_mask = 3
text = "Pencil"
[node name="LeftIndicator" type="Sprite" parent="UI/ToolPanel/VBoxContainer/ToolsContainer/Pencil"]
z_index = 1
texture = ExtResource( 3 )
centered = false
offset = Vector2( 0, -10 )
[node name="Eraser" type="Button" parent="UI/ToolPanel/VBoxContainer/ToolsContainer"]
margin_left = 55.0
margin_right = 106.0
margin_bottom = 20.0
button_mask = 3
text = "Eraser"
[node name="RightIndicator" type="Sprite" parent="UI/ToolPanel/VBoxContainer/ToolsContainer/Eraser"]
z_index = 1
texture = ExtResource( 4 )
centered = false
offset = Vector2( 35, -10 )
[node name="Fill" type="Button" parent="UI/ToolPanel/VBoxContainer/ToolsContainer"]
margin_left = 110.0
margin_right = 166.0
margin_bottom = 20.0
button_mask = 3
text = "Bucket"
[node name="ColorPickers" type="HBoxContainer" parent="UI/ToolPanel/VBoxContainer"]
margin_top = 48.0
margin_right = 166.0
margin_bottom = 80.0
[node name="LeftColorPickerButton" type="ColorPickerButton" parent="UI/ToolPanel/VBoxContainer/ColorPickers"]
margin_right = 32.0
margin_bottom = 32.0
rect_min_size = Vector2( 32, 32 )
size_flags_horizontal = 0
[node name="RightColorPickerButton" type="ColorPickerButton" parent="UI/ToolPanel/VBoxContainer/ColorPickers"]
margin_left = 36.0
margin_right = 68.0
margin_bottom = 32.0
rect_min_size = Vector2( 32, 32 )
size_flags_horizontal = 0
[node name="ViewportContainer" type="ViewportContainer" parent="UI"]
editor/display_folded = true
margin_left = 324.0
margin_right = 860.0
margin_bottom = 600.0
size_flags_horizontal = 3
stretch = true
[node name="Viewport" type="Viewport" parent="UI/ViewportContainer"]
size = Vector2( 536, 600 )
handle_input_locally = false
render_target_update_mode = 3
[node name="Canvas" parent="UI/ViewportContainer/Viewport" instance=ExtResource( 5 )]
[node name="Camera2D" type="Camera2D" parent="UI/ViewportContainer/Viewport"]
current = true
zoom = Vector2( 0.15, 0.15 )
script = ExtResource( 6 )
[node name="LayerPanel" type="Panel" parent="UI"]
margin_left = 864.0
margin_right = 1024.0
margin_bottom = 600.0
rect_min_size = Vector2( 160, 0 )
[node name="ScrollContainer" type="ScrollContainer" parent="UI/LayerPanel"]
margin_right = 160.0
margin_bottom = 600.0
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="VBoxLayerContainer" type="VBoxContainer" parent="UI/LayerPanel/ScrollContainer"]
margin_right = 160.0
margin_bottom = 38.0
size_flags_horizontal = 3
[node name="LayerLabel" type="Label" parent="UI/LayerPanel/ScrollContainer/VBoxLayerContainer"]
margin_right = 160.0
margin_bottom = 14.0
size_flags_horizontal = 3
size_flags_vertical = 0
text = "Layers"
align = 1
[node name="HBoxContainer" type="HBoxContainer" parent="UI/LayerPanel/ScrollContainer/VBoxLayerContainer"]
margin_top = 18.0
margin_right = 160.0
margin_bottom = 38.0
[node name="AddLayerButton" type="Button" parent="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer"]
margin_right = 20.0
margin_bottom = 20.0
text = "+"
[node name="RemoveLayerButton" type="Button" parent="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer"]
margin_left = 24.0
margin_right = 44.0
margin_bottom = 20.0
disabled = true
text = "X"
[node name="MoveUpLayer" type="Button" parent="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer"]
margin_left = 48.0
margin_right = 67.0
margin_bottom = 20.0
disabled = true
text = "^"
[node name="MoveDownLayer" type="Button" parent="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer"]
margin_left = 71.0
margin_right = 90.0
margin_bottom = 20.0
disabled = true
text = "v"
[node name="CloneLayer" type="Button" parent="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer"]
margin_left = 94.0
margin_right = 118.0
margin_bottom = 20.0
text = "Cl"
[node name="MergeDownLayer" type="Button" parent="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer"]
margin_left = 122.0
margin_right = 146.0
margin_bottom = 20.0
disabled = true
text = "M"
[node name="CreateNewImage" type="ConfirmationDialog" parent="."]
editor/display_folded = true
margin_right = 200.0
margin_bottom = 70.0
[node name="VBoxContainer" type="VBoxContainer" parent="CreateNewImage"]
margin_left = 8.0
margin_top = 8.0
margin_right = 192.0
margin_bottom = 78.0
[node name="ImageSize" type="Label" parent="CreateNewImage/VBoxContainer"]
margin_right = 184.0
margin_bottom = 14.0
text = "Image Size"
[node name="WidthCont" type="HBoxContainer" parent="CreateNewImage/VBoxContainer"]
margin_top = 18.0
margin_right = 184.0
margin_bottom = 42.0
[node name="WidthLabel" type="Label" parent="CreateNewImage/VBoxContainer/WidthCont"]
margin_top = 5.0
margin_right = 46.0
margin_bottom = 19.0
text = "Width: "
[node name="LineEdit" type="LineEdit" parent="CreateNewImage/VBoxContainer/WidthCont"]
margin_left = 50.0
margin_right = 108.0
margin_bottom = 24.0
text = "64"
[node name="HeightCont" type="HBoxContainer" parent="CreateNewImage/VBoxContainer"]
margin_top = 46.0
margin_right = 184.0
margin_bottom = 70.0
[node name="Height" type="Label" parent="CreateNewImage/VBoxContainer/HeightCont"]
margin_top = 5.0
margin_right = 46.0
margin_bottom = 19.0
text = "Height:"
[node name="LineEdit" type="LineEdit" parent="CreateNewImage/VBoxContainer/HeightCont"]
margin_left = 50.0
margin_right = 108.0
margin_bottom = 24.0
text = "64"
[node name="OpenSprite" type="FileDialog" parent="."]
margin_right = 515.0
margin_bottom = 348.0
window_title = "Open a File"
resizable = true
mode = 0
access = 2
filters = PoolStringArray( "*jpg, *.png ; JPG, PNG Images" )
current_dir = "C:/Users/Overloaded/Dropbox/Orama Founding Members/εταιρικα αρχεια/Godot Projects/Pixelorama"
current_path = "C:/Users/Overloaded/Dropbox/Orama Founding Members/εταιρικα αρχεια/Godot Projects/Pixelorama/"
[node name="SaveSprite" type="FileDialog" parent="."]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -512.0
margin_top = -300.0
margin_right = 3.0
margin_bottom = 48.0
window_title = "Create a new image"
resizable = true
access = 2
filters = PoolStringArray( "*.png ; PNG Image" )
current_dir = "C:/Users/Overloaded/Dropbox/Orama Founding Members/εταιρικα αρχεια/Godot Projects/Pixelorama"
current_path = "C:/Users/Overloaded/Dropbox/Orama Founding Members/εταιρικα αρχεια/Godot Projects/Pixelorama/"
[node name="ScaleImage" type="ConfirmationDialog" parent="."]
editor/display_folded = true
margin_right = 200.0
margin_bottom = 114.0
[node name="VBoxContainer" type="VBoxContainer" parent="ScaleImage"]
margin_left = 8.0
margin_top = 8.0
margin_right = 192.0
margin_bottom = 78.0
[node name="ImageSize" type="Label" parent="ScaleImage/VBoxContainer"]
margin_right = 184.0
margin_bottom = 14.0
text = "Image Size"
[node name="WidthCont" type="HBoxContainer" parent="ScaleImage/VBoxContainer"]
margin_top = 18.0
margin_right = 184.0
margin_bottom = 42.0
[node name="WidthLabel" type="Label" parent="ScaleImage/VBoxContainer/WidthCont"]
margin_top = 5.0
margin_right = 46.0
margin_bottom = 19.0
text = "Width: "
[node name="LineEdit" type="LineEdit" parent="ScaleImage/VBoxContainer/WidthCont"]
margin_left = 50.0
margin_right = 108.0
margin_bottom = 24.0
text = "64"
[node name="HeightCont" type="HBoxContainer" parent="ScaleImage/VBoxContainer"]
margin_top = 46.0
margin_right = 184.0
margin_bottom = 70.0
[node name="Height" type="Label" parent="ScaleImage/VBoxContainer/HeightCont"]
margin_top = 5.0
margin_right = 46.0
margin_bottom = 19.0
text = "Height:"
[node name="LineEdit" type="LineEdit" parent="ScaleImage/VBoxContainer/HeightCont"]
margin_left = 50.0
margin_right = 108.0
margin_bottom = 24.0
text = "64"
[connection signal="popup_closed" from="UI/ToolPanel/VBoxContainer/ColorPickers/LeftColorPickerButton" to="." method="_can_draw_true"]
[connection signal="pressed" from="UI/ToolPanel/VBoxContainer/ColorPickers/LeftColorPickerButton" to="." method="_can_draw_false"]
[connection signal="popup_closed" from="UI/ToolPanel/VBoxContainer/ColorPickers/RightColorPickerButton" to="." method="_can_draw_true"]
[connection signal="pressed" from="UI/ToolPanel/VBoxContainer/ColorPickers/RightColorPickerButton" to="." method="_can_draw_false"]
[connection signal="mouse_entered" from="UI/ViewportContainer" to="." method="_on_ViewportContainer_mouse_entered"]
[connection signal="mouse_exited" from="UI/ViewportContainer" to="." method="_on_ViewportContainer_mouse_exited"]
[connection signal="pressed" from="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer/AddLayerButton" to="." method="_on_AddLayerButton_pressed"]
[connection signal="pressed" from="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer/RemoveLayerButton" to="." method="_on_RemoveLayerButton_pressed"]
[connection signal="pressed" from="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer/MoveUpLayer" to="." method="_on_MoveUpLayer_pressed"]
[connection signal="pressed" from="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer/MoveDownLayer" to="." method="_on_MoveDownLayer_pressed"]
[connection signal="pressed" from="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer/CloneLayer" to="." method="_on_CloneLayer_pressed"]
[connection signal="pressed" from="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer/MergeDownLayer" to="." method="_on_MergeLayer_pressed"]
[connection signal="confirmed" from="CreateNewImage" to="." method="_on_CreateNewImage_confirmed"]
[connection signal="popup_hide" from="CreateNewImage" to="." method="_can_draw_true"]
[connection signal="file_selected" from="OpenSprite" to="." method="_on_OpenSprite_file_selected"]
[connection signal="popup_hide" from="OpenSprite" to="." method="_on_OpenSprite_popup_hide"]
[connection signal="file_selected" from="SaveSprite" to="." method="_on_SaveSprite_file_selected"]
[connection signal="popup_hide" from="SaveSprite" to="." method="_can_draw_true"]
[connection signal="confirmed" from="ScaleImage" to="." method="_on_ScaleImage_confirmed"]
[connection signal="popup_hide" from="ScaleImage" to="." method="_can_draw_true"]

2
README.md Normal file
View file

@ -0,0 +1,2 @@
# Pixelorama
A free & open-source 2D sprite editor, made with Godot Engine!

25
Scripts/CameraMovement.gd Normal file
View file

@ -0,0 +1,25 @@
extends Camera2D
var zoom_min := Vector2(0.005, 0.005)
var zoom_max := Vector2(0.8, 0.8)
var drag := false
func _input(event) -> void:
if Global.can_draw && Global.has_focus:
if event.is_action_pressed("camera_drag"):
drag = true
elif event.is_action_released("camera_drag"):
drag = false
elif event.is_action_pressed("zoom_in"): # Wheel Up Event
zoom_camera(-1)
elif event.is_action_pressed("zoom_out"): # Wheel Down Event
zoom_camera(1)
elif event is InputEventMouseMotion && drag:
offset = offset - event.relative * zoom
# Zoom Camera
func zoom_camera(dir : int) -> void:
var zoom_margin = zoom * dir / 10
if zoom + zoom_margin > zoom_min && zoom + zoom_margin < zoom_max:
zoom += zoom_margin

233
Scripts/Canvas.gd Normal file
View file

@ -0,0 +1,233 @@
extends Node2D
class_name Canvas
var layers := []
var current_layer_index := 0
var trans_background : ImageTexture
var current_sprite : Image
var location := Vector2.ZERO
var size := Vector2(64, 64)
var previous_mouse_pos := Vector2.ZERO
var mouse_inside_canvas := false #used for undo
var sprite_changed_this_frame := false #for optimization purposes
var is_making_line := false
var line_2d : Line2D
var draw_grid := false
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
Global.can_draw = false
#Background
trans_background = ImageTexture.new()
trans_background.create_from_image(load("res://Transparent Background.png"), 0)
#The sprite itself
if !current_sprite:
current_sprite = Image.new()
current_sprite.create(size.x, size.y, false, Image.FORMAT_RGBA8)
current_sprite.lock()
var tex := ImageTexture.new()
tex.create_from_image(current_sprite, 0)
#Store [Image, ImageTexture, Layer Name, Visibity boolean]
layers.append([current_sprite, tex, "Layer 0", true])
generate_layer_panels()
#Set camera offset to the center of canvas
$"../Camera2D".offset = size / 2
#Set camera zoom based on the sprite size
var bigger = max(size.x, size.y)
$"../Camera2D".zoom_max = Vector2(bigger, bigger) * 0.01
$"../Camera2D".zoom = Vector2(bigger, bigger) * 0.002
# warning-ignore:unused_argument
func _process(delta) -> void:
sprite_changed_this_frame = false
update()
var mouse_pos := get_local_mouse_position() - location
var current_mouse_button := "None"
var current_action := "None"
if Input.is_mouse_button_pressed(BUTTON_LEFT):
current_mouse_button = "L"
current_action = Global.current_left_tool
elif Input.is_mouse_button_pressed(BUTTON_RIGHT):
current_mouse_button = "R"
current_action = Global.current_right_tool
if !point_in_rectangle(mouse_pos, location, location + size):
if !Input.is_mouse_button_pressed(BUTTON_LEFT) && !Input.is_mouse_button_pressed(BUTTON_RIGHT):
if mouse_inside_canvas:
mouse_inside_canvas = false
match current_action:
"Pencil":
var current_color : Color
if current_mouse_button == "L":
current_color = Global.left_color_picker.color
elif current_mouse_button == "R":
current_color = Global.right_color_picker.color
pencil_and_eraser(mouse_pos, current_color)
"Eraser":
pencil_and_eraser(mouse_pos, Color(0, 0, 0, 0))
"Fill":
if point_in_rectangle(mouse_pos, location, location + size) && Global.can_draw && Global.has_focus:
var current_color : Color
if current_mouse_button == "L":
current_color = Global.left_color_picker.color
elif current_mouse_button == "R":
current_color = Global.right_color_picker.color
flood_fill(mouse_pos, layers[current_layer_index][0].get_pixelv(mouse_pos), current_color)
if !is_making_line:
previous_mouse_pos = mouse_pos
previous_mouse_pos.x = clamp(previous_mouse_pos.x, location.x, location.x + size.x)
previous_mouse_pos.y = clamp(previous_mouse_pos.y, location.y, location.y + size.y)
else:
line_2d.set_point_position(1, mouse_pos)
if sprite_changed_this_frame:
update_texture(current_layer_index)
func update_texture(layer_index : int):
layers[layer_index][1].create_from_image(layers[layer_index][0], 0)
get_layer_container(layer_index).get_child(0).get_child(1).texture = layers[layer_index][1]
func get_layer_container(layer_index : int) -> PanelContainer:
for container in Global.vbox_layer_container.get_children():
if container is PanelContainer && container.i == layer_index:
return container
return null
func _draw() -> void:
draw_texture_rect(trans_background, Rect2(location, size), true)
#for texture in layer_textures:
for texture in layers:
if texture[3]: #if it's visible
draw_texture(texture[1], location)
#Draw grid (causes lag - unused. If you wanna test it just set draw_grid = true)
if draw_grid:
for x in size.x:
for y in size.y:
draw_rect(Rect2(location.x + x, location.y + y, 1, 1), Color.black, false)
#Draw rectangle to indicate the pixel currently being hovered on
var mouse_pos := get_local_mouse_position() - location
if point_in_rectangle(mouse_pos, location, location + size):
mouse_pos = mouse_pos.floor()
draw_rect(Rect2(mouse_pos.x, mouse_pos.y, 1, 1), Color.red, false)
func generate_layer_panels() -> void:
for child in Global.vbox_layer_container.get_children():
if child is PanelContainer:
child.queue_free()
current_layer_index = layers.size() - 1
if layers.size() == 1:
Global.remove_layer_button.disabled = true
else:
Global.remove_layer_button.disabled = false
for i in range(layers.size() -1, -1, -1):
var layer_container = load("res://LayerContainer.tscn").instance()
#layer_names.insert(i, "Layer %s" % i)
layers[i][2] = "Layer %s" % i
layer_container.i = i
#layer_container.get_child(0).get_child(2).text = layer_names[i]
layer_container.get_child(0).get_child(2).text = layers[i][2]
layers[i][3] = true #set visible
layer_container.get_child(0).get_child(1).texture = layers[i][1]
Global.vbox_layer_container.add_child(layer_container)
func pencil_and_eraser(mouse_pos : Vector2, color : Color) -> void:
if Input.is_key_pressed(KEY_SHIFT):
if !is_making_line:
line_2d = Line2D.new()
line_2d.width = 0.5
line_2d.default_color = Color.darkgray
line_2d.add_point(previous_mouse_pos)
line_2d.add_point(mouse_pos)
add_child(line_2d)
is_making_line = true
else:
if is_making_line:
fill_gaps(mouse_pos, color)
is_making_line = false
line_2d.queue_free()
else:
if point_in_rectangle(mouse_pos, location, location + size):
mouse_inside_canvas = true
#Draw
draw_pixel(mouse_pos, color)
fill_gaps(mouse_pos, color) #Fill the gaps
#If mouse is not inside bounds but it used to be, fill the gaps
elif point_in_rectangle(previous_mouse_pos, location, location + size):
fill_gaps(mouse_pos, color)
func draw_pixel(pos : Vector2, color : Color) -> void:
if layers[current_layer_index][0].get_pixelv(pos) != color: #don't draw the same pixel over and over
if Global.can_draw && Global.has_focus:
#sprite.lock()
layers[current_layer_index][0].set_pixelv(pos, color)
#sprite.unlock()
sprite_changed_this_frame = true
func point_in_rectangle(p : Vector2, coord1 : Vector2, coord2 : Vector2) -> bool:
return p.x > coord1.x && p.y > coord1.y && p.x < coord2.x && p.y < coord2.y
#Bresenham's Algorithm
#Thanks to https://godotengine.org/qa/35276/tile-based-line-drawing-algorithm-efficiency
func fill_gaps(mouse_pos : Vector2, color : Color) -> void:
var previous_mouse_pos_floored = previous_mouse_pos.floor()
var mouse_pos_floored = mouse_pos.floor()
mouse_pos_floored.x = clamp(mouse_pos_floored.x, location.x - 1, location.x + size.x)
mouse_pos_floored.y = clamp(mouse_pos_floored.y, location.y - 1, location.y + size.y)
var dx := int(abs(mouse_pos_floored.x - previous_mouse_pos_floored.x))
var dy := int(-abs(mouse_pos_floored.y - previous_mouse_pos_floored.y))
var err := dx + dy
var e2 := err << 1 #err * 2
var sx = 1 if previous_mouse_pos_floored.x < mouse_pos_floored.x else -1
var sy = 1 if previous_mouse_pos_floored.y < mouse_pos_floored.y else -1
var x = previous_mouse_pos_floored.x
var y = previous_mouse_pos_floored.y
while !(x == mouse_pos_floored.x && y == mouse_pos_floored.y):
draw_pixel(Vector2(x, y), color)
e2 = err << 1
if e2 >= dy:
err += dy
x += sx
if e2 <= dx:
err += dx
y += sy
#Thanks to https://en.wikipedia.org/wiki/Flood_fill
func flood_fill(pos : Vector2, target_color : Color, replace_color : Color) -> void:
pos = pos.floor()
var pixel = layers[current_layer_index][0].get_pixelv(pos)
if target_color == replace_color:
return
elif pixel != target_color:
return
else:
var q = [pos]
for n in q:
var west : Vector2 = n
var east : Vector2 = n
while west.x >= location.x && layers[current_layer_index][0].get_pixelv(west) == target_color:
west += Vector2.LEFT
while east.x < location.x + size.x && layers[current_layer_index][0].get_pixelv(east) == target_color:
east += Vector2.RIGHT
for px in range(west.x + 1, east.x):
var p := Vector2(px, n.y)
draw_pixel(p, replace_color)
var north := p + Vector2.UP
var south := p + Vector2.DOWN
if north.y >= location.y && layers[current_layer_index][0].get_pixelv(north) == target_color:
q.append(north)
if south.y < location.y + size.y && layers[current_layer_index][0].get_pixelv(south) == target_color:
q.append(south)
func _on_Timer_timeout() -> void:
Global.can_draw = true

51
Scripts/Global.gd Normal file
View file

@ -0,0 +1,51 @@
extends Node
# warning-ignore:unused_class_variable
var can_draw := false
# warning-ignore:unused_class_variable
var has_focus := true
var canvas : Canvas
var canvas_parent
var left_color_picker : ColorPickerButton
var right_color_picker : ColorPickerButton
var file_menu : MenuButton
var edit_menu : MenuButton
var left_indicator : Sprite
var right_indicator : Sprite
var vbox_layer_container : VBoxContainer
var remove_layer_button : Button
var move_up_layer_button : Button
var move_down_layer_button : Button
var merge_down_layer_button : Button
# warning-ignore:unused_class_variable
var current_left_tool := "Pencil"
# warning-ignore:unused_class_variable
var current_right_tool := "Eraser"
func _ready() -> void:
var root = get_tree().get_root()
canvas = find_node_by_name(root, "Canvas")
canvas_parent = canvas.get_parent()
left_color_picker = find_node_by_name(root, "LeftColorPickerButton")
right_color_picker = find_node_by_name(root, "RightColorPickerButton")
file_menu = find_node_by_name(root, "FileMenu")
edit_menu = find_node_by_name(root, "EditMenu")
left_indicator = find_node_by_name(root, "LeftIndicator")
right_indicator = find_node_by_name(root, "RightIndicator")
vbox_layer_container = find_node_by_name(root, "VBoxLayerContainer")
remove_layer_button = find_node_by_name(root, "RemoveLayerButton")
move_up_layer_button = find_node_by_name(root, "MoveUpLayer")
move_down_layer_button = find_node_by_name(root, "MoveDownLayer")
merge_down_layer_button = find_node_by_name(root, "MergeDownLayer")
#Thanks to https://godotengine.org/qa/17524/how-to-find-an-instanced-scene-by-its-name
func find_node_by_name(root, node_name) -> Node:
if root.get_name() == node_name:
return root
for child in root.get_children():
if child.get_name() == node_name:
return child
var found = find_node_by_name(child, node_name)
if found:
return found
return null

60
Scripts/LayerContainer.gd Normal file
View file

@ -0,0 +1,60 @@
extends PanelContainer
var i
var currently_selected := false
var visibility_toggled := false
func _ready() -> void:
var stylebox = StyleBoxFlat.new()
stylebox.bg_color = Color("3d3b45")
add_stylebox_override("panel", stylebox)
changed_selection()
# warning-ignore:unused_argument
func _process(delta) -> void:
var mouse_pos := get_local_mouse_position() + rect_position
if point_in_rectangle(mouse_pos, rect_position, rect_position + rect_size) && !visibility_toggled:
if Input.is_action_just_pressed("left_mouse"):
Global.canvas.current_layer_index = i
changed_selection()
func changed_selection() -> void:
var parent = get_parent()
for child in parent.get_children():
if child is PanelContainer:
if Global.canvas.current_layer_index == child.i:
child.currently_selected = true
child.get_stylebox("panel").bg_color = Color("282532")
if Global.canvas.current_layer_index < Global.canvas.layers.size() - 1:
Global.move_up_layer_button.disabled = false
else:
Global.move_up_layer_button.disabled = true
if Global.canvas.current_layer_index > 0:
Global.move_down_layer_button.disabled = false
Global.merge_down_layer_button.disabled = false
else:
Global.move_down_layer_button.disabled = true
Global.merge_down_layer_button.disabled = true
else:
child.currently_selected = false
child.get_stylebox("panel").bg_color = Color("3d3b45")
func point_in_rectangle(p : Vector2, coord1 : Vector2, coord2 : Vector2) -> bool:
return p.x > coord1.x && p.y > coord1.y && p.x < coord2.x && p.y < coord2.y
func _on_VisibilityButton_pressed() -> void:
if Global.canvas.layers[i][3]:
Global.canvas.layers[i][3] = false
get_child(0).get_child(0).text = "I"
else:
Global.canvas.layers[i][3] = true
get_child(0).get_child(0).text = "V"
func _on_VisibilityButton_button_down() -> void:
visibility_toggled = true
func _on_VisibilityButton_button_up() -> void:
visibility_toggled = false

214
Scripts/Main.gd Normal file
View file

@ -0,0 +1,214 @@
extends Control
var current_path := ""
var opensprite_file_selected := false
var pencil_tool
var eraser_tool
var fill_tool
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
var file_menu_items := {
"New..." : KEY_MASK_CTRL + KEY_N,
"Import..." : KEY_MASK_CTRL + KEY_O,
"Export..." : KEY_MASK_CTRL + KEY_S,
"Export as..." : KEY_MASK_SHIFT + KEY_MASK_CTRL + KEY_S,
"Quit" : KEY_MASK_CTRL + KEY_Q
}
# var edit_menu_items := {
# "Undo" : KEY_MASK_CTRL + KEY_Z,
# "Redo" : KEY_MASK_SHIFT + KEY_MASK_CTRL + KEY_Z,
# "Scale Image" : 0
# }
var file_menu : PopupMenu = Global.file_menu.get_popup()
var edit_menu : PopupMenu = Global.edit_menu.get_popup()
var i = 0
for item in file_menu_items.keys():
file_menu.add_item(item, i, file_menu_items[item])
i += 1
# i = 0
# for item in edit_menu_items.keys():
# edit_menu.add_item(item, i, edit_menu_items[item])
# i += 1
file_menu.connect("id_pressed", self, "file_menu_id_pressed")
#edit_menu.connect("id_pressed", self, "edit_menu_id_pressed")
pencil_tool = $UI/ToolPanel/VBoxContainer/ToolsContainer/Pencil
eraser_tool = $UI/ToolPanel/VBoxContainer/ToolsContainer/Eraser
fill_tool = $UI/ToolPanel/VBoxContainer/ToolsContainer/Fill
pencil_tool.connect("pressed", self, "_on_Tool_pressed", [pencil_tool])
eraser_tool.connect("pressed", self, "_on_Tool_pressed", [eraser_tool])
fill_tool.connect("pressed", self, "_on_Tool_pressed", [fill_tool])
pencil_tool.hint_tooltip = "P for left mouse button, Alt + P for right mouse button"
eraser_tool.hint_tooltip = "E for left mouse button, Alt + E for right mouse button"
fill_tool.hint_tooltip = "B for left mouse button, Alt + B for right mouse button"
func _input(event):
#Handle tool shortcuts
if event.is_action_pressed("right_pencil_tool"):
_on_Tool_pressed(pencil_tool, false, false)
elif event.is_action_pressed("left_pencil_tool"):
_on_Tool_pressed(pencil_tool, false, true)
elif event.is_action_pressed("right_eraser_tool"):
_on_Tool_pressed(eraser_tool, false, false)
elif event.is_action_pressed("left_eraser_tool"):
_on_Tool_pressed(eraser_tool, false, true)
elif event.is_action_pressed("right_fill_tool"):
_on_Tool_pressed(fill_tool, false, false)
elif event.is_action_pressed("left_fill_tool"):
_on_Tool_pressed(fill_tool, false, true)
func file_menu_id_pressed(id : int) -> void:
match id:
0: #New
$CreateNewImage.popup_centered()
Global.can_draw = false
1: #Import
$OpenSprite.popup_centered()
Global.can_draw = false
opensprite_file_selected = false
2: #Export
if current_path == "":
$SaveSprite.popup_centered()
Global.can_draw = false
else:
save_sprite()
3: #Export as
$SaveSprite.popup_centered()
Global.can_draw = false
4: #Quit
get_tree().quit()
func _on_CreateNewImage_confirmed() -> void:
var width = float($CreateNewImage/VBoxContainer/WidthCont/LineEdit.text)
var height = float($CreateNewImage/VBoxContainer/HeightCont/LineEdit.text)
width = clamp(width, 1, 16384)
height = clamp(height, 1, 16384)
new_canvas(Vector2(width, height).floor())
func _on_OpenSprite_file_selected(path : String) -> void:
var image = Image.new()
var err = image.load(path)
if err == OK:
opensprite_file_selected = true
new_canvas(image.get_size(), image)
else:
OS.alert("Can't load file")
func new_canvas(size : Vector2, sprite : Image = null) -> void:
for child in Global.vbox_layer_container.get_children():
if child is PanelContainer:
child.queue_free()
Global.canvas.queue_free()
Global.canvas = load("res://Canvas.tscn").instance()
Global.canvas.size = size
if sprite:
Global.canvas.current_sprite = sprite
Global.canvas.current_sprite.convert(Image.FORMAT_RGBA8)
Global.canvas_parent.add_child(Global.canvas)
func _on_SaveSprite_file_selected(path : String) -> void:
current_path = path
save_sprite()
func save_sprite() -> void:
var whole_image := Image.new()
whole_image.create(Global.canvas.size.x, Global.canvas.size.y, false, Image.FORMAT_RGBA8)
for layer in Global.canvas.layers:
whole_image.blend_rect(layer[0], Rect2(Global.canvas.position, Global.canvas.size), Vector2.ZERO)
layer[0].lock()
#var err = Global.canvas.current_sprite.save_png(current_path)
var err = whole_image.save_png(current_path)
if err != OK:
OS.alert("Can't save file")
func _on_OpenSprite_popup_hide() -> void:
if !opensprite_file_selected:
Global.can_draw = true
print(Global.can_draw)
func _on_ViewportContainer_mouse_entered() -> void:
Global.has_focus = true
func _on_ViewportContainer_mouse_exited() -> void:
Global.has_focus = false
func _can_draw_true() -> void:
Global.can_draw = true
func _can_draw_false() -> void:
Global.can_draw = false
func _on_Tool_pressed(tool_pressed : BaseButton, mouse_press := true, key_for_left := true) -> void:
var current_action := tool_pressed.name
if (mouse_press && Input.is_action_just_released("left_mouse")) || (!mouse_press && key_for_left):
Global.current_left_tool = current_action
Global.left_indicator.get_parent().remove_child(Global.left_indicator)
tool_pressed.add_child(Global.left_indicator)
elif (mouse_press && Input.is_action_just_released("right_mouse")) || (!mouse_press && !key_for_left):
Global.current_right_tool = current_action
Global.right_indicator.get_parent().remove_child(Global.right_indicator)
tool_pressed.add_child(Global.right_indicator)
func _on_ScaleImage_confirmed() -> void:
var width = float($ScaleImage/VBoxContainer/WidthCont/LineEdit.text)
var height = float($ScaleImage/VBoxContainer/HeightCont/LineEdit.text)
width = clamp(width, 1, 16384)
height = clamp(height, 1, 16384)
#var sprites := []
for i in range(Global.canvas.layers.size() - 1, -1, -1):
var sprite = Image.new()
sprite = Global.canvas.layers[i][1].get_data()
sprite.resize(width, height)
Global.canvas.layers[i][0] = sprite
Global.canvas.layers[i][0].lock()
Global.canvas.update_texture(i)
Global.canvas.size = Vector2(width, height).floor()
func add_layer(is_new := true) -> void:
var new_layer := Image.new()
if is_new:
new_layer.create(Global.canvas.size.x, Global.canvas.size.y, false, Image.FORMAT_RGBA8)
else: #clone layer
new_layer.copy_from(Global.canvas.layers[Global.canvas.current_layer_index][0])
new_layer.lock()
var new_layer_tex := ImageTexture.new()
new_layer_tex.create_from_image(new_layer, 0)
Global.canvas.layers.append([new_layer, new_layer_tex, null, true])
Global.canvas.generate_layer_panels()
func _on_AddLayerButton_pressed() -> void:
add_layer()
func _on_RemoveLayerButton_pressed() -> void:
Global.canvas.layers.remove(Global.canvas.current_layer_index)
Global.canvas.generate_layer_panels()
func _on_MoveUpLayer_pressed() -> void:
change_layer_order(1)
func _on_MoveDownLayer_pressed() -> void:
change_layer_order(-1)
func change_layer_order(rate : int) -> void:
var change = Global.canvas.current_layer_index + rate
var temp = Global.canvas.layers[Global.canvas.current_layer_index]
Global.canvas.layers[Global.canvas.current_layer_index] = Global.canvas.layers[change]
Global.canvas.layers[change] = temp
Global.canvas.generate_layer_panels()
Global.canvas.current_layer_index = change
Global.canvas.get_layer_container(Global.canvas.current_layer_index).changed_selection()
func _on_CloneLayer_pressed() -> void:
add_layer(false)
func _on_MergeLayer_pressed() -> void:
var selected_layer = Global.canvas.layers[Global.canvas.current_layer_index][0]
Global.canvas.layers[Global.canvas.current_layer_index - 1][0].blend_rect(selected_layer, Rect2(Global.canvas.position, Global.canvas.size), Vector2.ZERO)
Global.canvas.layers[Global.canvas.current_layer_index - 1][0].lock()
Global.canvas.update_texture(Global.canvas.current_layer_index - 1)
_on_RemoveLayerButton_pressed()

BIN
Transparent Background.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 558 B

View file

@ -0,0 +1,13 @@
[remap]
importer="image"
type="Image"
path="res://.import/Transparent Background.png-b5955c8e7e6eaecd8f24a1732239745d.image"
[deps]
source_file="res://Transparent Background.png"
dest_files=[ "res://.import/Transparent Background.png-b5955c8e7e6eaecd8f24a1732239745d.image" ]
[params]

BIN
default_env.tres Normal file

Binary file not shown.

55
export_presets.cfg Normal file
View file

@ -0,0 +1,55 @@
[preset.0]
name="HTML5"
platform="HTML5"
runnable=true
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="C:/Users/Overloaded/Dropbox/Orama Founding Members/εταιρικα αρχεια/Godot Projects/Sprite Editor/Exported/HTML5/Sprite Editor.html"
patch_list=PoolStringArray( )
script_export_mode=1
script_encryption_key=""
[preset.0.options]
vram_texture_compression/for_desktop=true
vram_texture_compression/for_mobile=false
html/custom_html_shell=""
html/head_include=""
custom_template/release=""
custom_template/debug=""
[preset.1]
name="Windows Desktop"
platform="Windows Desktop"
runnable=true
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="C:/Users/manos/Dropbox/Orama Founding Members/εταιρικα αρχεια/Godot Projects/Sprite Editor/Exported/Sprite Editor.exe"
patch_list=PoolStringArray( )
script_export_mode=1
script_encryption_key=""
[preset.1.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=""
application/product_version=""
application/company_name=""
application/product_name=""
application/file_description=""
application/copyright=""
application/trademarks=""

BIN
icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

34
icon.png.import Normal file
View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.png"
dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

103
project.godot Normal file
View file

@ -0,0 +1,103 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=4
_global_script_classes=[ {
"base": "Node2D",
"class": "Canvas",
"language": "GDScript",
"path": "res://Scripts/Canvas.gd"
}, {
"base": "Node2D",
"class": "CanvasOLD",
"language": "GDScript",
"path": "res://Scripts/Old/Canvas.gd"
} ]
_global_script_class_icons={
"Canvas": "",
"CanvasOLD": ""
}
[application]
config/name="Pixelorama"
run/main_scene="res://Main.tscn"
config/icon="res://icon.png"
[autoload]
Global="*res://Scripts/Global.gd"
[debug]
gdscript/warnings/return_value_discarded=false
[input]
zoom_in={
"deadzone": 0.5,
"events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":4,"pressed":false,"doubleclick":false,"script":null)
]
}
zoom_out={
"deadzone": 0.5,
"events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":5,"pressed":false,"doubleclick":false,"script":null)
]
}
camera_drag={
"deadzone": 0.5,
"events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":3,"pressed":false,"doubleclick":false,"script":null)
]
}
left_mouse={
"deadzone": 0.5,
"events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":1,"pressed":false,"doubleclick":false,"script":null)
]
}
right_mouse={
"deadzone": 0.5,
"events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":2,"pressed":false,"doubleclick":false,"script":null)
]
}
left_pencil_tool={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":80,"unicode":0,"echo":false,"script":null)
]
}
right_pencil_tool={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":true,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":80,"unicode":0,"echo":false,"script":null)
]
}
left_eraser_tool={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":69,"unicode":0,"echo":false,"script":null)
]
}
right_eraser_tool={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":true,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":69,"unicode":0,"echo":false,"script":null)
]
}
left_fill_tool={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":66,"unicode":0,"echo":false,"script":null)
]
}
right_fill_tool={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":true,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":66,"unicode":0,"echo":false,"script":null)
]
}
[rendering]
quality/driver/driver_name="GLES2"
vram_compression/import_etc=true
vram_compression/import_etc2=false