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

Merge pull request #83 from greusser/master

Added Gimp Palette Library (GPL) importer, Palette code updates
This commit is contained in:
Overloaded 2019-12-21 22:05:32 +02:00 committed by GitHub
commit b5ea3303a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 336 additions and 139 deletions

View file

@ -2,15 +2,15 @@
importer="texture"
type="StreamTexture"
path="res://.import/Next_Frame_Hover.png-ba92cf8a5dbcda245610c78c96d6bf93.stex"
path="res://.import/Next_Frame_hover.png-29e3bdc3bfb09dbf24f0d4ef57cdadd0.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Assets/Graphics/Dark Themes/Timeline/Next_Frame_Hover.png"
dest_files=[ "res://.import/Next_Frame_Hover.png-ba92cf8a5dbcda245610c78c96d6bf93.stex" ]
source_file="res://Assets/Graphics/Dark Themes/Timeline/Next_Frame_hover.png"
dest_files=[ "res://.import/Next_Frame_hover.png-29e3bdc3bfb09dbf24f0d4ef57cdadd0.stex" ]
[params]

File diff suppressed because one or more lines are too long

View file

@ -1,11 +1,12 @@
[gd_scene load_steps=6 format=2]
[ext_resource path="res://Scripts/EditPalettePopup.gd" type="Script" id=1]
[ext_resource path="res://Scripts/Palette/EditPalettePopup.gd" type="Script" id=1]
[ext_resource path="res://Assets/Graphics/Palette/new_swatch_button.png" type="Texture" id=2]
[ext_resource path="res://Assets/Graphics/Palette/new_swatch_button_hover.png" type="Texture" id=3]
[ext_resource path="res://Assets/Graphics/Palette/remove_swatch_button.png" type="Texture" id=4]
[ext_resource path="res://Assets/Graphics/Palette/remove_swatch_button_hover.png" type="Texture" id=5]
[node name="EditPalettePopup" type="WindowDialog"]
visible = true
margin_right = 600.0

View file

