Added the color-palette plugin from the AssetLib.

This commit is contained in:
Relintai 2021-10-01 10:17:08 +02:00
parent bc1c8b2718
commit 88caf0d31f
28 changed files with 13195 additions and 3 deletions

View File

@ -13,5 +13,7 @@
!multirun/** !multirun/**
!mat_maker_gd !mat_maker_gd
!mat_maker_gd/** !mat_maker_gd/**
!color-palette
!color-palette/**
!addon_versions !addon_versions

View File

@ -0,0 +1,127 @@
tool
extends PanelContainer
signal palette_updated
signal palette_color_selected(palette, color_index)
signal palette_color_deleted(palette, color_index)
signal container_selected(container_object)
onready var btn_load_to_picker = $MarginContainer/VBoxContainer/HBoxContainer/BtnLoadToPicker
onready var btn_update_from_picker = $MarginContainer/VBoxContainer/HBoxContainer/BtnUpdateFromPicker
onready var name_label = $MarginContainer/VBoxContainer/HBoxContainer/PaletteName
onready var grid = $MarginContainer/VBoxContainer/PaletteTileContainer/TileContainer
var palette: Palette
var undoredo: UndoRedo
var selected: bool = false setget set_selected
func _ready():
btn_load_to_picker.connect("pressed", self, "load_to_picker")
btn_update_from_picker.connect("pressed", self, "update_from_picker")
grid.connect("grid_item_reordered", self, "_grid_item_reordered")
# Base settings for all color rects are set in the color tile class
var cr = ColorTile.new()
if palette:
name_label.text = palette.name
name_label.hint_tooltip = palette.comments
for c in palette.colors:
# Color rect instance properties
var cri = cr.duplicate()
cri.color = c
cri.connect("tile_selected", self, "_on_tile_selected")
cri.connect("tile_deleted", self, "_on_tile_deleted")
grid.add_child(cri)
func load_to_picker():
var new_picker_presets: PoolColorArray
for c in palette.colors:
new_picker_presets.append(c)
# Hack?
var ep = EditorPlugin.new()
ep.get_editor_interface() \
.get_editor_settings() \
.set_project_metadata("color_picker", "presets", new_picker_presets)
ep.free()
func update_from_picker():
var ep = EditorPlugin.new()
var colors: PoolColorArray = ep.get_editor_interface() \
.get_editor_settings() \
.get_project_metadata("color_picker", "presets")
palette.colors.clear()
for c in colors:
palette.add_color(c)
palette.save()
ep.free()
emit_signal("palette_updated")
func _grid_item_reordered(p_index_from: int, p_index_to: int) -> void:
undoredo.create_action("Reorder Palette %s" % palette.name)
# To do, move from "from" to "to"
undoredo.add_do_method(palette, "reorder_color", p_index_from, p_index_to)
undoredo.add_do_method(palette, "save")
undoredo.add_do_method(self, "emit_signal", "palette_updated")
undoredo.add_do_method(self, "emit_signal", "palette_color_selected", palette, p_index_to)
# To undo, just reverse the positions!
undoredo.add_undo_method(palette, "reorder_color", p_index_to, p_index_from)
undoredo.add_undo_method(palette, "save")
undoredo.add_undo_method(self, "emit_signal", "palette_updated")
undoredo.add_undo_method(self, "emit_signal", "palette_color_selected", palette, p_index_from)
undoredo.commit_action()
# Bubble the event up the tree
func _on_tile_selected(index):
emit_signal("palette_color_selected", palette, index)
func _on_tile_deleted(index):
var original_color = palette.colors[index]
undoredo.create_action("Delete Color %s from Palette %s" % [original_color.to_html(), palette.name])
# To do, move from "from" to "to"
undoredo.add_do_method(palette, "remove_color", index)
undoredo.add_do_method(palette, "save")
undoredo.add_do_method(self, "emit_signal", "palette_updated")
# To undo, just reverse the positions!
undoredo.add_undo_method(palette, "add_color", original_color, index)
undoredo.add_undo_method(palette, "save")
undoredo.add_undo_method(self, "emit_signal", "palette_updated")
undoredo.commit_action()
func set_selected(value: bool) -> void:
selected = value
if selected:
var sb: StyleBoxFlat = get_stylebox("panel").duplicate()
sb.bg_color = Color("#2c3141")
add_stylebox_override("panel", sb)
emit_signal("container_selected", self)
else:
var sb: StyleBoxFlat = get_stylebox("panel").duplicate()
sb.bg_color = Color(0.15, 0.17, 0.23)
add_stylebox_override("panel", sb)
func _gui_input(event):
if (event is InputEventMouseButton and
event.get_button_index() == 1 and
event.is_pressed()):
self.selected = true

View File

@ -0,0 +1,96 @@
[gd_scene load_steps=5 format=2]
[ext_resource path="res://addons/color-palette/TileContainer.gd" type="Script" id=1]
[ext_resource path="res://addons/color-palette/utilities/EditorTheme.tres" type="Theme" id=2]
[ext_resource path="res://addons/color-palette/ColorPaletteContainer.gd" type="Script" id=4]
[sub_resource type="StyleBoxFlat" id=1]
bg_color = Color( 0.14902, 0.172549, 0.231373, 1 )
border_width_left = 1
border_width_top = 1
border_width_right = 1
border_width_bottom = 1
border_color = Color( 0.0980392, 0.113725, 0.152941, 1 )
[node name="ColorPaletteContainer" type="PanelContainer"]
margin_right = 494.0
margin_bottom = 152.0
theme = ExtResource( 2 )
custom_styles/panel = SubResource( 1 )
script = ExtResource( 4 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="MarginContainer" type="MarginContainer" parent="."]
margin_left = 1.0
margin_top = 1.0
margin_right = 493.0
margin_bottom = 151.0
mouse_filter = 1
custom_constants/margin_right = 3
custom_constants/margin_top = 3
custom_constants/margin_left = 3
custom_constants/margin_bottom = 3
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"]
margin_left = 3.0
margin_top = 3.0
margin_right = 489.0
margin_bottom = 147.0
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer"]
margin_right = 486.0
margin_bottom = 22.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="PaletteName" type="Label" parent="MarginContainer/VBoxContainer/HBoxContainer"]
margin_right = 95.0
margin_bottom = 22.0
custom_colors/font_color = Color( 0.576471, 0.576471, 0.576471, 1 )
text = "Palette Name"
[node name="Spacer" type="Control" parent="MarginContainer/VBoxContainer/HBoxContainer"]
margin_left = 99.0
margin_right = 226.0
margin_bottom = 22.0
mouse_filter = 1
size_flags_horizontal = 3
__meta__ = {
"_edit_use_anchors_": false
}
[node name="BtnLoadToPicker" type="Button" parent="MarginContainer/VBoxContainer/HBoxContainer"]
margin_left = 230.0
margin_right = 344.0
margin_bottom = 22.0
hint_tooltip = "Loads the palette into the Color Picker presets (in your editor settings) so you can use these colors in all color selection dialogs."
text = "Load into Picker"
[node name="BtnUpdateFromPicker" type="Button" parent="MarginContainer/VBoxContainer/HBoxContainer"]
margin_left = 348.0
margin_right = 486.0
margin_bottom = 22.0
hint_tooltip = "Replaces the palette colors with whatever you have in your color picker presets."
custom_colors/font_color_disabled = Color( 0, 0, 0, 1 )
text = "Update From Picker"
[node name="HSeparator" type="HSeparator" parent="MarginContainer/VBoxContainer"]
margin_top = 26.0
margin_right = 486.0
margin_bottom = 26.0
mouse_filter = 1
custom_constants/separation = 0
[node name="PaletteTileContainer" type="MarginContainer" parent="MarginContainer/VBoxContainer"]
margin_top = 30.0
margin_right = 486.0
margin_bottom = 30.0
mouse_filter = 1
[node name="TileContainer" type="Container" parent="MarginContainer/VBoxContainer/PaletteTileContainer"]
margin_right = 486.0
mouse_filter = 1
script = ExtResource( 1 )

View File

@ -0,0 +1,127 @@
tool
extends MarginContainer
# Palette list
onready var refresh_list_button = $HBoxContainer/ColorPaletteContainer/OptionsContainer/RefreshList
onready var palette_list = $HBoxContainer/ColorPaletteContainer/PaletteListScroll/PaletteList
# Options
onready var palette_dir_le = $HBoxContainer/ColorPaletteContainer/OptionsContainer/PaletteDirectory
onready var new_palette_name_le = $HBoxContainer/ColorPaletteContainer/OptionsContainer/NewPaletteName
onready var new_palette_button = $HBoxContainer/ColorPaletteContainer/OptionsContainer/NewPalette
onready var open_palette_dir_button = $HBoxContainer/ColorPaletteContainer/OptionsContainer/OpenPaletteDirectory
# Color Editor
onready var color_picker = $HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer/ColorPicker
onready var color_preview_rect = $HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer/HBoxContainer/SelectedColorRect
onready var color_preview_label = $HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer/SelectedColorLabel
onready var apply_color_changed_button = $HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer/HBoxContainer/ApplyChanges
onready var new_color_rect = $HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer/HBoxContainer/NewColorRect
onready var new_color_button = $HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer/HBoxContainer/AddNewColor
var palette_container = preload("res://addons/color-palette/ColorPaletteContainer.tscn")
var palettes: Array # of Palette
var undoredo: UndoRedo # passed from EditorPlugin
var selected_palette: Palette
var selected_color_index: int
func _ready():
refresh_palettes()
refresh_list_button.connect("pressed", self, "refresh_palettes")
apply_color_changed_button.connect("pressed", self, "_apply_new_color_to_selected_palette")
new_palette_button.connect("pressed", self, "_create_new_palette")
color_picker.connect("color_changed", new_color_rect, "set_frame_color")
new_color_button.connect("pressed", self, "_add_color_to_selected_palette")
open_palette_dir_button.connect("pressed", self, "_open_dir_in_file_manager")
# Clear the palette list, load the gpl files and populate the list again
func refresh_palettes():
palettes.clear()
for plc in palette_list.get_children():
palette_list.remove_child(plc)
# Ensure trailing slash
if not palette_dir_le.text.ends_with("/"):
palette_dir_le.text += "/"
var gpl_files = PaletteImporter.get_gpl_files(palette_dir_le.text)
for i in gpl_files:
palettes.append(PaletteImporter.import_gpl(i))
for p in palettes:
var pc = palette_container.instance()
pc.palette = p
pc.undoredo = undoredo
if selected_palette:
pc.selected = true if pc.palette.name == selected_palette.name else false
pc.connect("palette_updated", self, "refresh_palettes")
pc.connect("palette_color_selected", self, "_on_palette_color_selected")
pc.connect("container_selected", self, "_on_palette_container_selected")
palette_list.add_child(pc)
func _on_palette_color_selected(palette: Palette, index: int):
color_preview_label.text = ("%s (Color #%s)" % [palette.name, index+1])
color_preview_rect.color = palette.colors[index]
color_picker.color = palette.colors[index]
new_color_rect.color = palette.colors[index]
selected_palette = palette
selected_color_index = index
func _apply_new_color_to_selected_palette() -> void:
# Check that we can actually apply before doing so
var size = selected_palette.colors.size()
if size == 0 or selected_color_index >= size:
return
var new_color = color_picker.color
var original_color = selected_palette.colors[selected_color_index]
undoredo.create_action("Change Palette Color")
undoredo.add_do_method(selected_palette, "change_color", selected_color_index, new_color)
undoredo.add_do_method(selected_palette, "save")
undoredo.add_do_method(self, "refresh_palettes")
undoredo.add_undo_method(selected_palette, "change_color", selected_color_index, original_color)
undoredo.add_undo_method(selected_palette, "save")
undoredo.add_undo_method(self, "refresh_palettes")
undoredo.commit_action()
func _create_new_palette() -> void:
if new_palette_name_le.text.strip_edges().length() > 0:
var palette = Palette.new()
palette.path = palette_dir_le.text + new_palette_name_le.text + ".gpl"
palette.save()
refresh_palettes()
else:
push_error("Name cannot be blank")
func _on_palette_container_selected(container: Control) -> void:
for pc in palette_list.get_children():
if pc != container:
pc.selected = false
selected_palette = container.palette
selected_color_index = 0
color_preview_label.text = ("%s (No Color Selected)" % selected_palette.name)
func _add_color_to_selected_palette() -> void:
if selected_palette != null:
selected_palette.add_color(color_picker.color)
selected_palette.save()
refresh_palettes()
func _open_dir_in_file_manager():
var dir := Directory.new()
var path = ProjectSettings.globalize_path(palette_dir_le.text)
if dir.dir_exists(path):
OS.shell_open(path)
else:
push_error("Invalid directory.")

View File

@ -0,0 +1,214 @@
[gd_scene load_steps=8 format=2]
[ext_resource path="res://addons/color-palette/utilities/EditorTheme.tres" type="Theme" id=1]
[ext_resource path="res://addons/color-palette/ColorPaletteManager.gd" type="Script" id=2]
[ext_resource path="res://addons/color-palette/icons/Add.svg" type="Texture" id=3]
[ext_resource path="res://addons/color-palette/icons/Reload.svg" type="Texture" id=4]
[ext_resource path="res://addons/color-palette/icons/Override.svg" type="Texture" id=5]
[ext_resource path="res://addons/color-palette/icons/Filesystem.svg" type="Texture" id=6]
[sub_resource type="StyleBoxFlat" id=1]
bg_color = Color( 0.180392, 0.207843, 0.278431, 1 )
border_width_left = 1
border_width_top = 1
border_width_right = 1
border_width_bottom = 1
border_color = Color( 0.137255, 0.160784, 0.215686, 1 )
[node name="ColorPaletteManager" type="MarginContainer"]
anchor_right = 1.0
anchor_bottom = 1.0
rect_min_size = Vector2( 0, 340 )
theme = ExtResource( 1 )
custom_constants/margin_right = 5
custom_constants/margin_top = 5
custom_constants/margin_left = 5
custom_constants/margin_bottom = 5
script = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="HBoxContainer" type="HBoxContainer" parent="."]
margin_left = 5.0
margin_top = 5.0
margin_right = 1019.0
margin_bottom = 595.0
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="ColorPaletteContainer" type="VBoxContainer" parent="HBoxContainer"]
margin_right = 695.0
margin_bottom = 590.0
size_flags_horizontal = 3
[node name="OptionsContainer" type="HBoxContainer" parent="HBoxContainer/ColorPaletteContainer"]
margin_right = 695.0
margin_bottom = 24.0
[node name="Title" type="Label" parent="HBoxContainer/ColorPaletteContainer/OptionsContainer"]
margin_top = 1.0
margin_right = 116.0
margin_bottom = 23.0
text = "Palette Directory"
[node name="PaletteDirectory" type="LineEdit" parent="HBoxContainer/ColorPaletteContainer/OptionsContainer"]
margin_left = 120.0
margin_right = 420.0
margin_bottom = 24.0
rect_min_size = Vector2( 300, 0 )
text = "res://addons/color-palette/_palettes/"
placeholder_text = "Palette Directory"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="OpenPaletteDirectory" type="Button" parent="HBoxContainer/ColorPaletteContainer/OptionsContainer"]
margin_left = 424.0
margin_right = 452.0
margin_bottom = 24.0
hint_tooltip = "Open directory in the File Manager"
custom_colors/font_color_disabled = Color( 0.180392, 0.207843, 0.278431, 1 )
icon = ExtResource( 6 )
[node name="Spacer" type="Control" parent="HBoxContainer/ColorPaletteContainer/OptionsContainer"]
margin_left = 456.0
margin_right = 477.0
margin_bottom = 24.0
size_flags_horizontal = 3
__meta__ = {
"_edit_use_anchors_": false
}
[node name="NewPaletteName" type="LineEdit" parent="HBoxContainer/ColorPaletteContainer/OptionsContainer"]
margin_left = 481.0
margin_right = 631.0
margin_bottom = 24.0
rect_min_size = Vector2( 150, 0 )
placeholder_text = "New Palette Name"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="NewPalette" type="Button" parent="HBoxContainer/ColorPaletteContainer/OptionsContainer"]
margin_left = 635.0
margin_right = 663.0
margin_bottom = 24.0
hint_tooltip = "Add new palette (creates new .gpl file on disk)"
custom_colors/font_color_disabled = Color( 0.180392, 0.207843, 0.278431, 1 )
icon = ExtResource( 3 )
[node name="RefreshList" type="Button" parent="HBoxContainer/ColorPaletteContainer/OptionsContainer"]
margin_left = 667.0
margin_right = 695.0
margin_bottom = 24.0
hint_tooltip = "Reload/Refresh list"
custom_colors/font_color_disabled = Color( 0.180392, 0.207843, 0.278431, 1 )
icon = ExtResource( 4 )
[node name="PaletteListScroll" type="ScrollContainer" parent="HBoxContainer/ColorPaletteContainer"]
margin_top = 28.0
margin_right = 695.0
margin_bottom = 590.0
size_flags_horizontal = 3
size_flags_vertical = 3
scroll_horizontal_enabled = false
[node name="PaletteList" type="VBoxContainer" parent="HBoxContainer/ColorPaletteContainer/PaletteListScroll"]
margin_right = 695.0
margin_bottom = 562.0
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="ColorEditorContainer" type="PanelContainer" parent="HBoxContainer"]
margin_left = 699.0
margin_right = 1014.0
margin_bottom = 590.0
rect_min_size = Vector2( 315, 0 )
size_flags_vertical = 3
custom_styles/panel = SubResource( 1 )
[node name="Margin" type="MarginContainer" parent="HBoxContainer/ColorEditorContainer"]
margin_left = 1.0
margin_top = 1.0
margin_right = 314.0
margin_bottom = 589.0
custom_constants/margin_right = 5
custom_constants/margin_top = 5
custom_constants/margin_left = 5
custom_constants/margin_bottom = 5
[node name="Scroll" type="ScrollContainer" parent="HBoxContainer/ColorEditorContainer/Margin"]
margin_left = 5.0
margin_top = 5.0
margin_right = 308.0
margin_bottom = 583.0
[node name="ColorPickerContainer" type="VBoxContainer" parent="HBoxContainer/ColorEditorContainer/Margin/Scroll"]
margin_right = 290.0
margin_bottom = 492.0
[node name="SelectedColorLabel" type="Label" parent="HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer"]
margin_right = 290.0
margin_bottom = 22.0
text = "Select a palette or color..."
autowrap = true
[node name="HBoxContainer" type="HBoxContainer" parent="HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer"]
margin_top = 26.0
margin_right = 290.0
margin_bottom = 50.0
[node name="SelectedColorRect" type="ColorRect" parent="HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer/HBoxContainer"]
margin_right = 99.0
margin_bottom = 24.0
rect_min_size = Vector2( 50, 0 )
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="Label" type="Label" parent="HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer/HBoxContainer"]
margin_left = 103.0
margin_top = 1.0
margin_right = 119.0
margin_bottom = 23.0
rect_min_size = Vector2( 16, 0 )
text = ">"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="NewColorRect" type="ColorRect" parent="HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer/HBoxContainer"]
margin_left = 123.0
margin_right = 222.0
margin_bottom = 24.0
rect_min_size = Vector2( 50, 0 )
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="ApplyChanges" type="ToolButton" parent="HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer/HBoxContainer"]
margin_left = 226.0
margin_right = 256.0
margin_bottom = 24.0
rect_min_size = Vector2( 30, 0 )
hint_tooltip = "Replace/Override the existing color with the selected color."
theme = ExtResource( 1 )
icon = ExtResource( 5 )
[node name="AddNewColor" type="ToolButton" parent="HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer/HBoxContainer"]
margin_left = 260.0
margin_right = 290.0
margin_bottom = 24.0
rect_min_size = Vector2( 30, 0 )
hint_tooltip = "Add the selected color to the palette"
theme = ExtResource( 1 )
icon = ExtResource( 3 )
[node name="ColorPicker" type="ColorPicker" parent="HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer"]
margin_top = 54.0
margin_right = 290.0
margin_bottom = 492.0
presets_enabled = false
presets_visible = false
__meta__ = {
"_edit_use_anchors_": false
}

View File

@ -0,0 +1,28 @@
tool
class_name ColorTile
extends ColorRect
signal tile_deleted(index)
signal tile_selected(index)
onready var parent = get_parent()
var dragging: bool = false
func _ready():
rect_min_size = Vector2(30,30)
mouse_filter = MOUSE_FILTER_PASS
func _gui_input(event):
if event is InputEventMouseButton:
if event.button_index == BUTTON_LEFT and event.is_pressed():
parent.dragging = self
parent.drag_start_index = get_index()
emit_signal("tile_selected", get_index())
accept_event()
return
if event.button_index == BUTTON_RIGHT and event.is_pressed():
emit_signal("tile_deleted", get_index())
accept_event()
return

View File

@ -0,0 +1,6 @@
tool
extends GridContainer
func _get_minimum_size():
return Vector2.ZERO

View File

@ -0,0 +1,63 @@
tool
class_name Palette
extends Reference
var name: String = "Palette"
var colors: Array = [] # of Color
var comments: String = ""
var path: String = ""
func add_color(p_color : Color, p_index: int = -1) -> void:
if p_index != -1:
colors.insert(p_index, p_color)
else:
colors.append(p_color)
func change_color(p_index: int, p_color: Color) -> void:
colors[p_index] = p_color
func reorder_color(p_index_from: int, p_index_to: int):
if p_index_from == p_index_to:
return
var moving_color = colors[p_index_from]
if p_index_from < p_index_to:
colors.remove(p_index_from)
colors.insert(p_index_to, moving_color)
if p_index_from > p_index_to:
colors.remove(p_index_from)
colors.insert(p_index_to, moving_color)
func remove_color(p_index: int):
colors.remove(p_index)
func save():
if path.ends_with(".gpl") == false:
push_error("To export gpl, file name must end in .gpl")
return
var file = File.new()
file.open(path, file.WRITE)
file.store_line("GIMP Palette")
var comment_lines = comments.split("\n")
for cl in comment_lines:
file.store_line("# " + cl)
for c in colors:
var color_data = [
str(c.r8),
str(c.g8),
str(c.b8),
"Untitled"
]
var line = PoolStringArray(color_data).join(" ")
file.store_line(line)
file.close()

View File

@ -0,0 +1,26 @@
# NOT USED
# Currently not used in order to simplify the addon
# May be used at a later date
#tool
#class_name PaletteColor
#extends Reference
#
#var color: Color = Color.black setget _set_color
#var data: String = "" setget _set_data
#var name: String = "Untitled"
#
#func _init(p_color: Color, p_name: String):
# self.color = p_color
# self.name = p_name
#
#
#func _set_color(p_color):
# color = p_color
# data = color.to_html(true)
#
#
#func _set_data(p_data):
# data = p_data
# color = Color(p_data)

View File

@ -0,0 +1,73 @@
tool
class_name PaletteImporter
extends Reference
# Adapted from Github -> Orama-Interactive/Pixelorama/src/Autoload/Import.gd
static func import_gpl(path : String) -> Palette:
var color_line_regex = RegEx.new()
color_line_regex.compile("(?<red>[0-9]{1,3})[ \t]+(?<green>[0-9]{1,3})[ \t]+(?<blue>[0-9]{1,3})")
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:
line = line.lstrip(" ")
# Check if valid Gimp Palette Library file
if line_number == 0:
if line != "GIMP Palette":
push_error("File \"%s\" is not a valid GIMP Palette." % path)
break
else:
result = Palette.new()
result.path = path
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
elif line.begins_with('#'):
comments += line.trim_prefix('#') + '\n'
elif not line.empty():
var matches = color_line_regex.search(line)
if matches:
var red: float = matches.get_string("red").to_float() / 255.0
var green: float = matches.get_string("green").to_float() / 255.0
var blue: float = matches.get_string("blue").to_float() / 255.0
var color = Color(red, green, blue)
result.add_color(color)
else:
push_error("Unable to parse line %s with content: %s" % [line_number + 1, line])
line_number += 1
if result:
result.comments = comments
file.close()
else:
push_error("File \"%s\" does not exist." % path)
return result
# Get all gpl files in a path
static func get_gpl_files(path) -> Array:
var files = []
var dir = Directory.new()
if dir.open(path) == OK:
dir.list_dir_begin()
var file_name = dir.get_next()
while file_name != "":
if !dir.current_is_dir() and file_name.ends_with(".gpl"):
files.append(path + file_name)
file_name = dir.get_next()
else:
print("An error occurred when trying to access the color palette path")
return files

View File

@ -0,0 +1,28 @@
tool
extends FlexGridContainer
signal grid_item_reordered(index_from, index_to)
var dragging: ColorRect = null
var drag_start_index = -1
func _gui_input(event):
if event is InputEventMouseMotion and dragging != null:
# Move the color rect as the user drags it for a live preview
var mp = event.position
for c in get_children():
c = c as ColorRect
if c.get_rect().has_point(mp):
move_child(dragging, c.get_index())
# When dragging finished
if (event is InputEventMouseButton and
dragging != null and
event.get_button_index() == 1 and
event.is_pressed() == false):
emit_signal("grid_item_reordered",
drag_start_index,
dragging.get_index())
dragging = null

View File

@ -0,0 +1,11 @@
GIMP Palette
#
#
#
#
#
255 255 255 Untitled
0 41 255 Untitled
255 0 0 Untitled
255 143 0 Untitled
0 183 255 Untitled

View File

@ -0,0 +1 @@
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v6h-6v2h6v6h2v-6h6v-2h-6v-6z" fill="#e0e0e0"/></svg>

After

Width:  |  Height:  |  Size: 148 B

View File

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

View File

@ -0,0 +1 @@
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v5h2v8h1 5v1h6v-3h-6v1h-5v-4h5v1h6v-3h-6v1h-5v-2h3v-4h-2l-1-1z" fill="#e0e0e0"/></svg>

After

Width:  |  Height:  |  Size: 182 B

View File

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

View File

@ -0,0 +1 @@
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 1c-1.108 0-2 .89199-2 2v1h4v-1h2v1h4v-1c0-1.108-.89199-2-2-2zm-2 5c-1.108 0-2 .89199-2 2v5c0 1.108.89199 2 2 2h10c1.108 0 2-.89199 2-2v-5c0-1.108-.89199-2-2-2h-4v3h2l-3 4-3-4h2v-3z" fill="#e0e0e0"/></svg>

After

Width:  |  Height:  |  Size: 299 B

View File

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

View File

@ -0,0 +1 @@
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" fill-opacity=".99608" transform="translate(0 -1036.4)"><path d="m9 2a6 6 0 0 0 -6 6h2a4 4 0 0 1 4-4 4 4 0 0 1 4 4 4 4 0 0 1 -4 4v2a6 6 0 0 0 6-6 6 6 0 0 0 -6-6z" transform="translate(0 1036.4)"/><path d="m4.118 1048.3-1.6771-.9683-1.6771-.9682 1.6771-.9683 1.6771-.9682-.0000001 1.9365z" transform="matrix(0 -1.1926 1.5492 0 -1617 1049.3)"/></g></svg>

After

Width:  |  Height:  |  Size: 452 B

View File

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

View File

@ -0,0 +1,7 @@
[plugin]
name="ColorPalette"
description="Color palette manager for Godot"
author="EricEzaM"
version="1.0"
script="plugin.gd"

View File

@ -0,0 +1,14 @@
tool
extends EditorPlugin
var cpm
func _enter_tree():
cpm = preload("res://addons/color-palette/ColorPaletteManager.tscn").instance()
cpm.undoredo = get_undo_redo()
add_control_to_bottom_panel(cpm, "Color Palette")
func _exit_tree():
remove_control_from_bottom_panel(cpm)
cpm.free()

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,178 @@
tool
class_name FlexGridContainer, "res://addons/color-palette/utilities/FlexGridContainerIcon.png"
extends Container
var columns: int = 1 setget set_columns
func _notification(p_what):
match p_what:
NOTIFICATION_SORT_CHILDREN:
var col_minw: Dictionary # Max of min_width of all controls in each col (indexed by col).
var row_minh: Dictionary # Max of min_height of all controls in each row (indexed by row).
var col_expanded: Array # Columns which have the SIZE_EXPAND flag set.
var row_expanded: Array # Rows which have the SIZE_EXPAND flag set.
var hsep = get_constant("hseparation", "GridContainer")
var vsep = get_constant("vseparation", "GridContainer")
var min_columns = 1
if get_child_count() > 0:
min_columns = int(floor(rect_size.x / (get_child(0).get_combined_minimum_size().x + hsep)))
self.columns = min_columns
var max_col = min(get_child_count(), columns)
var max_row = ceil(float(get_child_count()) / float(columns))
# Compute the per-column/per-row data.
var valid_controls_index = 0
for i in range(get_child_count()):
var c: Control = get_child(i)
if !c or !c.is_visible_in_tree():
continue
var row = valid_controls_index / columns
var col = valid_controls_index % columns
valid_controls_index += 1
var ms: Vector2 = c.get_combined_minimum_size()
if col_minw.has(col):
col_minw[col] = max(col_minw[col], ms.x)
else:
col_minw[col] = ms.x
if row_minh.has(row):
row_minh[row] = max(row_minh[row], ms.y)
else:
row_minh[row] = ms.y
if c.get_h_size_flags() & SIZE_EXPAND:
col_expanded.push_front(col)
if c.get_v_size_flags() & SIZE_EXPAND:
row_expanded.push_front(row)
# Consider all empty columns expanded.
for i in range(valid_controls_index, columns):
col_expanded.push_front(i)
# Evaluate the remaining space for expanded columns/rows.
var remaining_space: Vector2 = get_size()
for e in col_minw.keys():
if !col_expanded.has(e):
remaining_space.x -= col_minw.get(e)
for e in row_minh.keys():
if !row_expanded.has(e):
remaining_space.y -= row_minh.get(e)
remaining_space.y -= vsep * max(max_row - 1, 0)
remaining_space.x -= hsep * max(max_col - 1, 0)
var can_fit = false
while !can_fit && col_expanded.size() > 0:
# Check if all minwidth constraints are OK if we use the remaining space.
can_fit = true
var max_index = col_expanded.front()
for e in col_expanded:
if col_minw.has(e):
if col_minw[e] > col_minw[max_index]:
max_index = e
if can_fit && (remaining_space.x / col_expanded.size()) < col_minw[e]:
can_fit = false
# If not, the column with maximum minwidth is not expanded.
if (!can_fit):
col_expanded.erase(max_index)
remaining_space.x -= col_minw[max_index]
can_fit = false
while !can_fit && row_expanded.size() > 0:
# Check if all minheight constraints are OK if we use the remaining space.
can_fit = true
var max_index = row_expanded.front()
for e in row_expanded:
if row_minh[e] > row_minh[max_index]:
max_index = e
if can_fit && (remaining_space.y / row_expanded.size()) < row_minh[e]:
can_fit = false
# If not, the row with maximum minheight is not expanded.
if (!can_fit):
row_expanded.erase(max_index)
remaining_space.y -= row_minh[max_index]
# Finally, fit the nodes.
var col_expand = remaining_space.x / col_expanded.size() if col_expanded.size() > 0 else 0
var row_expand = remaining_space.y / row_expanded.size() if row_expanded.size() > 0 else 0
var col_ofs = 0
var row_ofs = 0
valid_controls_index = 0
for i in range(get_child_count()):
var c: Control = get_child(i)
if (!c || !c.is_visible_in_tree()):
continue
var row = valid_controls_index / columns
var col = valid_controls_index % columns
valid_controls_index += 1
if (col == 0):
col_ofs = 0
if (row > 0):
row_ofs += (row_expand if row_expanded.has(row - 1) else row_minh[row - 1]) + vsep
var p = Vector2(col_ofs, row_ofs)
var s = Vector2(col_expand if col_expanded.has(col) else col_minw[col], row_expand if row_expanded.has(row) else row_minh[row])
fit_child_in_rect(c, Rect2(p, s))
col_ofs += s.x + hsep
NOTIFICATION_THEME_CHANGED:
minimum_size_changed()
func _get_minimum_size():
# Only worry about max height, not width (since it does width automatically)
var row_minh: Dictionary
var vsep = get_constant("vseparation", "GridContainer")
var max_row = 0
var valid_controls_index = 0
for i in range(get_child_count()):
var c: Control = get_child(i)
if !c or !c.is_visible():
continue
var row = valid_controls_index / columns
valid_controls_index += 1
var ms = c.get_combined_minimum_size()
if row_minh.has(row):
row_minh[row] = max(row_minh[row], ms.y)
else:
row_minh[row] = ms.y
max_row = max(row, max_row)
var ms: Vector2
for e in row_minh.keys():
ms.y += row_minh.get(e)
ms.y += vsep * max_row
return ms
func set_columns(p_columns: int):
columns = p_columns
minimum_size_changed()

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

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

File diff suppressed because one or more lines are too long

View File

@ -24,6 +24,11 @@ _global_script_classes=[ {
"language": "GDScript", "language": "GDScript",
"path": "res://player/CharacterSkeletonAttachPoint.gd" "path": "res://player/CharacterSkeletonAttachPoint.gd"
}, { }, {
"base": "ColorRect",
"class": "ColorTile",
"language": "GDScript",
"path": "res://addons/color-palette/ColorTile.gd"
}, {
"base": "Entity", "base": "Entity",
"class": "DisplayPlayerGD", "class": "DisplayPlayerGD",
"language": "GDScript", "language": "GDScript",
@ -39,6 +44,11 @@ _global_script_classes=[ {
"language": "GDScript", "language": "GDScript",
"path": "res://scripts/entities/EntityDataGD.gd" "path": "res://scripts/entities/EntityDataGD.gd"
}, { }, {
"base": "Container",
"class": "FlexGridContainer",
"language": "GDScript",
"path": "res://addons/color-palette/utilities/FlexGridContainer.gd"
}, {
"base": "Node", "base": "Node",
"class": "GEAction", "class": "GEAction",
"language": "GDScript", "language": "GDScript",
@ -164,6 +174,16 @@ _global_script_classes=[ {
"language": "GDScript", "language": "GDScript",
"path": "res://player/NetworkedPlayer.gd" "path": "res://player/NetworkedPlayer.gd"
}, { }, {
"base": "Reference",
"class": "Palette",
"language": "GDScript",
"path": "res://addons/color-palette/Palette.gd"
}, {
"base": "Reference",
"class": "PaletteImporter",
"language": "GDScript",
"path": "res://addons/color-palette/PaletteImporter.gd"
}, {
"base": "", "base": "",
"class": "PlayerGD", "class": "PlayerGD",
"language": "GDScript", "language": "GDScript",
@ -203,9 +223,11 @@ _global_script_class_icons={
"AuraGD": "", "AuraGD": "",
"BrushPrefabs": "", "BrushPrefabs": "",
"CharacterSkeketonAttachPoint": "", "CharacterSkeketonAttachPoint": "",
"ColorTile": "",
"DisplayPlayerGD": "", "DisplayPlayerGD": "",
"EntityAIGD": "", "EntityAIGD": "",
"EntityDataGD": "", "EntityDataGD": "",
"FlexGridContainer": "res://addons/color-palette/utilities/FlexGridContainerIcon.png",
"GEAction": "", "GEAction": "",
"GEBrighten": "", "GEBrighten": "",
"GEBrush": "", "GEBrush": "",
@ -231,6 +253,8 @@ _global_script_class_icons={
"Menu": "", "Menu": "",
"MobGD": "", "MobGD": "",
"NetworkedPlayerGD": "", "NetworkedPlayerGD": "",
"Palette": "",
"PaletteImporter": "",
"PlayerGD": "", "PlayerGD": "",
"PlayerMaster": "", "PlayerMaster": "",
"SpeedResource": "", "SpeedResource": "",
@ -286,7 +310,7 @@ window/size/ui_scale_touch=1.0
[editor_plugins] [editor_plugins]
enabled=PoolStringArray( "res://addons/Godoxel/plugin.cfg", "res://addons/mesh_data_resource_editor/plugin.cfg" ) enabled=PoolStringArray( "res://addons/Godoxel/plugin.cfg", "res://addons/color-palette/plugin.cfg", "res://addons/mesh_data_resource_editor/plugin.cfg" )
[ess] [ess]