ChocolateBird/widgets/WebFileSelect.gd

154 lines
5.6 KiB
GDScript3
Raw Normal View History

extends PanelContainer
#warning-ignore-all:return_value_discarded
signal continue_pressed
2023-12-06 18:19:19 +10:30
const FOLDER_ICON := globals.FOLDER_ICON
const ALLOWED_EXTS := globals.ALLOWED_EXTS
const CD_EXTS := globals.CD_EXTS
const EXT_ICONS := globals.EXT_ICONS
const TYPE_DESCS := globals.TYPE_DESCS
var uploaded_files := {} # filename: data
var uploaded_files_types := {} # filename: type
var cached_cd_bin_paths := {}
onready var itemlist: ItemList = $VBoxContainer/HBoxContainer/PanelContainer/ItemList
onready var vscroller: VScrollBar = itemlist.get_child(0)
onready var folder_buttons_scroller: ScrollContainer = $VBoxContainer/ScrollContainer
onready var folder_buttons: HBoxContainer = $VBoxContainer/ScrollContainer/folder_buttons
onready var btn_ok: Button = $'%btn_ok'
onready var btn_continue: Button = $'%btn_continue'
onready var lbl_filename_header: Label = $'%lbl_filename_header'
onready var lbl_filename_content: Label = $'%lbl_filename_content'
onready var lbl_filetype_header: Label = $'%lbl_filetype_header'
onready var lbl_filetype_content: Label = $'%lbl_filetype_content'
onready var lbl_filesize_header: Label = $'%lbl_filesize_header'
onready var lbl_filesize_content: Label = $'%lbl_filesize_content'
onready var lbl_fileinfo_header: Label = $'%lbl_fileinfo_header'
onready var lbl_fileinfo_content: Label = $'%lbl_fileinfo_content'
const inactive_modulate_color := Color(0.5, 0.5, 0.5)
const active_modulate_color := Color.white
var last_dir := ''
static func get_human_size(n: int) -> String:
if n > 0x100000000:
return '%.2f GiB' % (n/float(0x40000000))
if n > 0x400000:
return '%.1f MiB' % (n/float(0x100000))
if n > 0x1000:
return '%.1f KiB' % (n/float(0x400))
return '%d B' % n
static func tokenize_path(path: String) -> PoolStringArray:
return path.rstrip('/').split('/', true) # Allow empty means '/' will return ['']
static func join_path(tokens) -> String:
var path = '/'.join(tokens)
return path if path else '/'
func update_view():
for child in folder_buttons.get_children():
child.queue_free()
itemlist.clear()
var files := []
for entry in uploaded_files.keys():
if entry in cached_cd_bin_paths:
files.append([entry, EXT_ICONS.iso])
elif '.' in entry:
var extension = entry.rsplit('.', true, 1)[1]
if extension in ALLOWED_EXTS:
files.append([entry, EXT_ICONS.get(extension)])
files.sort()
for entry in files:
itemlist.add_item(entry[0], entry[1])
func load_file(entry: String):
var ext = entry.rsplit('.', true, 1)[1].to_lower()
match ext:
2023-12-06 18:19:19 +10:30
'sfc', 'smc':
RomLoader.load_snes_rom_from_bytes(uploaded_files[entry])
func activate_entry(entry: String, _index: int = -1):
load_file(entry)
func activate_current_entry():
var selected := itemlist.get_selected_items()
if len(selected) > 0:
activate_entry(itemlist.get_item_text(selected[0]))
func view_entry(entry: String, _index: int = -1):
init_labels()
lbl_filename_header.modulate = active_modulate_color
lbl_filename_content.text = entry
lbl_filetype_header.modulate = active_modulate_color
var size = len(uploaded_files[entry])
var human_size = get_human_size(size)
var ext = entry.rsplit('.', true, 1)[1].to_lower()
var type = TYPE_DESCS.get(ext, 'Unknown')
var prodcode: String = uploaded_files_types[entry]
if ext in CD_EXTS:
pass # TODO: Update cd image loader to accept PoolByteArray or a buffer view
# var cd := RomLoader.loader_cd_image.new(uploaded_files[entry])
# for key in cd.directory:
# var s = key.trim_prefix('./')
# var re_match := RomLoader.psx_productcode_regex.search(s)
# if re_match:
# prodcode = '%s\n%s\n%s' % [cd.pvd.system_identifier.strip_edges(), cd.pvd.volume_identifier.strip_edges(), re_match.get_string(1)]
# type = 'PSX CD-ROM Image'
# cached_cd_bin_paths[entry] = prodcode
# if index >= 0:
# itemlist.set_item_icon(index, EXT_ICONS.iso)
# break
var info = ('Info:\n %s' % prodcode) if prodcode else ''
lbl_filetype_content.text = type
lbl_filesize_header.modulate = active_modulate_color
lbl_filesize_content.text = human_size
lbl_fileinfo_header.modulate = active_modulate_color if prodcode else inactive_modulate_color
lbl_fileinfo_content.text = prodcode
2023-12-06 18:19:19 +10:30
btn_ok.disabled = (ext != 'sfc' and ext != 'smc') # Only allow opening snes roms for now
func init_labels():
lbl_filename_header.modulate = inactive_modulate_color
lbl_filename_content.text = ''
lbl_filetype_header.modulate = inactive_modulate_color
lbl_filetype_content.text = ''
lbl_filesize_header.modulate = inactive_modulate_color
lbl_filesize_content.text = ''
lbl_fileinfo_header.modulate = inactive_modulate_color
lbl_fileinfo_content.text = ''
func _upload_file(filename: String, file_type: String, data): # data is Javascript ArrayBuffer, which should be castable to PoolByteArray
uploaded_files[filename] = data
uploaded_files_types[filename] = file_type
update_view()
func _ready() -> void:
if OS.get_name() != 'HTML5' or !OS.has_feature('JavaScript'):
return
init_labels()
update_view()
btn_ok.connect('pressed', self, 'activate_current_entry')
btn_continue.connect('pressed', self, '_on_continue_pressed')
RomLoader.connect('rom_loaded', self, '_on_rom_loaded')
HTML5.connect('uploaded_file', self, '_upload_file')
func _on_ItemList_item_activated(index: int) -> void:
activate_entry(itemlist.get_item_text(index), index)
func _on_ItemList_item_selected(index: int) -> void:
view_entry(itemlist.get_item_text(index), index)
func _on_btn_upload_pressed() -> void:
HTML5.upload_file()
func _on_rom_loaded() -> void:
$'%lbl_prompt'.text = "Select a save file from your device's storage"
btn_continue.disabled = false
func _on_continue_pressed() -> void:
emit_signal('continue_pressed')