@ -4,9 +4,10 @@
[ext_resource path="res://Themes & Styles/StyleBoxes/palette_stylebox_pressedr.tres" type="StyleBox" id=2]
[ext_resource path="res://Themes & Styles/StyleBoxes/palette_stylebox_focus.tres" type="StyleBox" id=3]
[ext_resource path="res://Themes & Styles/StyleBoxes/palette_stylebox_normal.tres" type="StyleBox" id=4]
[ext_resource path="res://Scripts/PaletteButton.gd" type="Script" id=5]
[ext_resource path="res://Scripts/Palette/PaletteButton.gd" type="Script" 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"]

53
Scripts/Import.gd Normal file
View file

@ -0,0 +1,53 @@
extends Node
# Declare member variables here. Examples:
# var a = 2
# var b = "text"
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
func import_gpl(path : String) -> Palette:
var result : Palette = null
var file = File.new()
if file.file_exists(path):
file.open(path, File.READ)
var text = file.get_as_text()
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 line != "GIMP Palette":
break
else:
result = Palette.new()
var name_start = path.find_last('/') + 1
var name_end = path.find_last('.')
if name_end > name_start:
result.name = path.substr(name_start, name_end - name_start)
# Comments
if line.begins_with('#'):
comments += line.trim_prefix('#') + '\n'
pass
elif line_number > 0 && line.length() >= 12:
var red : float = line.substr(0, 4).to_float() / 255.0
var green : float = line.substr(4, 4).to_float() / 255.0
var blue : float = line.substr(8, 4).to_float() / 255.0
var name : String = line.substr(12, line.length() - 12)
var color = Color(red, green, blue)
result.add_color(color, name)
line_number += 1
if result:
result.comments = comments
file.close()
return result
# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
# pass

View file

@ -8,8 +8,7 @@ var palette_button = preload("res://Prefabs/PaletteButton.tscn");
var current_palette : String
var current_swatch := -1
var working_palette : Dictionary
var working_palette : Palette
func open(palette : String) -> void:
current_palette = palette
@ -26,7 +25,7 @@ func _display_palette() -> void:
var index := 0
for color_data in working_palette.colors:
var color = Color(color_data.data)
var color = color_data.color
var new_button = palette_button.instance()
new_button.color = color
@ -48,14 +47,12 @@ func _clear_swatches() -> void:
func on_swatch_select(index : int) -> void:
current_swatch = index
color_name_edit.text = working_palette.colors[index].name
color_picker.color = working_palette.colors[index].data
color_name_edit.text = working_palette.get_color_name(index)
color_picker.color = working_palette.get_color(index)
pass
func on_move_swatch(from : int, to : int) -> void:
var color_to_move = working_palette.colors[from]
working_palette.colors.remove(from)
working_palette.colors.insert(to, color_to_move)
working_palette.move_color(from, to)
palette_grid.move_child(palette_grid.get_child(from), to)
@ -68,15 +65,14 @@ func on_move_swatch(from : int, to : int) -> void:
func _on_AddSwatchButton_pressed() -> void:
var color = Color.white
var color_data = {}
color_data.data = color.to_html(true)
color_data.name = "no name"
working_palette.colors.push_back(color_data)
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 = color_data.data.to_upper() + " " + color_data.name
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
@ -87,7 +83,7 @@ func _on_AddSwatchButton_pressed() -> void:
pass # Replace with function body.
func _on_RemoveSwatchButton_pressed() -> void:
working_palette.colors.remove(current_swatch)
working_palette.remove_color(current_swatch)
palette_grid.remove_child(palette_grid.get_child(current_swatch))
pass # Replace with function body.
@ -104,17 +100,17 @@ func _on_EditPaletteCancelButton_pressed() -> void:
func _on_EditPaletteColorNameLineEdit_text_changed(new_text) -> void:
if current_swatch >= 0 && current_swatch < working_palette.colors.size():
working_palette.colors[current_swatch].name = new_text
working_palette.set_color_name(current_swatch, new_text)
_refresh_hint_tooltip(current_swatch)
pass
func _on_EditPaletteColorPicker_color_changed(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.colors[current_swatch].data = color.to_html(true)
working_palette.set_color(current_swatch, color)
_refresh_hint_tooltip(current_swatch)
pass
func _refresh_hint_tooltip(index : int):
palette_grid.get_child(current_swatch).hint_tooltip = working_palette.colors[current_swatch].data.to_upper() + " " + working_palette.colors[current_swatch].name
palette_grid.get_child(current_swatch).hint_tooltip = "#" + working_palette.get_color_data(current_swatch).to_upper() + " " + working_palette.get_color_name(current_swatch)
pass

132
Scripts/Palette/Palette.gd Normal file
View file

@ -0,0 +1,132 @@
extends Reference
class_name Palette
func get_class(): return "Palette"
func is_class(name): return name == "Palette" or .is_class(name)
var name : String = "Custom_Palette"
var colors : Array = []
var comments : String = ""
var editable : bool = true
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)
func add_color(new_color : Color, name : String = "no name") -> void:
var c := PaletteColor.new(new_color, name)
colors.push_back(c)
func remove_color(index : int) -> void:
if index < colors.size():
colors.remove(index)
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
func set_color(index : int, new_color : Color) -> void:
if index < colors.size():
colors[index].color = new_color
func get_color_data(index : int) -> String:
var result := ""
if index < colors.size():
result = colors[index].data
return result
func set_color_data(index : int, new_color : String) -> void:
if index < colors.size():
colors[index].data = new_color
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()
func duplicate() -> Palette:
var copy : Palette = get_script().new()
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,
"colors" : [],
"comments" : comments,
"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
result.comments = data.comments
result.editable = data.editable
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 : Palette = null
var file = File.new()
if file.file_exists(path):
file.open(path, File.READ)
var text : String = file.get_as_text()
result = deserialize(text)
file.close()
return result

View file

@ -0,0 +1,42 @@
extends Reference
class_name PaletteColor
func get_class(): return "PaletteColor"
func is_class(name): return name == "PaletteColor" or .is_class(name)
var color : Color = Color.black setget _set_color
var data : String = "" setget _set_data
var name : String = "no name"
func _init(new_color : Color = Color.black, new_name : String = "no name"):
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 : PaletteColor = get_script().new()
copy.data = data
copy.name = name
return copy

View file

@ -3,7 +3,7 @@ extends GridContainer
const palette_button = preload("res://Prefabs/PaletteButton.tscn");
var current_palette = "Default"
var from_palette : = {}
var from_palette : Palette
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
@ -22,10 +22,9 @@ 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 : Dictionary = Global.palettes[palette_name]
var palette : Palette = Global.palettes[palette_name]
Global.remove_palette_button.disabled = true # Cannot remove by default
if palette.has("editable"):
if palette.editable:
Global.remove_palette_button.disabled = false # Can remove if custom palette
@ -37,7 +36,7 @@ func on_palette_select(palette_name : String) -> void:
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 = {}
from_palette = null
Global.new_palette_dialog.popup_centered()
pass
@ -47,40 +46,33 @@ func on_import_palette() -> void:
func on_palette_import_file_selected(path) -> void:
var file := File.new()
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"):
palette = Import.import_gpl(path)
file.open(path, File.READ)
var text = file.get_as_text()
var result_json = JSON.parse(text)
var result = {}
var palette_name = null # Default error condition
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)
else: # If parse OK
var data = result_json.result
if data.has("name"): #If data is 'valid' palette file
palette_name = data.name
if not Global.palettes.has(palette_name):
Global.palettes[palette_name] = data
Global.palette_option_button.add_item(palette_name)
if palette:
if not Global.palettes.has(palette.name):
Global.palettes[palette.name] = palette
Global.palette_option_button.add_item(palette.name)
var index := Global.palette_option_button.get_item_count() - 1
Global.palette_option_button.set_item_metadata(index, palette_name)
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")
on_palette_select(palette.name)
save_palette(palette.name, palette.name + ".json")
else:
Global.error_dialog.set_text("Palette named '" + palette_name + "' already exists");
Global.error_dialog.set_text("Palette named '" + palette.name + "' already exists");
Global.error_dialog.popup_centered()
else:
Global.error_dialog.set_text("Invalid Palette file!")
Global.error_dialog.popup_centered()
file.close()
pass
func on_edit_palette() -> void:
var palette : Dictionary = Global.palettes[current_palette]
var create_new_palette := true # Create new palette by default
if palette.has("editable"):
if palette.editable:
create_new_palette = false # Edit if already a custom palette
@ -90,7 +82,7 @@ func on_edit_palette() -> void:
Global.new_palette_name_line_edit.text = "Custom_" + current_palette
Global.new_palette_dialog.popup_centered()
else:
from_palette = {}
from_palette = null
Global.edit_palette_popup.open(current_palette)
func on_new_palette_confirmed() -> void:
@ -100,8 +92,8 @@ func on_new_palette_confirmed() -> void:
Global.error_dialog.set_text(result);
Global.error_dialog.popup_centered()
func create_new_palette(name : String, from_palette : Dictionary = {}) -> String: # Returns empty string, else error string
var new_palette : Dictionary = {}
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():
@ -112,14 +104,10 @@ func create_new_palette(name : String, from_palette : Dictionary = {}) -> String
new_palette.name = name
# Check if source palette has data
if from_palette.has("name"):
if from_palette:
new_palette = from_palette.duplicate()
new_palette.name = name
new_palette.editable = true
else:
new_palette.colors = []
new_palette.comments = ""
new_palette.editable = true
# Add palette to Global and options
Global.palettes[name] = new_palette
@ -133,22 +121,22 @@ func create_new_palette(name : String, from_palette : Dictionary = {}) -> String
on_palette_select(name)
return ""
func _display_palette(palette : Dictionary) -> void:
func _display_palette(palette : Palette) -> void:
var index := 0
for color_data in palette.colors:
var color = Color(color_data.data)
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.hint_tooltip = "#" + color_data.data.to_upper() + " " + color_data.name
new_button.connect("pressed", self, "on_color_select", [index])
add_child(new_button)
index += 1
func on_color_select(index : int) -> void:
var color = Color(Global.palettes[current_palette].colors[index].data)
var color : Color = Global.palettes[current_palette].get_color(index)
if Input.is_action_just_released("left_mouse"):
Global.left_color_picker.color = color
@ -173,23 +161,25 @@ func _load_palettes() -> void:
var palette_files : Array = get_palette_files("user://palettes")
for file_name in palette_files:
var result : String = load_palette("user://palettes/" + file_name)
if result:
Global.palette_option_button.add_item(result)
var palette : Palette = Palette.new().load_from_file("user://palettes/" + file_name)
if palette:
Global.palettes[palette.name] = palette
Global.palette_option_button.add_item(palette.name)
var index := Global.palette_option_button.get_item_count() - 1
Global.palette_option_button.set_item_metadata(index, result)
if result == "Default":
Global.palette_option_button.set_item_metadata(index, palette.name)
if palette.name == "Default":
Global.palette_option_button.select(index)
dir.open("user://palettes/custom")
var custom_palette_files : Array = get_palette_files("user://palettes/custom")
for file_name in custom_palette_files:
var result : String = load_palette("user://palettes/custom/" + file_name)
if result:
Global.palette_option_button.add_item(result)
var palette : Palette = Palette.new().load_from_file("user://palettes/custom/" + file_name)
if palette:
Global.palettes[palette.name] = palette
Global.palette_option_button.add_item(palette.name)
var index := Global.palette_option_button.get_item_count() - 1
Global.palette_option_button.set_item_metadata(index, result)
Global.palette_option_button.set_item_metadata(index, palette.name)
func get_palette_files(path : String) -> Array:
var dir := Directory.new()
@ -209,33 +199,7 @@ func get_palette_files(path : String) -> Array:
return results
func load_palette(path : String) -> String:
# Open file for reading
var file := File.new()
file.open(path, File.READ)
var text = file.get_as_text()
var result_json = JSON.parse(text)
var result = {}
var palette_name = null # Default error condition
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)
else: # If parse OK
var data = result_json.result
if data.has("name"): #If data is 'valid' palette file
palette_name = data.name
Global.palettes[data.name] = data
file.close()
return palette_name
func remove_current_palette() -> void:
if Global.palettes[current_palette].has("editable"):
if Global.palettes[current_palette].editable:
_delete_palette_file(current_palette + ".json")
Global.palettes.erase(current_palette)
@ -251,11 +215,6 @@ func _delete_palette_file(file_name : String) -> void:
dir.remove("user://palettes/custom/" + file_name)
func save_palette(palette_name : String, filename : String) -> void:
var palette_data = Global.palettes[palette_name]
# Open file for writing
var file := File.new()
file.open("user://palettes/custom/" + filename, File.WRITE)
var palette = Global.palettes[palette_name]
# Write palette data to file
file.store_string(JSON.print(palette_data))
file.close()
palette.save_to_file("user://palettes/custom/" + filename)

