keebie/scripts/globals/layout_config.gd

185 lines
4.7 KiB
GDScript

extends Node
signal layout_swapped(new_layout: AbstractLayout)
const CONFIG_PATH := "user://layout.cfg"
const CUSTOM_LAYOUTS_PATH := "user://custom_layouts"
const CUSTOM_LAYOUTS_README := "res://resources/kle/README.txt"
const SECTION_INFO := "info"
const SECTION_KEYS := "keys"
const PARAM_NAME := "name"
var current_layout: AbstractLayout
var layout_rows: Array[Array]
var layouts: Dictionary[String, AbstractLayout] = {
LayoutANSI.name: LayoutANSI.new(),
LayoutANSIVariant.name: LayoutANSIVariant.new(),
LayoutISO.name: LayoutISO.new(),
LayoutABNT.name: LayoutABNT.new(),
LayoutJIS.name: LayoutJIS.new(),
# LayoutTest.name: LayoutTest.new(),
}
var _config := ConfigFile.new()
func _ready() -> void:
_load_custom_layouts(CUSTOM_LAYOUTS_PATH)
var err := _load_config()
if err != OK:
_set_defaults()
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("save_config"):
_save_config()
print("layout config saved!")
func get_key_config_dict(keycode: Key) -> Dictionary[KeyProps.Char, String]:
var param_key := str(keycode)
if not _config.has_section_key(SECTION_KEYS, param_key):
return {}
return (
_config.get_value(SECTION_KEYS, param_key, {})
as Dictionary[KeyProps.Char, String]
)
func swap_layout(layout_name: String) -> void:
if layouts.has(layout_name):
_set_layout(layouts[layout_name])
layout_swapped.emit(current_layout)
else:
printerr("layout '%s' not found" % layout_name)
func _set_defaults() -> void:
print("\nsetting defaults")
_set_layout(layouts.values()[0] as AbstractLayout)
# _set_layout(layouts[LayoutANSI.name_static()])
func _set_layout(layout: AbstractLayout) -> void:
print("SETTING LAYOUT: '%s'" % layout.get_name())
current_layout = layout
layout_rows = []
for dict_row: Array[Dictionary] in current_layout.get_rows():
var row: Array[KeyProps] = []
for props_dict: Dictionary in dict_row:
row.append(KeyProps.new().props_from_dict(props_dict))
layout_rows.append(row)
func _load_config() -> Error:
print("\nloading layout config....")
var err := _config.load(CONFIG_PATH)
if err == ERR_FILE_NOT_FOUND:
print("layout config file not found\n")
return FAILED
if err != OK:
printerr("failed to load layout config file: '%s'" % err)
print()
return FAILED
var layout_name := ""
if _config.has_section_key(SECTION_INFO, PARAM_NAME):
layout_name = _config.get_value(SECTION_INFO, PARAM_NAME, "") as String
else:
printerr("layout config is missing '%s/%s'" % [SECTION_INFO, PARAM_NAME])
if layout_name != "" and layouts.has(layout_name):
_set_layout(layouts[layout_name])
else:
printerr("layout '%s' not found" % layout_name)
_set_defaults()
for row: Array[KeyProps] in layout_rows:
for key_props in row:
var param_key := str(key_props.physical_keycode)
if (
not key_props.is_char()
or not _config.has_section_key(SECTION_KEYS, param_key)
):
continue
var dictionary := (
_config.get_value(SECTION_KEYS, param_key, {}) as Dictionary
)
key_props.chars_from_dict(dictionary)
print("layout config loaded!\n")
return OK
func _save_config() -> Error:
_config.set_value(SECTION_INFO, PARAM_NAME, current_layout.get_name())
for row: Array[KeyProps] in layout_rows:
for key_props in row:
if not key_props.is_char():
continue
_config.set_value(
SECTION_KEYS, str(key_props.physical_keycode), key_props.chars_to_dict()
)
var err := _config.save(CONFIG_PATH)
if err != OK:
printerr("failed to save config file: '%s'" % err)
return err
return OK
func _load_custom_layouts(path: String) -> void:
if not DirAccess.dir_exists_absolute(path):
var dir_err := DirAccess.make_dir_absolute(path)
if dir_err != OK:
printerr("error creating directory '%s': %s" % [path, dir_err])
print()
return
var file_err := DirAccess.copy_absolute(
CUSTOM_LAYOUTS_README, path.path_join(CUSTOM_LAYOUTS_README.get_file())
)
if file_err != OK:
printerr("error copying file '%s': %s" % [CUSTOM_LAYOUTS_README, file_err])
var dir := DirAccess.open(path)
if not dir:
var err := DirAccess.get_open_error()
if err == ERR_FILE_NOT_FOUND:
printerr("directory not found '%s'" % path)
else:
printerr("error opening directory '%s': %s" % [path, err])
print()
return
var files := dir.get_files()
if files:
print("loading custom layouts..\n")
for file_name in files:
if file_name.get_extension().to_lower() != "json":
continue
var layout := LayoutCustom.new(path.path_join(file_name))
if layout.failed:
continue
if layouts.has(layout.get_name()):
printerr(
(
"layout '%s' already exists and will be replaced by the new one"
% [layout.get_name()]
)
)
print()
layouts[layout.get_name()] = layout