diff --git a/boards/kyria/main.py b/boards/kyria/main.py index f022e1a..6969ffa 100644 --- a/boards/kyria/main.py +++ b/boards/kyria/main.py @@ -1,42 +1,67 @@ from kyria_v1_rp2040 import KMKKeyboard -from kmk.extensions.media_keys import MediaKeys -from kmk.extensions.rgb import RGB, AnimationModes +from kmk.hid import HIDModes from kmk.keys import KC -from kmk.modules.encoder import EncoderHandler from kmk.modules.layers import Layers from kmk.modules.modtap import ModTap from kmk.modules.split import Split, SplitType +from kmk.modules.tapdance import TapDance +from kmk.modules.encoder import EncoderHandler +from kmk.extensions.rgb import RGB, AnimationModes +from kmk.extensions.media_keys import MediaKeys +from kmk.extensions.oled import ( + Oled, + OledData, +) +from kmk.extensions.international import International keyboard = KMKKeyboard() keyboard.debug_enabled = True -keyboard.modules.append(Layers()) -keyboard.modules.append(ModTap()) -keyboard.extensions.append(MediaKeys()) - -# Using drive names (KYRIAL, KYRIAR) to recognize sides; use split_side arg if you're not doing it -split = Split(split_type=SplitType.UART, use_pio=True) -keyboard.modules.append(split) - -# Uncomment below if you're using encoder encoder_handler = EncoderHandler() encoder_handler.pins = ((keyboard.encoder_pin_0, keyboard.encoder_pin_1, None, False),) -# Uncomment below if you're having RGB +keyboard.modules = [Layers(), ModTap(), TapDance()] +keyboard.extensions = [MediaKeys(), International()] + +split = Split(split_type=SplitType.UART, use_pio=True) +keyboard.modules.append(split) + rgb_ext = RGB( pixel_pin=keyboard.rgb_pixel_pin, num_pixels=10, + val_limit=200, + val_default=20, animation_mode=AnimationModes.BREATHING_RAINBOW, ) keyboard.extensions.append(rgb_ext) +oled_ext = Oled( + OledData( + labels=[ + OledData.oled_text_entry(text="Kyria v1.4", x=0, y=0), + OledData.oled_text_entry(text="KB2040", x=0, y=10), + OledData.oled_text_entry(text="Layer: ", x=0, y=20), + OledData.oled_text_entry(text="BASE", x=42, y=20, layer=0), + OledData.oled_text_entry(text="LOWER", x=0, y=30, layer=3), + OledData.oled_text_entry(text="RAISE", x=42, y=20, layer=4), + OledData.oled_text_entry(text="ADJUST", x=42, y=20, layer=6), + ] + ), + oHeight=64, + flip=True, +) + +keyboard.extensions.append(oled_ext) + # Edit your layout below # Currently, that's a default QMK Kyria Layout - https://config.qmk.fm/#/splitkb/kyria/rev1/LAYOUT ESC_LCTL = KC.MT(KC.ESC, KC.LCTL) QUOTE_RCTL = KC.MT(KC.QUOTE, KC.RCTL) ENT_LALT = KC.MT(KC.ENT, KC.LALT) MINUS_RCTL = KC.MT(KC.MINUS, KC.RCTL) + +# fmt: off keyboard.keymap = [ [ KC.TAB, KC.Q, KC.W, KC.E, KC.R, KC.T, KC.Y, KC.U, KC.I, KC.O, KC.P, KC.BSPC, @@ -81,8 +106,8 @@ keyboard.keymap = [ KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, ], ] +# fmt: on -# Uncomment below if using an encoder # Edit your encoder layout below encoder_handler.map = ( ((KC.VOLD, KC.VOLU),), @@ -93,7 +118,8 @@ encoder_handler.map = ( ((KC.MPRV, KC.MNXT),), ((KC.MPRV, KC.MNXT),), ) -keyboard.modules.append(encoder_handler) -if __name__ == '__main__': - keyboard.go() +keyboard.extensions.append(encoder_handler) + +if __name__ == "__main__": + keyboard.go(hid_type=HIDModes.USB) diff --git a/kmk/extensions/oled.py b/kmk/extensions/oled.py new file mode 100644 index 0000000..5d9d124 --- /dev/null +++ b/kmk/extensions/oled.py @@ -0,0 +1,136 @@ +import busio +import gc + +from kmk.handlers.stock import passthrough as handler_passthrough +from kmk.keys import make_key +import adafruit_displayio_ssd1306 +import displayio +import terminalio +from adafruit_display_text import label + +from kmk.extensions import Extension + +DISPLAY_OFFSET = 10 + + +class OledData: + def __init__( + self, + labels=None, + ): + if labels != None: + self.data = labels + + +class Oled(Extension): + def __init__( + self, + views, + oWidth=128, + oHeight=32, + flip: bool = False, + device_address=0x3C, + brightness=0.8, + ): + displayio.release_displays() + self.rotation = 180 if flip else 0 + self._views = views.data + self._width = oWidth + self._height = oHeight + self._prevLayers = 0 + self._device_address = device_address + self._brightness = brightness + gc.collect() + + make_key( + names=('OLED_BRI',), on_press=self._oled_bri, on_release=handler_passthrough + ) + make_key( + names=('OLED_BRD',), on_press=self._oled_brd, on_release=handler_passthrough + ) + + @staticmethod + def oled_text_entry(x=0, y=0, text="", layer=None): + return { + 0: label.Label( + terminalio.FONT, + text=text, + color=0xFFFFFF, + x=x, + y=y + DISPLAY_OFFSET, + ), + 1: layer, + } + + @staticmethod + def oled_image_entry(x=0, y=0, image="", layer=None): + odb = displayio.OnDiskBitmap(image) + return { + 0: displayio.TileGrid( + odb, pixel_shader=odb.pixel_shader, x=x, y=y + DISPLAY_OFFSET + ), + 1: layer, + } + + def render_oled(self, layer): + splash = displayio.Group() + self._display.show(splash) + print(f"views={self._views}, layer={layer}") + for view in self._views: + if view[1] == layer or view[1] == None: + splash.append(view[0]) + gc.collect() + + def updateOLED(self, sandbox): + self.render_oled(sandbox.active_layers[0]) + gc.collect() + + def on_runtime_enable(self, sandbox): + return + + def on_runtime_disable(self, sandbox): + return + + def during_bootup(self, board): + displayio.release_displays() + i2c = busio.I2C(board.SCL, board.SDA) + self._display = adafruit_displayio_ssd1306.SSD1306( + displayio.I2CDisplay(i2c, device_address=self._device_address), + width=self._width, + height=self._height, + rotation=self.rotation, + brightness=self._brightness, + ) + self.render_oled(0) + return + + def before_matrix_scan(self, sandbox): + if sandbox.active_layers[0] != self._prevLayers: + self._prevLayers = sandbox.active_layers[0] + self.updateOLED(sandbox) + return + + def after_matrix_scan(self, sandbox): + return + + def before_hid_send(self, sandbox): + return + + def after_hid_send(self, sandbox): + return + + def on_powersave_enable(self, sandbox): + return + + def on_powersave_disable(self, sandbox): + return + + def _oled_bri(self, *args, **kwargs): + self._display.brightness = ( + self._display.brightness + 0.1 if self._display.brightness < 0.9 else 1.0 + ) + + def _oled_brd(self, *args, **kwargs): + self._display.brightness = ( + self._display.brightness - 0.1 if self._display.brightness > 0.1 else 0.1 + )