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

Replace old palette system with a new one (#447)

* Replace old palette system with a new one

* Replace default json palettes with new resource versions

* Add missing translation strings

* Fix Erevoid's issues 2, 3 and 4

* Rewrite palette grid to improve performance
Add middle click scrolling

* Fix index conversion functions

* Fix palettes editing by copying them to XDG user write path

* Add Windows specific fixes

* Add import support for old json palette format

* Add create/edit palette settings check.
Hide add/delete color buttons when no palette is displayed.
This commit is contained in:
Martin Novák 2021-04-16 20:09:03 +02:00 committed by GitHub
parent 05eda55bc7
commit 42696e7b37
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
52 changed files with 3273 additions and 2445 deletions

View file

@ -1618,3 +1618,39 @@ msgstr ""
msgid "Tiled In Y Axis"
msgstr ""
msgid "Create a new palette"
msgstr ""
msgid "Create New Palette"
msgstr ""
msgid "Comment:"
msgstr ""
msgid "Empty"
msgstr ""
msgid "From Current Palette"
msgstr ""
msgid "From Current Sprite"
msgstr ""
msgid "From Current Selection"
msgstr ""
msgid "Add a new color"
msgstr ""
msgid "Remove a selected color"
msgstr ""
msgid "Palette with the same name and path already exists!"
msgstr ""
msgid "Palette name is required!"
msgstr ""
msgid "Reducing palette size will reset positions of colors. Colors that don't fit in new palette size will be lost!"
msgstr ""

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 B

View file

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/palette_button.png-ff1f1a8ad429574b463411c02e244a2a.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/palette/palette_button.png"
dest_files=[ "res://.import/palette_button.png-ff1f1a8ad429574b463411c02e244a2a.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=false
svg/scale=1.0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 B

View file

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/palette_button_fill.png-220233529c0ea9f05bc5b7117ad5f75a.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/palette/palette_button_fill.png"
dest_files=[ "res://.import/palette_button_fill.png-220233529c0ea9f05bc5b7117ad5f75a.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=false
svg/scale=1.0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 B

View file

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/swatch_drag_preview.png-89cc3cf5786bed806d66f0ca30a8c714.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/palette/swatch_drag_preview.png"
dest_files=[ "res://.import/swatch_drag_preview.png-89cc3cf5786bed806d66f0ca30a8c714.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=false
svg/scale=1.0

View file

@ -1,11 +0,0 @@
[gd_resource type="StyleBoxTexture" load_steps=2 format=2]
[ext_resource path="res://assets/graphics/palette/palette_button.png" type="Texture" id=1]
[resource]
texture = ExtResource( 1 )
region_rect = Rect2( 0, 0, 8, 8 )
margin_left = 2.0
margin_right = 2.0
margin_top = 2.0
margin_bottom = 2.0

View file

@ -1,12 +0,0 @@
[gd_resource type="StyleBoxTexture" load_steps=2 format=2]
[ext_resource path="res://assets/graphics/palette/palette_button.png" type="Texture" id=1]
[resource]
texture = ExtResource( 1 )
region_rect = Rect2( 0, 0, 8, 8 )
margin_left = 2.0
margin_right = 2.0
margin_top = 2.0
margin_bottom = 2.0
modulate_color = Color( 1, 0.537255, 0, 1 )

View file

@ -1,12 +0,0 @@
[gd_resource type="StyleBoxTexture" load_steps=2 format=2]
[ext_resource path="res://assets/graphics/palette/palette_button.png" type="Texture" id=1]
[resource]
texture = ExtResource( 1 )
region_rect = Rect2( 0, 0, 8, 8 )
margin_left = 2.0
margin_right = 2.0
margin_top = 2.0
margin_bottom = 2.0
modulate_color = Color( 0, 0, 0, 1 )

View file

@ -1,12 +0,0 @@
[gd_resource type="StyleBoxTexture" load_steps=2 format=2]
[ext_resource path="res://assets/graphics/palette/palette_button.png" type="Texture" id=1]
[resource]
texture = ExtResource( 1 )
region_rect = Rect2( 0, 0, 8, 8 )
margin_left = 2.0
margin_right = 2.0
margin_top = 2.0
margin_bottom = 2.0
modulate_color = Color( 1, 0, 0, 1 )

View file

@ -0,0 +1,111 @@
[gd_resource type="Resource" load_steps=19 format=2]
[ext_resource path="res://src/Palette/Palette.gd" type="Script" id=1]
[ext_resource path="res://src/Palette/PaletteColor.gd" type="Script" id=2]
[sub_resource type="Resource" id=1]
script = ExtResource( 2 )
color = Color( 0, 0, 0, 1 )
index = 0
[sub_resource type="Resource" id=2]
script = ExtResource( 2 )
color = Color( 0.498039, 0.0235294, 0.133333, 1 )
index = 1
[sub_resource type="Resource" id=3]
script = ExtResource( 2 )
color = Color( 0.839216, 0.141176, 0.0666667, 1 )
index = 2
[sub_resource type="Resource" id=4]
script = ExtResource( 2 )
color = Color( 1, 0.517647, 0.14902, 1 )
index = 3
[sub_resource type="Resource" id=5]
script = ExtResource( 2 )
color = Color( 1, 0.819608, 0, 1 )
index = 4
[sub_resource type="Resource" id=6]
script = ExtResource( 2 )
color = Color( 0.980392, 0.992157, 1, 1 )
index = 5
[sub_resource type="Resource" id=7]
script = ExtResource( 2 )
color = Color( 1, 0.501961, 0.643137, 1 )
index = 6
[sub_resource type="Resource" id=8]
script = ExtResource( 2 )
color = Color( 1, 0.14902, 0.454902, 1 )
index = 7
[sub_resource type="Resource" id=9]
script = ExtResource( 2 )
color = Color( 0.580392, 0.129412, 0.415686, 1 )
index = 8
[sub_resource type="Resource" id=10]
script = ExtResource( 2 )
color = Color( 0.262745, 0, 0.403922, 1 )
index = 9
[sub_resource type="Resource" id=11]
script = ExtResource( 2 )
color = Color( 0.137255, 0.286275, 0.458824, 1 )
index = 10
[sub_resource type="Resource" id=12]
script = ExtResource( 2 )
color = Color( 0.407843, 0.682353, 0.831373, 1 )
index = 11
[sub_resource type="Resource" id=13]
script = ExtResource( 2 )
color = Color( 0.74902, 1, 0.235294, 1 )
index = 12
[sub_resource type="Resource" id=14]
script = ExtResource( 2 )
color = Color( 0.0627451, 0.823529, 0.458824, 1 )
index = 13
[sub_resource type="Resource" id=15]
script = ExtResource( 2 )
color = Color( 0, 0.470588, 0.6, 1 )
index = 14
[sub_resource type="Resource" id=16]
script = ExtResource( 2 )
color = Color( 0, 0.156863, 0.34902, 1 )
index = 15
[resource]
resource_name = "BubbleGum16"
script = ExtResource( 1 )
name = "BubbleGum16"
comment = "Author: PineTreePizza/CheetoHead"
width = 8
height = 8
colors = {
0: SubResource( 1 ),
1: SubResource( 2 ),
2: SubResource( 3 ),
3: SubResource( 4 ),
4: SubResource( 5 ),
5: SubResource( 6 ),
6: SubResource( 7 ),
7: SubResource( 8 ),
8: SubResource( 9 ),
9: SubResource( 10 ),
10: SubResource( 11 ),
11: SubResource( 12 ),
12: SubResource( 13 ),
13: SubResource( 14 ),
14: SubResource( 15 ),
15: SubResource( 16 )
}
colors_max = 64

View file

@ -1,107 +0,0 @@
{
"name": "Complementary",
"comments": "By Erevos",
"colors": [
{
"data": "ffb35102",
"name": "no name"
},
{
"data": "ffff9945",
"name": "no name"
},
{
"data": "ffff7100",
"name": "no name"
},
{
"data": "ff0099b3",
"name": "no name"
},
{
"data": "ff00daff",
"name": "no name"
},
{
"data": "ffb30202",
"name": "no name"
},
{
"data": "ffff4545",
"name": "no name"
},
{
"data": "ffff0201",
"name": "no name"
},
{
"data": "ff00b333",
"name": "no name"
},
{
"data": "ff00ff48",
"name": "no name"
},
{
"data": "ff8002b3",
"name": "no name"
},
{
"data": "ffca45ff",
"name": "no name"
},
{
"data": "ffb400fe",
"name": "no name"
},
{
"data": "ff7fb300",
"name": "no name"
},
{
"data": "ffb5ff00",
"name": "no name"
},
{
"data": "ff0211b3",
"name": "no name"
},
{
"data": "ff4554ff",
"name": "no name"
},
{
"data": "ff0116ff",
"name": "no name"
},
{
"data": "ffb38c00",
"name": "no name"
},
{
"data": "ffffc900",
"name": "no name"
},
{
"data": "ff029eb3",
"name": "no name"
},
{
"data": "ff7af0ff",
"name": "no name"
},
{
"data": "ff00e1ff",
"name": "no name"
},
{
"data": "ffb34d00",
"name": "no name"
},
{
"data": "ffff6f00",
"name": "no name"
}
],
"editable": true
}

View file

@ -0,0 +1,165 @@
[gd_resource type="Resource" load_steps=28 format=2]
[ext_resource path="res://src/Palette/Palette.gd" type="Script" id=1]
[ext_resource path="res://src/Palette/PaletteColor.gd" type="Script" id=2]
[sub_resource type="Resource" id=1]
script = ExtResource( 2 )
color = Color( 0.701961, 0.317647, 0.00784314, 1 )
index = 0
[sub_resource type="Resource" id=2]
script = ExtResource( 2 )
color = Color( 1, 0.6, 0.270588, 1 )
index = 1
[sub_resource type="Resource" id=3]
script = ExtResource( 2 )
color = Color( 1, 0.443137, 0, 1 )
index = 2
[sub_resource type="Resource" id=4]
script = ExtResource( 2 )
color = Color( 0, 0.6, 0.701961, 1 )
index = 3
[sub_resource type="Resource" id=5]
script = ExtResource( 2 )
color = Color( 0, 0.854902, 1, 1 )
index = 4
[sub_resource type="Resource" id=6]
script = ExtResource( 2 )
color = Color( 0.701961, 0.00784314, 0.00784314, 1 )
index = 5
[sub_resource type="Resource" id=7]
script = ExtResource( 2 )
color = Color( 1, 0.270588, 0.270588, 1 )
index = 6
[sub_resource type="Resource" id=8]
script = ExtResource( 2 )
color = Color( 1, 0.00784314, 0.00392157, 1 )
index = 7
[sub_resource type="Resource" id=9]
script = ExtResource( 2 )
color = Color( 0, 0.701961, 0.2, 1 )
index = 8
[sub_resource type="Resource" id=10]
script = ExtResource( 2 )
color = Color( 0, 1, 0.282353, 1 )
index = 9
[sub_resource type="Resource" id=11]
script = ExtResource( 2 )
color = Color( 0.501961, 0.00784314, 0.701961, 1 )
index = 10
[sub_resource type="Resource" id=12]
script = ExtResource( 2 )
color = Color( 0.792157, 0.270588, 1, 1 )
index = 11
[sub_resource type="Resource" id=13]
script = ExtResource( 2 )
color = Color( 0.705882, 0, 0.996078, 1 )
index = 12
[sub_resource type="Resource" id=14]
script = ExtResource( 2 )
color = Color( 0.498039, 0.701961, 0, 1 )
index = 13
[sub_resource type="Resource" id=15]
script = ExtResource( 2 )
color = Color( 0.709804, 1, 0, 1 )
index = 14
[sub_resource type="Resource" id=16]
script = ExtResource( 2 )
color = Color( 0.00784314, 0.0666667, 0.701961, 1 )
index = 15
[sub_resource type="Resource" id=17]
script = ExtResource( 2 )
color = Color( 0.270588, 0.329412, 1, 1 )
index = 16
[sub_resource type="Resource" id=18]
script = ExtResource( 2 )
color = Color( 0.00392157, 0.0862745, 1, 1 )
index = 17
[sub_resource type="Resource" id=19]
script = ExtResource( 2 )
color = Color( 0.701961, 0.54902, 0, 1 )
index = 18
[sub_resource type="Resource" id=20]
script = ExtResource( 2 )
color = Color( 1, 0.788235, 0, 1 )
index = 19
[sub_resource type="Resource" id=21]
script = ExtResource( 2 )
color = Color( 0.00784314, 0.619608, 0.701961, 1 )
index = 20
[sub_resource type="Resource" id=22]
script = ExtResource( 2 )
color = Color( 0.478431, 0.941176, 1, 1 )
index = 21
[sub_resource type="Resource" id=23]
script = ExtResource( 2 )
color = Color( 0, 0.882353, 1, 1 )
index = 22
[sub_resource type="Resource" id=24]
script = ExtResource( 2 )
color = Color( 0.701961, 0.301961, 0, 1 )
index = 23
[sub_resource type="Resource" id=25]
script = ExtResource( 2 )
color = Color( 1, 0.435294, 0, 1 )
index = 24
[resource]
resource_name = "Complementary"
script = ExtResource( 1 )
name = "Complementary"
comment = "Author: Erevoid"
width = 8
height = 8
colors = {
0: SubResource( 1 ),
1: SubResource( 2 ),
2: SubResource( 3 ),
3: SubResource( 4 ),
4: SubResource( 5 ),
5: SubResource( 6 ),
6: SubResource( 7 ),
7: SubResource( 8 ),
8: SubResource( 9 ),
9: SubResource( 10 ),
10: SubResource( 11 ),
11: SubResource( 12 ),
12: SubResource( 13 ),
13: SubResource( 14 ),
14: SubResource( 15 ),
15: SubResource( 16 ),
16: SubResource( 17 ),
17: SubResource( 18 ),
18: SubResource( 19 ),
19: SubResource( 20 ),
20: SubResource( 21 ),
21: SubResource( 22 ),
22: SubResource( 23 ),
23: SubResource( 24 ),
24: SubResource( 25 )
}
colors_max = 64

View file

@ -1,135 +0,0 @@
{
"name": "Default",
"comments": "",
"colors": [
{
"data": "ff000000",
"name": "no name"
},
{
"data": "ff222034",
"name": "no name"
},
{
"data": "ff45283c",
"name": "no name"
},
{
"data": "ff663931",
"name": "no name"
},
{
"data": "ff8f563b",
"name": "no name"
},
{
"data": "ffdf7126",
"name": "no name"
},
{
"data": "ffd9a066",
"name": "no name"
},
{
"data": "ffeec39a",
"name": "no name"
},
{
"data": "fffbf236",
"name": "no name"
},
{
"data": "ff99e550",
"name": "no name"
},
{
"data": "ff6abe30",
"name": "no name"
},
{
"data": "ff37946e",
"name": "no name"
},
{
"data": "ff4b692f",
"name": "no name"
},
{
"data": "ff524b24",
"name": "no name"
},
{
"data": "ff323c39",
"name": "no name"
},
{
"data": "ff3f3f74",
"name": "no name"
},
{
"data": "ff306082",
"name": "no name"
},
{
"data": "ff5b6ee1",
"name": "no name"
},
{
"data": "ff639bff",
"name": "no name"
},
{
"data": "ff5fcde4",
"name": "no name"
},
{
"data": "ffcbdbfc",
"name": "no name"
},
{
"data": "ffffffff",
"name": "no name"
},
{
"data": "ff9badb7",
"name": "no name"
},
{
"data": "ff847e87",
"name": "no name"
},
{
"data": "ff696a6a",
"name": "no name"
},
{
"data": "ff595652",
"name": "no name"
},
{
"data": "ff76428a",
"name": "no name"
},
{
"data": "ffac3232",
"name": "no name"
},
{
"data": "ffd95763",
"name": "no name"
},
{
"data": "ffd77bba",
"name": "no name"
},
{
"data": "ff8f974a",
"name": "no name"
},
{
"data": "ff8a6f30",
"name": "no name"
}
],
"editable": true
}

View file

@ -0,0 +1,207 @@
[gd_resource type="Resource" load_steps=35 format=2]
[ext_resource path="res://src/Palette/PaletteColor.gd" type="Script" id=1]
[ext_resource path="res://src/Palette/Palette.gd" type="Script" id=2]
[sub_resource type="Resource" id=1]
script = ExtResource( 1 )
color = Color( 0, 0, 0, 1 )
index = 0
[sub_resource type="Resource" id=2]
script = ExtResource( 1 )
color = Color( 0.133333, 0.12549, 0.203922, 1 )
index = 1
[sub_resource type="Resource" id=3]
script = ExtResource( 1 )
color = Color( 0.270588, 0.156863, 0.235294, 1 )
index = 2
[sub_resource type="Resource" id=4]
script = ExtResource( 1 )
color = Color( 0.4, 0.223529, 0.192157, 1 )
index = 3
[sub_resource type="Resource" id=5]
script = ExtResource( 1 )
color = Color( 0.560784, 0.337255, 0.231373, 1 )
index = 4
[sub_resource type="Resource" id=6]
script = ExtResource( 1 )
color = Color( 0.87451, 0.443137, 0.14902, 1 )
index = 5
[sub_resource type="Resource" id=7]
script = ExtResource( 1 )
color = Color( 0.85098, 0.627451, 0.4, 1 )
index = 6
[sub_resource type="Resource" id=8]
script = ExtResource( 1 )
color = Color( 0.933333, 0.764706, 0.603922, 1 )
index = 7
[sub_resource type="Resource" id=9]
script = ExtResource( 1 )
color = Color( 0.984314, 0.94902, 0.211765, 1 )
index = 8
[sub_resource type="Resource" id=10]
script = ExtResource( 1 )
color = Color( 0.6, 0.898039, 0.313726, 1 )
index = 9
[sub_resource type="Resource" id=11]
script = ExtResource( 1 )
color = Color( 0.415686, 0.745098, 0.188235, 1 )
index = 10
[sub_resource type="Resource" id=12]
script = ExtResource( 1 )
color = Color( 0.215686, 0.580392, 0.431373, 1 )
index = 11
[sub_resource type="Resource" id=13]
script = ExtResource( 1 )
color = Color( 0.294118, 0.411765, 0.184314, 1 )
index = 12
[sub_resource type="Resource" id=14]
script = ExtResource( 1 )
color = Color( 0.321569, 0.294118, 0.141176, 1 )
index = 13
[sub_resource type="Resource" id=15]
script = ExtResource( 1 )
color = Color( 0.196078, 0.235294, 0.223529, 1 )
index = 14
[sub_resource type="Resource" id=16]
script = ExtResource( 1 )
color = Color( 0.247059, 0.247059, 0.454902, 1 )
index = 15
[sub_resource type="Resource" id=17]
script = ExtResource( 1 )
color = Color( 0.188235, 0.376471, 0.509804, 1 )
index = 16
[sub_resource type="Resource" id=18]
script = ExtResource( 1 )
color = Color( 0.356863, 0.431373, 0.882353, 1 )
index = 17
[sub_resource type="Resource" id=19]
script = ExtResource( 1 )
color = Color( 0.388235, 0.607843, 1, 1 )
index = 18
[sub_resource type="Resource" id=20]
script = ExtResource( 1 )
color = Color( 0.372549, 0.803922, 0.894118, 1 )
index = 19
[sub_resource type="Resource" id=21]
script = ExtResource( 1 )
color = Color( 0.796078, 0.858824, 0.988235, 1 )
index = 20
[sub_resource type="Resource" id=22]
script = ExtResource( 1 )
color = Color( 1, 1, 1, 1 )
index = 21
[sub_resource type="Resource" id=23]
script = ExtResource( 1 )
color = Color( 0.607843, 0.678431, 0.717647, 1 )
index = 22
[sub_resource type="Resource" id=24]
script = ExtResource( 1 )
color = Color( 0.517647, 0.494118, 0.529412, 1 )
index = 23
[sub_resource type="Resource" id=25]
script = ExtResource( 1 )
color = Color( 0.411765, 0.415686, 0.415686, 1 )
index = 24
[sub_resource type="Resource" id=26]
script = ExtResource( 1 )
color = Color( 0.34902, 0.337255, 0.321569, 1 )
index = 25
[sub_resource type="Resource" id=27]
script = ExtResource( 1 )
color = Color( 0.462745, 0.258824, 0.541176, 1 )
index = 26
[sub_resource type="Resource" id=28]
script = ExtResource( 1 )
color = Color( 0.67451, 0.196078, 0.196078, 1 )
index = 27
[sub_resource type="Resource" id=29]
script = ExtResource( 1 )
color = Color( 0.85098, 0.341176, 0.388235, 1 )
index = 28
[sub_resource type="Resource" id=30]
script = ExtResource( 1 )
color = Color( 0.843137, 0.482353, 0.729412, 1 )
index = 29
[sub_resource type="Resource" id=31]
script = ExtResource( 1 )
color = Color( 0.560784, 0.592157, 0.290196, 1 )
index = 30
[sub_resource type="Resource" id=32]
script = ExtResource( 1 )
color = Color( 0.541176, 0.435294, 0.188235, 1 )
index = 31
[resource]
resource_name = "Default"
script = ExtResource( 2 )
name = "Default"
comment = "Author: CheetoHead/greusser"
width = 8
height = 8
colors = {
0: SubResource( 1 ),
1: SubResource( 2 ),
2: SubResource( 3 ),
3: SubResource( 4 ),
4: SubResource( 5 ),
5: SubResource( 6 ),
6: SubResource( 7 ),
7: SubResource( 8 ),
8: SubResource( 9 ),
9: SubResource( 10 ),
10: SubResource( 11 ),
11: SubResource( 12 ),
12: SubResource( 13 ),
13: SubResource( 14 ),
14: SubResource( 15 ),
15: SubResource( 16 ),
16: SubResource( 17 ),
17: SubResource( 18 ),
18: SubResource( 19 ),
19: SubResource( 20 ),
20: SubResource( 21 ),
21: SubResource( 22 ),
22: SubResource( 23 ),
23: SubResource( 24 ),
24: SubResource( 25 ),
25: SubResource( 26 ),
26: SubResource( 27 ),
27: SubResource( 28 ),
28: SubResource( 29 ),
29: SubResource( 30 ),
30: SubResource( 31 ),
31: SubResource( 32 )
}
colors_max = 64

View file

@ -1,167 +0,0 @@
{
"name": "Monochromatic",
"comments": "By Erevos",
"colors": [
{
"data": "ff323880",
"name": "no name"
},
{
"data": "ffb0b7ff",
"name": "no name"
},
{
"data": "ff636fff",
"name": "no name"
},
{
"data": "ff4d5182",
"name": "no name"
},
{
"data": "ff505acc",
"name": "no name"
},
{
"data": "ff347685",
"name": "no name"
},
{
"data": "ffb0f1ff",
"name": "no name"
},
{
"data": "ff63e2ff",
"name": "no name"
},
{
"data": "ff487985",
"name": "no name"
},
{
"data": "ff50b5cc",
"name": "no name"
},
{
"data": "ff40852c",
"name": "no name"
},
{
"data": "ffadff94",
"name": "no name"
},
{
"data": "ff7cff54",
"name": "no name"
},
{
"data": "ff228a03",
"name": "no name"
},
{
"data": "ff64cc43",
"name": "no name"
},
{
"data": "ff857f1c",
"name": "no name"
},
{
"data": "fffffba8",
"name": "no name"
},
{
"data": "fffff536",
"name": "no name"
},
{
"data": "ff8a863b",
"name": "no name"
},
{
"data": "ffccc32b",
"name": "no name"
},
{
"data": "ff854d15",
"name": "no name"
},
{
"data": "ffffcd9c",
"name": "no name"
},
{
"data": "ffff9429",
"name": "no name"
},
{
"data": "ff8a5f34",
"name": "no name"
},
{
"data": "ffcc7520",
"name": "no name"
},
{
"data": "ff57100a",
"name": "no name"
},
{
"data": "ffeb2d1c",
"name": "no name"
},
{
"data": "ffd12617",
"name": "no name"
},
{
"data": "ff5c120b",
"name": "no name"
},
{
"data": "ff9e1d11",
"name": "no name"
},
{
"data": "ff521157",
"name": "no name"
},
{
"data": "ffde31eb",
"name": "no name"
},
{
"data": "ffc62ad1",
"name": "no name"
},
{
"data": "ff57135c",
"name": "no name"
},
{
"data": "ff96209e",
"name": "no name"
},
{
"data": "ff141414",
"name": "no name"
},
{
"data": "ffababab",
"name": "no name"
},
{
"data": "ff6e6e6e",
"name": "no name"
},
{
"data": "ff2d2d2d",
"name": "no name"
},
{
"data": "ff616161",
"name": "no name"
}
],
"editable": true
}

View file

@ -0,0 +1,255 @@
[gd_resource type="Resource" load_steps=43 format=2]
[ext_resource path="res://src/Palette/Palette.gd" type="Script" id=1]
[ext_resource path="res://src/Palette/PaletteColor.gd" type="Script" id=2]
[sub_resource type="Resource" id=1]
script = ExtResource( 2 )
color = Color( 0.196078, 0.219608, 0.501961, 1 )
index = 0
[sub_resource type="Resource" id=2]
script = ExtResource( 2 )
color = Color( 0.690196, 0.717647, 1, 1 )
index = 1
[sub_resource type="Resource" id=3]
script = ExtResource( 2 )
color = Color( 0.388235, 0.435294, 1, 1 )
index = 2
[sub_resource type="Resource" id=4]
script = ExtResource( 2 )
color = Color( 0.301961, 0.317647, 0.509804, 1 )
index = 3
[sub_resource type="Resource" id=5]
script = ExtResource( 2 )
color = Color( 0.313726, 0.352941, 0.8, 1 )
index = 4
[sub_resource type="Resource" id=6]
script = ExtResource( 2 )
color = Color( 0.203922, 0.462745, 0.521569, 1 )
index = 5
[sub_resource type="Resource" id=7]
script = ExtResource( 2 )
color = Color( 0.690196, 0.945098, 1, 1 )
index = 6
[sub_resource type="Resource" id=8]
script = ExtResource( 2 )
color = Color( 0.388235, 0.886275, 1, 1 )
index = 7
[sub_resource type="Resource" id=9]
script = ExtResource( 2 )
color = Color( 0.282353, 0.47451, 0.521569, 1 )
index = 8
[sub_resource type="Resource" id=10]
script = ExtResource( 2 )
color = Color( 0.313726, 0.709804, 0.8, 1 )
index = 9
[sub_resource type="Resource" id=11]
script = ExtResource( 2 )
color = Color( 0.25098, 0.521569, 0.172549, 1 )
index = 10
[sub_resource type="Resource" id=12]
script = ExtResource( 2 )
color = Color( 0.678431, 1, 0.580392, 1 )
index = 11
[sub_resource type="Resource" id=13]
script = ExtResource( 2 )
color = Color( 0.486275, 1, 0.329412, 1 )
index = 12
[sub_resource type="Resource" id=14]
script = ExtResource( 2 )
color = Color( 0.133333, 0.541176, 0.0117647, 1 )
index = 13
[sub_resource type="Resource" id=15]
script = ExtResource( 2 )
color = Color( 0.392157, 0.8, 0.262745, 1 )
index = 14
[sub_resource type="Resource" id=16]
script = ExtResource( 2 )
color = Color( 0.521569, 0.498039, 0.109804, 1 )
index = 15
[sub_resource type="Resource" id=17]
script = ExtResource( 2 )
color = Color( 1, 0.984314, 0.658824, 1 )
index = 16
[sub_resource type="Resource" id=18]
script = ExtResource( 2 )
color = Color( 1, 0.960784, 0.211765, 1 )
index = 17
[sub_resource type="Resource" id=19]
script = ExtResource( 2 )
color = Color( 0.541176, 0.52549, 0.231373, 1 )
index = 18
[sub_resource type="Resource" id=20]
script = ExtResource( 2 )
color = Color( 0.8, 0.764706, 0.168627, 1 )
index = 19
[sub_resource type="Resource" id=21]
script = ExtResource( 2 )
color = Color( 0.521569, 0.301961, 0.0823529, 1 )
index = 20
[sub_resource type="Resource" id=22]
script = ExtResource( 2 )
color = Color( 1, 0.803922, 0.611765, 1 )
index = 21
[sub_resource type="Resource" id=23]
script = ExtResource( 2 )
color = Color( 1, 0.580392, 0.160784, 1 )
index = 22
[sub_resource type="Resource" id=24]
script = ExtResource( 2 )
color = Color( 0.541176, 0.372549, 0.203922, 1 )
index = 23
[sub_resource type="Resource" id=25]
script = ExtResource( 2 )
color = Color( 0.8, 0.458824, 0.12549, 1 )
index = 24
[sub_resource type="Resource" id=26]
script = ExtResource( 2 )
color = Color( 0.341176, 0.0627451, 0.0392157, 1 )
index = 25
[sub_resource type="Resource" id=27]
script = ExtResource( 2 )
color = Color( 0.921569, 0.176471, 0.109804, 1 )
index = 26
[sub_resource type="Resource" id=28]
script = ExtResource( 2 )
color = Color( 0.819608, 0.14902, 0.0901961, 1 )
index = 27
[sub_resource type="Resource" id=29]
script = ExtResource( 2 )
color = Color( 0.360784, 0.0705882, 0.0431373, 1 )
index = 28
[sub_resource type="Resource" id=30]
script = ExtResource( 2 )
color = Color( 0.619608, 0.113725, 0.0666667, 1 )
index = 29
[sub_resource type="Resource" id=31]
script = ExtResource( 2 )
color = Color( 0.321569, 0.0666667, 0.341176, 1 )
index = 30
[sub_resource type="Resource" id=32]
script = ExtResource( 2 )
color = Color( 0.870588, 0.192157, 0.921569, 1 )
index = 31
[sub_resource type="Resource" id=33]
script = ExtResource( 2 )
color = Color( 0.776471, 0.164706, 0.819608, 1 )
index = 32
[sub_resource type="Resource" id=34]
script = ExtResource( 2 )
color = Color( 0.341176, 0.0745098, 0.360784, 1 )
index = 33
[sub_resource type="Resource" id=35]
script = ExtResource( 2 )
color = Color( 0.588235, 0.12549, 0.619608, 1 )
index = 34
[sub_resource type="Resource" id=36]
script = ExtResource( 2 )
color = Color( 0.0784314, 0.0784314, 0.0784314, 1 )
index = 35
[sub_resource type="Resource" id=37]
script = ExtResource( 2 )
color = Color( 0.670588, 0.670588, 0.670588, 1 )
index = 36
[sub_resource type="Resource" id=38]
script = ExtResource( 2 )
color = Color( 0.431373, 0.431373, 0.431373, 1 )
index = 37
[sub_resource type="Resource" id=39]
script = ExtResource( 2 )
color = Color( 0.176471, 0.176471, 0.176471, 1 )
index = 38
[sub_resource type="Resource" id=40]
script = ExtResource( 2 )
color = Color( 0.380392, 0.380392, 0.380392, 1 )
index = 39
[resource]
resource_name = "Monochromatic"
script = ExtResource( 1 )
name = "Monochromatic"
comment = "Author: Erevoid"
width = 8
height = 8
colors = {
0: SubResource( 1 ),
1: SubResource( 2 ),
2: SubResource( 3 ),
3: SubResource( 4 ),
4: SubResource( 5 ),
5: SubResource( 6 ),
6: SubResource( 7 ),
7: SubResource( 8 ),
8: SubResource( 9 ),
9: SubResource( 10 ),
10: SubResource( 11 ),
11: SubResource( 12 ),
12: SubResource( 13 ),
13: SubResource( 14 ),
14: SubResource( 15 ),
15: SubResource( 16 ),
16: SubResource( 17 ),
17: SubResource( 18 ),
18: SubResource( 19 ),
19: SubResource( 20 ),
20: SubResource( 21 ),
21: SubResource( 22 ),
22: SubResource( 23 ),
23: SubResource( 24 ),
24: SubResource( 25 ),
25: SubResource( 26 ),
26: SubResource( 27 ),
27: SubResource( 28 ),
28: SubResource( 29 ),
29: SubResource( 30 ),
30: SubResource( 31 ),
31: SubResource( 32 ),
32: SubResource( 33 ),
33: SubResource( 34 ),
34: SubResource( 35 ),
35: SubResource( 36 ),
36: SubResource( 37 ),
37: SubResource( 38 ),
38: SubResource( 39 ),
39: SubResource( 40 )
}
colors_max = 64

View file

@ -1,147 +0,0 @@
{
"name": "Shades",
"comments": "By Erevos",
"colors": [
{
"data": "ffc25400",
"name": "no name"
},
{
"data": "ff803900",
"name": "no name"
},
{
"data": "ffff7300",
"name": "no name"
},
{
"data": "ff401d00",
"name": "no name"
},
{
"data": "ffe66700",
"name": "no name"
},
{
"data": "ffc20000",
"name": "no name"
},
{
"data": "ff800000",
"name": "no name"
},
{
"data": "ffff0000",
"name": "no name"
},
{
"data": "ff400000",
"name": "no name"
},
{
"data": "ffe60101",
"name": "no name"
},
{
"data": "ff8800c2",
"name": "no name"
},
{
"data": "ff590080",
"name": "no name"
},
{
"data": "ffb300ff",
"name": "no name"
},
{
"data": "ff2d0040",
"name": "no name"
},
{
"data": "ffa200e5",
"name": "no name"
},
{
"data": "ff0010c2",
"name": "no name"
},
{
"data": "ff000b80",
"name": "no name"
},
{
"data": "ff0015ff",
"name": "no name"
},
{
"data": "ff000540",
"name": "no name"
},
{
"data": "ff0114e6",
"name": "no name"
},
{
"data": "ff00abc2",
"name": "no name"
},
{
"data": "ff007180",
"name": "no name"
},
{
"data": "ff00e1ff",
"name": "no name"
},
{
"data": "ff003840",
"name": "no name"
},
{
"data": "ff00cbe6",
"name": "no name"
},
{
"data": "ff00c237",
"name": "no name"
},
{
"data": "ff008024",
"name": "no name"
},
{
"data": "ff00ff48",
"name": "no name"
},
{
"data": "ff004012",
"name": "no name"
},
{
"data": "ff00e641",
"name": "no name"
},
{
"data": "ffb8c200",
"name": "no name"
},
{
"data": "ff798000",
"name": "no name"
},
{
"data": "fff2ff00",
"name": "no name"
},
{
"data": "ff3d4000",
"name": "no name"
},
{
"data": "ffdce600",
"name": "no name"
}
],
"editable": true
}

View file

@ -0,0 +1,225 @@
[gd_resource type="Resource" load_steps=38 format=2]
[ext_resource path="res://src/Palette/Palette.gd" type="Script" id=1]
[ext_resource path="res://src/Palette/PaletteColor.gd" type="Script" id=2]
[sub_resource type="Resource" id=1]
script = ExtResource( 2 )
color = Color( 0.760784, 0.329412, 0, 1 )
index = 0
[sub_resource type="Resource" id=2]
script = ExtResource( 2 )
color = Color( 0.501961, 0.223529, 0, 1 )
index = 1
[sub_resource type="Resource" id=3]
script = ExtResource( 2 )
color = Color( 1, 0.45098, 0, 1 )
index = 2
[sub_resource type="Resource" id=4]
script = ExtResource( 2 )
color = Color( 0.25098, 0.113725, 0, 1 )
index = 3
[sub_resource type="Resource" id=5]
script = ExtResource( 2 )
color = Color( 0.901961, 0.403922, 0, 1 )
index = 4
[sub_resource type="Resource" id=6]
script = ExtResource( 2 )
color = Color( 0.760784, 0, 0, 1 )
index = 5
[sub_resource type="Resource" id=7]
script = ExtResource( 2 )
color = Color( 0.501961, 0, 0, 1 )
index = 6
[sub_resource type="Resource" id=8]
script = ExtResource( 2 )
color = Color( 1, 0, 0, 1 )
index = 7
[sub_resource type="Resource" id=9]
script = ExtResource( 2 )
color = Color( 0.25098, 0, 0, 1 )
index = 8
[sub_resource type="Resource" id=10]
script = ExtResource( 2 )
color = Color( 0.901961, 0.00392157, 0.00392157, 1 )
index = 9
[sub_resource type="Resource" id=11]
script = ExtResource( 2 )
color = Color( 0.533333, 0, 0.760784, 1 )
index = 10
[sub_resource type="Resource" id=12]
script = ExtResource( 2 )
color = Color( 0.34902, 0, 0.501961, 1 )
index = 11
[sub_resource type="Resource" id=13]
script = ExtResource( 2 )
color = Color( 0.701961, 0, 1, 1 )
index = 12
[sub_resource type="Resource" id=14]
script = ExtResource( 2 )
color = Color( 0.176471, 0, 0.25098, 1 )
index = 13
[sub_resource type="Resource" id=15]
script = ExtResource( 2 )
color = Color( 0.635294, 0, 0.898039, 1 )
index = 14
[sub_resource type="Resource" id=16]
script = ExtResource( 2 )
color = Color( 0, 0.0627451, 0.760784, 1 )
index = 15
[sub_resource type="Resource" id=17]
script = ExtResource( 2 )
color = Color( 0, 0.0431373, 0.501961, 1 )
index = 16
[sub_resource type="Resource" id=18]
script = ExtResource( 2 )
color = Color( 0, 0.0823529, 1, 1 )
index = 17
[sub_resource type="Resource" id=19]
script = ExtResource( 2 )
color = Color( 0, 0.0196078, 0.25098, 1 )
index = 18
[sub_resource type="Resource" id=20]
script = ExtResource( 2 )
color = Color( 0.00392157, 0.0784314, 0.901961, 1 )
index = 19
[sub_resource type="Resource" id=21]
script = ExtResource( 2 )
color = Color( 0, 0.670588, 0.760784, 1 )
index = 20
[sub_resource type="Resource" id=22]
script = ExtResource( 2 )
color = Color( 0, 0.443137, 0.501961, 1 )
index = 21
[sub_resource type="Resource" id=23]
script = ExtResource( 2 )
color = Color( 0, 0.882353, 1, 1 )
index = 22
[sub_resource type="Resource" id=24]
script = ExtResource( 2 )
color = Color( 0, 0.219608, 0.25098, 1 )
index = 23
[sub_resource type="Resource" id=25]
script = ExtResource( 2 )
color = Color( 0, 0.796078, 0.901961, 1 )
index = 24
[sub_resource type="Resource" id=26]
script = ExtResource( 2 )
color = Color( 0, 0.760784, 0.215686, 1 )
index = 25
[sub_resource type="Resource" id=27]
script = ExtResource( 2 )
color = Color( 0, 0.501961, 0.141176, 1 )
index = 26
[sub_resource type="Resource" id=28]
script = ExtResource( 2 )
color = Color( 0, 1, 0.282353, 1 )
index = 27
[sub_resource type="Resource" id=29]
script = ExtResource( 2 )
color = Color( 0, 0.25098, 0.0705882, 1 )
index = 28
[sub_resource type="Resource" id=30]
script = ExtResource( 2 )
color = Color( 0, 0.901961, 0.254902, 1 )
index = 29
[sub_resource type="Resource" id=31]
script = ExtResource( 2 )
color = Color( 0.721569, 0.760784, 0, 1 )
index = 30
[sub_resource type="Resource" id=32]
script = ExtResource( 2 )
color = Color( 0.47451, 0.501961, 0, 1 )
index = 31
[sub_resource type="Resource" id=33]
script = ExtResource( 2 )
color = Color( 0.94902, 1, 0, 1 )
index = 32
[sub_resource type="Resource" id=34]
script = ExtResource( 2 )
color = Color( 0.239216, 0.25098, 0, 1 )
index = 33
[sub_resource type="Resource" id=35]
script = ExtResource( 2 )
color = Color( 0.862745, 0.901961, 0, 1 )
index = 34
[resource]
resource_name = "Shades"
script = ExtResource( 1 )
name = "Shades"
comment = "Author: Erevoid"
width = 8
height = 8
colors = {
0: SubResource( 1 ),
1: SubResource( 2 ),
2: SubResource( 3 ),
3: SubResource( 4 ),
4: SubResource( 5 ),
5: SubResource( 6 ),
6: SubResource( 7 ),
7: SubResource( 8 ),
8: SubResource( 9 ),
9: SubResource( 10 ),
10: SubResource( 11 ),
11: SubResource( 12 ),
12: SubResource( 13 ),
13: SubResource( 14 ),
14: SubResource( 15 ),
15: SubResource( 16 ),
16: SubResource( 17 ),
17: SubResource( 18 ),
18: SubResource( 19 ),
19: SubResource( 20 ),
20: SubResource( 21 ),
21: SubResource( 22 ),
22: SubResource( 23 ),
23: SubResource( 24 ),
24: SubResource( 25 ),
25: SubResource( 26 ),
26: SubResource( 27 ),
27: SubResource( 28 ),
28: SubResource( 29 ),
29: SubResource( 30 ),
30: SubResource( 31 ),
31: SubResource( 32 ),
32: SubResource( 33 ),
33: SubResource( 34 ),
34: SubResource( 35 )
}
colors_max = 64

View file

@ -1,107 +0,0 @@
{
"name": "Triad",
"comments": "By Erevos",
"colors": [
{
"data": "ff852c32",
"name": "no name"
},
{
"data": "ffcc646b",
"name": "no name"
},
{
"data": "ffe3df66",
"name": "no name"
},
{
"data": "ff3c7899",
"name": "no name"
},
{
"data": "ff386680",
"name": "no name"
},
{
"data": "ff141a85",
"name": "no name"
},
{
"data": "ff353cd1",
"name": "no name"
},
{
"data": "ffe66930",
"name": "no name"
},
{
"data": "ff409e18",
"name": "no name"
},
{
"data": "ff3a851b",
"name": "no name"
},
{
"data": "ff8a0500",
"name": "no name"
},
{
"data": "ffd10600",
"name": "no name"
},
{
"data": "ffdee609",
"name": "no name"
},
{
"data": "ff105f9e",
"name": "no name"
},
{
"data": "ff074c85",
"name": "no name"
},
{
"data": "ff84168a",
"name": "no name"
},
{
"data": "ffc942d1",
"name": "no name"
},
{
"data": "ffe6bf40",
"name": "no name"
},
{
"data": "ff239e85",
"name": "no name"
},
{
"data": "ff248571",
"name": "no name"
},
{
"data": "ff1e8a1a",
"name": "no name"
},
{
"data": "ff4fd14a",
"name": "no name"
},
{
"data": "ff6047e6",
"name": "no name"
},
{
"data": "ff9e5a28",
"name": "no name"
},
{
"data": "ff854f28",
"name": "no name"
}
],
"editable": true
}

View file

@ -0,0 +1,165 @@
[gd_resource type="Resource" load_steps=28 format=2]
[ext_resource path="res://src/Palette/Palette.gd" type="Script" id=1]
[ext_resource path="res://src/Palette/PaletteColor.gd" type="Script" id=2]
[sub_resource type="Resource" id=1]
script = ExtResource( 2 )
color = Color( 0.521569, 0.172549, 0.196078, 1 )
index = 0
[sub_resource type="Resource" id=2]
script = ExtResource( 2 )
color = Color( 0.8, 0.392157, 0.419608, 1 )
index = 1
[sub_resource type="Resource" id=3]
script = ExtResource( 2 )
color = Color( 0.890196, 0.87451, 0.4, 1 )
index = 2
[sub_resource type="Resource" id=4]
script = ExtResource( 2 )
color = Color( 0.235294, 0.470588, 0.6, 1 )
index = 3
[sub_resource type="Resource" id=5]
script = ExtResource( 2 )
color = Color( 0.219608, 0.4, 0.501961, 1 )
index = 4
[sub_resource type="Resource" id=6]
script = ExtResource( 2 )
color = Color( 0.0784314, 0.101961, 0.521569, 1 )
index = 5
[sub_resource type="Resource" id=7]
script = ExtResource( 2 )
color = Color( 0.207843, 0.235294, 0.819608, 1 )
index = 6
[sub_resource type="Resource" id=8]
script = ExtResource( 2 )
color = Color( 0.901961, 0.411765, 0.188235, 1 )
index = 7
[sub_resource type="Resource" id=9]
script = ExtResource( 2 )
color = Color( 0.25098, 0.619608, 0.0941176, 1 )
index = 8
[sub_resource type="Resource" id=10]
script = ExtResource( 2 )
color = Color( 0.227451, 0.521569, 0.105882, 1 )
index = 9
[sub_resource type="Resource" id=11]
script = ExtResource( 2 )
color = Color( 0.541176, 0.0196078, 0, 1 )
index = 10
[sub_resource type="Resource" id=12]
script = ExtResource( 2 )
color = Color( 0.819608, 0.0235294, 0, 1 )
index = 11
[sub_resource type="Resource" id=13]
script = ExtResource( 2 )
color = Color( 0.870588, 0.901961, 0.0352941, 1 )
index = 12
[sub_resource type="Resource" id=14]
script = ExtResource( 2 )
color = Color( 0.0627451, 0.372549, 0.619608, 1 )
index = 13
[sub_resource type="Resource" id=15]
script = ExtResource( 2 )
color = Color( 0.027451, 0.298039, 0.521569, 1 )
index = 14
[sub_resource type="Resource" id=16]
script = ExtResource( 2 )
color = Color( 0.517647, 0.0862745, 0.541176, 1 )
index = 15
[sub_resource type="Resource" id=17]
script = ExtResource( 2 )
color = Color( 0.788235, 0.258824, 0.819608, 1 )
index = 16
[sub_resource type="Resource" id=18]
script = ExtResource( 2 )
color = Color( 0.901961, 0.74902, 0.25098, 1 )
index = 17
[sub_resource type="Resource" id=19]
script = ExtResource( 2 )
color = Color( 0.137255, 0.619608, 0.521569, 1 )
index = 18
[sub_resource type="Resource" id=20]
script = ExtResource( 2 )
color = Color( 0.141176, 0.521569, 0.443137, 1 )
index = 19
[sub_resource type="Resource" id=21]
script = ExtResource( 2 )
color = Color( 0.117647, 0.541176, 0.101961, 1 )
index = 20
[sub_resource type="Resource" id=22]
script = ExtResource( 2 )
color = Color( 0.309804, 0.819608, 0.290196, 1 )
index = 21
[sub_resource type="Resource" id=23]
script = ExtResource( 2 )
color = Color( 0.376471, 0.278431, 0.901961, 1 )
index = 22
[sub_resource type="Resource" id=24]
script = ExtResource( 2 )
color = Color( 0.619608, 0.352941, 0.156863, 1 )
index = 23
[sub_resource type="Resource" id=25]
script = ExtResource( 2 )
color = Color( 0.521569, 0.309804, 0.156863, 1 )
index = 24
[resource]
resource_name = "Triad"
script = ExtResource( 1 )
name = "Triad"
comment = "Author: Erevoid"
width = 8
height = 8
colors = {
0: SubResource( 1 ),
1: SubResource( 2 ),
2: SubResource( 3 ),
3: SubResource( 4 ),
4: SubResource( 5 ),
5: SubResource( 6 ),
6: SubResource( 7 ),
7: SubResource( 8 ),
8: SubResource( 9 ),
9: SubResource( 10 ),
10: SubResource( 11 ),
11: SubResource( 12 ),
12: SubResource( 13 ),
13: SubResource( 14 ),
14: SubResource( 15 ),
15: SubResource( 16 ),
16: SubResource( 17 ),
17: SubResource( 18 ),
18: SubResource( 19 ),
19: SubResource( 20 ),
20: SubResource( 21 ),
21: SubResource( 22 ),
22: SubResource( 23 ),
23: SubResource( 24 ),
24: SubResource( 25 )
}
colors_max = 64

View file

@ -1,71 +0,0 @@
{
"name": "BubbleGum16",
"comments": "by PineTreePizza - https://twitter.com/PineTreePizza",
"colors": [
{
"data": "ff000000",
"name": "no name"
},
{
"data": "ff7f0622",
"name": "no name"
},
{
"data": "ffd62411",
"name": "no name"
},
{
"data": "ffff8426",
"name": "no name"
},
{
"data": "ffffd100",
"name": "no name"
},
{
"data": "fffafdff",
"name": "no name"
},
{
"data": "ffff80a4",
"name": "no name"
},
{
"data": "ffff2674",
"name": "no name"
},
{
"data": "ff94216a",
"name": "no name"
},
{
"data": "ff430067",
"name": "no name"
},
{
"data": "ff234975",
"name": "no name"
},
{
"data": "ff68aed4",
"name": "no name"
},
{
"data": "ffbfff3c",
"name": "no name"
},
{
"data": "ff10d275",
"name": "no name"
},
{
"data": "ff007899",
"name": "no name"
},
{
"data": "ff002859",
"name": "no name"
}
],
"editable": true
}

View file

@ -64,16 +64,31 @@ _global_script_classes=[ {
"language": "GDScript",
"path": "res://src/UI/Timeline/LayerButton.gd"
}, {
"base": "Reference",
"base": "Resource",
"class": "Palette",
"language": "GDScript",
"path": "res://src/Palette/Palette.gd"
}, {
"base": "Reference",
"base": "Resource",
"class": "PaletteColor",
"language": "GDScript",
"path": "res://src/Palette/PaletteColor.gd"
}, {
"base": "GridContainer",
"class": "PaletteGrid",
"language": "GDScript",
"path": "res://src/Palette/PaletteGrid.gd"
}, {
"base": "PanelContainer",
"class": "PalettePanel",
"language": "GDScript",
"path": "res://src/Palette/PalettePanel.gd"
}, {
"base": "ColorRect",
"class": "PaletteSwatch",
"language": "GDScript",
"path": "res://src/Palette/PaletteSwatch.gd"
}, {
"base": "PopupPanel",
"class": "Patterns",
"language": "GDScript",
@ -103,6 +118,9 @@ _global_script_class_icons={
"LayerButton": "",
"Palette": "",
"PaletteColor": "",
"PaletteGrid": "",
"PalettePanel": "",
"PaletteSwatch": "",
"Patterns": "",
"Project": "",
"SymmetryGuide": ""
@ -134,6 +152,7 @@ DrawingAlgos="*res://src/Autoload/DrawingAlgos.gd"
Tools="*res://src/Autoload/Tools.gd"
Html5FileExchange="*res://src/Autoload/HTML5FileExchange.gd"
Export="*res://src/Autoload/Export.gd"
Palettes="*res://src/Autoload/Palettes.gd"
[debug]

View file

@ -176,14 +176,7 @@ var layer_opacity_slider : HSlider
var layer_opacity_spinbox : SpinBox
var preview_zoom_slider : VSlider
var add_palette_button : BaseButton
var edit_palette_button : BaseButton
var palette_option_button : OptionButton
var palette_container : GridContainer
var edit_palette_popup : WindowDialog
var new_palette_dialog : ConfirmationDialog
var new_palette_name_line_edit : LineEdit
var palette_import_file_dialog : FileDialog
var palette_panel : PalettePanel
var error_dialog : AcceptDialog
var quit_dialog : ConfirmationDialog
@ -320,14 +313,7 @@ func _ready() -> void:
preview_zoom_slider = find_node_by_name(root, "PreviewZoomSlider")
add_palette_button = find_node_by_name(root, "AddPalette")
edit_palette_button = find_node_by_name(root, "EditPalette")
palette_option_button = find_node_by_name(root, "PaletteOptionButton")
palette_container = find_node_by_name(root, "PaletteContainer")
edit_palette_popup = find_node_by_name(root, "EditPalettePopup")
new_palette_dialog = find_node_by_name(root, "NewPaletteDialog")
new_palette_name_line_edit = find_node_by_name(new_palette_dialog, "NewPaletteNameLineEdit")
palette_import_file_dialog = find_node_by_name(root, "PaletteImportFileDialog")
palette_panel = find_node_by_name(root, "PalettePanel")
error_dialog = find_node_by_name(root, "ErrorDialog")
quit_dialog = find_node_by_name(root, "QuitDialog")

View file

@ -223,101 +223,3 @@ func import_patterns(priority_ordered_search_path: Array) -> void:
image.convert(Image.FORMAT_RGBA8)
var tooltip_name = pattern.get_basename()
Global.patterns_popup.add(image, tooltip_name)
func import_gpl(path : String, text : String) -> Palette:
# Refer to app/core/gimppalette-load.c of the GIMP for the "living spec"
var result : Palette = null
var lines = text.split('\n')
var line_number := 0
var comments := ""
for line in lines:
# Check if valid Gimp Palette Library file
if line_number == 0:
if not "GIMP Palette" in line:
break
else:
result = Palette.new()
# Use filename as palette name in case reading old
# palette format (must read more to determine)
result.name = path.get_basename().get_file()
# Comments
if line.begins_with('#'):
comments += line.trim_prefix('#') + '\n'
# Some programs output palette name in a comment for old format
if line.begins_with("#Palette Name: "):
result.name = line.replace("#Palette Name: ", "")
pass
elif line.begins_with("Name: "):
result.name = line.replace("Name: ", "")
pass
elif line.begins_with("Columns: "):
# Number of colors in this palette. Unecessary and often wrong
pass
elif line_number > 0 && line.length() >= 9:
line = line.replace("\t", " ")
var color_data : PoolStringArray = line.split(" ", false, 4)
if color_data.size() < 3:
continue
var red : float = color_data[0].to_float() / 255.0
var green : float = color_data[1].to_float() / 255.0
var blue : float = color_data[2].to_float() / 255.0
var color = Color(red, green, blue)
if color_data.size() >= 4:
result.add_color(color, color_data[3])
else:
result.add_color(color)
line_number += 1
if result:
result.comments = comments
return result
func import_png_palette(path: String, image : Image) -> Palette:
var result: Palette = null
var height: int = image.get_height()
var width: int = image.get_width()
result = Palette.new()
# Iterate all pixels and store unique colors to palete
image.lock()
for y in range(0, height):
for x in range(0, width):
var color: Color = image.get_pixel(x, y)
if not result.has_color(color):
result.add_color(color, "#" + color.to_html())
image.unlock()
result.name = path.get_basename().get_file()
return result
func import_pal_palette(path : String, text : String) -> Palette:
var result: Palette = null
var lines = text.split('\n')
if not 'JASC-PAL' in lines[0] or not '0100' in lines[1]:
return result
else:
result = Palette.new()
result.name = path.get_basename().get_file()
var num_colors = int(lines[2])
for i in range(3, num_colors + 3):
var color_data = lines[i].split(' ')
var red : float = color_data[0].to_float() / 255.0
var green : float = color_data[1].to_float() / 255.0
var blue : float = color_data[2].to_float() / 255.0
var color = Color(red, green, blue)
result.add_color(color)
return result

View file

@ -23,8 +23,8 @@ func handle_loading_files(files : PoolStringArray) -> void:
var file_ext : String = file.get_extension().to_lower()
if file_ext == "pxo": # Pixelorama project file
open_pxo_file(file)
elif file_ext == "json" or file_ext == "gpl" or file_ext == "pal": # Palettes
Global.palette_container.on_palette_import_file_selected(file)
elif file_ext == "tres" or file_ext == "gpl" or file_ext == "pal" or file_ext == "json": # Palettes
Palettes.import_palette(file)
else: # Image files
var image := Image.new()
var err := image.load(file)

550
src/Autoload/Palettes.gd Normal file
View file

@ -0,0 +1,550 @@
extends Node
const DEFAULT_PALETTE_NAME = "Default"
# Presets for creating a new palette
enum NewPalettePresetType {
Empty = 0,
FromCurrentPalette = 1,
FromCurrentSprite = 2,
FromCurrentSelection = 3
}
# Color options when user creates a new palette from current sprite or selection
enum GetColorsFrom {
CurrentFrame = 0,
CurrentCel = 1,
AllFrames = 2
}
# All available palettes
var palettes := {}
# Currently displayed palette
var current_palette = null
# Indexes of colors that are selected in palette
# by left and right mouse button
var left_selected_color := -1
var right_selected_color := -1
func _ready() -> void:
load_palettes()
pass
func get_palettes() -> Dictionary:
return palettes
func get_current_palette() -> Palette:
return current_palette
func does_palette_exist(palette_name: String) -> bool:
for palette_path in palettes.keys():
var file_name = palette_path.get_basename().get_file()
var stripped_palette_name = Palette.strip_unvalid_characters(palette_name)
if file_name == stripped_palette_name:
return true
return false
func select_palette(palette_path: String) -> void:
current_palette = palettes.get(palette_path)
clear_selected_colors()
func is_any_palette_selected() -> bool:
if self.current_palette:
return true
return false
func current_palette_save() -> String:
var save_path = ""
if current_palette:
save_path = save_palette(self.current_palette)
return save_path
func save_palette(palette: Palette) -> String:
Global.directory_module.ensure_xdg_user_dirs_exist()
var palettes_write_path: String = Global.directory_module.get_palette_write_path()
# Save old resource name and set new resource name
var old_resource_name = palette.resource_name
palette.set_resource_name(palette.name)
# If resource name changed remove the old palette file
if old_resource_name != palette.resource_name:
var old_palette = palettes_write_path.plus_file(old_resource_name) + ".tres"
delete_palette(old_palette)
# Save palette
var save_path = palettes_write_path.plus_file(palette.resource_name) + ".tres"
palette.resource_path = save_path
var err = ResourceSaver.save(save_path, palette)
if err != OK:
Global.notification_label("Failed to save palette")
return save_path
func create_new_palette(preset: int, name: String, comment: String, width: int, height: int, add_alpha_colors: bool, get_colors_from: int) -> void:
check_palette_settings_values(name, width, height)
match preset:
NewPalettePresetType.Empty:
create_new_empty_palette(name, comment, width, height)
NewPalettePresetType.FromCurrentPalette:
create_new_palette_from_current_palette(name, comment)
NewPalettePresetType.FromCurrentSprite:
create_new_palette_from_current_sprite(name, comment, width, height, add_alpha_colors, get_colors_from)
NewPalettePresetType.FromCurrentSelection:
create_new_palette_from_current_selection(name, comment, width, height, add_alpha_colors, get_colors_from)
func create_new_empty_palette(name: String, comment: String, width: int, height: int) -> void:
var new_palette: Palette = Palette.new(name, width, height, comment)
var palette_path := save_palette(new_palette)
palettes[palette_path] = new_palette
select_palette(palette_path)
func create_new_palette_from_current_palette(name: String, comment: String) -> void:
var new_palette: Palette = current_palette.duplicate()
new_palette.name = name
new_palette.comment = comment
new_palette.set_resource_name(name)
var palette_path := save_palette(new_palette)
palettes[palette_path] = new_palette
select_palette(palette_path)
func create_new_palette_from_current_selection(name: String, comment: String, width: int, height: int, add_alpha_colors: bool, get_colors_from: int):
var new_palette: Palette = Palette.new(name, width, height, comment)
var current_project = Global.current_project
var pixels = current_project.selected_pixels.duplicate()
fill_new_palette_with_colors(pixels, new_palette, add_alpha_colors, get_colors_from)
func create_new_palette_from_current_sprite(name: String, comment: String, width: int, height: int, add_alpha_colors: bool, get_colors_from: int):
var new_palette: Palette = Palette.new(name, width, height, comment)
var current_project = Global.current_project
var pixels := []
for x in current_project.size.x:
for y in current_project.size.y:
pixels.append(Vector2(x, y))
fill_new_palette_with_colors(pixels, new_palette, add_alpha_colors, get_colors_from)
func fill_new_palette_with_colors(pixels: Array, new_palette: Palette, add_alpha_colors: bool, get_colors_from: int):
var current_project = Global.current_project
var cels := []
match get_colors_from:
GetColorsFrom.CurrentCel:
cels.append(current_project.frames[current_project.current_frame].cels[current_project.current_layer])
GetColorsFrom.CurrentFrame:
for cel in current_project.frames[current_project.current_frame].cels:
cels.append(cel)
GetColorsFrom.AllFrames:
for frame in current_project.frames:
for cel in frame.cels:
cels.append(cel)
for cel in cels:
var cel_image := Image.new()
cel_image.copy_from(cel.image)
cel_image.lock()
if cel_image.is_invisible():
continue
for i in pixels:
var color : Color = cel_image.get_pixelv(i)
if color.a > 0:
if not add_alpha_colors:
color.a = 1
if not new_palette.has_color(color):
new_palette.add_color(color)
cel_image.unlock()
var palette_path := save_palette(new_palette)
palettes[palette_path] = new_palette
select_palette(palette_path)
func current_palette_edit(name: String, comment: String, width: int, height: int) -> void:
check_palette_settings_values(name, width, height)
current_palette.edit(name, width, height, comment)
var palette_path = current_palette_save()
palettes[palette_path] = current_palette
func delete_palette(path: String) -> void:
var dir = Directory.new()
dir.remove(path)
palettes.erase(path)
func current_palete_delete() -> void:
delete_palette(current_palette.resource_path)
if palettes.size() > 0:
select_palette(palettes.keys()[0])
else:
current_palette = null
func current_palette_add_color(mouse_button: int, start_index: int = 0) -> void:
if not current_palette.is_full() and (mouse_button == BUTTON_LEFT or mouse_button == BUTTON_RIGHT):
# Get color on left or right tool
var color = Tools.get_assigned_color(mouse_button)
current_palette.add_color(color, start_index)
current_palette_save()
func current_palette_get_color(index: int) -> Color:
return current_palette.get_color(index)
func current_palette_set_color(index: int, color: Color) -> void:
current_palette.set_color(index, color)
current_palette_save()
func current_palette_delete_color(index: int) -> void:
current_palette.remove_color(index)
current_palette_save()
func current_palette_swap_colors(source_index: int, target_index: int) -> void:
current_palette.swap_colors(source_index, target_index)
select_color(BUTTON_LEFT, target_index)
current_palette_save()
func current_palette_copy_colors(from: int, to: int) -> void:
current_palette.copy_colors(from, to)
current_palette_save()
func current_palette_insert_color(from: int, to: int) -> void:
var from_color = current_palette.colors[from]
current_palette.remove_color(from)
current_palette.insert_color(to, from_color.color)
current_palette_save()
func current_palette_get_selected_color_index(mouse_button: int) -> int:
match mouse_button:
BUTTON_LEFT:
return left_selected_color
BUTTON_RIGHT:
return right_selected_color
_:
return -1
func current_palette_select_color(mouse_button: int, index: int) -> void:
var color = current_palette_get_color(index)
if color == null:
return
match mouse_button:
BUTTON_LEFT:
Tools.assign_color(color, mouse_button)
BUTTON_RIGHT:
Tools.assign_color(color, mouse_button)
select_color(mouse_button, index)
func select_color(mouse_button: int, index: int) -> void:
match mouse_button:
BUTTON_LEFT:
left_selected_color = index
BUTTON_RIGHT:
right_selected_color = index
func clear_selected_colors() -> void:
left_selected_color = -1
right_selected_color = -1
func current_palette_is_empty() -> bool:
return current_palette.is_empty()
func current_palette_is_full() -> bool:
return current_palette.is_full()
func check_palette_settings_values(name: String, width: int, height: int) -> bool:
# Just in case. These values should be not allowed in gui.
if name.length() <= 0 or width <= 0 or height <= 0:
printerr("Palette width, height and name length must be greater than 0!")
return false
return true
func load_palettes() -> void:
Global.directory_module.ensure_xdg_user_dirs_exist()
var search_locations = Global.directory_module.get_palette_search_path_in_order()
var priority_ordered_files := get_palette_priority_file_map(search_locations)
var palettes_write_path: String = Global.directory_module.get_palette_write_path()
# Iterate backwards, so any palettes defined in default files
# get overwritten by those of the same name in user files
search_locations.invert()
priority_ordered_files.invert()
for i in range(len(search_locations)):
# If palette is not in palettes write path - make it's copy in the write path
var make_copy := false
if search_locations[i] != palettes_write_path:
make_copy = true
var base_directory : String = search_locations[i]
var palette_files : Array = priority_ordered_files[i]
for file_name in palette_files:
var palette: Palette = load(base_directory.plus_file(file_name))
if palette:
if make_copy:
# Makes a copy of the palette
save_palette(palette)
palette.resource_name = palette.resource_path.get_file().trim_suffix(".tres")
# On Windows for some reason paths can contain "res://" in front of them which breaks saving
palette.resource_path = palette.resource_path.trim_prefix("res://")
palettes[palette.resource_path] = palette
# Store index of the default palette
if palette.name == DEFAULT_PALETTE_NAME:
select_palette(palette.resource_path)
if not current_palette && palettes.size() > 0:
select_palette(palettes.keys()[0])
# This returns an array of arrays, with priorities.
# In particular, it takes an array of paths to look for
# arrays in, in order of file and palette override priority
# such that the files in the first directory override the
# second, third, etc. ^.^
# It returns an array of arrays, where each output array
# corresponds to the given input array at the same index, and
# contains the (relative to the given directory) palette files
# to load, excluding all ones already existing in higher-priority
# directories. nya
# in particular, this also means you can run backwards on the result
# so that palettes with the given palette name in the higher priority
# directories override those set in lower priority directories :)
func get_palette_priority_file_map(looking_paths: Array) -> Array:
var final_list := []
# Holds pattern files already found
var working_file_set : Dictionary = {}
for search_directory in looking_paths:
var to_add_files := []
var files = get_palette_files(search_directory)
# files to check
for maybe_to_add in files:
if not maybe_to_add in working_file_set:
to_add_files.append(maybe_to_add)
working_file_set[maybe_to_add] = true
final_list.append(to_add_files)
return final_list
# Get the palette files in a single directory.
# if it does not exist, return []
func get_palette_files(path : String ) -> Array:
var dir := Directory.new()
var results = []
if not dir.dir_exists(path):
return []
dir.open(path)
dir.list_dir_begin()
while true:
var file_name = dir.get_next()
if file_name == "":
break
elif (not file_name.begins_with(".")) && file_name.to_lower().ends_with("tres") && not dir.current_is_dir():
results.append(file_name)
dir.list_dir_end()
return results
# Locate the highest priority palette by the given relative filename
# If none is found in the directories, then do nothing and return null
func get_best_palette_file_location(looking_paths: Array, fname: String): # -> String:
var priority_fmap : Array = get_palette_priority_file_map(looking_paths)
for i in range(len(looking_paths)):
var base_path : String = looking_paths[i]
var the_files : Array = priority_fmap[i]
if the_files.has(fname):
return base_path.plus_file(fname)
return null
func import_palette(path: String) -> void:
if does_palette_exist(path.get_basename().get_file()):
# If there is a palette with same name ignore import for now
return
var palette : Palette = null
match path.to_lower().get_extension():
"tres":
palette = load(path)
"gpl":
var file = File.new()
if file.file_exists(path):
file.open(path, File.READ)
var text = file.get_as_text()
file.close()
palette = import_gpl(path, text)
"pal":
var file = File.new()
if file.file_exists(path):
file.open(path, File.READ)
var text = file.get_as_text()
file.close()
palette = import_pal_palette(path, text)
"png", "bmp", "hdr", "jpg", "jpeg", "svg", "tga", "webp":
var image := Image.new()
var err := image.load(path)
if !err:
palette = import_image_palette(path, image)
"json":
var file = File.new()
if file.file_exists(path):
file.open(path, File.READ)
var text = file.get_as_text()
file.close()
palette = import_json_palette(text)
if palette:
var palette_path := save_palette(palette)
palettes[palette_path] = palette
select_palette(palette_path)
Global.palette_panel.setup_palettes_selector()
Global.palette_panel.select_palette(palette_path)
func import_gpl(path: String, text: String) -> Palette:
# Refer to app/core/gimppalette-load.c of the GIMP for the "living spec"
var result : Palette = null
var lines = text.split('\n')
var line_number := 0
var comments := ""
for line in lines:
# Check if valid Gimp Palette Library file
if line_number == 0:
if not "GIMP Palette" in line:
break
else:
# Use filename as palette name in case reading old
# palette format (must read more to determine)
result = Palette.new(path.get_basename().get_file())
# Comments
if line.begins_with('#'):
comments += line.trim_prefix('#') + '\n'
# Some programs output palette name in a comment for old format
if line.begins_with("#Palette Name: "):
result.name = line.replace("#Palette Name: ", "")
pass
elif line.begins_with("Name: "):
result.name = line.replace("Name: ", "")
pass
elif line.begins_with("Columns: "):
# Number of colors in this palette. Unecessary and often wrong
pass
elif line_number > 0 && line.length() >= 9:
line = line.replace("\t", " ")
var color_data : PoolStringArray = line.split(" ", false, 4)
var red : float = color_data[0].to_float() / 255.0
var green : float = color_data[1].to_float() / 255.0
var blue : float = color_data[2].to_float() / 255.0
var color = Color(red, green, blue)
if color_data.size() >= 4:
# Ignore color name for now - result.add_color(color, color_data[3])
result.add_color(color)
#
else:
result.add_color(color)
line_number += 1
if result:
result.comment = comments
return result
func import_pal_palette(path: String, text: String) -> Palette:
var result: Palette = null
var lines = text.split('\n')
if not 'JASC-PAL' in lines[0] or not '0100' in lines[1]:
return result
else:
result = Palette.new(path.get_basename().get_file())
var num_colors = int(lines[2])
for i in range(3, num_colors + 3):
var color_data = lines[i].split(' ')
var red : float = color_data[0].to_float() / 255.0
var green : float = color_data[1].to_float() / 255.0
var blue : float = color_data[2].to_float() / 255.0
var color = Color(red, green, blue)
result.add_color(color)
return result
func import_image_palette(path: String, image: Image) -> Palette:
var result: Palette = Palette.new(path.get_basename().get_file())
var height: int = image.get_height()
var width: int = image.get_width()
# Iterate all pixels and store unique colors to palete
image.lock()
for y in range(0, height):
for x in range(0, width):
var color: Color = image.get_pixel(x, y)
if not result.has_color(color):
result.add_color(color)
image.unlock()
return result
# Import of deprecated older json palette format
func import_json_palette(text: String):
var result: Palette = Palette.new()
var result_json = JSON.parse(text)
if result_json.error != OK: # If parse has errors
printerr("JSON palette import error")
printerr("Error: ", result_json.error)
printerr("Error Line: ", result_json.error_line)
printerr("Error String: ", result_json.error_string)
result = null
else: # If parse OK
var data = result_json.result
if data.has("name"): # If data is 'valid' palette file
result.name = data.name
if data.has("comments"):
result.comment = data.comments
if data.has("colors"):
for color_data in data.colors:
var color: Color = Color(color_data.data)
result.add_color(color)
return result

View file

@ -58,12 +58,16 @@ __meta__ = {
margin_right = 375.0
[node name="OpenSprite" parent="Dialogs" instance=ExtResource( 12 )]
current_dir = "/run/media/novhack/Orange/Pixelorama"
current_path = "/run/media/novhack/Orange/Pixelorama/"
[node name="SaveSprite" parent="Dialogs" instance=ExtResource( 11 )]
margin_left = 108.0
margin_top = 40.0
margin_right = 623.0
margin_bottom = 388.0
current_dir = "/run/media/novhack/Orange/Pixelorama"
current_path = "/run/media/novhack/Orange/Pixelorama/untitled"
[node name="SaveSpriteHTML5" parent="Dialogs" instance=ExtResource( 8 )]

View file

@ -0,0 +1,111 @@
extends ConfirmationDialog
# Emitted when user confirms his changes
signal saved(preset, name, comment, width, height, add_alpha_colors, colors_from)
# Reference to current palette stored when dialog opens
var current_palette: Palette
onready var preset_input := $VBoxContainer/PaletteMetadata/Preset
onready var name_input := $VBoxContainer/PaletteMetadata/Name
onready var comment_input := $VBoxContainer/PaletteMetadata/Comment
onready var width_input := $VBoxContainer/PaletteMetadata/Width
onready var height_input := $VBoxContainer/PaletteMetadata/Height
onready var alpha_colors_input := $VBoxContainer/ColorsSettings/AddAlphaColors
onready var get_colors_from_input := $VBoxContainer/ColorsSettings/GetColorsFrom/GetColorsFrom
onready var colors_settings := $VBoxContainer/ColorsSettings
onready var already_exists_warning := $VBoxContainer/AlreadyExistsWarning
onready var enter_name_warning := $VBoxContainer/EnterNameWarning
# Opens dialog
func open(opened_current_palette: Palette) -> void:
# Only to fill dialog when preset is FromCurrentPalette
current_palette = opened_current_palette
set_default_values()
preset_input.selected = Palettes.NewPalettePresetType.Empty
# Colors settings are only available for FromCurrentSprite and FromCurrentSelection presets
colors_settings.hide()
# Hide warning
toggle_already_exists_warning(false)
# Disable ok button until user enters name
toggle_ok_button_disability(true)
# Stop all inputs in the rest of the app
Global.dialog_open(true)
popup_centered()
# Resets all dialog values to default
func set_default_values() -> void:
name_input.text = ""
comment_input.text = ""
width_input.value = Palette.DEFAULT_WIDTH
height_input.value = Palette.DEFAULT_HEIGHT
alpha_colors_input.pressed = true
get_colors_from_input.selected = Palettes.GetColorsFrom.CurrentFrame
# Shows/hides a warning when palette already exists
func toggle_already_exists_warning(visible: bool) -> void:
already_exists_warning.visible = visible
# Required to resize window to correct size if warning causes content overflow
rect_size = rect_size
func toggle_ok_button_disability(disable: bool) -> void:
get_ok().disabled = disable
enter_name_warning.visible = disable
func _on_CreatePaletteDialog_popup_hide() -> void:
Global.dialog_open(false)
func _on_CreatePaletteDialog_confirmed() -> void:
emit_signal("saved", preset_input.selected, name_input.text, comment_input.text, width_input.value, height_input.value, alpha_colors_input.pressed, get_colors_from_input.selected)
func _on_Preset_item_selected(index: int) -> void:
# Enable width and height inputs (can be disabled by current palette preset)
width_input.editable = true
height_input.editable = true
toggle_already_exists_warning(false)
toggle_ok_button_disability(true)
match index:
Palettes.NewPalettePresetType.Empty:
colors_settings.hide()
set_default_values()
Palettes.NewPalettePresetType.FromCurrentPalette:
colors_settings.hide()
# If any palette was selected copy it's settings to dialog
if current_palette:
name_input.text = current_palette.name
comment_input.text = current_palette.comment
width_input.value = current_palette.width
height_input.value = current_palette.height
toggle_already_exists_warning(true)
# Copying palette presets grid size
width_input.editable = false
height_input.editable = false
Palettes.NewPalettePresetType.FromCurrentSprite, Palettes.NewPalettePresetType.FromCurrentSelection:
colors_settings.show()
set_default_values()
func _on_Name_text_changed(new_name):
var disable_warning := false
if Palettes.does_palette_exist(new_name):
disable_warning = true
toggle_already_exists_warning(disable_warning)
toggle_ok_button_disability(disable_warning)
# Disable ok button on empty name
if new_name == "":
toggle_ok_button_disability(true)

View file

@ -0,0 +1,183 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://src/Palette/CreatePaletteDialog.gd" type="Script" id=1]
[node name="CreatePaletteDialog" type="ConfirmationDialog"]
margin_top = 1.0
margin_right = 300.0
margin_bottom = 438.0
window_title = "Create New Palette"
resizable = true
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="VBoxContainer" type="VBoxContainer" parent="."]
anchor_left = 0.000793701
anchor_right = 0.000793701
margin_left = 7.76189
margin_top = 8.0
margin_right = 291.762
margin_bottom = 401.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="PaletteMetadata" type="GridContainer" parent="VBoxContainer"]
margin_right = 284.0
margin_bottom = 162.0
columns = 2
__meta__ = {
"_edit_use_anchors_": false
}
[node name="PresetLabel" type="Label" parent="VBoxContainer/PaletteMetadata"]
margin_right = 67.0
margin_bottom = 24.0
rect_min_size = Vector2( 0, 24 )
text = "Preset:"
valign = 1
[node name="Preset" type="OptionButton" parent="VBoxContainer/PaletteMetadata"]
margin_left = 71.0
margin_right = 284.0
margin_bottom = 24.0
rect_min_size = Vector2( 0, 24 )
size_flags_horizontal = 3
text = "Empty"
items = [ "Empty", null, false, 0, null, "From Current Palette", null, false, 1, null, "From Current Sprite", null, false, 2, null, "From Current Selection", null, false, 3, null ]
selected = 0
[node name="NameLabel" type="Label" parent="VBoxContainer/PaletteMetadata"]
margin_top = 33.0
margin_right = 67.0
margin_bottom = 47.0
rect_min_size = Vector2( 50, 0 )
text = "Name:"
[node name="Name" type="LineEdit" parent="VBoxContainer/PaletteMetadata"]
margin_left = 71.0
margin_top = 28.0
margin_right = 284.0
margin_bottom = 52.0
rect_min_size = Vector2( 0, 24 )
size_flags_horizontal = 3
[node name="CommentLabel" type="Label" parent="VBoxContainer/PaletteMetadata"]
margin_top = 74.0
margin_right = 67.0
margin_bottom = 88.0
rect_min_size = Vector2( 50, 0 )
text = "Comment:"
[node name="Comment" type="TextEdit" parent="VBoxContainer/PaletteMetadata"]
margin_left = 71.0
margin_top = 56.0
margin_right = 284.0
margin_bottom = 106.0
rect_min_size = Vector2( 0, 50 )
size_flags_horizontal = 3
[node name="WidthLabel" type="Label" parent="VBoxContainer/PaletteMetadata"]
margin_top = 115.0
margin_right = 67.0
margin_bottom = 129.0
text = "Width:"
[node name="Width" type="SpinBox" parent="VBoxContainer/PaletteMetadata"]
margin_left = 71.0
margin_top = 110.0
margin_right = 284.0
margin_bottom = 134.0
rect_min_size = Vector2( 0, 24 )
size_flags_horizontal = 3
min_value = 1.0
max_value = 64.0
value = 1.0
align = 2
[node name="HeightLabel" type="Label" parent="VBoxContainer/PaletteMetadata"]
margin_top = 143.0
margin_right = 67.0
margin_bottom = 157.0
text = "Height:"
[node name="Height" type="SpinBox" parent="VBoxContainer/PaletteMetadata"]
margin_left = 71.0
margin_top = 138.0
margin_right = 284.0
margin_bottom = 162.0
rect_min_size = Vector2( 0, 24 )
size_flags_horizontal = 3
min_value = 1.0
max_value = 64.0
value = 1.0
align = 2
[node name="ColorsSettings" type="VBoxContainer" parent="VBoxContainer"]
margin_top = 166.0
margin_right = 284.0
margin_bottom = 226.0
[node name="HSeparator" type="HSeparator" parent="VBoxContainer/ColorsSettings"]
margin_right = 284.0
margin_bottom = 4.0
[node name="AddAlphaColors" type="CheckBox" parent="VBoxContainer/ColorsSettings"]
margin_top = 8.0
margin_right = 284.0
margin_bottom = 32.0
rect_min_size = Vector2( 0, 24 )
text = "Create colors with alpha component"
[node name="GetColorsFrom" type="HBoxContainer" parent="VBoxContainer/ColorsSettings"]
margin_top = 36.0
margin_right = 284.0
margin_bottom = 60.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="GetColorsFromLabel" type="Label" parent="VBoxContainer/ColorsSettings/GetColorsFrom"]
margin_top = 5.0
margin_right = 104.0
margin_bottom = 19.0
text = "Get colors from:"
[node name="GetColorsFrom" type="OptionButton" parent="VBoxContainer/ColorsSettings/GetColorsFrom"]
margin_left = 108.0
margin_right = 284.0
margin_bottom = 24.0
rect_min_size = Vector2( 0, 24 )
mouse_default_cursor_shape = 2
size_flags_horizontal = 3
text = "Current frame"
items = [ "Current frame", null, false, 0, null, "Current cel", null, false, 1, null, "All frames", null, false, 2, null ]
selected = 0
[node name="AlreadyExistsWarning" type="Label" parent="VBoxContainer"]
margin_top = 230.0
margin_right = 284.0
margin_bottom = 309.0
size_flags_vertical = 7
custom_colors/font_color = Color( 1, 0.603922, 0.603922, 1 )
text = "Palette with the same name and path already exists!"
align = 1
valign = 2
autowrap = true
[node name="EnterNameWarning" type="Label" parent="VBoxContainer"]
margin_top = 313.0
margin_right = 284.0
margin_bottom = 393.0
size_flags_vertical = 7
custom_colors/font_color = Color( 1, 0.603922, 0.603922, 1 )
text = "Palette name is required!"
align = 1
valign = 2
autowrap = true
[connection signal="confirmed" from="." to="." method="_on_CreatePaletteDialog_confirmed"]
[connection signal="popup_hide" from="." to="." method="_on_CreatePaletteDialog_popup_hide"]
[connection signal="item_selected" from="VBoxContainer/PaletteMetadata/Preset" to="." method="_on_Preset_item_selected"]
[connection signal="text_changed" from="VBoxContainer/PaletteMetadata/Name" to="." method="_on_Name_text_changed"]

View file

@ -0,0 +1,99 @@
extends ConfirmationDialog
# Emitted when user confirms his changes
signal saved(name, comment, width, height)
signal deleted()
const DELETE_ACTION := "delete"
# Keeps original size of edited palette
var origin_width := 0
var origin_height := 0
var old_name := ""
onready var name_input := $VBoxContainer/PaletteMetadata/Name
onready var comment_input := $VBoxContainer/PaletteMetadata/Comment
onready var width_input := $VBoxContainer/PaletteMetadata/Width
onready var height_input := $VBoxContainer/PaletteMetadata/Height
onready var path_input := $VBoxContainer/PaletteMetadata/Path
onready var size_reduced_warning := $VBoxContainer/SizeReducedWarning
onready var already_exists_warning := $VBoxContainer/AlreadyExistsWarning
func _ready() -> void:
# Add delete button to edit palette dialog
add_button(tr("Delete"), false, DELETE_ACTION)
func open(current_palette: Palette) -> void:
if current_palette:
name_input.text = current_palette.name
comment_input.text = current_palette.comment
width_input.value = current_palette.width
height_input.value = current_palette.height
path_input.text = current_palette.resource_path
# Store original size so it can be compared with changed values
# and warning can be shown if it is reduced
origin_width = current_palette.width
origin_height = current_palette.height
toggle_size_reduced_warning(false)
# Hide warning
old_name = current_palette.name
toggle_already_exists_warning(false)
# Stop all inputs in the rest of the app
Global.dialog_open(true)
popup_centered()
# Shows/hides a warning when palette size is being reduced
func toggle_size_reduced_warning(visible: bool) -> void:
size_reduced_warning.visible = visible
# Required to resize window to correct size if warning causes content overflow
rect_size = rect_size
# Shows/hides a warning when palette already exists
func toggle_already_exists_warning(visible: bool) -> void:
already_exists_warning.visible = visible
# Disable confirm button so user cannot save
get_ok().disabled = visible
# Required to resize window to correct size if warning causes content overflow
rect_size = rect_size
func _on_EditPaletteDialog_popup_hide() -> void:
Global.dialog_open(false)
func _on_EditPaletteDialog_confirmed() -> void:
emit_signal("saved", name_input.text, comment_input.text, width_input.value, height_input.value)
func _on_EditPaletteDialog_custom_action(action: String) -> void:
if action == DELETE_ACTION:
hide()
emit_signal("deleted")
func _on_size_value_changed(_value):
# Toggle resize warning label if palette size was reduced
var size_decreased: bool = height_input.value < origin_height or width_input.value < origin_width
toggle_size_reduced_warning(size_decreased)
func _on_Name_text_changed(new_name):
if old_name != new_name:
if Palettes.does_palette_exist(new_name):
toggle_already_exists_warning(true)
else:
toggle_already_exists_warning(false)
# Disable ok button on empty name
if new_name == "":
get_ok().disabled = true

View file

@ -0,0 +1,145 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://src/Palette/EditPaletteDialog.gd" type="Script" id=1]
[node name="EditPaletteDialog" type="ConfirmationDialog"]
margin_right = 409.0
margin_bottom = 535.0
window_title = "Edit Palette"
resizable = true
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="VBoxContainer" type="VBoxContainer" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 8.0
margin_top = 8.0
margin_right = -8.0
margin_bottom = -36.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="PaletteMetadata" type="GridContainer" parent="VBoxContainer"]
margin_right = 393.0
margin_bottom = 188.0
columns = 2
__meta__ = {
"_edit_use_anchors_": false
}
[node name="NameLabel" type="Label" parent="VBoxContainer/PaletteMetadata"]
margin_top = 5.0
margin_right = 67.0
margin_bottom = 19.0
rect_min_size = Vector2( 50, 0 )
text = "Name:"
[node name="Name" type="LineEdit" parent="VBoxContainer/PaletteMetadata"]
margin_left = 71.0
margin_right = 393.0
margin_bottom = 24.0
rect_min_size = Vector2( 0, 24 )
size_flags_horizontal = 3
[node name="CommentLabel" type="Label" parent="VBoxContainer/PaletteMetadata"]
margin_top = 46.0
margin_right = 67.0
margin_bottom = 60.0
rect_min_size = Vector2( 50, 0 )
text = "Comment:"
[node name="Comment" type="TextEdit" parent="VBoxContainer/PaletteMetadata"]
margin_left = 71.0
margin_top = 28.0
margin_right = 393.0
margin_bottom = 78.0
rect_min_size = Vector2( 0, 50 )
size_flags_horizontal = 3
[node name="WidthLabel" type="Label" parent="VBoxContainer/PaletteMetadata"]
margin_top = 87.0
margin_right = 67.0
margin_bottom = 101.0
text = "Width:"
[node name="Width" type="SpinBox" parent="VBoxContainer/PaletteMetadata"]
margin_left = 71.0
margin_top = 82.0
margin_right = 393.0
margin_bottom = 106.0
rect_min_size = Vector2( 0, 24 )
size_flags_horizontal = 3
min_value = 1.0
max_value = 64.0
value = 1.0
align = 2
[node name="HeightLabel" type="Label" parent="VBoxContainer/PaletteMetadata"]
margin_top = 115.0
margin_right = 67.0
margin_bottom = 129.0
text = "Height:"
[node name="Height" type="SpinBox" parent="VBoxContainer/PaletteMetadata"]
margin_left = 71.0
margin_top = 110.0
margin_right = 393.0
margin_bottom = 134.0
rect_min_size = Vector2( 0, 24 )
size_flags_horizontal = 3
min_value = 1.0
max_value = 64.0
value = 1.0
align = 2
[node name="PathLabel" type="Label" parent="VBoxContainer/PaletteMetadata"]
margin_top = 156.0
margin_right = 67.0
margin_bottom = 170.0
text = "Path:"
[node name="Path" type="TextEdit" parent="VBoxContainer/PaletteMetadata"]
margin_left = 71.0
margin_top = 138.0
margin_right = 393.0
margin_bottom = 188.0
rect_min_size = Vector2( 0, 50 )
size_flags_horizontal = 3
readonly = true
wrap_enabled = true
[node name="SizeReducedWarning" type="Label" parent="VBoxContainer"]
margin_top = 192.0
margin_right = 393.0
margin_bottom = 223.0
custom_colors/font_color = Color( 1, 0.603922, 0.603922, 1 )
text = "Reducing palette size will reset positions of colors. Colors that don't fit in new palette size will be lost!"
align = 1
valign = 2
autowrap = true
__meta__ = {
"_edit_use_anchors_": false
}
[node name="AlreadyExistsWarning" type="Label" parent="VBoxContainer"]
margin_top = 227.0
margin_right = 393.0
margin_bottom = 241.0
custom_colors/font_color = Color( 1, 0.603922, 0.603922, 1 )
text = "Palette with the same name and path already exists!"
align = 1
valign = 1
autowrap = true
__meta__ = {
"_edit_use_anchors_": false
}
[connection signal="confirmed" from="." to="." method="_on_EditPaletteDialog_confirmed"]
[connection signal="custom_action" from="." to="." method="_on_EditPaletteDialog_custom_action"]
[connection signal="popup_hide" from="." to="." method="_on_EditPaletteDialog_popup_hide"]
[connection signal="text_changed" from="VBoxContainer/PaletteMetadata/Name" to="." method="_on_Name_text_changed"]
[connection signal="value_changed" from="VBoxContainer/PaletteMetadata/Width" to="." method="_on_size_value_changed"]
[connection signal="value_changed" from="VBoxContainer/PaletteMetadata/Height" to="." method="_on_size_value_changed"]

View file

@ -1,193 +0,0 @@
extends WindowDialog
var palette_button = preload("res://src/Palette/PaletteButton.tscn")
var current_palette : String
var current_swatch := -1
var working_palette : Palette
onready var color_picker = $VBoxContainer/HBoxContainer/EditPaletteColorPicker
onready var palette_grid = $VBoxContainer/HBoxContainer/VBoxContainer/Panel/ScrollContainer/EditPaletteGridContainer
onready var color_name_edit = $VBoxContainer/PaletteOptions/EditPaletteColorNameLineEdit
onready var palette_name_edit = $VBoxContainer/PaletteOptions/EditPaletteNameLineEdit
onready var left_color_button = $VBoxContainer/HBoxContainer/VBoxContainer/CenterContainer/HBoxContainer/LeftColor/NinePatchRect
onready var right_color_button = $VBoxContainer/HBoxContainer/VBoxContainer/CenterContainer/HBoxContainer/RightColor/NinePatchRect
onready var dummyBtn = $DummyBtn
func _ready() -> void:
$VBoxContainer/HBoxContainer/EditPaletteColorPicker.presets_visible = false
func open(palette : String) -> void:
current_palette = palette
palette_name_edit.text = current_palette
if Global.palettes.has(palette):
working_palette = Global.palettes[palette].duplicate()
_display_palette()
self.popup_centered()
Global.dialog_open(true)
left_color_button.modulate = Tools.get_assigned_color(BUTTON_LEFT)
right_color_button.modulate = Tools.get_assigned_color(BUTTON_RIGHT)
func _display_palette() -> void:
_clear_swatches()
var index := 0
for color_data in working_palette.colors:
var color = color_data.color
var new_button = palette_button.instance()
new_button.color = color
new_button.get_child(0).modulate = color
new_button.hint_tooltip = color_data.data.to_upper() + " " + color_data.name
new_button.draggable = true
new_button.index = index
new_button.connect("on_drop_data", self, "on_move_swatch")
new_button.connect("pressed", self, "on_swatch_select", [new_button])
new_button.group = dummyBtn.group
palette_grid.add_child(new_button)
index += 1
if index > 0: # If there are colors, select the first
on_swatch_select(palette_grid.get_child(0))
func _clear_swatches() -> void:
for child in palette_grid.get_children():
if child is BaseButton and child.text != "Dummy":
child.disconnect("on_drop_data", self, "on_move_swatch")
child.queue_free()
func on_swatch_select(new_button) -> void:
current_swatch = new_button.index
color_name_edit.text = working_palette.get_color_name(current_swatch)
color_picker.color = working_palette.get_color(current_swatch)
func on_move_swatch(from : int, to : int) -> void:
working_palette.move_color(from, to)
palette_grid.move_child(palette_grid.get_child(from), to)
current_swatch = to
re_index_swatches()
func _on_AddSwatchButton_pressed() -> void:
var color : Color = color_picker.color
var new_index : int = working_palette.colors.size()
working_palette.add_color(color)
var new_button = palette_button.instance()
new_button.color = color
new_button.get_child(0).modulate = color
new_button.hint_tooltip = "#" + working_palette.get_color_data(new_index).to_upper() + " " + working_palette.get_color_name(new_index)
new_button.draggable = true
var index : int = palette_grid.get_child_count()
new_button.index = index
new_button.connect("on_drop_data", self, "on_move_swatch")
new_button.connect("pressed", self, "on_swatch_select", [new_button])
new_button.group = dummyBtn.group
palette_grid.add_child(new_button)
on_swatch_select(new_button)
func _on_RemoveSwatchButton_pressed() -> void:
if working_palette.colors.size() > 0:
working_palette.remove_color(current_swatch)
palette_grid.remove_child(palette_grid.get_child(current_swatch))
re_index_swatches()
if current_swatch == working_palette.colors.size():
current_swatch -= 1
if current_swatch >= 0:
on_swatch_select(palette_grid.get_child(current_swatch))
func re_index_swatches() -> void:
# Re-index swatches with new order
var index := 0
for child in palette_grid.get_children():
child.index = index
index += 1
# Rename a palette, copying to user directory if necessary.
func rename_palette_file_with_priority_dirs(old_fname: String, new_fname: String) -> void:
var user_write_directory: String = Global.directory_module.get_palette_write_path()
var usrwrite_dir := Directory.new()
usrwrite_dir.open(user_write_directory)
if usrwrite_dir.file_exists(old_fname):
usrwrite_dir.rename(old_fname, new_fname)
else:
# Scan through the main system directories
var priority_dirs : Array = Global.directory_module.get_palette_search_path_in_order()
var best_clone_location = Global.palette_container.get_best_palette_file_location(
priority_dirs,
old_fname
)
if best_clone_location != null:
usrwrite_dir.copy(best_clone_location, new_fname)
func _on_EditPaletteSaveButton_pressed() -> void:
if palette_name_edit.text != current_palette:
Global.palettes.erase(current_palette)
rename_palette_file_with_priority_dirs(
current_palette + ".json",
palette_name_edit.text + ".json"
)
current_palette = palette_name_edit.text
working_palette.name = current_palette
var optionbutton_index = Global.palette_option_button.selected
Global.palette_option_button.set_item_text(optionbutton_index, current_palette)
Global.palette_option_button.set_item_metadata(optionbutton_index, current_palette)
Global.palette_option_button.text = current_palette
Global.palettes[current_palette] = working_palette
Global.palette_container.on_palette_select(current_palette)
Global.palette_container.save_palette(current_palette, working_palette.name + ".json")
self.hide()
func _on_EditPaletteCancelButton_pressed() -> void:
self.hide()
func _on_EditPaletteColorNameLineEdit_text_changed(new_text : String) -> void:
if current_swatch >= 0 && current_swatch < working_palette.colors.size():
working_palette.set_color_name(current_swatch, new_text)
_refresh_hint_tooltip(current_swatch)
func _on_EditPaletteColorPicker_color_changed(color : Color) -> void:
if current_swatch >= 0 && current_swatch < working_palette.colors.size():
palette_grid.get_child(current_swatch).get_child(0).modulate = color
working_palette.set_color(current_swatch, color)
_refresh_hint_tooltip(current_swatch)
func _refresh_hint_tooltip(_index : int) -> void:
palette_grid.get_child(current_swatch).hint_tooltip = "#" + working_palette.get_color_data(current_swatch).to_upper() + " " + working_palette.get_color_name(current_swatch)
func _on_LeftColor_pressed() -> void:
color_picker.color = Tools.get_assigned_color(BUTTON_LEFT)
_on_EditPaletteColorPicker_color_changed(color_picker.color)
func _on_RightColor_pressed() -> void:
color_picker.color = Tools.get_assigned_color(BUTTON_RIGHT)
_on_EditPaletteColorPicker_color_changed(color_picker.color)
func _on_EditPalettePopup_popup_hide() -> void:
Global.dialog_open(false)

View file

@ -1,250 +0,0 @@
[gd_scene load_steps=6 format=2]
[ext_resource path="res://src/Palette/EditPalettePopup.gd" type="Script" id=1]
[ext_resource path="res://assets/graphics/dark_themes/timeline/new_frame.png" type="Texture" id=2]
[ext_resource path="res://assets/graphics/dark_themes/timeline/remove_frame.png" type="Texture" id=3]
[ext_resource path="res://assets/graphics/palette/palette_button_fill.png" type="Texture" id=6]
[sub_resource type="ButtonGroup" id=1]
[node name="EditPalettePopup" type="WindowDialog"]
margin_right = 600.0
margin_bottom = 550.0
rect_min_size = Vector2( 600, 570 )
window_title = "Edit Palette"
script = ExtResource( 1 )
[node name="VBoxContainer" type="VBoxContainer" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 10.0
margin_top = 10.0
margin_right = -10.0
margin_bottom = -10.0
size_flags_horizontal = 3
custom_constants/separation = 8
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"]
margin_right = 580.0
margin_bottom = 462.0
size_flags_vertical = 3
[node name="EditPaletteColorPicker" type="ColorPicker" parent="VBoxContainer/HBoxContainer"]
margin_right = 308.0
margin_bottom = 462.0
[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/HBoxContainer"]
margin_left = 312.0
margin_right = 556.0
margin_bottom = 462.0
size_flags_horizontal = 3
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Panel" type="Panel" parent="VBoxContainer/HBoxContainer/VBoxContainer"]
margin_right = 244.0
margin_bottom = 408.0
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="ScrollContainer" type="ScrollContainer" parent="VBoxContainer/HBoxContainer/VBoxContainer/Panel"]
margin_right = 244.0
margin_bottom = 438.0
size_flags_horizontal = 3
size_flags_vertical = 3
__meta__ = {
"_edit_use_anchors_": false
}
[node name="EditPaletteGridContainer" type="GridContainer" parent="VBoxContainer/HBoxContainer/VBoxContainer/Panel/ScrollContainer"]
margin_right = 244.0
margin_bottom = 438.0
size_flags_horizontal = 3
size_flags_vertical = 3
columns = 8
[node name="Label" type="Label" parent="VBoxContainer/HBoxContainer/VBoxContainer"]
margin_top = 412.0
margin_right = 244.0
margin_bottom = 426.0
text = "Use current left & right colors"
align = 1
autowrap = true
[node name="CenterContainer" type="CenterContainer" parent="VBoxContainer/HBoxContainer/VBoxContainer"]
margin_top = 430.0
margin_right = 244.0
margin_bottom = 462.0
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/HBoxContainer/VBoxContainer/CenterContainer"]
margin_left = 56.0
margin_right = 188.0
margin_bottom = 32.0
[node name="LeftColor" type="Button" parent="VBoxContainer/HBoxContainer/VBoxContainer/CenterContainer/HBoxContainer"]
margin_right = 64.0
margin_bottom = 32.0
rect_min_size = Vector2( 64, 32 )
mouse_default_cursor_shape = 2
[node name="NinePatchRect" type="NinePatchRect" parent="VBoxContainer/HBoxContainer/VBoxContainer/CenterContainer/HBoxContainer/LeftColor"]
modulate = Color( 0, 0, 0, 1 )
margin_left = 2.0
margin_top = 3.0
margin_right = 62.0
margin_bottom = 29.0
texture = ExtResource( 6 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="RightColor" type="Button" parent="VBoxContainer/HBoxContainer/VBoxContainer/CenterContainer/HBoxContainer"]
margin_left = 68.0
margin_right = 132.0
margin_bottom = 32.0
rect_min_size = Vector2( 64, 32 )
mouse_default_cursor_shape = 2
[node name="NinePatchRect" type="NinePatchRect" parent="VBoxContainer/HBoxContainer/VBoxContainer/CenterContainer/HBoxContainer/RightColor"]
margin_left = 2.0
margin_top = 3.0
margin_right = 62.0
margin_bottom = 29.0
texture = ExtResource( 6 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="ColorButtons" type="VBoxContainer" parent="VBoxContainer/HBoxContainer"]
margin_left = 560.0
margin_right = 580.0
margin_bottom = 462.0
[node name="AddSwatchButton" type="Button" parent="VBoxContainer/HBoxContainer/ColorButtons" groups=[
"UIButtons",
]]
margin_right = 20.0
margin_bottom = 20.0
mouse_default_cursor_shape = 2
[node name="TextureRect" type="TextureRect" parent="VBoxContainer/HBoxContainer/ColorButtons/AddSwatchButton"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -6.0
margin_top = -6.0
margin_right = 6.0
margin_bottom = 6.0
texture = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="RemoveSwatchButton" type="Button" parent="VBoxContainer/HBoxContainer/ColorButtons" groups=[
"UIButtons",
]]
margin_top = 24.0
margin_right = 20.0
margin_bottom = 44.0
rect_min_size = Vector2( 20, 0 )
mouse_default_cursor_shape = 2
[node name="TextureRect" type="TextureRect" parent="VBoxContainer/HBoxContainer/ColorButtons/RemoveSwatchButton"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -6.0
margin_top = -1.0
margin_right = 6.0
margin_bottom = 1.0
texture = ExtResource( 3 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="PaletteOptions" type="GridContainer" parent="VBoxContainer"]
margin_top = 470.0
margin_right = 580.0
margin_bottom = 522.0
columns = 2
[node name="Label" type="Label" parent="VBoxContainer/PaletteOptions"]
margin_top = 5.0
margin_right = 91.0
margin_bottom = 19.0
text = "Color Name:"
[node name="EditPaletteColorNameLineEdit" type="LineEdit" parent="VBoxContainer/PaletteOptions"]
margin_left = 95.0
margin_right = 580.0
margin_bottom = 24.0
size_flags_horizontal = 3
[node name="Label2" type="Label" parent="VBoxContainer/PaletteOptions"]
margin_top = 33.0
margin_right = 91.0
margin_bottom = 47.0
text = "Palette Name:"
[node name="EditPaletteNameLineEdit" type="LineEdit" parent="VBoxContainer/PaletteOptions"]
margin_left = 95.0
margin_top = 28.0
margin_right = 580.0
margin_bottom = 52.0
size_flags_horizontal = 3
[node name="WindowOptionsContainer" type="HBoxContainer" parent="VBoxContainer"]
margin_top = 530.0
margin_right = 580.0
margin_bottom = 550.0
size_flags_horizontal = 3
[node name="SpacerControl" type="Control" parent="VBoxContainer/WindowOptionsContainer"]
margin_right = 156.0
margin_bottom = 20.0
size_flags_horizontal = 3
[node name="EditPaletteSaveButton" type="Button" parent="VBoxContainer/WindowOptionsContainer"]
margin_left = 160.0
margin_right = 201.0
margin_bottom = 20.0
text = "Save"
[node name="SpacerControl2" type="Control" parent="VBoxContainer/WindowOptionsContainer"]
margin_left = 205.0
margin_right = 361.0
margin_bottom = 20.0
size_flags_horizontal = 3
[node name="EditPaletteCancelButton" type="Button" parent="VBoxContainer/WindowOptionsContainer"]
margin_left = 365.0
margin_right = 419.0
margin_bottom = 20.0
text = "Cancel"
[node name="SpacerControl3" type="Control" parent="VBoxContainer/WindowOptionsContainer"]
margin_left = 423.0
margin_right = 580.0
margin_bottom = 20.0
size_flags_horizontal = 3
[node name="DummyBtn" type="Button" parent="."]
visible = false
margin_left = 322.0
margin_top = 10.0
margin_right = 385.0
margin_bottom = 30.0
group = SubResource( 1 )
text = "Dummy"
[connection signal="popup_hide" from="." to="." method="_on_EditPalettePopup_popup_hide"]
[connection signal="color_changed" from="VBoxContainer/HBoxContainer/EditPaletteColorPicker" to="." method="_on_EditPaletteColorPicker_color_changed"]
[connection signal="pressed" from="VBoxContainer/HBoxContainer/VBoxContainer/CenterContainer/HBoxContainer/LeftColor" to="." method="_on_LeftColor_pressed"]
[connection signal="pressed" from="VBoxContainer/HBoxContainer/VBoxContainer/CenterContainer/HBoxContainer/RightColor" to="." method="_on_RightColor_pressed"]
[connection signal="pressed" from="VBoxContainer/HBoxContainer/ColorButtons/AddSwatchButton" to="." method="_on_AddSwatchButton_pressed"]
[connection signal="pressed" from="VBoxContainer/HBoxContainer/ColorButtons/RemoveSwatchButton" to="." method="_on_RemoveSwatchButton_pressed"]
[connection signal="text_changed" from="VBoxContainer/PaletteOptions/EditPaletteColorNameLineEdit" to="." method="_on_EditPaletteColorNameLineEdit_text_changed"]
[connection signal="pressed" from="VBoxContainer/WindowOptionsContainer/EditPaletteSaveButton" to="." method="_on_EditPaletteSaveButton_pressed"]
[connection signal="pressed" from="VBoxContainer/WindowOptionsContainer/EditPaletteCancelButton" to="." method="_on_EditPaletteCancelButton_pressed"]

View file

@ -1,25 +0,0 @@
[gd_scene format=2]
[node name="NewPaletteDialog" type="ConfirmationDialog"]
margin_right = 200.0
margin_bottom = 70.0
window_title = "Create a new custom palette from existing default?"
[node name="HBoxContainer2" type="HBoxContainer" parent="."]
margin_left = 8.0
margin_top = 8.0
margin_right = 365.0
margin_bottom = 34.0
[node name="Label" type="Label" parent="HBoxContainer2"]
margin_top = 6.0
margin_right = 91.0
margin_bottom = 20.0
text = "Palette Name:"
[node name="NewPaletteNameLineEdit" type="LineEdit" parent="HBoxContainer2"]
margin_left = 95.0
margin_right = 357.0
margin_bottom = 26.0
size_flags_horizontal = 3
expand_to_text_length = true

View file

@ -1,171 +1,200 @@
class_name Palette
extends Reference
extends Resource
const DEFAULT_WIDTH = 8
const DEFAULT_HEIGHT = 8
# Metadata
export var name: String = "Custom Palette"
export var comment: String = ""
# Grid size
export var width := DEFAULT_WIDTH
export var height := DEFAULT_HEIGHT
# Sparse colors dictionary - actual color position in the palette is determined by it's index
export var colors: Dictionary = {}
# How many colors fit in palette grid
export var colors_max := 0
var name : String = "Custom_Palette"
# Its purpose is to store pallete source path to enable removing it in the future.
var source_path : String
var colors : Array = []
var comments : String = ""
var editable : bool = true
func _init(init_name: String = "Custom Palette", init_width: int = DEFAULT_WIDTH, init_height: int = DEFAULT_HEIGHT, init_comment: String = "") -> void:
name = init_name
comment = init_comment
width = init_width
height = init_height
colors_max = init_width * init_height
colors = {}
func get_class() -> String:
return "Palette"
func edit(new_name: String, new_width: int, new_height: int, new_comment: String) -> void:
var old_width = width
width = new_width
height = new_height
name = new_name
comment = new_comment
func is_class(_name : String) -> bool:
return _name == "Palette" or .is_class(_name)
var old_colors_max = colors_max
colors_max = width * height
if colors_max < old_colors_max:
# If size was reduced colors must be reindexed to fit into new smaller size
reindex_colors_on_size_reduce(true)
if old_width < new_width:
# If width increases colors have to be reindexed so they keep same grid positions
reindex_colors_on_width_increase(old_width)
func insert_color(index : int, new_color : Color, _name : String = "no name") -> void:
if index <= colors.size():
var c := PaletteColor.new(new_color, _name)
colors.insert(index, c)
# Iterates all colors from lowest index and reindexes them so they start at zero index
# Remove trailing removes all colors that are over colors_max limit and thus don't fit into grid
func reindex_colors_on_size_reduce(remove_trailing: bool) -> void:
var sorted_colors_indexes = colors.keys()
sorted_colors_indexes.sort()
var new_index = 0
for old_index in sorted_colors_indexes:
# Color cannot fit into grid anymore - erase it
if remove_trailing and new_index >= colors_max:
colors.erase(old_index)
# Move color to new lower index - erase it from it's original index
elif new_index < old_index:
colors[new_index] = colors[old_index]
colors[new_index].index = new_index
colors.erase(old_index)
new_index += 1
func add_color(new_color : Color, _name : String = "no name") -> void:
var c := PaletteColor.new(new_color, _name)
colors.push_back(c)
# Adds difference of old and new width to color indexes
# so they remain on the same position as before resize
func reindex_colors_on_width_increase(old_width: int) -> void:
var sorted_colors_indexes = colors.keys()
sorted_colors_indexes.sort()
var new_colors = {}
for old_index in sorted_colors_indexes:
var new_index: int = old_index + (width - old_width) * (old_index / old_width)
new_colors[new_index ] = colors[old_index]
colors = new_colors
func remove_color(index : int) -> void:
if index < colors.size():
colors.remove(index)
# Adds new color to the first empty swatch
func add_color(new_color: Color, start_index: int = 0) -> void:
if start_index >= colors_max:
return
# If palette is full automatically increase the palette height
if is_full():
height += 1
# Find the first empty index since start index and insert a new color
for i in range(start_index, colors_max):
if not colors.has(i):
colors[i] = PaletteColor.new(new_color, i)
break
func move_color(from : int, to : int) -> void:
if from < colors.size() && to < colors.size():
var c : PaletteColor = colors[from]
remove_color(from)
insert_color(to, c.color, c.name)
func get_color(index : int) -> Color:
var result := Color.black
if index < colors.size():
result = colors[index].color
return result
# Returns color at index or null if no color exists
func get_color(index: int):
var palette_color = colors.get(index)
if palette_color != null:
return palette_color.color
return null
# Changes color data
func set_color(index: int, new_color: Color) -> void:
if index < colors.size():
colors[index].color = new_color
if self.colors.has(index):
self.colors[index].color = new_color
func get_color_data(index : int) -> String:
var result := ""
# Removes a color at the specified index
func remove_color(index: int) -> void:
colors.erase(index)
if index < colors.size():
result = colors[index].data
return result
# Inserts a color to the specified index
# If index is already occupied move the original color to right
func insert_color(index: int, new_color: Color) -> void:
var c := PaletteColor.new(new_color, index)
# If insert happens on non empty swatch recursively move the original color
# and every other color to it's right one swatch to right
if colors.get(index) != null:
move_right(index)
colors[index] = c
# Recursive function that moves every color to right until one of them is moved to empty swatch
func move_right(index: int) -> void:
# Moving colors to right would overflow the size of the palette so increase it's height automatically
if index + 1 == colors_max:
height += 1
colors_max = width * height
# If swatch to right to this color is not empty move that color right too
if colors.get(index + 1) != null:
move_right(index + 1)
colors[index + 1] = colors.get(index)
# Swaps two colors
func swap_colors(from_index: int, to_index: int) -> void:
var from_color = colors.get(from_index)
var to_color = colors.get(to_index)
if not from_color and to_color:
colors[from_index] = to_color
colors[from_index].index = from_index
colors.erase(to_index)
elif from_color and not to_color:
colors[to_index] = from_color
colors[to_index].index = to_index
colors.erase(from_index)
elif from_color and to_color:
colors[to_index] = from_color
colors[to_index].index = to_index
colors[from_index] = to_color
colors[from_index].index = from_index
# Copies color
func copy_colors(from_index: int, to_index: int) -> void:
# Only allow copy of existing colors
if colors.has(from_index):
colors[to_index] = colors[from_index].duplicate()
colors[to_index].index = to_index
# True if all swatches are occupied
func is_full() -> bool:
return self.colors.size() >= self.colors_max
# True if palette has no colors
func is_empty() -> bool:
return self.colors.size() == 0
func has_color(color: Color) -> bool:
for palette_color in colors:
for palette_color in colors.values():
if palette_color.color == color:
return true
return false
func set_color_data(index : int, new_color : String) -> void:
if index < colors.size():
colors[index].data = new_color
# Sets name that is used to save the palette to disk
func set_resource_name(new_resource_name: String) -> void:
# Store palette path name only with valid path characters
resource_name = strip_unvalid_characters(new_resource_name)
func get_color_name(index : int) -> String:
var result = ""
if index < colors.size():
result = colors[index].name
return result
func set_color_name(index : int, new_name : String) -> void:
if index < colors.size():
colors[index].name = new_name
func save_to_file(path : String) -> void:
var file = File.new()
file.open(path, File.WRITE)
file.store_string(_serialize())
file.close()
source_path = path
func duplicate(): # -> Palette
var copy = get_script().new() # : Palette
copy.name = name
copy.comments = comments
copy.editable = editable
for color in colors:
copy.colors.push_back(color.duplicate())
return copy
func _serialize() -> String:
var result = ""
var serialize_data : Dictionary = {
"name" : name,
"comments" : comments,
"colors" : [],
"editable" : editable
}
for color in colors:
serialize_data.colors.push_back(color.toDict())
result = JSON.print(serialize_data, " ")
return result
func deserialize(input_string : String): # -> Palette
var result = get_script().new()
var result_json = JSON.parse(input_string)
if result_json.error != OK: # If parse has errors
print("Error: ", result_json.error)
print("Error Line: ", result_json.error_line)
print("Error String: ", result_json.error_string)
result = null
else: # If parse OK
var data = result_json.result
if data.has("name"): # If data is 'valid' palette file
result = get_script().new()
result.name = data.name
if data.has("comments"):
result.comments = data.comments
if data.has("editable"):
result.editable = data.editable
if data.has("colors"):
for color_data in data.colors:
result.add_color(color_data.data, color_data.name)
return result
func load_from_file(path : String): # -> Palette
var result = null # : Palette
var file = File.new()
if file.file_exists(path):
file.open(path, File.READ)
var text : String = file.get_as_text()
result = deserialize(text)
result.source_path = path
file.close()
return result
func remove_file() -> int:
var dir = Directory.new()
return dir.remove(source_path)
static func strip_unvalid_characters(string_to_strip: String) -> String:
var regex := RegEx.new()
regex.compile("[^a-zA-Z0-9_]+")
return regex.sub(string_to_strip, "", true)

View file

@ -1,27 +0,0 @@
extends Button
signal on_drop_data
export var index := 0;
export var color : Color = Color.white
export var draggable := false
var drag_preview_texture = preload("res://assets/graphics/palette/swatch_drag_preview.png")
func get_drag_data(_position):
var data = null
if draggable:
data = {source_index = index}
var drag_icon = TextureRect.new()
drag_icon.texture = drag_preview_texture
drag_icon.modulate = color
set_drag_preview(drag_icon)
return data
func can_drop_data(_position, _data) -> bool:
return true
func drop_data(_position, data) -> void:
emit_signal("on_drop_data", data.source_index, index)

View file

@ -1,47 +0,0 @@
[gd_scene load_steps=8 format=2]
[ext_resource path="res://assets/themes/palette_styleboxes/palette_stylebox_pressedr.tres" type="StyleBox" id=1]
[ext_resource path="res://assets/themes/palette_styleboxes/palette_stylebox_hover.tres" type="StyleBox" id=2]
[ext_resource path="res://src/Palette/PaletteButton.gd" type="Script" id=3]
[ext_resource path="res://assets/themes/palette_styleboxes/palette_stylebox_focus.tres" type="StyleBox" id=4]
[ext_resource path="res://assets/themes/palette_styleboxes/palette_stylebox_normal.tres" type="StyleBox" id=5]
[ext_resource path="res://assets/graphics/palette/palette_button_fill.png" type="Texture" id=6]
[sub_resource type="ImageTexture" id=1]
[node name="PaletteButton" type="Button"]
margin_right = 26.0
margin_bottom = 26.0
rect_min_size = Vector2( 26, 26 )
hint_tooltip = "Color Name"
mouse_default_cursor_shape = 2
custom_styles/hover = ExtResource( 2 )
custom_styles/pressed = ExtResource( 1 )
custom_styles/focus = ExtResource( 4 )
custom_styles/normal = ExtResource( 5 )
toggle_mode = true
action_mode = 0
button_mask = 3
icon = SubResource( 1 )
script = ExtResource( 3 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="NinePatchRect" type="NinePatchRect" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 1.0
margin_top = 1.0
margin_right = -1.0
margin_bottom = -1.0
size_flags_horizontal = 3
size_flags_vertical = 3
texture = ExtResource( 6 )
patch_margin_left = 2
patch_margin_top = 2
patch_margin_right = 2
patch_margin_bottom = 2
__meta__ = {
"_edit_use_anchors_": false
}

View file

@ -1,54 +1,12 @@
class_name PaletteColor
extends Reference
extends Resource
const UNSET_INDEX := -1
export var color : Color = Color.transparent
export var index := UNSET_INDEX
var color : Color = Color.black setget _set_color
var data : String = "" setget _set_data
var name : String = "no name"
func get_class() -> String:
return "PaletteColor"
func is_class(_name : String) -> bool:
return _name == "PaletteColor" or .is_class(_name)
func _init(new_color : Color = Color.black, new_name : String = "no name") -> void:
self.color = new_color
self.name = new_name
func _set_color(new_value : Color) -> void:
color = new_value
data = color.to_html(true)
func _set_data(new_value : String) -> void:
data = new_value
color = Color(data)
func toDict() -> Dictionary:
var result = {
"data" : data,
"name" : name
}
return result
func fromDict(input_dict : Dictionary): # -> PaletteColor
var result = get_script().new()
result.data = input_dict.data
result.name = input_dict.name
return result
func duplicate(): # -> PaletteColor
var copy = get_script().new() # : PaletteColor
copy.data = data
copy.name = name
return copy
func _init(init_color: Color = Color.black, init_index: int = UNSET_INDEX) -> void:
color = init_color
index = init_index

View file

@ -1,432 +0,0 @@
extends GridContainer
enum {CEL, FRAME, ALL_FRAMES}
const palette_button = preload("res://src/Palette/PaletteButton.tscn")
var current_palette = "Default"
var from_palette : Palette
onready var palette_from_sprite_dialog = $"../../../../PaletteFromSpriteDialog"
onready var remove_palette_warning = $"../../../../RemovePaletteWarning"
func _ready() -> void:
_load_palettes()
# Select default palette "Default"
on_palette_select(current_palette)
var add_palette_menu : PopupMenu = Global.add_palette_button.get_node("PopupMenu")
add_palette_menu.connect("id_pressed", self, "add_palette_menu_id_pressed")
func _clear_swatches() -> void:
for child in get_children():
if child is BaseButton and child.text != "Dummy":
child.disconnect("pressed", self, "on_color_select")
child.queue_free()
func on_palette_select(palette_name : String) -> void:
_clear_swatches()
if Global.palettes.has(palette_name): # Palette exists in memory
current_palette = palette_name
var palette : Palette = Global.palettes[palette_name]
_display_palette(palette)
func on_new_empty_palette() -> void:
Global.new_palette_dialog.window_title = "Create a new empty palette?"
Global.new_palette_name_line_edit.text = "Custom_Palette"
from_palette = null
Global.new_palette_dialog.popup_centered()
Global.dialog_open(true)
func on_import_palette() -> void:
if OS.get_name() == "HTML5":
Html5FileExchange.load_palette()
else:
Global.palette_import_file_dialog.popup_centered()
Global.dialog_open(true)
func on_palette_import_file_selected(path : String) -> void:
var palette : Palette = null
if path.to_lower().ends_with("json"):
palette = Palette.new().load_from_file(path)
elif path.to_lower().ends_with("gpl"):
var file = File.new()
if file.file_exists(path):
file.open(path, File.READ)
var text = file.get_as_text()
file.close()
palette = Import.import_gpl(path, text)
elif path.to_lower().ends_with("pal"):
var file = File.new()
if file.file_exists(path):
file.open(path, File.READ)
var text = file.get_as_text()
file.close()
palette = Import.import_pal_palette(path, text)
elif path.to_lower().ends_with("png") or path.to_lower().ends_with("bmp") or path.to_lower().ends_with("hdr") or path.to_lower().ends_with("jpg") or path.to_lower().ends_with("svg") or path.to_lower().ends_with("tga") or path.to_lower().ends_with("webp"):
var image := Image.new()
var err := image.load(path)
if !err:
import_image_palette(path, image)
return
attempt_to_import_palette(palette)
func import_image_palette(path : String, image : Image) -> void:
var palette : Palette = null
palette = Import.import_png_palette(path, image)
attempt_to_import_palette(palette)
func attempt_to_import_palette(palette : Palette) -> void:
if palette:
palette.name = palette_name_replace(palette.name)
Global.palettes[palette.name] = palette
Global.palette_option_button.add_item(palette.name)
var index: int = Global.palette_option_button.get_item_count() - 1
Global.palette_option_button.set_item_metadata(index, palette.name)
Global.palette_option_button.select(index)
on_palette_select(palette.name)
save_palette(palette.name, palette.name + ".json")
else:
Global.error_dialog.set_text("Invalid Palette file!")
Global.error_dialog.popup_centered()
Global.dialog_open(true)
func _on_AddPalette_pressed() -> void:
Global.add_palette_button.get_node("PopupMenu").popup(Rect2(Global.add_palette_button.rect_global_position, Vector2.ONE))
func on_new_palette_confirmed() -> void:
var new_palette_name : String = Global.new_palette_name_line_edit.text
var result : String = create_new_palette(new_palette_name, from_palette)
if not result.empty():
Global.error_dialog.set_text(result)
Global.error_dialog.popup_centered()
Global.dialog_open(true)
func add_palette_menu_id_pressed(id : int) -> void:
match id:
0: # New Empty Palette
on_new_empty_palette()
1: # Import Palette
on_import_palette()
2: # Create Palette From Current Sprite
palette_from_sprite_dialog.popup_centered()
Global.dialog_open(true)
func create_new_palette(name : String, _from_palette : Palette) -> String: # Returns empty string, else error string
var new_palette : Palette = Palette.new()
# Check if new name is valid
if name.empty():
return tr("Error: Palette must have a valid name.")
name = palette_name_replace(name)
new_palette.name = name
# Check if source palette has data
if _from_palette:
new_palette = _from_palette.duplicate()
new_palette.name = name
new_palette.editable = true
# Add palette to Global and options
Global.palettes[name] = new_palette
Global.palette_option_button.add_item(name)
var index : int = Global.palette_option_button.get_item_count() - 1
Global.palette_option_button.set_item_metadata(index, name)
Global.palette_option_button.select(index)
save_palette(name, name + ".json")
on_palette_select(name)
return ""
# Checks if the palette name already exists
# If it does, add a number to its name, for example
# "Palette_Name" will become "Palette_Name (2)", "Palette_Name (3)", etc.
func palette_name_replace(name : String) -> String:
var i := 1
var temp_name := name
while Global.palettes.has(temp_name):
i += 1
temp_name = name + " (%s)" % i
name = temp_name
return name
func on_edit_palette() -> void:
var palette : Palette = Global.palettes[current_palette]
var create_new_palette := true # Create new palette by default
if palette.editable:
create_new_palette = false # Edit if already a custom palette
if create_new_palette:
from_palette = Global.palettes[current_palette]
Global.new_palette_dialog.window_title = "Create a new custom palette from existing default?"
Global.new_palette_name_line_edit.text = "Custom_" + current_palette
Global.new_palette_dialog.popup_centered()
Global.dialog_open(true)
else:
from_palette = null
Global.edit_palette_popup.open(current_palette)
func create_palette_from_sprite() -> void:
var current_project : Project = Global.current_project
var new_palette_name : String = current_project.name
var result : String = create_new_palette(new_palette_name, null)
if not result.empty():
Global.error_dialog.set_text(result)
Global.error_dialog.popup_centered()
Global.dialog_open(true)
return
var alpha_checkbox : CheckBox = palette_from_sprite_dialog.get_node("VBoxContainer/AlphaCheckBox")
var selection_checkbox : CheckBox = palette_from_sprite_dialog.get_node("VBoxContainer/SelectionCheckBox")
var colors_from_optionbutton : OptionButton = palette_from_sprite_dialog.get_node("VBoxContainer/HBoxContainer/ColorsFromOptionButton")
var palette : Palette = Global.palettes[current_palette]
var pixels := []
if selection_checkbox.pressed and current_project.selected_pixels:
pixels = current_project.selected_pixels.duplicate()
else:
for x in current_project.size.x:
for y in current_project.size.y:
pixels.append(Vector2(x, y))
var cels := []
match colors_from_optionbutton.selected:
CEL:
cels.append(current_project.frames[current_project.current_frame].cels[current_project.current_layer])
FRAME:
for cel in current_project.frames[current_project.current_frame].cels:
cels.append(cel)
ALL_FRAMES:
for frame in current_project.frames:
for cel in frame.cels:
cels.append(cel)
for cel in cels:
var cel_image := Image.new()
cel_image.copy_from(cel.image)
cel_image.lock()
if cel_image.is_invisible():
continue
for i in pixels:
var color : Color = cel_image.get_pixelv(i)
if color.a > 0:
if !alpha_checkbox.pressed:
color.a = 1
if !palette.has_color(color):
palette.add_color(color)
cel_image.unlock()
save_palette(current_palette, current_palette + ".json")
_display_palette(palette)
func _on_PaletteOptionButton_item_selected(ID : int) -> void:
var palette_name = Global.palette_option_button.get_item_metadata(ID)
if palette_name != null:
on_palette_select(palette_name)
func _display_palette(palette : Palette) -> void:
var index := 0
for color_data in palette.colors:
var color = color_data.color
var new_button = palette_button.instance()
new_button.get_child(0).modulate = color
new_button.hint_tooltip = "#" + color_data.data.to_upper() + " " + color_data.name
new_button.connect("pressed", self, "on_color_select", [index])
new_button.group = $DummyBtn.group
add_child(new_button)
index += 1
func on_color_select(index : int) -> void:
var color : Color = Global.palettes[current_palette].get_color(index)
if Input.is_action_just_pressed("left_mouse"):
Tools.assign_color(color, BUTTON_LEFT, false)
elif Input.is_action_just_pressed("right_mouse"):
Tools.assign_color(color, BUTTON_RIGHT, false)
func _load_palettes() -> void:
Global.directory_module.ensure_xdg_user_dirs_exist()
var search_locations = Global.directory_module.get_palette_search_path_in_order()
var priority_ordered_files := get_palette_priority_file_map(search_locations)
# Iterate backwards, so any palettes defined in default files
# get overwritten by those of the same name in user files
search_locations.invert()
priority_ordered_files.invert()
for i in range(len(search_locations)):
var base_directory : String = search_locations[i]
var palette_files : Array = priority_ordered_files[i]
for file_name in palette_files:
var palette : Palette = Palette.new().load_from_file(base_directory.plus_file(file_name))
if palette:
Global.palettes[palette.name] = palette
Global.palette_option_button.add_item(palette.name)
var index: int = Global.palette_option_button.get_item_count() - 1
Global.palette_option_button.set_item_metadata(index, palette.name)
if palette.name == "Default":
# You need these two lines because when you remove a palette
# Then this just won't work and _on_PaletteOptionButton_item_selected
# method won't fire.
Global.palette_option_button.selected = index
on_palette_select("Default")
Global.palette_option_button.select(index)
if not "Default" in Global.palettes && Global.palettes.size() > 0:
Global.palette_container._on_PaletteOptionButton_item_selected(0)
# Get the palette files in a single directory.
# if it does not exist, return []
func get_palette_files(path : String ) -> Array:
var dir := Directory.new()
var results = []
if not dir.dir_exists(path):
return []
dir.open(path)
dir.list_dir_begin()
while true:
var file_name = dir.get_next()
if file_name == "":
break
elif (not file_name.begins_with(".")) && file_name.to_lower().ends_with("json") && not dir.current_is_dir():
results.append(file_name)
dir.list_dir_end()
return results
# This returns an array of arrays, with priorities.
# In particular, it takes an array of paths to look for
# arrays in, in order of file and palette override priority
# such that the files in the first directory override the
# second, third, etc. ^.^
# It returns an array of arrays, where each output array
# corresponds to the given input array at the same index, and
# contains the (relative to the given directory) palette files
# to load, excluding all ones already existing in higher-priority
# directories. nya
# in particular, this also means you can run backwards on the result
# so that palettes with the given palette name in the higher priority
# directories override those set in lower priority directories :)
func get_palette_priority_file_map(looking_paths: Array) -> Array:
var final_list := []
# Holds pattern files already found
var working_file_set : Dictionary = {}
for search_directory in looking_paths:
var to_add_files := []
var files = get_palette_files(search_directory)
# files to check
for maybe_to_add in files:
if not maybe_to_add in working_file_set:
to_add_files.append(maybe_to_add)
working_file_set[maybe_to_add] = true
final_list.append(to_add_files)
return final_list
# Locate the highest priority palette by the given relative filename
# If none is found in the directories, then do nothing and return
# null
func get_best_palette_file_location(looking_paths: Array, fname: String): # -> String:
var priority_fmap : Array = get_palette_priority_file_map(looking_paths)
for i in range(len(looking_paths)):
var base_path : String = looking_paths[i]
var the_files : Array = priority_fmap[i]
if the_files.has(fname):
return base_path.plus_file(fname)
return null
func remove_palette(palette_name : String) -> void:
# Don't allow user to remove palette if there is no one left
if Global.palettes.size() < 2:
Global.error_dialog.set_text("You can't remove more palettes!")
Global.error_dialog.popup_centered()
Global.dialog_open(true)
return
# Don't allow user to try to remove not existing palettes
if not palette_name in Global.palettes:
Global.error_dialog.set_text("Cannot remove the palette, because it doesn't exist!")
Global.error_dialog.popup_centered()
Global.dialog_open(true)
return
Global.directory_module.ensure_xdg_user_dirs_exist()
var palette = Global.palettes[palette_name]
var result = palette.remove_file()
# Inform user if pallete hasn't been removed from disk because of an error
if result != OK:
Global.error_dialog.set_text(tr("An error occured while removing the palette! Error code: %s") % str(result))
Global.error_dialog.popup_centered()
Global.dialog_open(true)
# Remove palette in the program anyway, because if you don't do it
# then Pixelorama will crash
Global.palettes.erase(palette_name)
Global.palette_option_button.clear()
current_palette = "Default"
_load_palettes()
func save_palette(palette_name : String, filename : String) -> void:
Global.directory_module.ensure_xdg_user_dirs_exist()
var palette = Global.palettes[palette_name]
var palettes_write_path: String = Global.directory_module.get_palette_write_path()
palette.save_to_file(palettes_write_path.plus_file(filename))
func _on_NewPaletteDialog_popup_hide() -> void:
Global.dialog_open(false)
func _on_RemovePalette_pressed() -> void:
remove_palette_warning.popup_centered()
Global.dialog_open(true)
func _on_PaletteFromSpriteDialog_confirmed() -> void:
create_palette_from_sprite()
func _on_PaletteFromSpriteDialog_popup_hide() -> void:
Global.dialog_open(false)
func _on_RemovePaletteWarning_confirmed() -> void:
remove_palette(current_palette)
func _on_RemovePaletteWarning_popup_hide() -> void:
Global.dialog_open(false)

156
src/Palette/PaletteGrid.gd Normal file
View file

@ -0,0 +1,156 @@
extends GridContainer
class_name PaletteGrid
signal swatch_pressed(mouse_button, index)
signal swatch_double_clicked(mouse_button, index, position)
signal swatch_dropped(source_index, target_index)
const PaletteSwatchScene := preload("res://src/Palette/PaletteSwatch.tscn")
# Must be integer values
const MAX_GRID_SIZE = Vector2(8, 8)
var swatches := [] # PaletteSwatch
var displayed_palette = null
var grid_window_origin := Vector2.ZERO
var grid_size := Vector2(8, 8)
func _ready():
init_swatches()
func init_swatches() -> void:
columns = grid_size.x
for j in range(grid_size.y):
for i in range(grid_size.x):
var index: int = i + grid_size.x * j
var swatch: PaletteSwatch = PaletteSwatchScene.instance()
swatch.index = index
swatch.color = PaletteSwatch.DEFAULT_COLOR
swatch.show_left_highlight = false
swatch.show_right_highlight = false
swatch.empty = true
swatch.connect("pressed", self, "_on_PaletteSwatch_pressed", [index])
swatch.connect("double_clicked", self, "_on_PaletteSwatch_double_clicked", [index])
swatch.connect("dropped", self, "_on_PaletteSwatch_dropped")
add_child(swatch)
swatches.push_back(swatch)
# Origin determines a position in palette which will be displayed on top left of grid
func display_palette(palette: Palette) -> void:
# Reset grid origin when palette changes
if displayed_palette != palette:
displayed_palette = palette
grid_window_origin = Vector2.ZERO
# Only display valid palette objects
if not palette:
return
if swatches.size() == 0:
init_swatches()
if palette.width < MAX_GRID_SIZE.x or palette.height < MAX_GRID_SIZE.y:
grid_size = Vector2(palette.width, palette.height)
clear_swatches()
init_swatches()
elif palette.width >= MAX_GRID_SIZE.x and palette.height >= MAX_GRID_SIZE.y and grid_size != MAX_GRID_SIZE:
grid_size = MAX_GRID_SIZE
clear_swatches()
init_swatches()
# Create empty palette buttons
for j in range(grid_size.y):
for i in range(grid_size.x):
var grid_index: int = i + grid_size.x * j
var index: int = convert_grid_index_to_palette_index(grid_index)
var swatch = swatches[grid_index]
swatch.show_left_highlight = false
swatch.show_right_highlight = false
var color = palette.get_color(index)
if color != null:
swatch.color = color
swatch.empty = false
else:
swatch.color = PaletteSwatch.DEFAULT_COLOR
swatch.empty = true
func scroll_palette(origin: Vector2) -> void:
grid_window_origin = origin
display_palette(displayed_palette)
# Removes all swatches
func clear_swatches() -> void:
swatches.clear()
for swatch in get_children():
swatch.queue_free()
# Displays a left/right highlight over a swatch
func select_swatch(mouse_button: int, palette_index: int, old_palette_index: int) -> void:
var index = convert_palette_index_to_grid_index(palette_index)
var old_index = convert_palette_index_to_grid_index(old_palette_index)
if index >= 0 and index < swatches.size():
# Remove highlight from old index swatch and add to index swatch
if old_index >= 0 and old_index < swatches.size():
# Old index could be undefined when no swatch was previously selected
swatches[old_index].show_selected_highlight(false, mouse_button)
swatches[index].show_selected_highlight(true, mouse_button)
func unselect_swatch(mouse_button: int, palette_index: int) -> void:
var index = convert_palette_index_to_grid_index(palette_index)
if index >= 0 and index < swatches.size():
swatches[index].show_selected_highlight(false, mouse_button)
func set_swatch_color(palette_index: int, color: Color) -> void:
var index = convert_palette_index_to_grid_index(palette_index)
if index >= 0 and index < swatches.size():
swatches[index].color = color
func get_swatch_color(palette_index: int) -> Color:
var index = convert_palette_index_to_grid_index(palette_index)
if index >= 0 and index < swatches.size():
return swatches[index].color
return Color.transparent
# Used to reload empty swatch color from a theme
func reset_empty_swatches_color() -> void:
for swatch in swatches:
if swatch.empty:
swatch.empty = true
func _on_PaletteSwatch_pressed(mouse_button: int, index: int) -> void:
var palette_index = convert_grid_index_to_palette_index(index)
emit_signal("swatch_pressed", mouse_button, palette_index)
func _on_PaletteSwatch_double_clicked(mouse_button: int, position: Vector2, index: int) -> void:
var palette_index = convert_grid_index_to_palette_index(index)
emit_signal("swatch_double_clicked", mouse_button, palette_index, position)
func _on_PaletteSwatch_dropped(source_index: int, target_index: int) -> void:
var palette_source_index = convert_grid_index_to_palette_index(source_index)
var palette_target_index = convert_grid_index_to_palette_index(target_index)
emit_signal("swatch_dropped", palette_source_index, palette_target_index)
# Grid index adds grid window origin
func convert_grid_index_to_palette_index(index: int) -> int:
return int(index / grid_size.x + grid_window_origin.y) * displayed_palette.width + (index % int(grid_size.x) + grid_window_origin.x)
func convert_palette_index_to_grid_index(palette_index: int) -> int:
var x: int = palette_index % displayed_palette.width
var y: int = palette_index / displayed_palette.height
return int((x - grid_window_origin.x) + (y - grid_window_origin.y) * grid_size.x)

View file

@ -1,15 +0,0 @@
[gd_scene format=2]
[node name="PaletteImportFileDialog" type="FileDialog"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_right = -780.0
margin_bottom = -420.0
rect_min_size = Vector2( 500, 300 )
window_title = "Open a File"
resizable = true
mode = 0
access = 2
filters = PoolStringArray( "*.json ; JavaScript Object Notation", "*.gpl ; Gimp Palette Library", "*.png; Portable Network Graphics", "*.pal; JASC Palette" )
current_dir = "/Users"
current_path = "/Users/"

202
src/Palette/PalettePanel.gd Normal file
View file

@ -0,0 +1,202 @@
extends PanelContainer
class_name PalettePanel
var palettes_path_id := {}
var palettes_id_path := {}
var edited_swatch_index = -1
onready var palette_select := $PaletteVBoxContainer/PaletteButtons/PaletteSelect
onready var add_palette_button := $PaletteVBoxContainer/PaletteButtons/AddPalette
onready var palette_grid := $PaletteVBoxContainer/SwatchesContainer/PaletteScroll/HBoxContainer/CenterContainer/HBoxContainer/PaletteGrid
onready var palette_scroll := $PaletteVBoxContainer/SwatchesContainer/PaletteScroll
onready var add_color_button := $PaletteVBoxContainer/SwatchesContainer/ColorButtons/AddColor
onready var delete_color_button := $PaletteVBoxContainer/SwatchesContainer/ColorButtons/DeleteColor
onready var edit_palette_dialog := $EditPaletteDialog
onready var create_palette_dialog := $CreatePaletteDialog
# Color picker button itself is hidden but it's popup is used to edit color swatches
onready var hidden_color_picker := $HiddenColorPickerButton
func _ready() -> void:
Tools.connect("color_changed", self, "_color_changed")
setup_palettes_selector()
redraw_current_palette()
# Hide presets from color picker
hidden_color_picker.get_picker().presets_visible = false
# Setup palettes selector with available palettes
func setup_palettes_selector() -> void:
# Clear selector
palettes_path_id.clear()
palettes_id_path.clear()
palette_select.clear()
var id := 0
for palette_path in Palettes.get_palettes():
# Add palette selector item
palette_select.add_item(Palettes.get_palettes()[palette_path].name, id)
# Map palette paths to item id's and otherwise
palettes_path_id[palette_path] = id
palettes_id_path[id] = palette_path
id += 1
func select_palette(palette_path: String) -> void:
var palette_id = palettes_path_id.get(palette_path)
if palette_id != null:
palette_select.selected = palette_id
Palettes.select_palette(palette_path)
palette_grid.display_palette(Palettes.get_current_palette())
palette_scroll.set_sliders(Palettes.get_current_palette(), palette_grid.grid_window_origin)
var left_selected = Palettes.current_palette_get_selected_color_index(BUTTON_LEFT)
var right_selected = Palettes.current_palette_get_selected_color_index(BUTTON_RIGHT)
palette_grid.select_swatch(BUTTON_LEFT, left_selected, left_selected)
palette_grid.select_swatch(BUTTON_RIGHT, right_selected, right_selected)
toggle_add_delete_buttons()
# Has to be called on every Pixelorama theme change
func reset_empty_palette_swatches_color() -> void:
palette_grid.reset_empty_swatches_color()
func redraw_current_palette() -> void:
# Select and display current palette
var current_palette = Palettes.get_current_palette()
if current_palette:
select_palette(current_palette.resource_path)
add_color_button.show()
delete_color_button.show()
else:
palette_grid.clear_swatches()
add_color_button.hide()
delete_color_button.hide()
func toggle_add_delete_buttons() -> void:
add_color_button.disabled = Palettes.current_palette_is_full()
if add_color_button.disabled:
add_color_button.mouse_default_cursor_shape = CURSOR_FORBIDDEN
else:
add_color_button.mouse_default_cursor_shape = CURSOR_POINTING_HAND
delete_color_button.disabled = Palettes.current_palette_is_empty()
if delete_color_button.disabled:
delete_color_button.mouse_default_cursor_shape = CURSOR_FORBIDDEN
else:
delete_color_button.mouse_default_cursor_shape = CURSOR_POINTING_HAND
func _on_AddPalette_pressed() -> void:
create_palette_dialog.open(Palettes.current_palette)
func _on_EditPalette_pressed() -> void:
edit_palette_dialog.open(Palettes.current_palette)
func _on_PaletteSelect_item_selected(index: int) -> void:
select_palette(palettes_id_path.get(index))
func _on_AddColor_gui_input(event: InputEvent) -> void:
if Palettes.is_any_palette_selected():
if event is InputEventMouseButton and event.pressed and (event.button_index == BUTTON_LEFT or event.button_index == BUTTON_RIGHT):
# Gets the grid index that corresponds to the top left of current grid window
# Color will be added at the start of the currently scrolled part of palette - not the absolute beginning of palette
var start_index = palette_grid.convert_grid_index_to_palette_index(0)
Palettes.current_palette_add_color(event.button_index, start_index)
redraw_current_palette()
toggle_add_delete_buttons()
func _on_DeleteColor_gui_input(event: InputEvent) -> void:
if Palettes.is_any_palette_selected():
if event is InputEventMouseButton and event.pressed:
var selected_color_index = Palettes.current_palette_get_selected_color_index(event.button_index)
if selected_color_index != -1:
Palettes.current_palette_delete_color(selected_color_index)
redraw_current_palette()
toggle_add_delete_buttons()
func _on_CreatePaletteDialog_saved(preset: int, name: String, comment: String, width: int, height: int, add_alpha_colors: bool, colors_from: int) -> void:
Palettes.create_new_palette(preset, name, comment, width, height, add_alpha_colors, colors_from)
setup_palettes_selector()
redraw_current_palette()
func _on_EditPaletteDialog_saved(name: String, comment: String, width: int, height: int) -> void:
Palettes.current_palette_edit(name, comment, width, height)
setup_palettes_selector()
redraw_current_palette()
func _on_PaletteGrid_swatch_double_clicked(_mouse_button: int, index: int, click_position: Vector2) -> void:
var color = Palettes.current_palette_get_color(index)
edited_swatch_index = index
hidden_color_picker.color = color
# Open color picker popup with it's right bottom corner next to swatch
var popup = hidden_color_picker.get_popup()
popup.rect_position = click_position - popup.rect_size
popup.popup()
func _on_PaletteGrid_swatch_dropped(source_index: int, target_index: int) -> void:
if Input.is_key_pressed(KEY_SHIFT):
Palettes.current_palette_insert_color(source_index, target_index)
elif Input.is_key_pressed(KEY_CONTROL):
Palettes.current_palette_copy_colors(source_index, target_index)
else:
Palettes.current_palette_swap_colors(source_index, target_index)
redraw_current_palette()
func _on_PaletteGrid_swatch_pressed(mouse_button: int, index: int) -> void:
# Gets previously selected color index
var old_index = Palettes.current_palette_get_selected_color_index(mouse_button)
Palettes.current_palette_select_color(mouse_button, index)
palette_grid.select_swatch(mouse_button, index, old_index)
func _on_ColorPicker_color_changed(color: Color) -> void:
if edited_swatch_index != -1:
Palettes.current_palette_set_color(edited_swatch_index, color)
palette_grid.set_swatch_color(edited_swatch_index, color)
if edited_swatch_index == Palettes.current_palette_get_selected_color_index(BUTTON_LEFT):
Tools.assign_color(color, BUTTON_LEFT)
if edited_swatch_index == Palettes.current_palette_get_selected_color_index(BUTTON_RIGHT):
Tools.assign_color(color, BUTTON_RIGHT)
func _on_EditPaletteDialog_deleted() -> void:
Palettes.current_palete_delete()
setup_palettes_selector()
redraw_current_palette()
func _color_changed(_color: Color, button: int) -> void:
if hidden_color_picker.get_popup().visible == false and Palettes.get_current_palette():
# Unselect swatches when tools color is changed
var swatch_to_unselect = -1
if button == BUTTON_LEFT:
swatch_to_unselect = Palettes.left_selected_color
Palettes.left_selected_color = -1
elif button == BUTTON_RIGHT:
swatch_to_unselect = Palettes.right_selected_color
Palettes.right_selected_color = -1
palette_grid.unselect_swatch(button, swatch_to_unselect)

View file

@ -0,0 +1,228 @@
[gd_scene load_steps=8 format=2]
[ext_resource path="res://src/Palette/EditPaletteDialog.tscn" type="PackedScene" id=1]
[ext_resource path="res://assets/graphics/dark_themes/palette/edit_palette.png" type="Texture" id=2]
[ext_resource path="res://assets/graphics/dark_themes/palette/add_palette.png" type="Texture" id=3]
[ext_resource path="res://src/Palette/CreatePaletteDialog.tscn" type="PackedScene" id=4]
[ext_resource path="res://src/Palette/PaletteGrid.gd" type="Script" id=5]
[ext_resource path="res://src/Palette/PaletteScroll.gd" type="Script" id=6]
[ext_resource path="res://src/Palette/PalettePanel.gd" type="Script" id=8]
[node name="PalettePanel" type="PanelContainer"]
margin_right = 324.0
margin_bottom = 319.0
rect_min_size = Vector2( 300, 0 )
size_flags_horizontal = 4
size_flags_vertical = 3
script = ExtResource( 8 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="PaletteVBoxContainer" type="VBoxContainer" parent="."]
margin_left = 7.0
margin_top = 7.0
margin_right = 317.0
margin_bottom = 312.0
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="PalettesLabel" type="Label" parent="PaletteVBoxContainer"]
margin_right = 310.0
margin_bottom = 14.0
size_flags_horizontal = 3
size_flags_vertical = 0
text = "Palettes"
align = 1
[node name="PaletteButtons" type="HBoxContainer" parent="PaletteVBoxContainer"]
margin_top = 18.0
margin_right = 310.0
margin_bottom = 50.0
[node name="PaletteSelect" type="OptionButton" parent="PaletteVBoxContainer/PaletteButtons"]
margin_right = 238.0
margin_bottom = 32.0
grow_horizontal = 0
rect_min_size = Vector2( 100, 0 )
hint_tooltip = "Choose a palette"
mouse_default_cursor_shape = 2
size_flags_horizontal = 3
clip_text = true
[node name="EditPalette" type="Button" parent="PaletteVBoxContainer/PaletteButtons" groups=[
"UIButtons",
]]
margin_left = 242.0
margin_right = 274.0
margin_bottom = 32.0
rect_min_size = Vector2( 32, 32 )
hint_tooltip = "Edit currently selected palette"
mouse_default_cursor_shape = 2
__meta__ = {
"_edit_group_": true
}
[node name="TextureRect" type="TextureRect" parent="PaletteVBoxContainer/PaletteButtons/EditPalette"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -12.0
margin_top = -12.0
margin_right = 12.0
margin_bottom = 12.0
size_flags_horizontal = 0
size_flags_vertical = 0
texture = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="AddPalette" type="Button" parent="PaletteVBoxContainer/PaletteButtons" groups=[
"UIButtons",
]]
margin_left = 278.0
margin_right = 310.0
margin_bottom = 32.0
rect_min_size = Vector2( 32, 32 )
hint_tooltip = "Create a new palette"
mouse_default_cursor_shape = 2
__meta__ = {
"_edit_group_": true
}
[node name="TextureRect" type="TextureRect" parent="PaletteVBoxContainer/PaletteButtons/AddPalette"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -12.0
margin_top = -12.0
margin_right = 12.0
margin_bottom = 12.0
size_flags_horizontal = 0
size_flags_vertical = 0
texture = ExtResource( 3 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="HSeparator" type="HSeparator" parent="PaletteVBoxContainer"]
margin_top = 54.0
margin_right = 310.0
margin_bottom = 58.0
[node name="SwatchesContainer" type="HBoxContainer" parent="PaletteVBoxContainer"]
margin_top = 62.0
margin_right = 310.0
margin_bottom = 305.0
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="ColorButtons" type="VBoxContainer" parent="PaletteVBoxContainer/SwatchesContainer"]
margin_right = 24.0
margin_bottom = 243.0
[node name="AddColor" type="Button" parent="PaletteVBoxContainer/SwatchesContainer/ColorButtons"]
margin_right = 24.0
margin_bottom = 24.0
rect_min_size = Vector2( 24, 24 )
hint_tooltip = "Add a new color"
mouse_default_cursor_shape = 2
text = "+"
[node name="DeleteColor" type="Button" parent="PaletteVBoxContainer/SwatchesContainer/ColorButtons"]
margin_top = 28.0
margin_right = 24.0
margin_bottom = 52.0
rect_min_size = Vector2( 24, 24 )
hint_tooltip = "Remove a selected color"
mouse_default_cursor_shape = 2
text = "-"
[node name="PaletteScroll" type="VBoxContainer" parent="PaletteVBoxContainer/SwatchesContainer"]
margin_left = 28.0
margin_right = 310.0
margin_bottom = 243.0
size_flags_horizontal = 3
size_flags_vertical = 3
script = ExtResource( 6 )
[node name="HBoxContainer" type="HBoxContainer" parent="PaletteVBoxContainer/SwatchesContainer/PaletteScroll"]
margin_right = 282.0
size_flags_horizontal = 3
[node name="CenterContainer" type="CenterContainer" parent="PaletteVBoxContainer/SwatchesContainer/PaletteScroll/HBoxContainer"]
margin_right = 282.0
size_flags_horizontal = 3
[node name="HBoxContainer" type="HBoxContainer" parent="PaletteVBoxContainer/SwatchesContainer/PaletteScroll/HBoxContainer/CenterContainer"]
margin_left = 141.0
margin_right = 141.0
[node name="PaletteGrid" type="GridContainer" parent="PaletteVBoxContainer/SwatchesContainer/PaletteScroll/HBoxContainer/CenterContainer/HBoxContainer"]
rect_pivot_offset = Vector2( -123.214, 138.568 )
columns = 8
script = ExtResource( 5 )
[node name="VScrollBar" type="VScrollBar" parent="PaletteVBoxContainer/SwatchesContainer/PaletteScroll/HBoxContainer/CenterContainer/HBoxContainer"]
visible = false
margin_left = 4.0
margin_right = 16.0
margin_bottom = 12.0
step = 1.0
page = 8.0
custom_step = 1.0
[node name="MarginContainer" type="MarginContainer" parent="PaletteVBoxContainer/SwatchesContainer/PaletteScroll"]
margin_top = 4.0
margin_right = 282.0
margin_bottom = 4.0
custom_constants/margin_right = 20
custom_constants/margin_left = 6
[node name="HScrollBar" type="HScrollBar" parent="PaletteVBoxContainer/SwatchesContainer/PaletteScroll/MarginContainer"]
visible = false
margin_left = 6.0
margin_right = 262.0
margin_bottom = 12.0
step = 1.0
page = 8.0
custom_step = 1.0
[node name="EditPaletteDialog" parent="." instance=ExtResource( 1 )]
margin_left = 7.0
margin_top = 7.0
margin_right = 317.0
margin_bottom = 442.0
rect_min_size = Vector2( 250, 87.5 )
[node name="CreatePaletteDialog" parent="." instance=ExtResource( 4 )]
margin_left = 7.0
margin_top = 7.0
margin_right = 317.0
margin_bottom = 312.0
rect_min_size = Vector2( 250, 87.5 )
[node name="HiddenColorPickerButton" type="ColorPickerButton" parent="."]
visible = false
margin_left = 7.0
margin_top = 7.0
margin_right = 317.0
margin_bottom = 312.0
[connection signal="item_selected" from="PaletteVBoxContainer/PaletteButtons/PaletteSelect" to="." method="_on_PaletteSelect_item_selected"]
[connection signal="pressed" from="PaletteVBoxContainer/PaletteButtons/EditPalette" to="." method="_on_EditPalette_pressed"]
[connection signal="pressed" from="PaletteVBoxContainer/PaletteButtons/AddPalette" to="." method="_on_AddPalette_pressed"]
[connection signal="gui_input" from="PaletteVBoxContainer/SwatchesContainer/ColorButtons/AddColor" to="." method="_on_AddColor_gui_input"]
[connection signal="gui_input" from="PaletteVBoxContainer/SwatchesContainer/ColorButtons/DeleteColor" to="." method="_on_DeleteColor_gui_input"]
[connection signal="gui_input" from="PaletteVBoxContainer/SwatchesContainer/PaletteScroll/HBoxContainer/CenterContainer/HBoxContainer/PaletteGrid" to="PaletteVBoxContainer/SwatchesContainer/PaletteScroll" method="_on_PaletteGrid_gui_input"]
[connection signal="swatch_double_clicked" from="PaletteVBoxContainer/SwatchesContainer/PaletteScroll/HBoxContainer/CenterContainer/HBoxContainer/PaletteGrid" to="." method="_on_PaletteGrid_swatch_double_clicked"]
[connection signal="swatch_dropped" from="PaletteVBoxContainer/SwatchesContainer/PaletteScroll/HBoxContainer/CenterContainer/HBoxContainer/PaletteGrid" to="." method="_on_PaletteGrid_swatch_dropped"]
[connection signal="swatch_pressed" from="PaletteVBoxContainer/SwatchesContainer/PaletteScroll/HBoxContainer/CenterContainer/HBoxContainer/PaletteGrid" to="." method="_on_PaletteGrid_swatch_pressed"]
[connection signal="value_changed" from="PaletteVBoxContainer/SwatchesContainer/PaletteScroll/HBoxContainer/CenterContainer/HBoxContainer/VScrollBar" to="PaletteVBoxContainer/SwatchesContainer/PaletteScroll" method="_on_VSlider_value_changed"]
[connection signal="value_changed" from="PaletteVBoxContainer/SwatchesContainer/PaletteScroll/MarginContainer/HScrollBar" to="PaletteVBoxContainer/SwatchesContainer/PaletteScroll" method="_on_HSlider_value_changed"]
[connection signal="deleted" from="EditPaletteDialog" to="." method="_on_EditPaletteDialog_deleted"]
[connection signal="saved" from="EditPaletteDialog" to="." method="_on_EditPaletteDialog_saved"]
[connection signal="saved" from="CreatePaletteDialog" to="." method="_on_CreatePaletteDialog_saved"]
[connection signal="color_changed" from="HiddenColorPickerButton" to="." method="_on_ColorPicker_color_changed"]

View file

@ -1,263 +0,0 @@
[gd_scene load_steps=9 format=2]
[ext_resource path="res://src/Palette/PaletteContainer.gd" type="Script" id=1]
[ext_resource path="res://assets/graphics/dark_themes/palette/edit_palette.png" type="Texture" id=2]
[ext_resource path="res://assets/graphics/dark_themes/palette/add_palette.png" type="Texture" id=3]
[ext_resource path="res://assets/graphics/dark_themes/palette/remove_palette.png" type="Texture" id=4]
[ext_resource path="res://src/Palette/PaletteImportFileDialog.tscn" type="PackedScene" id=5]
[ext_resource path="res://src/Palette/NewPaletteDialog.tscn" type="PackedScene" id=6]
[ext_resource path="res://src/Palette/EditPalettePopup.tscn" type="PackedScene" id=7]
[sub_resource type="ButtonGroup" id=1]
[node name="PalettePanelContainer" type="PanelContainer"]
margin_left = 15.0
margin_top = 261.0
margin_right = 315.0
margin_bottom = 516.0
rect_min_size = Vector2( 300, 0 )
size_flags_horizontal = 4
size_flags_vertical = 3
__meta__ = {
"_edit_use_anchors_": false
}
[node name="PaletteVBoxContainer" type="VBoxContainer" parent="."]
margin_left = 7.0
margin_top = 7.0
margin_right = 293.0
margin_bottom = 248.0
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="PalettesLabel" type="Label" parent="PaletteVBoxContainer"]
margin_right = 286.0
margin_bottom = 14.0
size_flags_horizontal = 3
size_flags_vertical = 0
text = "Palettes"
align = 1
[node name="CenterContainer" type="CenterContainer" parent="PaletteVBoxContainer"]
margin_top = 18.0
margin_right = 286.0
margin_bottom = 50.0
[node name="PaletteButtons" type="HBoxContainer" parent="PaletteVBoxContainer/CenterContainer"]
margin_left = 37.0
margin_right = 248.0
margin_bottom = 32.0
[node name="AddPalette" type="Button" parent="PaletteVBoxContainer/CenterContainer/PaletteButtons" groups=[
"UIButtons",
]]
margin_right = 32.0
margin_bottom = 32.0
rect_min_size = Vector2( 32, 32 )
hint_tooltip = "Add a new palette"
mouse_default_cursor_shape = 2
[node name="PopupMenu" type="PopupMenu" parent="PaletteVBoxContainer/CenterContainer/PaletteButtons/AddPalette"]
margin_right = 115.0
margin_bottom = 54.0
items = [ "New Empty Palette", null, 0, false, false, 0, 0, null, "", false, "Import Palette", null, 0, false, false, 1, 0, null, "", false, "Create Palette From Current Sprite", null, 0, false, false, 2, 0, null, "", false ]
__meta__ = {
"_edit_use_anchors_": false
}
[node name="TextureRect" type="TextureRect" parent="PaletteVBoxContainer/CenterContainer/PaletteButtons/AddPalette"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -12.0
margin_top = -12.0
margin_right = 12.0
margin_bottom = 12.0
size_flags_horizontal = 0
size_flags_vertical = 0
texture = ExtResource( 3 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="EditPalette" type="Button" parent="PaletteVBoxContainer/CenterContainer/PaletteButtons" groups=[
"UIButtons",
]]
margin_left = 36.0
margin_right = 68.0
margin_bottom = 32.0
rect_min_size = Vector2( 32, 32 )
hint_tooltip = "Edit currently selected palette"
mouse_default_cursor_shape = 2
[node name="TextureRect" type="TextureRect" parent="PaletteVBoxContainer/CenterContainer/PaletteButtons/EditPalette"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -12.0
margin_top = -12.0
margin_right = 12.0
margin_bottom = 12.0
size_flags_horizontal = 0
size_flags_vertical = 0
texture = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="RemovePalette" type="Button" parent="PaletteVBoxContainer/CenterContainer/PaletteButtons" groups=[
"UIButtons",
]]
margin_left = 72.0
margin_right = 104.0
margin_bottom = 32.0
rect_min_size = Vector2( 32, 32 )
hint_tooltip = "Remove currently selected palette"
mouse_default_cursor_shape = 2
[node name="TextureRect" type="TextureRect" parent="PaletteVBoxContainer/CenterContainer/PaletteButtons/RemovePalette"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -12.0
margin_top = -12.0
margin_right = 12.0
margin_bottom = 12.0
size_flags_horizontal = 0
size_flags_vertical = 0
texture = ExtResource( 4 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="PaletteOptionButton" type="OptionButton" parent="PaletteVBoxContainer/CenterContainer/PaletteButtons"]
margin_left = 108.0
margin_right = 211.0
margin_bottom = 32.0
grow_horizontal = 0
rect_min_size = Vector2( 103, 0 )
hint_tooltip = "Choose a palette"
mouse_default_cursor_shape = 2
clip_text = true
[node name="ScrollPalette" type="ScrollContainer" parent="PaletteVBoxContainer"]
margin_top = 54.0
margin_right = 286.0
margin_bottom = 241.0
rect_min_size = Vector2( 0, 100 )
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="CenterPalette" type="CenterContainer" parent="PaletteVBoxContainer/ScrollPalette"]
margin_right = 286.0
size_flags_horizontal = 3
[node name="PaletteContainer" type="GridContainer" parent="PaletteVBoxContainer/ScrollPalette/CenterPalette"]
margin_left = 143.0
margin_right = 143.0
size_flags_horizontal = 3
columns = 10
script = ExtResource( 1 )
[node name="DummyBtn" type="Button" parent="PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer"]
visible = false
margin_right = 12.0
margin_bottom = 20.0
group = SubResource( 1 )
text = "Dummy"
[node name="NewPaletteDialog" parent="." instance=ExtResource( 6 )]
margin_left = 7.0
margin_top = 7.0
margin_right = 380.0
margin_bottom = 77.0
size_flags_horizontal = 0
size_flags_vertical = 0
[node name="PaletteImportFileDialog" parent="." instance=ExtResource( 5 )]
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 7.0
margin_top = 7.0
margin_right = 507.0
margin_bottom = 307.0
[node name="EditPalettePopup" parent="." instance=ExtResource( 7 )]
margin_left = 7.0
margin_top = 7.0
margin_right = 607.0
margin_bottom = 577.0
[node name="PaletteFromSpriteDialog" type="ConfirmationDialog" parent="."]
margin_left = 7.0
margin_top = 7.0
margin_right = 281.0
margin_bottom = 127.0
window_title = "Create Palette From Current Sprite"
resizable = true
[node name="VBoxContainer" type="VBoxContainer" parent="PaletteFromSpriteDialog"]
margin_left = 8.0
margin_top = 8.0
margin_right = 266.0
margin_bottom = 84.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="AlphaCheckBox" type="CheckBox" parent="PaletteFromSpriteDialog/VBoxContainer"]
margin_right = 258.0
margin_bottom = 24.0
mouse_default_cursor_shape = 2
pressed = true
text = "Create colors with alpha component"
[node name="SelectionCheckBox" type="CheckBox" parent="PaletteFromSpriteDialog/VBoxContainer"]
margin_top = 28.0
margin_right = 258.0
margin_bottom = 52.0
mouse_default_cursor_shape = 2
text = "Get colors only from selection"
[node name="HBoxContainer" type="HBoxContainer" parent="PaletteFromSpriteDialog/VBoxContainer"]
margin_top = 56.0
margin_right = 258.0
margin_bottom = 76.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Label" type="Label" parent="PaletteFromSpriteDialog/VBoxContainer/HBoxContainer"]
margin_top = 3.0
margin_right = 104.0
margin_bottom = 17.0
text = "Get colors from"
[node name="ColorsFromOptionButton" type="OptionButton" parent="PaletteFromSpriteDialog/VBoxContainer/HBoxContainer"]
margin_left = 108.0
margin_right = 207.0
margin_bottom = 20.0
mouse_default_cursor_shape = 2
text = "Current cel"
items = [ "Current cel", null, false, 0, null, "Current frame", null, false, 1, null, "All frames", null, false, 2, null ]
selected = 0
[node name="RemovePaletteWarning" type="ConfirmationDialog" parent="."]
margin_right = 200.0
margin_bottom = 70.0
dialog_text = "Are you sure you want to remove this palette? (Cannot be undone)"
[connection signal="pressed" from="PaletteVBoxContainer/CenterContainer/PaletteButtons/AddPalette" to="PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="_on_AddPalette_pressed"]
[connection signal="pressed" from="PaletteVBoxContainer/CenterContainer/PaletteButtons/EditPalette" to="PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="on_edit_palette"]
[connection signal="pressed" from="PaletteVBoxContainer/CenterContainer/PaletteButtons/RemovePalette" to="PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="_on_RemovePalette_pressed"]
[connection signal="item_selected" from="PaletteVBoxContainer/CenterContainer/PaletteButtons/PaletteOptionButton" to="PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="_on_PaletteOptionButton_item_selected"]
[connection signal="confirmed" from="NewPaletteDialog" to="PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="on_new_palette_confirmed"]
[connection signal="popup_hide" from="NewPaletteDialog" to="PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="_on_NewPaletteDialog_popup_hide"]
[connection signal="file_selected" from="PaletteImportFileDialog" to="PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="on_palette_import_file_selected"]
[connection signal="popup_hide" from="PaletteImportFileDialog" to="PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="_on_NewPaletteDialog_popup_hide"]
[connection signal="confirmed" from="PaletteFromSpriteDialog" to="PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="_on_PaletteFromSpriteDialog_confirmed"]
[connection signal="popup_hide" from="PaletteFromSpriteDialog" to="PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="_on_PaletteFromSpriteDialog_popup_hide"]
[connection signal="confirmed" from="RemovePaletteWarning" to="PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="_on_RemovePaletteWarning_confirmed"]
[connection signal="popup_hide" from="RemovePaletteWarning" to="PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="_on_RemovePaletteWarning_popup_hide"]

View file

@ -0,0 +1,57 @@
extends VBoxContainer
var scroll := Vector2.ZERO
var drag_started := false
var drag_start_position := Vector2.ZERO
onready var h_slider := $MarginContainer/HScrollBar
onready var v_slider := $HBoxContainer/CenterContainer/HBoxContainer/VScrollBar
onready var palette_grid := $HBoxContainer/CenterContainer/HBoxContainer/PaletteGrid
func _input(event) -> void:
# Stops dragging even if middle mouse is released outside of this container
if event is InputEventMouseButton:
if event.button_index == BUTTON_MIDDLE and not event.pressed:
drag_started = false
func set_sliders(palette: Palette, origin: Vector2) -> void:
h_slider.value = origin.x
v_slider.value = origin.y
h_slider.max_value = palette.width
if h_slider.max_value <= PaletteGrid.MAX_GRID_SIZE.x:
h_slider.visible = false
else:
h_slider.visible = true
v_slider.max_value = palette.height
if v_slider.max_value <= PaletteGrid.MAX_GRID_SIZE.y:
v_slider.visible = false
else:
v_slider.visible = true
func scroll_grid() -> void:
palette_grid.scroll_palette(scroll)
func _on_VSlider_value_changed(value) -> void:
scroll.y = value
scroll_grid()
func _on_HSlider_value_changed(value: int) -> void:
scroll.x = value
scroll_grid()
func _on_PaletteGrid_gui_input(event) -> void:
if event is InputEventMouseButton:
if event.button_index == BUTTON_MIDDLE and event.pressed:
drag_started = true
# Keeps position where the dragging started
drag_start_position = event.position + Vector2(h_slider.value, v_slider.value) * PaletteSwatch.SWATCH_SIZE
if event is InputEventMouseMotion and drag_started:
h_slider.value = (drag_start_position.x - event.position.x) / PaletteSwatch.SWATCH_SIZE.x
v_slider.value = (drag_start_position.y - event.position.y) / PaletteSwatch.SWATCH_SIZE.y

View file

@ -0,0 +1,87 @@
extends ColorRect
class_name PaletteSwatch
# Required by grid sliders
const SWATCH_SIZE := Vector2(26, 26)
signal pressed(mouse_button)
signal double_clicked(mouse_button, position)
signal dropped(source_index, new_index)
const DEFAULT_COLOR := Color(0.0, 0.0, 0.0, 0.0)
var index := -1
var show_left_highlight := false
var show_right_highlight := false
var empty := true setget set_empty
func _ready():
rect_min_size = SWATCH_SIZE
rect_size = SWATCH_SIZE
func _draw() -> void:
if not empty:
# Black border around swatches with a color
draw_rect(Rect2(Vector2.ZERO, SWATCH_SIZE), Color.black, false, 1)
if show_left_highlight:
# Display outer border highlight
draw_rect(Rect2(Vector2.ZERO, SWATCH_SIZE), Color.white, false, 1)
draw_rect(Rect2(Vector2.ONE, SWATCH_SIZE - Vector2(2, 2)), Color.black, false, 1)
if show_right_highlight:
# Display inner border highlight
var margin := SWATCH_SIZE / 4
draw_rect(Rect2(margin, SWATCH_SIZE - margin * 2), Color.black, false, 1)
draw_rect(Rect2(margin - Vector2.ONE, SWATCH_SIZE - margin * 2 + Vector2(2, 2)), Color.white, false, 1)
# Enables drawing of highlights which indicate selected swatches
func show_selected_highlight(new_value: bool, mouse_button: int) -> void:
if not empty:
match mouse_button:
BUTTON_LEFT:
show_left_highlight = new_value
BUTTON_RIGHT:
show_right_highlight = new_value
update()
# Empties the swatch and displays disabled color from theme
func set_empty(new_value: bool) -> void:
empty = new_value
if empty:
mouse_default_cursor_shape = Control.CURSOR_ARROW
color = Global.control.theme.get_stylebox("disabled", "Button").bg_color
else:
mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
func get_drag_data(_position):
var data = null
if not empty:
var drag_icon: PaletteSwatch = self.duplicate()
drag_icon.show_left_highlight = false
drag_icon.show_right_highlight = false
drag_icon.empty = false
set_drag_preview(drag_icon)
data = {source_index = index}
return data
func can_drop_data(_position, _data) -> bool:
return true
func drop_data(_position, data) -> void:
emit_signal("dropped", data.source_index, index)
func _on_PaletteSlot_gui_input(event: InputEvent) -> void:
if event is InputEventMouseButton and event.is_pressed() and not empty:
if event.doubleclick:
emit_signal("double_clicked", event.button_index, get_global_rect().position)
else:
emit_signal("pressed", event.button_index)

View file

@ -0,0 +1,78 @@
[gd_scene load_steps=4 format=2]
[ext_resource path="res://src/Palette/PaletteSwatch.gd" type="Script" id=1]
[sub_resource type="Shader" id=1]
code = "shader_type canvas_item;
render_mode unshaded;
uniform float size = 10.0;
uniform vec4 color1 : hint_color = vec4(0.7, 0.7, 0.7, 1.0);
uniform vec4 color2 : hint_color = vec4(1.0);
uniform vec2 offset = vec2(0.0);
uniform vec2 scale = vec2(0.0);
uniform vec2 rect_size = vec2(0.0);
uniform bool follow_movement = false;
uniform bool follow_scale = false;
void fragment() {
vec2 ref_pos = FRAGCOORD.xy;
if (follow_scale) {
if (!follow_movement)
ref_pos /= scale;
else
ref_pos = UV * rect_size;
}
else if (follow_movement)
ref_pos -= mod(offset, size * 2.0);
vec2 pos = mod(ref_pos, size * 2.0);
bool c1 = any(lessThan(pos, vec2(size)));
bool c2 = any(greaterThanEqual(pos, vec2(size)));
float c = c1 && c2 ? 1.0: 0.0;
COLOR = mix(color1, color2, c);
COLOR.a = 1.0;
}
"
[sub_resource type="ShaderMaterial" id=2]
shader = SubResource( 1 )
shader_param/size = 10.0
shader_param/color1 = Color( 0.878431, 0.878431, 0.878431, 1 )
shader_param/color2 = Color( 1, 1, 1, 1 )
shader_param/offset = Vector2( 0, 0 )
shader_param/scale = Vector2( 0.8, 0.8 )
shader_param/rect_size = Vector2( 0, 0 )
shader_param/follow_movement = false
shader_param/follow_scale = true
[node name="PaletteSwatch" type="ColorRect"]
anchor_left = 2.60711e-05
anchor_top = -2.75612e-05
anchor_right = 2.60711e-05
anchor_bottom = -2.75612e-05
margin_left = -0.033371
margin_top = 0.0198441
margin_right = 25.9666
margin_bottom = 26.0198
rect_min_size = Vector2( 8, 8 )
mouse_filter = 1
mouse_default_cursor_shape = 2
color = Color( 0, 0, 0, 0 )
script = ExtResource( 1 )
__meta__ = {
"_edit_lock_": true,
"_edit_use_anchors_": false
}
[node name="TransparentChecker" type="ColorRect" parent="."]
show_behind_parent = true
material = SubResource( 2 )
anchor_right = 1.0
anchor_bottom = 1.0
mouse_filter = 2
__meta__ = {
"_edit_lock_": true,
"_edit_use_anchors_": false
}
[connection signal="gui_input" from="." to="." method="_on_PaletteSlot_gui_input"]

View file

@ -131,3 +131,6 @@ func change_theme(ID : int) -> void:
Global.current_project.current_frame = Global.current_project.current_frame
Global.preferences_dialog.get_node("Popups/ShortcutSelector").theme = main_theme
# Sets disabled theme color on palette swatches
Global.palette_panel.reset_empty_palette_swatches_color()

View file

@ -80,7 +80,7 @@ func _on_PreviewDialog_confirmed() -> void:
OpenSave.open_image_as_new_layer(image, path.get_basename().get_file(), frame_index)
elif current_import_option == ImageImportOptions.PALETTE:
Global.palette_container.import_image_palette(path, image)
Palettes.import_palette(path)
elif current_import_option == ImageImportOptions.BRUSH:
add_brush()

View file

@ -19,7 +19,7 @@
[ext_resource path="res://src/UI/ColorAndToolOptions.tscn" type="PackedScene" id=17]
[ext_resource path="res://src/UI/Timeline/AnimationTimeline.tscn" type="PackedScene" id=18]
[ext_resource path="res://src/UI/Canvas/Canvas.tscn" type="PackedScene" id=19]
[ext_resource path="res://src/Palette/PalettePanelContainer.tscn" type="PackedScene" id=20]
[ext_resource path="res://src/Palette/PalettePanel.tscn" type="PackedScene" id=20]
[ext_resource path="res://assets/graphics/dark_themes/tools/zoom.png" type="Texture" id=21]
[ext_resource path="res://assets/graphics/dark_themes/tools/pan.png" type="Texture" id=22]
[ext_resource path="res://src/UI/ViewportContainer.gd" type="Script" id=23]
@ -449,8 +449,10 @@ custom_constants/autohide = 0
[node name="ColorAndToolOptions" parent="RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit" instance=ExtResource( 17 )]
margin_bottom = 248.0
[node name="PalettePanelContainer" parent="RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit" instance=ExtResource( 20 )]
[node name="PalettePanel" parent="RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit" instance=ExtResource( 20 )]
margin_left = 15.0
margin_top = 260.0
margin_right = 315.0
margin_bottom = 508.0
[connection signal="reposition_active_tab_request" from="CanvasAndTimeline/ViewportAndRulers/TabsContainer/Tabs" to="CanvasAndTimeline/ViewportAndRulers/TabsContainer/Tabs" method="_on_Tabs_reposition_active_tab_request"]
[connection signal="tab_changed" from="CanvasAndTimeline/ViewportAndRulers/TabsContainer/Tabs" to="CanvasAndTimeline/ViewportAndRulers/TabsContainer/Tabs" method="_on_Tabs_tab_changed"]