|
|
@ -39,6 +39,9 @@ INITIAL_CONFIG = {
|
|
|
|
# some time between keystrokes might be required for them to be
|
|
|
|
# some time between keystrokes might be required for them to be
|
|
|
|
# detected properly in software.
|
|
|
|
# detected properly in software.
|
|
|
|
'keystroke_sleep_ms': 10
|
|
|
|
'keystroke_sleep_ms': 10
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
'gamepad': {
|
|
|
|
|
|
|
|
'non_linearity': 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -48,20 +51,74 @@ class _Config:
|
|
|
|
self._config = {}
|
|
|
|
self._config = {}
|
|
|
|
self.load_config()
|
|
|
|
self.load_config()
|
|
|
|
|
|
|
|
|
|
|
|
def set_autoload_preset(self, device, preset, load=True):
|
|
|
|
def _resolve(self, path, func):
|
|
|
|
"""Set a preset to be automatically applied on start."""
|
|
|
|
"""Call func for the given config value."""
|
|
|
|
if self._config.get('autoload') is None:
|
|
|
|
chunks = path.split('.')
|
|
|
|
self._config['autoload'] = {}
|
|
|
|
child = self._config
|
|
|
|
|
|
|
|
while True:
|
|
|
|
if load:
|
|
|
|
chunk = chunks.pop(0)
|
|
|
|
self._config['autoload'][device] = preset
|
|
|
|
parent = child
|
|
|
|
elif self._config['autoload'].get(device) is not None:
|
|
|
|
child = child.get(chunk)
|
|
|
|
del self._config['autoload'][device]
|
|
|
|
if len(chunks) == 0:
|
|
|
|
|
|
|
|
# child is the value _resolve is looking for
|
|
|
|
def get_keystroke_sleep(self):
|
|
|
|
return func(parent, child, chunk)
|
|
|
|
"""Get the seconds of sleep between key down and up events."""
|
|
|
|
else:
|
|
|
|
macros = self._config.get('macros', {})
|
|
|
|
# child is another object
|
|
|
|
return macros.get('keystroke_sleep_ms', 10)
|
|
|
|
if child is None:
|
|
|
|
|
|
|
|
parent[chunk] = {}
|
|
|
|
|
|
|
|
child = parent[chunk]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def remove(self, path):
|
|
|
|
|
|
|
|
"""Remove a config key.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
|
|
|
|
----------
|
|
|
|
|
|
|
|
path : string
|
|
|
|
|
|
|
|
For example 'macros.keystroke_sleep_ms'
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
def do(parent, child, chunk):
|
|
|
|
|
|
|
|
if child is not None:
|
|
|
|
|
|
|
|
del parent[chunk]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self._resolve(path, do)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def set(self, path, value):
|
|
|
|
|
|
|
|
"""Set a config key.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
|
|
|
|
----------
|
|
|
|
|
|
|
|
path : string
|
|
|
|
|
|
|
|
For example 'macros.keystroke_sleep_ms'
|
|
|
|
|
|
|
|
value : any
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
def do(parent, child, chunk):
|
|
|
|
|
|
|
|
parent[chunk] = value
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self._resolve(path, do)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get(self, path, default=None):
|
|
|
|
|
|
|
|
"""Get a config value.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
|
|
|
|
----------
|
|
|
|
|
|
|
|
path : string
|
|
|
|
|
|
|
|
For example 'macros.keystroke_sleep_ms'
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
return self._resolve(path, lambda parent, child, chunk: child)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def set_autoload_preset(self, device, preset):
|
|
|
|
|
|
|
|
"""Set a preset to be automatically applied on start.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
|
|
|
|
----------
|
|
|
|
|
|
|
|
device : string
|
|
|
|
|
|
|
|
preset : string or None
|
|
|
|
|
|
|
|
if None, don't autoload something for this device
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
if preset is not None:
|
|
|
|
|
|
|
|
self.set(f'autoload.{device}', preset)
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
self.remove(f'autoload.{device}')
|
|
|
|
|
|
|
|
|
|
|
|
def iterate_autoload_presets(self):
|
|
|
|
def iterate_autoload_presets(self):
|
|
|
|
"""Get tuples of (device, preset)."""
|
|
|
|
"""Get tuples of (device, preset)."""
|
|
|
@ -69,15 +126,7 @@ class _Config:
|
|
|
|
|
|
|
|
|
|
|
|
def is_autoloaded(self, device, preset):
|
|
|
|
def is_autoloaded(self, device, preset):
|
|
|
|
"""Should this preset be loaded automatically?"""
|
|
|
|
"""Should this preset be loaded automatically?"""
|
|
|
|
autoload_map = self._config.get('autoload')
|
|
|
|
return self.get(f'autoload.{device}') == preset
|
|
|
|
if autoload_map is None:
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
autoload_preset = autoload_map.get(device)
|
|
|
|
|
|
|
|
if autoload_preset is None:
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return autoload_preset == preset
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def load_config(self):
|
|
|
|
def load_config(self):
|
|
|
|
"""Load the config from the file system."""
|
|
|
|
"""Load the config from the file system."""
|
|
|
|