178 lines
4.6 KiB
GDScript
178 lines
4.6 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_key_props_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:
|
|
_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:
|
|
var config_key := OS.get_keycode_string(keycode)
|
|
if not _config.has_section_key(SECTION_KEYS, config_key):
|
|
return {}
|
|
return _config.get_value(SECTION_KEYS, config_key, {}) as Dictionary
|
|
|
|
|
|
func change_layout(layout_name: String) -> void:
|
|
if layouts.has(layout_name):
|
|
_set_layout(layouts[layout_name])
|
|
layout_swapped.emit(current_layout)
|
|
else:
|
|
push_error("layout '%s' not found" % layout_name)
|
|
|
|
|
|
func _set_defaults() -> void:
|
|
print("\nsetting defaults")
|
|
_set_layout(layouts.values()[0] as AbstractLayout)
|
|
|
|
|
|
func _set_layout(layout: AbstractLayout) -> void:
|
|
print("SETTING LAYOUT: '%s'" % layout.get_name())
|
|
current_layout = layout
|
|
layout_key_props_rows = current_layout.get_key_props_rows()
|
|
|
|
|
|
func _load_config() -> Error:
|
|
print("\nloading layout config....")
|
|
var err := _config.load(CONFIG_PATH)
|
|
|
|
if err:
|
|
push_error("failed to load layout config file: '%s'" % error_string(err))
|
|
print()
|
|
return err
|
|
|
|
var layout_name := ""
|
|
if _config.has_section_key(SECTION_INFO, PARAM_NAME):
|
|
var config_layout_name: Variant = _config.get_value(SECTION_INFO, PARAM_NAME)
|
|
if config_layout_name is String:
|
|
layout_name = config_layout_name as String
|
|
else:
|
|
push_error("layout config is missing '%s/%s'" % [SECTION_INFO, PARAM_NAME])
|
|
|
|
if layout_name != "" and layouts.has(layout_name):
|
|
_set_layout(layouts[layout_name])
|
|
else:
|
|
push_error("layout '%s' not found" % layout_name)
|
|
_set_defaults()
|
|
|
|
for key_props_row: Array[KeyProps] in layout_key_props_rows:
|
|
for key_props in key_props_row:
|
|
var config_key := OS.get_keycode_string(key_props.keycode)
|
|
if (
|
|
not key_props.is_unicode()
|
|
or not _config.has_section_key(SECTION_KEYS, config_key)
|
|
):
|
|
continue
|
|
|
|
var chars_dict: Variant = _config.get_value(SECTION_KEYS, config_key)
|
|
if chars_dict is not Dictionary:
|
|
continue
|
|
key_props.chars_from_dict(chars_dict as Dictionary)
|
|
|
|
print("layout config loaded!\n")
|
|
|
|
return OK
|
|
|
|
|
|
func _save_config() -> Error:
|
|
_config.set_value(SECTION_INFO, PARAM_NAME, current_layout.get_name())
|
|
|
|
for key_props_row: Array[KeyProps] in layout_key_props_rows:
|
|
for key_props in key_props_row:
|
|
if not key_props.is_unicode():
|
|
continue
|
|
|
|
_config.set_value(
|
|
SECTION_KEYS,
|
|
OS.get_keycode_string(key_props.keycode),
|
|
key_props.chars_to_dict()
|
|
)
|
|
|
|
var err := _config.save(CONFIG_PATH)
|
|
|
|
if err:
|
|
push_error("failed to save config file: '%s'" % error_string(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:
|
|
push_error(
|
|
"error creating directory '%s': %s" % [path, error_string(dir_err)]
|
|
)
|
|
print()
|
|
return
|
|
var file_err := DirAccess.copy_absolute(
|
|
CUSTOM_LAYOUTS_README, path.path_join(CUSTOM_LAYOUTS_README.get_file())
|
|
)
|
|
if file_err:
|
|
push_error(
|
|
(
|
|
"error creating file '%s': %s"
|
|
% [CUSTOM_LAYOUTS_README, error_string(file_err)]
|
|
)
|
|
)
|
|
|
|
var dir := DirAccess.open(path)
|
|
if not dir:
|
|
var err := DirAccess.get_open_error()
|
|
push_error("error opening directory '%s': %s" % [path, error_string(err)])
|
|
print()
|
|
return
|
|
|
|
var file_names := dir.get_files()
|
|
|
|
if not file_names:
|
|
return
|
|
|
|
print("loading custom layouts..\n")
|
|
for file_name in file_names:
|
|
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()):
|
|
push_warning(
|
|
(
|
|
"layout '%s' already exists and will be replaced by the new one"
|
|
% [layout.get_name()]
|
|
)
|
|
)
|
|
layouts[layout.get_name()] = layout
|