2022-06-27 02:03:10 +02:00
|
|
|
from random import randint
|
|
|
|
|
2022-06-27 01:46:16 +02:00
|
|
|
from kmk.keys import make_argumented_key
|
|
|
|
from kmk.modules import Module
|
|
|
|
|
|
|
|
|
|
|
|
class RapidFireMeta:
|
|
|
|
def __init__(
|
2022-06-27 17:36:11 +02:00
|
|
|
self,
|
|
|
|
kc,
|
2022-06-29 15:49:19 +02:00
|
|
|
interval=100,
|
|
|
|
timeout=200,
|
2022-06-29 16:43:36 +02:00
|
|
|
enable_interval_randomization=False,
|
2022-06-29 15:49:19 +02:00
|
|
|
randomization_magnitude=15,
|
2022-06-27 17:36:11 +02:00
|
|
|
toggle=False,
|
2022-06-27 01:46:16 +02:00
|
|
|
):
|
|
|
|
self.kc = kc
|
2022-06-29 15:49:19 +02:00
|
|
|
self.interval = interval
|
|
|
|
self.timeout = timeout
|
2022-06-29 16:43:36 +02:00
|
|
|
self.enable_interval_randomization = enable_interval_randomization
|
2022-06-29 15:49:19 +02:00
|
|
|
self.randomization_magnitude = randomization_magnitude
|
2022-06-27 17:36:11 +02:00
|
|
|
self.toggle = toggle
|
2022-06-27 01:46:16 +02:00
|
|
|
|
|
|
|
|
|
|
|
class RapidFire(Module):
|
|
|
|
_active_keys = {}
|
2022-06-27 17:36:11 +02:00
|
|
|
_toggled_keys = []
|
2022-06-27 18:20:28 +02:00
|
|
|
_waiting_keys = []
|
2022-06-27 01:46:16 +02:00
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
make_argumented_key(
|
|
|
|
validator=RapidFireMeta,
|
2022-06-27 02:09:50 +02:00
|
|
|
names=('RF',),
|
2022-06-27 01:46:16 +02:00
|
|
|
on_press=self._rf_pressed,
|
|
|
|
on_release=self._rf_released,
|
|
|
|
)
|
|
|
|
|
|
|
|
def _get_repeat(self, key):
|
2022-06-29 16:43:36 +02:00
|
|
|
if key.meta.enable_interval_randomization:
|
2022-06-29 15:49:19 +02:00
|
|
|
return key.meta.interval + randint(
|
|
|
|
-key.meta.randomization_magnitude, key.meta.randomization_magnitude
|
2022-06-27 01:46:16 +02:00
|
|
|
)
|
2022-06-29 15:49:19 +02:00
|
|
|
return key.meta.interval
|
2022-06-27 01:46:16 +02:00
|
|
|
|
2022-06-27 04:01:56 +02:00
|
|
|
def _on_timer_timeout(self, key, keyboard):
|
2022-06-27 01:46:16 +02:00
|
|
|
keyboard.tap_key(key.meta.kc)
|
2022-06-27 18:20:28 +02:00
|
|
|
if key in self._waiting_keys:
|
|
|
|
self._waiting_keys.remove(key)
|
2022-06-27 18:29:27 +02:00
|
|
|
if key.meta.toggle and key not in self._toggled_keys:
|
|
|
|
self._toggled_keys.append(key)
|
2022-06-27 05:57:53 +02:00
|
|
|
self._active_keys[key] = keyboard.set_timeout(
|
2022-06-27 04:01:56 +02:00
|
|
|
self._get_repeat(key), lambda: self._on_timer_timeout(key, keyboard)
|
2022-06-27 01:46:16 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
def _rf_pressed(self, key, keyboard, *args, **kwargs):
|
2022-06-27 17:36:11 +02:00
|
|
|
if key in self._toggled_keys:
|
|
|
|
self._toggled_keys.remove(key)
|
2022-06-27 18:20:28 +02:00
|
|
|
self._deactivate_key(key, keyboard)
|
2022-06-27 17:36:11 +02:00
|
|
|
return
|
2022-06-29 15:49:19 +02:00
|
|
|
if key.meta.timeout > 0:
|
2022-06-28 16:40:34 +02:00
|
|
|
keyboard.tap_key(key.meta.kc)
|
|
|
|
self._waiting_keys.append(key)
|
|
|
|
self._active_keys[key] = keyboard.set_timeout(
|
2022-06-29 15:49:19 +02:00
|
|
|
key.meta.timeout, lambda: self._on_timer_timeout(key, keyboard)
|
2022-06-28 16:40:34 +02:00
|
|
|
)
|
|
|
|
else:
|
|
|
|
self._on_timer_timeout(key, keyboard)
|
2022-06-27 01:46:16 +02:00
|
|
|
|
|
|
|
def _rf_released(self, key, keyboard, *args, **kwargs):
|
2022-06-27 18:20:28 +02:00
|
|
|
if key not in self._active_keys:
|
|
|
|
return
|
|
|
|
if key in self._toggled_keys:
|
|
|
|
if key not in self._waiting_keys:
|
|
|
|
return
|
|
|
|
self._toggled_keys.remove(key)
|
2022-06-28 16:40:34 +02:00
|
|
|
if key in self._waiting_keys:
|
|
|
|
self._waiting_keys.remove(key)
|
2022-06-27 18:20:28 +02:00
|
|
|
self._deactivate_key(key, keyboard)
|
|
|
|
|
|
|
|
def _deactivate_key(self, key, keyboard):
|
|
|
|
keyboard.cancel_timeout(self._active_keys[key])
|
|
|
|
self._active_keys.pop(key)
|
2022-06-27 01:46:16 +02:00
|
|
|
|
|
|
|
def during_bootup(self, keyboard):
|
|
|
|
return
|
|
|
|
|
|
|
|
def before_matrix_scan(self, keyboard):
|
|
|
|
return
|
|
|
|
|
|
|
|
def before_hid_send(self, keyboard):
|
|
|
|
return
|
|
|
|
|
|
|
|
def after_hid_send(self, keyboard):
|
|
|
|
return
|
|
|
|
|
|
|
|
def on_powersave_enable(self, keyboard):
|
|
|
|
return
|
|
|
|
|
|
|
|
def on_powersave_disable(self, keyboard):
|
|
|
|
return
|
|
|
|
|
|
|
|
def after_matrix_scan(self, keyboard):
|
|
|
|
return
|