1 Commits

Author SHA1 Message Date
Cole Smith
58a7f04d00 added draculad keyboard 2023-01-25 12:46:53 -08:00
31 changed files with 587 additions and 441 deletions

24
boards/draculad/README.md Normal file
View File

@@ -0,0 +1,24 @@
# Draculad
The Draculad is is a feature-packed 30% split columnar staggered keyboard.
Retailers (USA)
[Boardsource](https://boardsource.xyz/store)
Extensions enabled by default
- [Layers](/docs/en/layers.md) Need more keys than switches? Use layers.
- [ModTap](/docs/en/modtap.md) Allows mod keys to act as different keys when tapped.
- [Split](/docs/en/split_keyboards.md) Connects halves using a wire
- [peg_RGB_matrix](/docs/en/peg_rgb_matrix.md) Allows mod keys to act as different keys when tapped.
- [peg_oled_display](/docs/en/peg_oled_display.md) Connects halves using a wire
Common Extensions
- [Power](/docs/enpower.md) Powersaving features for battery life
## Microcontroller support
Update this line in `kb.py` to any supported microcontroller in `kmk/quickpin/pro_micro`:
```python
from kmk.quickpin.pro_micro.boardsource_blok import pinout as pins
```

69
boards/draculad/kb.py Normal file
View File

@@ -0,0 +1,69 @@
import board
from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard
from kmk.quickpin.pro_Micro.avr_promicro import translate as avr
from kmk.quickpin.pro_micro.boardsource_blok import pinout as pins
from kmk.scanners import DiodeOrientation
# from kmk.scanners.encoder import RotaryioEncoder
from kmk.scanners.keypad import MatrixScanner
class KMKKeyboard(_KMKKeyboard):
def __init__(self):
# create and register the scanner
self.matrix = [
MatrixScanner(
# required arguments:
column_pins = self.col_pins,
row_pins = self.row_pins,
# optional arguments with defaults:
columns_to_anodes=DiodeOrientation.COL2ROW,
interval=0.02,
max_events=64
),
# RotaryioEncoder(
# pin_a=self.pin_a1,
# pin_b=self.pin_b1,
# # optional
# divisor=4,
# ),
# RotaryioEncoder(
# pin_a=self.pin_a2,
# pin_b=self.pin_b2,
# # optional
# divisor=4,
# )
]
col_pins = (
pins[avr["F4"]],
pins[avr["F5"]],
pins[avr["F6"]],
pins[avr["F7"]],
pins[avr["B1"]],
)
row_pins = (pins[avr["D4"]], pins[avr["C6"]], pins[avr["D7"]], pins[avr["E6"]])
data_pin = pins[avr["D2"]]
rgb_pixel_pin = pins[avr["D3"]]
rgb_num_pixels = 20
i2c = board.I2C
SCL=pins[5]
SDA=pins[4]
pin_a1=pins[avr["B2"]]
pin_a2=pins[avr["B4"]]
pin_b1=pins[avr["B6"]]
pin_b2=pins[avr["B5"]]
led_key_pos=[
5,6,7,8,9,19,18,17,16,15,14,13,12,11,10,0,1,2,3,4
]
brightness_limit = 1.0
num_pixels = 20
# NOQA
# flake8: noqa
# fmt: off
coord_mapping = [
0, 1, 2, 3, 4, 24, 23, 22, 21, 20,
5, 6, 7, 8, 9, 29, 28, 27, 26, 25,
10, 11, 12, 13, 14, 34, 33, 32, 31, 30,
17, 18, 19, 39, 36, 35,
]

64
boards/draculad/main.py Normal file
View File

@@ -0,0 +1,64 @@
from kb import KMKKeyboard
from kmk.extensions.peg_oled_Display import (
Oled,
OledData,
OledDisplayMode,
OledReactionType,
)
from kmk.extensions.peg_rgb_matrix import Rgb_matrix
from kmk.keys import KC
from kmk.modules.layers import Layers
from kmk.modules.modtap import ModTap
from kmk.modules.split import Split
keyboard = KMKKeyboard()
keyboard.debug_enable=True
modtap = ModTap()
layers_ext = Layers()
keyboard.modules.append(layers_ext)
keyboard.modules.append(modtap)
# oled
oled_ext = Oled(OledData(corner_one={0:OledReactionType.STATIC,1:["1 2 3 4 5 6","","","","","","",""]},corner_two={0:OledReactionType.STATIC,1:[" 7 8 Layer","","","","","",""," 7 8 Layer"]},corner_three={0:OledReactionType.LAYER,1:["^"," ^"," ^"," ^"," ^"," ^","",""]},corner_four={0:OledReactionType.LAYER,1:["","","","","",""," ^"," ^"]}),toDisplay=OledDisplayMode.TXT,flip= True)
# oled
keyboard.extensions.append(oled_ext)
# ledmap
rgb_ext = Rgb_matrix(ledDisplay=[[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255]],split=True,rightSide=False,disable_auto_write=True)
# ledmap
keyboard.extensions.append(rgb_ext)
split = Split(use_pio=True)
keyboard.modules.append(split)
_______ = KC.TRNS
XXXXXXX = KC.NO
LOWER = KC.MO(2)
RAISE = KC.MO(1)
keyboard.keymap = [
[ #QWERTY
KC.Q, KC.W, KC.E, KC.R, KC.T, KC.Y, KC.U, KC.I, KC.O, KC.P,\
KC.A, KC.S, KC.D, KC.F, KC.G, KC.H, KC.J, KC.K, KC.L, KC.SCLN,\
KC.Z, KC.X, KC.C, KC.V, KC.B, KC.N, KC.M, KC.COMM, KC.DOT, KC.SLSH,\
KC.LCTL, LOWER, KC.SPC, KC.BSPC, RAISE, KC.ENT
],
[ #RAISE
KC.N1, KC.N2, KC.N3, KC.N4, KC.N5, KC.N6, KC.N7, KC.N8, KC.N9, KC.N0,\
KC.TAB, KC.LEFT, KC.DOWN, KC.UP, KC.RGHT, XXXXXXX, KC.MINS, KC.EQL, KC.LBRC, KC.RBRC,\
KC.LCTL, KC.GRV, KC.LGUI, KC.LALT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC.BSLS, KC.QUOT,\
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
],
[ #LOWER
KC.EXLM, KC.AT, KC.HASH, KC.DLR, KC.PERC, KC.CIRC, KC.AMPR, KC.ASTR, KC.LPRN, KC.RPRN,\
KC.ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC.UNDS, KC.PLUS, KC.LCBR, KC.RCBR,\
KC.CAPS, KC.TILD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC.PIPE, KC.DQT,\
XXXXXXX, XXXXXXX, XXXXXXX, KC.ENT, XXXXXXX, KC.DEL
]
]
if __name__ == '__main__':
keyboard.go()

View File

@@ -84,7 +84,7 @@ class Layers(_Layers):
last_top_layer = 0
hues = (4, 20, 69)
def after_hid_send(self, keyboard):
def after_hid_send(keyboard):
if keyboard.active_layers[0] != self.last_top_layer:
self.last_top_layer = keyboard.active_layers[0]
rgb.set_hsv_fill(self.hues[self.last_top_layer], 255, 255)

View File

@@ -1,42 +1,35 @@
'''Adds international keys'''
from kmk.extensions import Extension
from kmk.keys import KC, make_key
from kmk.keys import make_key
class International(Extension):
'''Adds international keys'''
def __init__(self):
KC._generators.append(self.maybe_make_media_key)
# International
make_key(code=50, names=('NONUS_HASH', 'NUHS'))
make_key(code=100, names=('NONUS_BSLASH', 'NUBS'))
make_key(code=101, names=('APP', 'APPLICATION', 'SEL', 'WINMENU'))
@staticmethod
def maybe_make_media_key(candidate):
codes = (
(50, ('NONUS_HASH', 'NUHS')),
(100, ('NONUS_BSLASH', 'NUBS')),
(101, ('APP', 'APPLICATION', 'SEL', 'WINMENU')),
(135, ('INT1', 'RO')),
(136, ('INT2', 'KANA')),
(137, ('INT3', 'JYEN')),
(138, ('INT4', 'HENK')),
(139, ('INT5', 'MHEN')),
(140, ('INT6',)),
(141, ('INT7',)),
(142, ('INT8',)),
(143, ('INT9',)),
(144, ('LANG1', 'HAEN')),
(145, ('LANG2', 'HAEJ')),
(146, ('LANG3',)),
(147, ('LANG4',)),
(148, ('LANG5',)),
(149, ('LANG6',)),
(150, ('LANG7',)),
(151, ('LANG8',)),
(152, ('LANG9',)),
)
for code, names in codes:
if candidate in names:
return make_key(code=code, names=names)
make_key(code=135, names=('INT1', 'RO'))
make_key(code=136, names=('INT2', 'KANA'))
make_key(code=137, names=('INT3', 'JYEN'))
make_key(code=138, names=('INT4', 'HENK'))
make_key(code=139, names=('INT5', 'MHEN'))
make_key(code=140, names=('INT6',))
make_key(code=141, names=('INT7',))
make_key(code=142, names=('INT8',))
make_key(code=143, names=('INT9',))
make_key(code=144, names=('LANG1', 'HAEN'))
make_key(code=145, names=('LANG2', 'HAEJ'))
make_key(code=146, names=('LANG3',))
make_key(code=147, names=('LANG4',))
make_key(code=148, names=('LANG5',))
make_key(code=149, names=('LANG6',))
make_key(code=150, names=('LANG7',))
make_key(code=151, names=('LANG8',))
make_key(code=152, names=('LANG9',))
def on_runtime_enable(self, sandbox):
return

View File

@@ -2,8 +2,7 @@ import pwmio
from math import e, exp, pi, sin
from kmk.extensions import Extension, InvalidExtensionEnvironment
from kmk.handlers.stock import passthrough as handler_passthrough
from kmk.keys import KC, make_argumented_key, make_key
from kmk.keys import make_argumented_key, make_key
from kmk.utils import clamp
@@ -62,50 +61,34 @@ class LED(Extension):
if user_animation is not None:
self.user_animation = user_animation
KC._generators.append(self.maybe_make_led_key())
def maybe_make_led_key(self):
argumented_keys = (
(
('LED_TOG',),
self._key_led_tog,
),
(
('LED_INC',),
self._key_led_inc,
),
(
('LED_DEC',),
self._key_led_dec,
),
(
('LED_SET',),
self._key_led_set,
),
)
keys = (
(('LED_ANI',), self._key_led_ani),
(('LED_AND',), self._key_led_and),
(('LED_MODE_PLAIN', 'LED_M_P'), self._key_led_mode_static),
(('LED_MODE_BREATHE', 'LED_M_B'), self._key_led_mode_breathe),
)
def closure(candidate):
for names, on_press in argumented_keys:
if candidate in names:
return make_argumented_key(
names=names,
make_argumented_key(
names=('LED_TOG',),
validator=self._led_key_validator,
on_press=on_press,
on_release=handler_passthrough,
on_press=self._key_led_tog,
)
for names, on_press in keys:
if candidate in names:
return make_key(
names=names, on_press=on_press, on_release=handler_passthrough
make_argumented_key(
names=('LED_INC',),
validator=self._led_key_validator,
on_press=self._key_led_inc,
)
make_argumented_key(
names=('LED_DEC',),
validator=self._led_key_validator,
on_press=self._key_led_dec,
)
make_argumented_key(
names=('LED_SET',),
validator=self._led_set_key_validator,
on_press=self._key_led_set,
)
make_key(names=('LED_ANI',), on_press=self._key_led_ani)
make_key(names=('LED_AND',), on_press=self._key_led_and)
make_key(
names=('LED_MODE_PLAIN', 'LED_M_P'), on_press=self._key_led_mode_static
)
make_key(
names=('LED_MODE_BREATHE', 'LED_M_B'), on_press=self._key_led_mode_breathe
)
return closure
def __repr__(self):
return f'LED({self._to_dict()})'

View File

@@ -1,13 +1,9 @@
from kmk.extensions import Extension
from kmk.keys import KC, make_consumer_key
from kmk.keys import make_consumer_key
class MediaKeys(Extension):
def __init__(self):
KC._generators.append(self.maybe_make_media_key)
@staticmethod
def maybe_make_media_key(candidate):
# Consumer ("media") keys. Most known keys aren't supported here. A much
# longer list used to exist in this file, but the codes were almost certainly
# incorrect, conflicting with each other, or otherwise 'weird'. We'll add them
@@ -18,23 +14,20 @@ class MediaKeys(Extension):
# support PC media keys, so I don't know how much value we would get out of
# adding the old Apple-specific consumer codes, but again, PRs welcome if the
# lack of them impacts you.
codes = (
(226, ('AUDIO_MUTE', 'MUTE')), # 0xE2
(233, ('AUDIO_VOL_UP', 'VOLU')), # 0xE9
(234, ('AUDIO_VOL_DOWN', 'VOLD')), # 0xEA
(111, ('BRIGHTNESS_UP', 'BRIU')), # 0x6F
(112, ('BRIGHTNESS_DOWN', 'BRID')), # 0x70
(181, ('MEDIA_NEXT_TRACK', 'MNXT')), # 0xB5
(182, ('MEDIA_PREV_TRACK', 'MPRV')), # 0xB6
(183, ('MEDIA_STOP', 'MSTP')), # 0xB7
(205, ('MEDIA_PLAY_PAUSE', 'MPLY')), # 0xCD (this may not be right)
(184, ('MEDIA_EJECT', 'EJCT')), # 0xB8
(179, ('MEDIA_FAST_FORWARD', 'MFFD')), # 0xB3
(180, ('MEDIA_REWIND', 'MRWD')), # 0xB4
)
for code, names in codes:
if candidate in names:
return make_consumer_key(code=code, names=names)
make_consumer_key(code=226, names=('AUDIO_MUTE', 'MUTE')) # 0xE2
make_consumer_key(code=233, names=('AUDIO_VOL_UP', 'VOLU')) # 0xE9
make_consumer_key(code=234, names=('AUDIO_VOL_DOWN', 'VOLD')) # 0xEA
make_consumer_key(code=111, names=('BRIGHTNESS_UP', 'BRIU')) # 0x6F
make_consumer_key(code=112, names=('BRIGHTNESS_DOWN', 'BRID')) # 0x70
make_consumer_key(code=181, names=('MEDIA_NEXT_TRACK', 'MNXT')) # 0xB5
make_consumer_key(code=182, names=('MEDIA_PREV_TRACK', 'MPRV')) # 0xB6
make_consumer_key(code=183, names=('MEDIA_STOP', 'MSTP')) # 0xB7
make_consumer_key(
code=205, names=('MEDIA_PLAY_PAUSE', 'MPLY')
) # 0xCD (this may not be right)
make_consumer_key(code=184, names=('MEDIA_EJECT', 'EJCT')) # 0xB8
make_consumer_key(code=179, names=('MEDIA_FAST_FORWARD', 'MFFD')) # 0xB3
make_consumer_key(code=180, names=('MEDIA_REWIND', 'MRWD')) # 0xB4
def on_runtime_enable(self, sandbox):
return

View File

@@ -4,7 +4,7 @@ from storage import getmount
from kmk.extensions import Extension
from kmk.handlers.stock import passthrough as handler_passthrough
from kmk.keys import KC, make_key
from kmk.keys import make_key
class Color:
@@ -69,34 +69,15 @@ class Rgb_matrix(Extension):
else:
self.ledDisplay = ledDisplay
KC._generators.append(self.maybe_make_peg_rgb_key())
def maybe_make_peg_rgb_key(self):
keys = (
(
('RGB_TOG',),
self._rgb_tog,
),
(
('RGB_BRI',),
self._rgb_bri,
),
(
('RGB_BRD',),
self._rgb_brd,
),
make_key(
names=('RGB_TOG',), on_press=self._rgb_tog, on_release=handler_passthrough
)
def closure(candidate):
for names, on_press in keys:
if candidate in names:
return make_key(
names=names,
on_press=on_press,
on_release=handler_passthrough,
make_key(
names=('RGB_BRI',), on_press=self._rgb_bri, on_release=handler_passthrough
)
make_key(
names=('RGB_BRD',), on_press=self._rgb_brd, on_release=handler_passthrough
)
return closure
def _rgb_tog(self, *args, **kwargs):
if self.enable:

View File

@@ -3,7 +3,7 @@ from math import e, exp, pi, sin
from kmk.extensions import Extension
from kmk.handlers.stock import passthrough as handler_passthrough
from kmk.keys import KC, make_key
from kmk.keys import make_key
from kmk.kmktime import PeriodicTimer
from kmk.utils import Debug, clamp
@@ -59,7 +59,7 @@ def hsv_to_rgb(hue, sat, val):
return (r >> 8), (g >> 8), (b >> 8)
def hsv_to_rgbw(hue, sat, val):
def hsv_to_rgbw(self, hue, sat, val):
'''
Converts HSV values, and returns a tuple of RGBW values
:param hue:
@@ -157,36 +157,68 @@ class RGB(Extension):
self._substep = 0
KC._generators.append(self.maybe_make_rgb_key())
def maybe_make_rgb_key(self):
keys = (
(('RGB_TOG',), self._rgb_tog),
(('RGB_HUI',), self._rgb_hui),
(('RGB_HUD',), self._rgb_hud),
(('RGB_SAI',), self._rgb_sai),
(('RGB_SAD',), self._rgb_sad),
(('RGB_VAI',), self._rgb_vai),
(('RGB_VAD',), self._rgb_vad),
(('RGB_ANI',), self._rgb_ani),
(('RGB_AND',), self._rgb_and),
(('RGB_MODE_PLAIN', 'RGB_M_P'), self._rgb_mode_static),
(('RGB_MODE_BREATHE', 'RGB_M_B'), self._rgb_mode_breathe),
(('RGB_MODE_RAINBOW', 'RGB_M_R'), self._rgb_mode_rainbow),
(('RGB_MODE_BREATHE_RAINBOW', 'RGB_M_BR'), self._rgb_mode_breathe_rainbow),
(('RGB_MODE_SWIRL', 'RGB_M_S'), self._rgb_mode_swirl),
(('RGB_MODE_KNIGHT', 'RGB_M_K'), self._rgb_mode_knight),
(('RGB_RESET', 'RGB_RST'), self._rgb_reset),
make_key(
names=('RGB_TOG',), on_press=self._rgb_tog, on_release=handler_passthrough
)
def closure(candidate):
for names, on_press in keys:
if candidate in names:
return make_key(
names=names, on_press=on_press, on_release=handler_passthrough
make_key(
names=('RGB_HUI',), on_press=self._rgb_hui, on_release=handler_passthrough
)
make_key(
names=('RGB_HUD',), on_press=self._rgb_hud, on_release=handler_passthrough
)
make_key(
names=('RGB_SAI',), on_press=self._rgb_sai, on_release=handler_passthrough
)
make_key(
names=('RGB_SAD',), on_press=self._rgb_sad, on_release=handler_passthrough
)
make_key(
names=('RGB_VAI',), on_press=self._rgb_vai, on_release=handler_passthrough
)
make_key(
names=('RGB_VAD',), on_press=self._rgb_vad, on_release=handler_passthrough
)
make_key(
names=('RGB_ANI',), on_press=self._rgb_ani, on_release=handler_passthrough
)
make_key(
names=('RGB_AND',), on_press=self._rgb_and, on_release=handler_passthrough
)
make_key(
names=('RGB_MODE_PLAIN', 'RGB_M_P'),
on_press=self._rgb_mode_static,
on_release=handler_passthrough,
)
make_key(
names=('RGB_MODE_BREATHE', 'RGB_M_B'),
on_press=self._rgb_mode_breathe,
on_release=handler_passthrough,
)
make_key(
names=('RGB_MODE_RAINBOW', 'RGB_M_R'),
on_press=self._rgb_mode_rainbow,
on_release=handler_passthrough,
)
make_key(
names=('RGB_MODE_BREATHE_RAINBOW', 'RGB_M_BR'),
on_press=self._rgb_mode_breathe_rainbow,
on_release=handler_passthrough,
)
make_key(
names=('RGB_MODE_SWIRL', 'RGB_M_S'),
on_press=self._rgb_mode_swirl,
on_release=handler_passthrough,
)
make_key(
names=('RGB_MODE_KNIGHT', 'RGB_M_K'),
on_press=self._rgb_mode_knight,
on_release=handler_passthrough,
)
make_key(
names=('RGB_RESET', 'RGB_RST'),
on_press=self._rgb_reset,
on_release=handler_passthrough,
)
return closure
def on_runtime_enable(self, sandbox):
return

View File

@@ -4,8 +4,7 @@ import pwmio
import time
from kmk.extensions import Extension, InvalidExtensionEnvironment
from kmk.handlers.stock import passthrough as handler_passthrough
from kmk.keys import KC, make_key
from kmk.keys import make_key
class statusLED(Extension):
@@ -33,24 +32,8 @@ class statusLED(Extension):
self.brightness_step = brightness_step
self.brightness_limit = brightness_limit
KC._generators.append(self.maybe_make_status_led_key())
def maybe_make_status_led_key(self):
keys = (
(('SLED_INC',), self._key_led_inc),
(('SLED_DEC',), self._key_led_dec),
)
def closure(candidate):
for names, on_press in keys:
if candidate in names:
return make_key(
names=names,
on_press=on_press,
on_release=handler_passthrough,
)
return closure
make_key(names=('SLED_INC',), on_press=self._key_led_inc)
make_key(names=('SLED_DEC',), on_press=self._key_led_dec)
def _layer_indicator(self, layer_active, *args, **kwargs):
'''

View File

@@ -35,7 +35,7 @@ def simple_key_sequence(seq):
meta=KeySequenceMeta(seq),
on_press=sequence_press_handler,
on_release=passthrough,
)[0]
)
def send_string(message):
@@ -124,7 +124,7 @@ def unicode_codepoint_sequence(codepoints):
simple_key_sequence(_winc_unicode_sequence(kc_macros, keyboard)), True
)
return make_key(on_press=_unicode_sequence)[0]
return make_key(on_press=_unicode_sequence)
def _ralt_unicode_sequence(kc_macros, keyboard):

View File

@@ -34,8 +34,8 @@ debug = Debug(__name__)
def maybe_make_key(
code: Optional[int] = None,
names: Tuple[str, ...] = tuple(), # NOQA
code: Optional[int],
names: Tuple[str, ...],
*args,
**kwargs,
) -> Callable[[str], Key]:
@@ -401,7 +401,6 @@ KEY_GENERATORS = (
class KeyAttrDict:
__cache = {}
_generators = list(KEY_GENERATORS)
def __iter__(self):
return self.__cache.__iter__()
@@ -420,30 +419,24 @@ class KeyAttrDict:
def clear(self):
self.__cache.clear()
self._generators = list(KEY_GENERATORS)
def __getitem__(self, name: str):
for names, key in self.__cache.items():
if name in names:
return key
def __getitem__(self, key: Key):
try:
return self.__cache[key]
except KeyError:
pass
for func in self._generators:
maybe_key = func(name)
for func in KEY_GENERATORS:
maybe_key = func(key)
if maybe_key:
break
if not maybe_key:
raise ValueError(f'Invalid key: {name}')
key, names = maybe_key
if names:
self.__cache[names] = key
else:
raise ValueError(f'Invalid key: {key}')
if debug.enabled:
debug(f'{name}: {key}')
debug(f'{key}: {maybe_key}')
return key
return self.__cache[key]
# Global state, will be filled in throughout this file, and
@@ -678,7 +671,7 @@ class ConsumerKey(Key):
def make_key(
code: Optional[int] = None,
names: Optional[Tuple[str, ...]] = tuple(), # NOQA
names: Tuple[str, ...] = tuple(), # NOQA
type: KeyType = KeyType.SIMPLE,
**kwargs,
) -> Key:
@@ -720,7 +713,10 @@ def make_key(
key = constructor(code=code, **kwargs)
return key, names
for name in names:
KC[name] = key
return key
def make_mod_key(code: int, names: Tuple[str, ...], *args, **kwargs) -> Key:
@@ -766,4 +762,7 @@ def make_argumented_key(
'should have been raised.'
)
return _argumented_key, names
for name in names:
KC[name] = _argumented_key
return _argumented_key

View File

@@ -1,5 +1,4 @@
from kmk.handlers.stock import passthrough as handler_passthrough
from kmk.keys import FIRST_KMK_INTERNAL_KEY, KC, ModifierKey, maybe_make_key
from kmk.keys import FIRST_KMK_INTERNAL_KEY, KC, ModifierKey, make_key
from kmk.modules import Module
@@ -17,16 +16,12 @@ class CapsWord(Module):
self._timeout_key = False
self._cw_active = False
self.timeout = timeout
KC._generators.append(self.maybe_make_capsword_key())
def maybe_make_capsword_key(self):
return maybe_make_key(
make_key(
names=(
'CAPSWORD',
'CW',
),
on_press=self.cw_pressed,
on_release=handler_passthrough,
)
def during_bootup(self, keyboard):

View File

@@ -1,4 +1,3 @@
from kmk.handlers.stock import passthrough as handler_passthrough
from kmk.keys import KC, ModifierKey, make_key
from kmk.modules import Module
@@ -13,25 +12,15 @@ class CgSwap(Module):
KC.LGUI: KC.LCTL,
KC.RGUI: KC.RCTL,
}
KC._generators.append(self.maybe_make_cgswap_key())
def maybe_make_cgswap_key(self):
keys = (
(('CG_SWAP',),),
(('CG_NORM',),),
(('CG_TOGG',),),
make_key(
names=('CG_SWAP',),
)
def closure(candidate):
for names in keys:
if candidate in names:
return make_key(
names=names,
on_press=handler_passthrough,
on_release=handler_passthrough,
make_key(
names=('CG_NORM',),
)
make_key(
names=('CG_TOGG',),
)
return closure
def during_bootup(self, keyboard):
return

View File

@@ -5,7 +5,7 @@ except ImportError:
from micropython import const
import kmk.handlers.stock as handlers
from kmk.keys import KC, Key, maybe_make_key
from kmk.keys import Key, make_key
from kmk.kmk_keyboard import KMKKeyboard
from kmk.modules import Module
@@ -102,13 +102,12 @@ class Combos(Module):
def __init__(self, combos=[]):
self.combos = combos
self._key_buffer = []
KC._generators.append(
maybe_make_key(
make_key(
names=('LEADER', 'LDR'),
on_press=handlers.passthrough,
on_release=handlers.passthrough,
)
)
def during_bootup(self, keyboard):
self.reset(keyboard)

View File

@@ -3,7 +3,6 @@ from supervisor import ticks_ms
from collections import namedtuple
from kmk.handlers.stock import passthrough as handler_passthrough
from kmk.keys import KC, make_argumented_key
from kmk.kmktime import check_deadline, ticks_diff
from kmk.modules import Module
@@ -46,33 +45,41 @@ class DynamicSequences(Module):
self.index = 0
self.start_time = 0
self.current_repetition = 0
self.last_config_frame = set()
self.timeout = timeout
self.key_interval = key_interval
self.use_recorded_speed = use_recorded_speed
KC._generators.append(self.maybe_make_sequence_key())
def maybe_make_sequence_key(self):
keys = (
(('RECORD_SEQUENCE',), DSMeta, self._record_sequence),
(('PLAY_SEQUENCE',), DSMeta, self._play_sequence),
(('SET_SEQUENCE', 'STOP_SEQUENCE'), DSMeta, self._stop_sequence),
(('SET_SEQUENCE_REPETITIONS',), DSMeta, self._set_sequence_repetitions),
(('SET_SEQUENCE_INTERVAL',), DSMeta, self._set_sequence_interval),
# Create keycodes
make_argumented_key(
validator=DSMeta, names=('RECORD_SEQUENCE',), on_press=self._record_sequence
)
def closure(candidate):
for names, validator, on_press in keys:
if candidate in names:
return make_argumented_key(
names=names,
validator=validator,
on_press=on_press,
on_release=handler_passthrough,
make_argumented_key(
validator=DSMeta, names=('PLAY_SEQUENCE',), on_press=self._play_sequence
)
return closure
make_argumented_key(
validator=DSMeta,
names=(
'SET_SEQUENCE',
'STOP_SEQUENCE',
),
on_press=self._stop_sequence,
)
make_argumented_key(
validator=DSMeta,
names=('SET_SEQUENCE_REPETITIONS',),
on_press=self._set_sequence_repetitions,
)
make_argumented_key(
validator=DSMeta,
names=('SET_SEQUENCE_INTERVAL',),
on_press=self._set_sequence_interval,
)
def _record_sequence(self, key, keyboard, *args, **kwargs):
self._stop_sequence(key, keyboard)

View File

@@ -1,6 +1,6 @@
from micropython import const
from kmk.keys import KC, maybe_make_argumented_key
from kmk.keys import KC, make_argumented_key
from kmk.modules import Module
from kmk.utils import Debug
@@ -55,14 +55,12 @@ class HoldTap(Module):
self.key_buffer = []
self.key_states = {}
if not KC.get('HT'):
KC._generators.append(
maybe_make_argumented_key(
make_argumented_key(
validator=HoldTapKeyMeta,
names=('HT',),
on_press=self.ht_pressed,
on_release=self.ht_released,
)
)
def during_bootup(self, keyboard):
return

View File

@@ -1,5 +1,4 @@
'''One layer isn't enough. Adds keys to get to more of them'''
from kmk.handlers.stock import passthrough as handler_passthrough
from kmk.keys import KC, make_argumented_key
from kmk.modules.holdtap import HoldTap, HoldTapKeyMeta
from kmk.utils import Debug
@@ -40,30 +39,39 @@ class Layers(HoldTap):
def __init__(self):
# Layers
super().__init__()
KC._generators.append(self.maybe_make_layer_key())
def maybe_make_layer_key(self):
keys = (
(('MO',), layer_key_validator, self._mo_pressed, self._mo_released),
(('DF',), layer_key_validator, self._df_pressed, handler_passthrough),
(('LM',), layer_key_validator, self._lm_pressed, self._lm_released),
(('TG',), layer_key_validator, self._tg_pressed, handler_passthrough),
(('TO',), layer_key_validator, self._to_pressed, handler_passthrough),
(('LT',), layer_key_validator_lt, self.ht_pressed, self.ht_released),
(('TT',), layer_key_validator_tt, self.ht_pressed, self.ht_released),
make_argumented_key(
validator=layer_key_validator,
names=('MO',),
on_press=self._mo_pressed,
on_release=self._mo_released,
)
def closure(candidate):
for names, validator, on_press, on_release in keys:
if candidate in names:
return make_argumented_key(
names=names,
validator=validator,
on_press=on_press,
on_release=on_release,
make_argumented_key(
validator=layer_key_validator, names=('DF',), on_press=self._df_pressed
)
make_argumented_key(
validator=layer_key_validator,
names=('LM',),
on_press=self._lm_pressed,
on_release=self._lm_released,
)
make_argumented_key(
validator=layer_key_validator, names=('TG',), on_press=self._tg_pressed
)
make_argumented_key(
validator=layer_key_validator, names=('TO',), on_press=self._to_pressed
)
make_argumented_key(
validator=layer_key_validator_lt,
names=('LT',),
on_press=self.ht_pressed,
on_release=self.ht_released,
)
make_argumented_key(
validator=layer_key_validator_tt,
names=('TT',),
on_press=self.ht_pressed,
on_release=self.ht_released,
)
return closure
def _df_pressed(self, key, keyboard, *args, **kwargs):
'''

View File

@@ -8,8 +8,7 @@ from adafruit_midi.program_change import ProgramChange
from adafruit_midi.start import Start
from adafruit_midi.stop import Stop
from kmk.handlers.stock import passthrough as handler_passthrough
from kmk.keys import KC, make_argumented_key
from kmk.keys import make_argumented_key
from kmk.modules import Module
@@ -22,6 +21,42 @@ class midiNoteValidator:
class MidiKeys(Module):
def __init__(self):
make_argumented_key(
names=('MIDI_CC',),
validator=ControlChange,
on_press=self.on_press,
)
make_argumented_key(
names=('MIDI_NOTE',),
validator=midiNoteValidator,
on_press=self.note_on,
on_release=self.note_off,
)
make_argumented_key(
names=('MIDI_PB',),
validator=PitchBend,
on_press=self.on_press,
)
make_argumented_key(
names=('MIDI_PC',),
validator=ProgramChange,
on_press=self.on_press,
)
make_argumented_key(
names=('MIDI_START',),
validator=Start,
on_press=self.on_press,
)
make_argumented_key(
names=('MIDI_STOP',),
validator=Stop,
on_press=self.on_press,
)
try:
self.midi = adafruit_midi.MIDI(midi_out=usb_midi.ports[1], out_channel=0)
@@ -30,37 +65,6 @@ class MidiKeys(Module):
# if debug_enabled:
print('No midi device found.')
KC._generators.append(self.maybe_make_midi_key())
def maybe_make_midi_key(self):
keys = (
(('MIDI_CC',), ControlChange),
(('MIDI_PB',), PitchBend),
(('MIDI_PC',), ProgramChange),
(('MIDI_START',), Start),
(('MIDI_STOP',), Stop),
)
note = ('MIDI_NOTE',)
def closure(candidate):
if candidate in note:
return make_argumented_key(
names=('MIDI_NOTE',),
validator=midiNoteValidator,
on_press=self.note_on,
on_release=self.note_off,
)
for names, validator in keys:
if candidate in names:
return make_argumented_key(
names=names,
validator=validator,
on_press=self.on_press,
on_release=handler_passthrough,
)
return closure
def during_bootup(self, keyboard):
return None

View File

@@ -1,15 +1,13 @@
from kmk.keys import KC, maybe_make_argumented_key
from kmk.keys import make_argumented_key
from kmk.modules.holdtap import HoldTap, HoldTapKeyMeta
class ModTap(HoldTap):
def __init__(self):
super().__init__()
KC._generators.append(
maybe_make_argumented_key(
make_argumented_key(
validator=HoldTapKeyMeta,
names=('MT',),
on_press=self.ht_pressed,
on_release=self.ht_released,
)
)

View File

@@ -1,7 +1,7 @@
from supervisor import ticks_ms
from kmk.hid import HID_REPORT_SIZES, HIDReportTypes
from kmk.keys import KC, make_key
from kmk.keys import make_key
from kmk.modules import Module
@@ -34,29 +34,64 @@ class MouseKeys(Module):
self.ac_interval = 100 # Delta ms to apply acceleration
self._next_interval = 0 # Time for next tick interval
self.move_step = 1
KC._generators.append(self.maybe_make_mouse_key())
def maybe_make_mouse_key(self):
keys = (
(('MB_LMB',), self._mb_lmb_press, self._mb_lmb_release),
(('MB_MMB',), self._mb_mmb_press, self._mb_mmb_release),
(('MB_RMB',), self._mb_rmb_press, self._mb_rmb_release),
(('MW_UP',), self._mw_up_press, self._mw_up_release),
(('MW_DOWN', 'MW_DN'), self._mw_down_press, self._mw_down_release),
(('MS_UP',), self._ms_up_press, self._ms_up_release),
(('MS_DOWN', 'MS_DN'), self._ms_down_press, self._ms_down_release),
(('MS_LEFT', 'MS_LT'), self._ms_left_press, self._ms_left_release),
(('MS_RIGHT', 'MS_RT'), self._ms_right_press, self._ms_right_release),
make_key(
names=('MB_LMB',),
on_press=self._mb_lmb_press,
on_release=self._mb_lmb_release,
)
def closure(candidate):
for names, on_press, on_release in keys:
if candidate in names:
return make_key(
names=names, on_press=on_press, on_release=on_release
make_key(
names=('MB_MMB',),
on_press=self._mb_mmb_press,
on_release=self._mb_mmb_release,
)
make_key(
names=('MB_RMB',),
on_press=self._mb_rmb_press,
on_release=self._mb_rmb_release,
)
make_key(
names=('MW_UP',),
on_press=self._mw_up_press,
on_release=self._mw_up_release,
)
make_key(
names=(
'MW_DOWN',
'MW_DN',
),
on_press=self._mw_down_press,
on_release=self._mw_down_release,
)
make_key(
names=('MS_UP',),
on_press=self._ms_up_press,
on_release=self._ms_up_release,
)
make_key(
names=(
'MS_DOWN',
'MS_DN',
),
on_press=self._ms_down_press,
on_release=self._ms_down_release,
)
make_key(
names=(
'MS_LEFT',
'MS_LT',
),
on_press=self._ms_left_press,
on_release=self._ms_left_release,
)
make_key(
names=(
'MS_RIGHT',
'MS_RT',
),
on_press=self._ms_right_press,
on_release=self._ms_right_release,
)
return closure
def during_bootup(self, keyboard):
return

View File

@@ -1,4 +1,4 @@
from kmk.keys import KC, maybe_make_argumented_key
from kmk.keys import make_argumented_key
from kmk.modules.holdtap import ActivationType, HoldTap, HoldTapKeyMeta
@@ -11,14 +11,12 @@ class OneShot(HoldTap):
def __init__(self):
super().__init__()
KC._generators.append(
maybe_make_argumented_key(
make_argumented_key(
validator=oneshot_validator,
names=('OS', 'ONESHOT'),
on_press=self.osk_pressed,
on_release=self.osk_released,
)
)
def process_key(self, keyboard, current_key, is_pressed, int_coord):
'''Release os key after interrupting keyup.'''

View File

@@ -7,7 +7,7 @@ from micropython import const
import math
import struct
from kmk.keys import KC, maybe_make_argumented_key, maybe_make_key
from kmk.keys import make_argumented_key, make_key
from kmk.kmktime import PeriodicTimer
from kmk.modules import Module
from kmk.modules.mouse_keys import PointingDevice
@@ -198,19 +198,16 @@ class Trackball(Module):
f'Invalid chip ID: 0x{chip_id:04X}, expected 0x{CHIP_ID:04X}'
)
KC._generators.append(
maybe_make_key(
make_key(
names=('TB_MODE', 'TB_NEXT_HANDLER', 'TB_N'),
on_press=self._tb_handler_next_press,
)
)
KC._generators.append(
maybe_make_argumented_key(
make_argumented_key(
validator=layer_key_validator,
names=('TB_HANDLER', 'TB_H'),
on_press=self._tb_handler_press,
)
)
def during_bootup(self, keyboard):
self._timer = PeriodicTimer(self.polling_interval)

View File

@@ -5,7 +5,7 @@ from supervisor import ticks_ms
from time import sleep
from kmk.handlers.stock import passthrough as handler_passthrough
from kmk.keys import KC, make_key
from kmk.keys import make_key
from kmk.kmktime import check_deadline
from kmk.modules import Module
@@ -20,25 +20,15 @@ class Power(Module):
self._i2c = 0
self._loopcounter = 0
KC._generators.append(self.maybe_make_power_key())
def maybe_make_power_key(self):
keys = (
(('PS_TOG',), self._ps_tog),
(('PS_ON',), self._ps_enable),
(('PS_OFF',), self._ps_disable),
make_key(
names=('PS_TOG',), on_press=self._ps_tog, on_release=handler_passthrough
)
def closure(candidate):
for names, on_press in keys:
if candidate in names:
return make_key(
names=names,
on_press=on_press,
on_release=handler_passthrough,
make_key(
names=('PS_ON',), on_press=self._ps_enable, on_release=handler_passthrough
)
make_key(
names=('PS_OFF',), on_press=self._ps_disable, on_release=handler_passthrough
)
return closure
def __repr__(self):
return f'Power({self._to_dict()})'

View File

@@ -1,6 +1,6 @@
from random import randint
from kmk.keys import KC, maybe_make_argumented_key
from kmk.keys import make_argumented_key
from kmk.modules import Module
@@ -28,14 +28,12 @@ class RapidFire(Module):
_waiting_keys = []
def __init__(self):
KC._generators.append(
maybe_make_argumented_key(
make_argumented_key(
validator=RapidFireMeta,
names=('RF',),
on_press=self._rf_pressed,
on_release=self._rf_released,
)
)
def _get_repeat(self, key):
if key.meta.enable_interval_randomization:

View File

@@ -1,4 +1,4 @@
from kmk.keys import KC, maybe_make_argumented_key
from kmk.keys import make_argumented_key
from kmk.modules import Module
@@ -12,14 +12,12 @@ class StickyMod(Module):
def __init__(self):
self._active = False
self._active_key = None
KC._generators.append(
maybe_make_argumented_key(
make_argumented_key(
names=('SM',),
validator=StickyModMeta,
on_press=self.sm_pressed,
on_release=self.sm_released,
)
)
def during_bootup(self, keyboard):
return

View File

@@ -1,4 +1,4 @@
from kmk.keys import KC, maybe_make_argumented_key
from kmk.keys import KC, make_argumented_key
from kmk.modules.holdtap import ActivationType, HoldTap, HoldTapKeyMeta
@@ -30,14 +30,12 @@ class TapDanceKeyMeta:
class TapDance(HoldTap):
def __init__(self):
super().__init__()
KC._generators.append(
maybe_make_argumented_key(
make_argumented_key(
validator=TapDanceKeyMeta,
names=('TD',),
on_press=self.td_pressed,
on_release=self.td_released,
)
)
self.td_counts = {}

View File

@@ -9,9 +9,6 @@ from tests.keyboard_test import KeyboardTest
class TestHoldTap(unittest.TestCase):
def setUp(self):
KC.clear()
def test_holdtap(self):
keyboard = KeyboardTest(
[Layers(), ModTap(), OneShot()],

View File

@@ -1,6 +1,6 @@
import unittest
from kmk.keys import KC, Key, ModifierKey, make_key, maybe_make_key
from kmk.keys import KC, Key, ModifierKey, make_key
from tests.keyboard_test import KeyboardTest
@@ -131,14 +131,20 @@ class TestKeys_dot(unittest.TestCase):
KC.invalid_key
def test_custom_key(self):
KC._generators.append(
maybe_make_key(
created = make_key(
KC.N2.code,
names=('EURO', ''),
names=(
'EURO',
'',
),
has_modifiers={KC.LSFT.code, KC.ROPT.code},
)
)
assert KC.get('') is KC.get('EURO')
assert created is KC.get('EURO')
assert created is KC.get('')
def test_match_exactly_case(self):
created = make_key(names=('ThIs_Is_A_StRaNgE_kEy',))
assert created is KC.get('ThIs_Is_A_StRaNgE_kEy')
class TestKeys_index(unittest.TestCase):
@@ -170,14 +176,20 @@ class TestKeys_index(unittest.TestCase):
KC['not_a_valid_key']
def test_custom_key(self):
KC._generators.append(
maybe_make_key(
KC.N2.code,
names=('EURO', ''),
has_modifiers={KC.LSFT.code, KC.ROPT.code},
created = make_key(
KC['N2'].code,
names=(
'EURO',
'',
),
has_modifiers={KC['LSFT'].code, KC['ROPT'].code},
)
)
assert KC.get('') is KC.get('EURO')
assert created is KC['EURO']
assert created is KC['']
def test_match_exactly_case(self):
created = make_key(names=('ThIs_Is_A_StRaNgE_kEy',))
assert created is KC['ThIs_Is_A_StRaNgE_kEy']
class TestKeys_get(unittest.TestCase):
@@ -212,14 +224,20 @@ class TestKeys_get(unittest.TestCase):
assert KC.get('not_a_valid_key') is None
def test_custom_key(self):
KC._generators.append(
maybe_make_key(
KC.N2.code,
names=('EURO', ''),
has_modifiers={KC.LSFT.code, KC.ROPT.code},
created = make_key(
KC.get('N2').code,
names=(
'EURO',
'',
),
has_modifiers={KC.get('LSFT').code, KC.get('ROPT').code},
)
)
assert KC.get('') is KC.get('EURO')
assert created is KC.get('EURO')
assert created is KC.get('')
def test_match_exactly_case(self):
created = make_key(names=('ThIs_Is_A_StRaNgE_kEy',))
assert created is KC.get('ThIs_Is_A_StRaNgE_kEy')
def test_underscore(self):
assert KC.get('_')
@@ -233,8 +251,8 @@ class TestKeys_instances(unittest.TestCase):
KC.clear()
def test_make_key_new_instance(self):
key1, _ = make_key(code=1)
key2, _ = make_key(code=1)
key1 = make_key(code=1)
key2 = make_key(code=1)
assert key1 is not key2
assert key1.code == key2.code

View File

@@ -7,7 +7,6 @@ from tests.keyboard_test import KeyboardTest
class TestLayers(unittest.TestCase):
def setUp(self):
KC.clear()
self.kb = KeyboardTest(
[Layers()],
[

View File

@@ -9,7 +9,6 @@ from tests.keyboard_test import KeyboardTest
class TestTapDance(unittest.TestCase):
def setUp(self):
KC.clear()
self.keyboard = KeyboardTest(
[Layers(), HoldTap(), TapDance()],
[