mirror of
https://github.com/tonytins/CozyPixelStudio.git
synced 2025-06-25 15:44:42 -04:00
Merged "Scripts" and "Prefabs" folders into "src"
Made a new "src" folder that will contain the source code files, like all the GDScript and scene files. Please read this for more details: https://www.gdquest.com/docs/guidelines/best-practices/godot-gdscript/ It made no sense to keep scenes separate from their scripts. More file organizing will follow soon.
This commit is contained in:
parent
5a54235604
commit
646fc19a70
63 changed files with 135 additions and 113 deletions
190
src/Palette/EditPalettePopup.gd
Normal file
190
src/Palette/EditPalettePopup.gd
Normal file
|
@ -0,0 +1,190 @@
|
|||
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
|
||||
|
||||
|
||||
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()
|
||||
Global.can_draw = false
|
||||
self.popup_centered()
|
||||
|
||||
left_color_button.modulate = Global.left_color_picker.color
|
||||
right_color_button.modulate = Global.right_color_picker.color
|
||||
|
||||
|
||||
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])
|
||||
|
||||
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:
|
||||
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])
|
||||
|
||||
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 = Global.left_color_picker.color
|
||||
_on_EditPaletteColorPicker_color_changed(color_picker.color)
|
||||
|
||||
|
||||
func _on_RightColor_pressed() -> void:
|
||||
color_picker.color = Global.right_color_picker.color
|
||||
_on_EditPaletteColorPicker_color_changed(color_picker.color)
|
||||
|
||||
|
||||
func _on_EditPalettePopup_popup_hide() -> void:
|
||||
Global.can_draw = true
|
240
src/Palette/EditPalettePopup.tscn
Normal file
240
src/Palette/EditPalettePopup.tscn
Normal file
|
@ -0,0 +1,240 @@
|
|||
[gd_scene load_steps=5 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]
|
||||
|
||||
[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_left = 4.0
|
||||
margin_top = 4.0
|
||||
margin_right = 4.0
|
||||
margin_bottom = 4.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
|
||||
|
||||
[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
|
||||
[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"]
|
25
src/Palette/NewPaletteDialog.tscn
Normal file
25
src/Palette/NewPaletteDialog.tscn
Normal file
|
@ -0,0 +1,25 @@
|
|||
[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
|
161
src/Palette/Palette.gd
Normal file
161
src/Palette/Palette.gd
Normal file
|
@ -0,0 +1,161 @@
|
|||
class_name Palette
|
||||
extends Reference
|
||||
|
||||
|
||||
var name : String = "Custom_Palette"
|
||||
var colors : Array = []
|
||||
var comments : String = ""
|
||||
var editable : bool = true
|
||||
|
||||
|
||||
func get_class() -> String:
|
||||
return "Palette"
|
||||
|
||||
|
||||
func is_class(_name : String) -> bool:
|
||||
return _name == "Palette" or .is_class(_name)
|
||||
|
||||
|
||||
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 has_color(color: Color) -> bool:
|
||||
for palette_color in colors:
|
||||
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
|
||||
|
||||
|
||||
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 = 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
|
||||
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)
|
||||
|
||||
file.close()
|
||||
|
||||
return result
|
27
src/Palette/PaletteButton.gd
Normal file
27
src/Palette/PaletteButton.gd
Normal file
|
@ -0,0 +1,27 @@
|
|||
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)
|
45
src/Palette/PaletteButton.tscn
Normal file
45
src/Palette/PaletteButton.tscn
Normal file
|
@ -0,0 +1,45 @@
|
|||
[gd_scene load_steps=8 format=2]
|
||||
|
||||
[ext_resource path="res://Themes & Styles/StyleBoxes/palette_stylebox_pressedr.tres" type="StyleBox" id=1]
|
||||
[ext_resource path="res://Themes & Styles/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://Themes & Styles/StyleBoxes/palette_stylebox_focus.tres" type="StyleBox" id=4]
|
||||
[ext_resource path="res://Themes & Styles/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"
|
||||
custom_styles/hover = ExtResource( 2 )
|
||||
custom_styles/pressed = ExtResource( 1 )
|
||||
custom_styles/focus = ExtResource( 4 )
|
||||
custom_styles/normal = ExtResource( 5 )
|
||||
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
|
||||
}
|
54
src/Palette/PaletteColor.gd
Normal file
54
src/Palette/PaletteColor.gd
Normal file
|
@ -0,0 +1,54 @@
|
|||
class_name PaletteColor
|
||||
extends Reference
|
||||
|
||||
|
||||
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
|
272
src/Palette/PaletteContainer.gd
Normal file
272
src/Palette/PaletteContainer.gd
Normal file
|
@ -0,0 +1,272 @@
|
|||
extends GridContainer
|
||||
|
||||
const palette_button = preload("res://src/Palette/PaletteButton.tscn")
|
||||
|
||||
var current_palette = "Default"
|
||||
var from_palette : Palette
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_load_palettes()
|
||||
|
||||
# Select default palette "Default"
|
||||
on_palette_select(current_palette)
|
||||
|
||||
var add_palette_menu : PopupMenu = Global.add_palette_button.get_child(0)
|
||||
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:
|
||||
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.can_draw = false
|
||||
|
||||
|
||||
func on_import_palette() -> void:
|
||||
Global.palette_import_file_dialog.popup_centered()
|
||||
Global.can_draw = false
|
||||
|
||||
|
||||
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"):
|
||||
palette = Import.import_gpl(path)
|
||||
elif path.to_lower().ends_with("png"):
|
||||
palette = Import.import_png_palette(path)
|
||||
|
||||
if palette:
|
||||
if not Global.palettes.has(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(tr("Error: Palette named '%s' already exists!") % palette.name)
|
||||
Global.error_dialog.popup_centered()
|
||||
else:
|
||||
Global.error_dialog.set_text("Invalid Palette file!")
|
||||
Global.error_dialog.popup_centered()
|
||||
|
||||
|
||||
func _on_AddPalette_pressed() -> void:
|
||||
Global.add_palette_button.get_child(0).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()
|
||||
|
||||
|
||||
func add_palette_menu_id_pressed(id : int) -> void:
|
||||
match id:
|
||||
0: # New Empty Palette
|
||||
Global.palette_container.on_new_empty_palette()
|
||||
1: # Import Palette
|
||||
Global.palette_container.on_import_palette()
|
||||
|
||||
|
||||
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.")
|
||||
if Global.palettes.has(name):
|
||||
return tr("Error: Palette named '%s' already exists!") % 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 ""
|
||||
|
||||
|
||||
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.can_draw = false
|
||||
else:
|
||||
from_palette = null
|
||||
Global.edit_palette_popup.open(current_palette)
|
||||
|
||||
|
||||
func _on_PaletteOptionButton_item_selected(ID : int) -> void:
|
||||
var palette_name = Global.palette_option_button.get_item_metadata(ID)
|
||||
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])
|
||||
|
||||
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"):
|
||||
Global.left_color_picker.color = color
|
||||
Global.update_left_custom_brush()
|
||||
elif Input.is_action_just_pressed("right_mouse"):
|
||||
Global.right_color_picker.color = color
|
||||
Global.update_right_custom_brush()
|
||||
|
||||
|
||||
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":
|
||||
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 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.can_draw = true
|
13
src/Palette/PaletteImportFileDialog.tscn
Normal file
13
src/Palette/PaletteImportFileDialog.tscn
Normal file
|
@ -0,0 +1,13 @@
|
|||
[gd_scene format=2]
|
||||
|
||||
[node name="PaletteImportFileDialog" type="FileDialog"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
rect_min_size = Vector2( 500, 300 )
|
||||
window_title = "Open a File"
|
||||
resizable = true
|
||||
mode = 0
|
||||
access = 2
|
||||
filters = PoolStringArray( "*.json ; JavaScript Object Notation" )
|
||||
current_dir = "D:/GitHub/Pixelorama"
|
||||
current_path = "D:/GitHub/Pixelorama/"
|
Loading…
Add table
Add a link
Reference in a new issue