diff --git a/src/Autoload/HTML5FileExchange.gd b/src/Autoload/HTML5FileExchange.gd index 81c113c63..19d4fad9c 100644 --- a/src/Autoload/HTML5FileExchange.gd +++ b/src/Autoload/HTML5FileExchange.gd @@ -43,6 +43,32 @@ func _define_js() -> void: } }); } + function upload_palette() { + canceled = true; + var input = document.createElement('INPUT'); + input.setAttribute("type", "file"); + input.setAttribute("accept", "application/json, .gpl, image/png, image/jpeg, image/webp"); + input.click(); + input.addEventListener('change', event => { + if (event.target.files.length > 0){ + canceled = false;} + var file = event.target.files[0]; + var reader = new FileReader(); + fileType = file.type; + fileName = file.name; + if (fileType == "image/png" || fileType == "image/jpeg" || fileType == "image/webp"){ + reader.readAsArrayBuffer(file); + } + else { + reader.readAsText(file); + } + reader.onloadend = function (evt) { + if (evt.target.readyState == FileReader.DONE) { + fileData = evt.target.result; + } + } + }); + } function download(fileName, byte, type) { var buffer = Uint8Array.from(byte); var blob = new Blob([buffer], { type: type}); @@ -69,10 +95,10 @@ func load_image() -> void: return # Use data from png data - var imageData + var image_data while true: - imageData = JavaScript.eval("fileData;", true) - if imageData != null: + image_data = JavaScript.eval("fileData;", true) + if image_data != null: break yield(get_tree().create_timer(1.0), "timeout") # Need more time to load data @@ -83,13 +109,13 @@ func load_image() -> void: var image_error match image_type: "image/png": - image_error = image.load_png_from_buffer(imageData) + image_error = image.load_png_from_buffer(image_data) "image/jpeg": - image_error = image.load_jpg_from_buffer(imageData) + image_error = image.load_jpg_from_buffer(image_data) "image/webp": - image_error = image.load_webp_from_buffer(imageData) + image_error = image.load_webp_from_buffer(image_data) var invalid_type: - print(invalid_type) + print("Invalid type: " + invalid_type) return if image_error: print("An error occurred while trying to display the image.") @@ -98,6 +124,50 @@ func load_image() -> void: OpenSave.handle_loading_image(image_name, image) +func load_palette() -> void: + if OS.get_name() != "HTML5" or !OS.has_feature('JavaScript'): + return + + # Execute JS function + JavaScript.eval("upload_palette();", true) # Opens prompt for choosing file + + yield(self, "InFocus") # Wait until JS prompt is closed + + yield(get_tree().create_timer(0.5), "timeout") # Give some time for async JS data load + + if JavaScript.eval("canceled;", true): # If File Dialog closed w/o file + return + + # Use data from palette file data + var palette_data + while true: + palette_data = JavaScript.eval("fileData;", true) + if palette_data != null: + break + yield(get_tree().create_timer(1.0), "timeout") # Need more time to load data + + var file_type = JavaScript.eval("fileType;", true) + var file_name = JavaScript.eval("fileName;", true) + if file_name.ends_with(".gpl"): + var palette := Palette.new() + palette = Import.import_gpl(file_name, palette_data) + Global.palette_container.attempt_to_import_palette(palette) + else: + match file_type: + "image/png": + var image := Image.new() + var err = image.load_png_from_buffer(palette_data) + if !err: + Global.palette_container.import_image_palette(file_name, image) + "application/json": + var palette : Palette = Palette.new().deserialize(palette_data) + palette.source_path = file_name + Global.palette_container.attempt_to_import_palette(palette) + var invalid_type: + print("Invalid type: " + invalid_type) + return + + func save_image(image : Image, file_name : String = "export") -> void: if OS.get_name() != "HTML5" or !OS.has_feature('JavaScript'): return diff --git a/src/Autoload/Import.gd b/src/Autoload/Import.gd index 1fd42c145..94b0c4e42 100644 --- a/src/Autoload/Import.gd +++ b/src/Autoload/Import.gd @@ -256,59 +256,51 @@ func import_patterns(priority_ordered_search_path: Array) -> void: Global.fill_pattern_containers[1].get_child(3).get_child(1).max_value = image_size.y - 1 -func import_gpl(path : String) -> Palette: +func import_gpl(path : String, text : String) -> Palette: # Refer to app/core/gimppalette-load.c of the GIMP for the "living spec" var result : Palette = null - var file = File.new() - if file.file_exists(path): - file.open(path, File.READ) - var text = file.get_as_text() - var lines = text.split('\n') - var line_number := 0 - var comments := "" - for line in lines: - # Check if valid Gimp Palette Library file - if line_number == 0: - if line != "GIMP Palette": - break - else: - result = Palette.new() - # Use filename as palette name in case reading old - # palette format (must read more to determine) - 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) + var lines = text.split('\n') + var line_number := 0 + var comments := "" + for line in lines: + # Check if valid Gimp Palette Library file + if line_number == 0: + if not "GIMP Palette" in line: + break + else: + result = Palette.new() + # Use filename as palette name in case reading old + # palette format (must read more to determine) + result.name = path.get_basename().get_file() - # Comments - if line.begins_with('#'): - comments += line.trim_prefix('#') + '\n' - # Some programs output palette name in a comment for old format - if line.begins_with("#Palette Name: "): - result.name = line.replace("#Palette Name: ", "") - pass - elif line.begins_with("Name: "): - result.name = line.replace("Name: ", "") - pass - elif line.begins_with("Columns: "): - # Number of colors in this palette. Unecessary and often wrong - pass - elif line_number > 0 && line.length() >= 9: - line = line.replace("\t", " ") - var color_data : PoolStringArray = line.split(" ", false, 4) - var red : float = color_data[0].to_float() / 255.0 - var green : float = color_data[1].to_float() / 255.0 - var blue : float = color_data[2].to_float() / 255.0 - var color = Color(red, green, blue) - if color_data.size() >= 4: - result.add_color(color, color_data[3]) - else: - result.add_color(color) - line_number += 1 + # Comments + if line.begins_with('#'): + comments += line.trim_prefix('#') + '\n' + # Some programs output palette name in a comment for old format + if line.begins_with("#Palette Name: "): + result.name = line.replace("#Palette Name: ", "") + pass + elif line.begins_with("Name: "): + result.name = line.replace("Name: ", "") + pass + elif line.begins_with("Columns: "): + # Number of colors in this palette. Unecessary and often wrong + pass + elif line_number > 0 && line.length() >= 9: + line = line.replace("\t", " ") + var color_data : PoolStringArray = line.split(" ", false, 4) + var red : float = color_data[0].to_float() / 255.0 + var green : float = color_data[1].to_float() / 255.0 + var blue : float = color_data[2].to_float() / 255.0 + var color = Color(red, green, blue) + if color_data.size() >= 4: + result.add_color(color, color_data[3]) + else: + result.add_color(color) + line_number += 1 - if result: - result.comments = comments - file.close() + if result: + result.comments = comments return result diff --git a/src/Palette/PaletteContainer.gd b/src/Palette/PaletteContainer.gd index ee9953228..4a98de4bb 100644 --- a/src/Palette/PaletteContainer.gd +++ b/src/Palette/PaletteContainer.gd @@ -40,8 +40,11 @@ func on_new_empty_palette() -> void: func on_import_palette() -> void: - Global.palette_import_file_dialog.popup_centered() - Global.dialog_open(true) + if OS.get_name() == "HTML5": + Html5FileExchange.load_palette() + else: + Global.palette_import_file_dialog.popup_centered() + Global.dialog_open(true) func on_palette_import_file_selected(path : String) -> void: @@ -49,7 +52,12 @@ func on_palette_import_file_selected(path : String) -> void: 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) + var file = File.new() + if file.file_exists(path): + file.open(path, File.READ) + var text = file.get_as_text() + file.close() + palette = Import.import_gpl(path, text) elif path.to_lower().ends_with("png") or path.to_lower().ends_with("bmp") or path.to_lower().ends_with("hdr") or path.to_lower().ends_with("jpg") or path.to_lower().ends_with("svg") or path.to_lower().ends_with("tga") or path.to_lower().ends_with("webp"): var image := Image.new() var err := image.load(path) diff --git a/src/Palette/PaletteImportFileDialog.tscn b/src/Palette/PaletteImportFileDialog.tscn index dadc2743b..303886672 100644 --- a/src/Palette/PaletteImportFileDialog.tscn +++ b/src/Palette/PaletteImportFileDialog.tscn @@ -11,5 +11,5 @@ resizable = true mode = 0 access = 2 filters = PoolStringArray( "*.json ; JavaScript Object Notation", "*.gpl ; Gimp Palette Library", "*.png; Portable Network Graphics" ) -current_dir = "C:/Users" -current_path = "C:/Users/" +current_dir = "/Users" +current_path = "/Users/"