View file

@ -23,11 +23,23 @@ _global_script_classes=[ {
"class": "LayerContainer",
"language": "GDScript",
"path": "res://Scripts/LayerContainer.gd"
}, {
"base": "Reference",
"class": "Palette",
"language": "GDScript",
"path": "res://Scripts/Palette/Palette.gd"
}, {
"base": "Reference",
"class": "PaletteColor",
"language": "GDScript",
"path": "res://Scripts/Palette/PaletteColor.gd"
} ]
_global_script_class_icons={
"Canvas": "",
"Guide": "",
"LayerContainer": ""
"LayerContainer": "",
"Palette": "",
"PaletteColor": ""
}
[application]
@ -43,6 +55,7 @@ config/Version="v0.5"
[autoload]
Global="*res://Scripts/Global.gd"
Import="*res://Scripts/Import.gd"
[debug]
@ -198,7 +211,7 @@ redo_secondary={
[locale]
translations=PoolStringArray( "res://Translations/#Translations.en.translation", "res://Translations/#Translations.el.translation", "res://Translations/#Translations.fr.translation", "res://Translations/#Translations.de.translation", "res://Translations/#Translations.pl.translation", "res://Translations/#Translations.ru.translation", "res://Translations/#Translations.zh_TW.translation", "res://Translations/#Translations.pt_BR.translation" )
translations=PoolStringArray( "res://Translations/#Translations.en.translation", "res://Translations/#Translations.el.translation", "res://Translations/#Translations.fr.translation", "res://Translations/#Translations.de.translation", "res://Translations/#Translations.pl.translation", "res://Translations/#Translations.ru.translation", "res://Translations/#Translations.zh_TW.translation" )
locale_filter=[ 0, [ ] ]
[rendering]