diff --git a/lorien/Assets/I18n/en.txt b/lorien/Assets/I18n/en.txt index 55895ce..5f1caa3 100644 --- a/lorien/Assets/I18n/en.txt +++ b/lorien/Assets/I18n/en.txt @@ -40,6 +40,7 @@ COLOR_PALETTE_PICKER_HINT_NEW Create new color palette COLOR_PALETTE_PICKER_HINT_EDIT Edit the current color palette COLOR_PALETTE_PICKER_HINT_DUPLICATE Duplicate the current color palette COLOR_PALETTE_PICKER_HINT_DELETE Delete the current color palette permanently +COLOR_PALETTE_PICKER_HINT_IMPORT Import color palette from file... # ----------------------------------------------------------------------------- # Statusbar strings @@ -161,4 +162,4 @@ ACTION_duplicate_strokes Duplicate strokes ACTION_toggle_zen_mode Toggle Zen Mode ACTION_toggle_player Toggle Easteregg ACTION_toggle_fullscreen Toggle Fullscreen -ACTION_canvas_pan_key Pan Key \ No newline at end of file +ACTION_canvas_pan_key Pan Key diff --git a/lorien/Assets/Icons/import.png b/lorien/Assets/Icons/import.png new file mode 100644 index 0000000..29fa115 Binary files /dev/null and b/lorien/Assets/Icons/import.png differ diff --git a/lorien/Assets/Icons/import.png.import b/lorien/Assets/Icons/import.png.import new file mode 100644 index 0000000..9197399 --- /dev/null +++ b/lorien/Assets/Icons/import.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cy1dw232wfupq" +path="res://.godot/imported/import.png-d4f00b97279432a3c7140df130354f78.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Icons/import.png" +dest_files=["res://.godot/imported/import.png-d4f00b97279432a3c7140df130354f78.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/lorien/Main.gd b/lorien/Main.gd index 9d6d2c7..45944b0 100644 --- a/lorien/Main.gd +++ b/lorien/Main.gd @@ -21,6 +21,7 @@ extends Control @onready var _delete_palette_window: Window = $DeletePaletteWindow @onready var _edit_palette_window: Window = $EditPaletteWindow @onready var _edit_palette_dialog: EditPaletteDialog = $EditPaletteWindow/EditPaletteDialog +@onready var _import_palette_dialog: FileDialog = $ImportPaletteDialog var _last_input_time := 0 var _ui_visible := true @@ -39,6 +40,7 @@ func _ready() -> void: var docs_folder := OS.get_system_dir(OS.SYSTEM_DIR_DOCUMENTS) _file_dialog.current_dir = Settings.get_value(Settings.GENERAL_DEFAULT_PROJECT_DIR, docs_folder) _export_dialog.current_dir = Settings.get_value(Settings.GENERAL_DEFAULT_PROJECT_DIR, docs_folder) + _import_palette_dialog.current_dir = Settings.get_value(Settings.GENERAL_DEFAULT_PROJECT_DIR, docs_folder) # Set tablet driver var driver: String = Settings.get_value(Settings.GENERAL_TABLET_DRIVER, DisplayServer.tablet_get_current_driver()) @@ -274,6 +276,8 @@ func _is_mouse_on_ui() -> bool: on_ui = on_ui || Utils.is_mouse_in_control(_toolbar) on_ui = on_ui || Utils.is_mouse_in_control(_statusbar) on_ui = on_ui || Utils.is_mouse_on_window(_file_dialog) + on_ui = on_ui || Utils.is_mouse_on_window(_export_dialog) + on_ui = on_ui || Utils.is_mouse_on_window(_import_palette_dialog) on_ui = on_ui || Utils.is_mouse_on_window(_about_window) on_ui = on_ui || Utils.is_mouse_on_window(_settings_window) on_ui = on_ui || Utils.is_mouse_in_control(_brush_color_picker) @@ -287,7 +291,8 @@ func is_dialog_open() -> bool: return _about_window.visible || _settings_window.visible || \ _new_palette_window.visible || _edit_palette_window.visible || \ _delete_palette_window.visible || _file_dialog.visible || \ - _unsaved_changes_window.visible || AlertDialog.visible + _import_palette_dialog.visible || AlertDialog.visible || \ + _unsaved_changes_window.visible # ------------------------------------------------------------------------------------------------- func _create_active_default_project() -> void: diff --git a/lorien/Main.tscn b/lorien/Main.tscn index 81fc7d6..ef37926 100644 --- a/lorien/Main.tscn +++ b/lorien/Main.tscn @@ -79,6 +79,7 @@ add_new_palette_dialog_path = NodePath("../NewPaletteWindow/NewPaletteDialog") edit_palette_dialog = NodePath("../EditPaletteWindow/EditPaletteDialog") delete_palette_dialog = NodePath("../DeletePaletteWindow/DeletePaletteDialog") toolbar_path = NodePath("../Topbar/Toolbar") +file_dialog_path = NodePath("../ImportPaletteDialog") [node name="BackgroundColorPickerPopup" type="Popup" parent="."] size = Vector2i(399, 525) @@ -103,6 +104,7 @@ presets_visible = false [node name="MainMenu" parent="." instance=ExtResource("5")] visible = false +unfocusable = false submenu_popup_delay = 0.1 file_dialog_path = NodePath("../FileDialog") @@ -184,6 +186,17 @@ access = 2 filters = PackedStringArray("*.lorien") use_native_dialog = true +[node name="ImportPaletteDialog" type="FileDialog" parent="."] +auto_translate_mode = 1 +title = "Import Palette" +initial_position = 2 +size = Vector2i(625, 175) +theme = ExtResource("8") +ok_button_text = "Import" +access = 2 +filters = PackedStringArray("*.gpl;GIMP GPL", "*.pal;JASC PAL") +use_native_dialog = true + [node name="ExportDialog" type="FileDialog" parent="."] initial_position = 2 size = Vector2i(625, 175) diff --git a/lorien/Palette/PaletteManager.gd b/lorien/Palette/PaletteManager.gd index 94f5818..c76339b 100644 --- a/lorien/Palette/PaletteManager.gd +++ b/lorien/Palette/PaletteManager.gd @@ -57,7 +57,7 @@ func duplicate_palette(palette: Palette, new_palette_name: String) -> Palette: var new_palette := Palette.new() new_palette.name = new_palette_name new_palette.builtin = false - new_palette.colors = palette.colors # TODO: make sure this is passed by-value + new_palette.colors = PackedColorArray(palette.colors) palettes.append(new_palette) _sort() @@ -73,7 +73,11 @@ func remove_palette(palette: Palette) -> bool: palettes.remove_at(index) return true return false - + +# ------------------------------------------------------------------------------------------------- +func import_palette() -> void: + pass + # ------------------------------------------------------------------------------------------------- func set_active_palette_by_index(index: int) -> void: if index < palettes.size(): diff --git a/lorien/UI/ColorPalettePicker.gd b/lorien/UI/ColorPalettePicker.gd index 2e10c52..f265f5c 100644 --- a/lorien/UI/ColorPalettePicker.gd +++ b/lorien/UI/ColorPalettePicker.gd @@ -13,6 +13,7 @@ signal closed @export var edit_palette_dialog: NodePath @export var delete_palette_dialog: NodePath @export var toolbar_path: NodePath +@export var file_dialog_path: NodePath @onready var _toolbar: Toolbar = get_node(toolbar_path) @onready var _palette_selection_button: OptionButton = $MarginContainer/VBoxContainer/Buttons/PaletteSelectionButton @@ -21,6 +22,7 @@ signal closed @onready var _new_button: TextureButton = $MarginContainer/VBoxContainer/Buttons/AddPaletteButton @onready var _duplicate_button: TextureButton = $MarginContainer/VBoxContainer/Buttons/DuplicatePaletteButton @onready var _delete_button: TextureButton = $MarginContainer/VBoxContainer/Buttons/DeletePaletteButton +@onready var _import_button: TextureButton = $MarginContainer/VBoxContainer/Buttons/ImportPaletteButton var _active_palette_button: PaletteButton var _active_color_index := -1 @@ -34,6 +36,7 @@ func _ready() -> void: _edit_button.pressed.connect(_on_EditColorButton_pressed) _duplicate_button.pressed.connect(_on_DuplicatePaletteButton_pressed) _delete_button.pressed.connect(_on_DeletePaletteButton_pressed) + _import_button.pressed.connect(_on_ImportPaletteButton_pressed) # ------------------------------------------------------------------------------------------------- func _input(event: InputEvent) -> void: @@ -157,6 +160,107 @@ func _on_DeletePaletteButton_pressed() -> void: var dialog: DeletePaletteDialog = get_node(delete_palette_dialog) dialog.get_parent().popup_centered() +# ------------------------------------------------------------------------------------------------- +func _on_ImportPaletteButton_pressed() -> void: + var file_dialog: FileDialog = get_node(file_dialog_path) + file_dialog.file_mode = FileDialog.FILE_MODE_OPEN_FILE + file_dialog.file_selected.connect(_on_palette_selected_to_import) + file_dialog.close_requested.connect(_on_file_dialog_closed) + file_dialog.invalidate() + file_dialog.popup_centered() + +# ------------------------------------------------------------------------------------------------- +func _on_palette_selected_to_import(filepath: String) -> void: + var palette : Palette + var palette_name: String + var palette_colors: PackedColorArray + var palette_string: String + var file := FileAccess.open(filepath, FileAccess.READ) + palette_string = file.get_as_text(true) + file.close() + match filepath.get_extension(): + "gpl": + if !is_valid_gpl(palette_string): + return + palette_name = get_gpl_palette_name(palette_string) + if !palette_name: + palette_name = filepath.get_file().trim_suffix(".gpl") + palette_colors = parse_gpl_palette(palette_string) + "pal": + if !is_valid_pal(palette_string): + return + palette_name = filepath.get_file().trim_suffix(".pal") + palette_colors = parse_pal_palette(palette_string) + _: + return + + palette = PaletteManager.create_custom_palette(palette_name) + if palette != null: + palette.colors = palette_colors + PaletteManager.save() + PaletteManager.set_active_palette(palette) + update_palettes() + +# ------------------------------------------------------------------------------------------------- +func is_valid_gpl(gpl_palette: String) -> bool: + return gpl_palette.begins_with("GIMP Palette") + +# ------------------------------------------------------------------------------------------------- +func get_gpl_palette_name(gpl_palette: String) -> String: + var name_line: String + name_line = gpl_palette.get_slice("\n", 1) + if name_line.begins_with("Name: "): + return name_line.right(-6).strip_edges() + else: + return "" + +# ------------------------------------------------------------------------------------------------- +func parse_gpl_palette(gpl_palette: String) -> PackedColorArray: + var color_array: PackedColorArray + for line in gpl_palette.split("\n"): + if !line or line.begins_with("#") or line == "GIMP Palette": + continue + var values: Array + if line.contains("\t"): + values = line.split("\t") + else: + values = line.split(" ") + color_array.append( + Color( + float(values[0])/255, + float(values[1])/255, + float(values[2])/255 + ) + ) + return color_array + +# ------------------------------------------------------------------------------------------------- +func is_valid_pal(pal_palette: String) -> bool: + return pal_palette.begins_with("JASC-PAL") + +# ------------------------------------------------------------------------------------------------- +func parse_pal_palette(pal_palette: String) -> PackedColorArray: + var color_array: PackedColorArray + var n_colors: int + n_colors = int(pal_palette.split("\n")[2]) + for i in range(3,n_colors+3): + var values: Array + values = pal_palette.split("\n")[i].split(" ") + color_array.append( + Color( + float(values[0])/255, + float(values[1])/255, + float(values[2])/255 + ) + ) + return color_array + +# ------------------------------------------------------------------------------------------------- +func _on_file_dialog_closed() -> void: + var file_dialog: FileDialog = get_node(file_dialog_path) + Utils.remove_signal_connections(file_dialog, "file_selected") + Utils.remove_signal_connections(file_dialog, "close_requested") + # ------------------------------------------------------------------------------------------------- func toggle() -> void: visible = !visible diff --git a/lorien/UI/ColorPalettePicker.tscn b/lorien/UI/ColorPalettePicker.tscn index 2703586..e64cccd 100644 --- a/lorien/UI/ColorPalettePicker.tscn +++ b/lorien/UI/ColorPalettePicker.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=11 format=3 uid="uid://dsxmmndtd4r2c"] +[gd_scene load_steps=12 format=3 uid="uid://dsxmmndtd4r2c"] [ext_resource type="Theme" uid="uid://u5qnpgxqykiv" path="res://UI/Themes/theme_dark.tres" id="1"] [ext_resource type="Script" path="res://UI/ColorPalettePicker.gd" id="2"] @@ -7,6 +7,7 @@ [ext_resource type="Texture2D" uid="uid://ci340bpx1hg78" path="res://Assets/Icons/copy.png" id="5"] [ext_resource type="Texture2D" uid="uid://c3maqrdnsjgiq" path="res://Assets/Icons/delete.png" id="6"] [ext_resource type="Script" path="res://UI/Components/FlatTextureButton.gd" id="7"] +[ext_resource type="Texture2D" uid="uid://cy1dw232wfupq" path="res://Assets/Icons/import.png" id="7_yo14x"] [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_eth5b"] bg_color = Color(0.12549, 0.129412, 0.141176, 1) @@ -81,6 +82,15 @@ script = ExtResource("7") hover_tint = Color(0.662745, 0.945098, 0.87451, 1) pressed_tint = Color(0.572549, 1, 0.894118, 1) +[node name="ImportPaletteButton" type="TextureButton" parent="MarginContainer/VBoxContainer/Buttons"] +layout_mode = 2 +size_flags_vertical = 4 +tooltip_text = "COLOR_PALETTE_PICKER_HINT_IMPORT" +texture_normal = ExtResource("7_yo14x") +script = ExtResource("7") +hover_tint = Color(0.662745, 0.945098, 0.87451, 1) +pressed_tint = Color(0.572549, 1, 0.894118, 1) + [node name="VSeparator" type="VSeparator" parent="MarginContainer/VBoxContainer/Buttons"] layout_mode = 2 theme_override_styles/separator = SubResource("1") diff --git a/lorien/UI/Themes/theme_dark.tres b/lorien/UI/Themes/theme_dark.tres index 0dfa382..d70eac3 100644 --- a/lorien/UI/Themes/theme_dark.tres +++ b/lorien/UI/Themes/theme_dark.tres @@ -1,6 +1,5 @@ -[gd_resource type="Theme" load_steps=27 format=4 uid="uid://u5qnpgxqykiv"] +[gd_resource type="Theme" load_steps=26 format=4 uid="uid://u5qnpgxqykiv"] -[ext_resource type="Texture2D" uid="uid://bp1yka17gbjtu" path="res://Assets/Icons/close.png" id="1_qgxa7"] [ext_resource type="StyleBox" uid="uid://kdduww61cjw" path="res://UI/Themes/tab_inactive_dark.tres" id="2_n6mkw"] [ext_resource type="StyleBox" uid="uid://dtn7ehcyfik4a" path="res://UI/Themes/tab_active_dark.tres" id="3_rqnin"] @@ -2562,7 +2561,7 @@ TabBar/constants/h_separation = 4 TabBar/constants/icon_max_width = 0 TabBar/constants/outline_size = 0 TabBar/fonts/font = SubResource("FontFile_1bm21") -TabBar/icons/close = ExtResource("1_qgxa7") +TabBar/icons/close = null TabBar/styles/button_highlight = SubResource("StyleBoxEmpty_me351") TabBar/styles/button_pressed = SubResource("StyleBoxEmpty_n0chp") TabBar/styles/tab_disabled = ExtResource("2_n6mkw")