Skip to content

Add arguments to setup layout on init #39

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 59 additions & 36 deletions adafruit_macropad.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@
import audiomp3
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
from adafruit_hid.keyboard_layout_base import KeyboardLayoutBase
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from adafruit_hid.keycode import Keycode
from adafruit_hid.consumer_control import ConsumerControl
from adafruit_hid.consumer_control_code import ConsumerControlCode
from adafruit_hid.mouse import Mouse
Expand All @@ -80,7 +81,7 @@
from typing import Tuple, Optional, Union, Iterator
from neopixel import NeoPixel
from keypad import Keys
import adafruit_hid
import adafruit_hid # pylint:disable=ungrouped-imports
except ImportError:
pass

Expand All @@ -93,6 +94,10 @@
ROTATED_KEYMAP_270 = (9, 6, 3, 0, 10, 7, 4, 1, 11, 8, 5, 2)


keycodes = Keycode
"""Module level Keycode class, to be changed when initing Macropad with a different language"""


class _PixelMapLite:
"""Generate a pixel map based on a specified order. Designed to work with a set of 12 pixels,
e.g. the MacroPad keypad LEDs.
Expand Down Expand Up @@ -163,7 +168,7 @@ def brightness(self, value: float) -> None:
self._pixels.brightness = value


# pylint: disable=too-many-lines
# pylint: disable=too-many-lines, disable=invalid-name, too-many-instance-attributes, too-many-public-methods, too-many-arguments
class MacroPad:
"""
Class representing a single MacroPad.
Expand All @@ -182,6 +187,14 @@ class MacroPad:
channels. Defaults to 1.
:param int midi_out_channel: The MIDI output channel. Defaults to 1.

:param type[KeyboardLayoutBase] layout_class: Class for the keyboard layout, to setup an
international or alternative keyboard. Defaults
to KeyboardLayoutUS from adafruit_hid.
:param type[Keycode] keycode_class: Class used for the keycode names provided by
adafruit_macropad.Keycode. Defaults to the standard Keycode
from adafruit_hid.


The following shows how to initialise the MacroPad library with the board rotated 90 degrees,
and the MIDI channels both set to 1.

Expand All @@ -192,9 +205,43 @@ class MacroPad:
macropad = MacroPad(rotation=90, midi_in_channel=1, midi_out_channel=1)
"""

# pylint: disable=invalid-name, too-many-instance-attributes, too-many-public-methods
Keycode = Keycode
"""
The contents of the Keycode module are available as a property of MacroPad. This includes all
keycode constants available within the Keycode module, which includes all the keys on a
regular PC or Mac keyboard.

Remember that keycodes are the names for key _positions_ on a US keyboard, and may not
correspond to the character that you mean to send if you want to emulate non-US keyboard.

For usage example, see the ``keyboard`` documentation in this library.
"""

ConsumerControlCode = ConsumerControlCode
"""
The contents of the ConsumerControlCode module are available as a property of MacroPad.
This includes the available USB HID Consumer Control Device constants. This list is not
exhaustive.

For usage example, see the ``consumer_control`` documentation in this library.
"""

Mouse = Mouse
"""
The contents of the Mouse module are available as a property of MacroPad. This includes the
``LEFT_BUTTON``, ``MIDDLE_BUTTON``, and ``RIGHT_BUTTON`` constants. The rest of the
functionality of the ``Mouse`` module should be used through ``macropad.mouse``.

For usage example, see the ``mouse`` documentation in this library.
"""

def __init__(
self, rotation: int = 0, midi_in_channel: int = 1, midi_out_channel: int = 1
self,
rotation: int = 0,
midi_in_channel: int = 1,
midi_out_channel: int = 1,
layout_class: type[KeyboardLayoutBase] = KeyboardLayoutUS,
keycode_class: type[Keycode] = Keycode,
):

if rotation not in (0, 90, 180, 270):
Expand Down Expand Up @@ -257,6 +304,12 @@ def _keys_and_pixels(
self._keyboard_layout = None
self._consumer_control = None
self._mouse = None
self._layout_class = layout_class
self.Keycode = keycode_class
# pylint:disable=global-statement
global keycodes
keycodes = keycode_class
# pylint:enable=global-statement

# Define MIDI:
try:
Expand All @@ -271,36 +324,6 @@ def _keys_and_pixels(
# No MIDI ports available.
self._midi = None

Keycode = Keycode
"""
The contents of the Keycode module are available as a property of MacroPad. This includes all
keycode constants available within the Keycode module, which includes all the keys on a
regular PC or Mac keyboard.

Remember that keycodes are the names for key _positions_ on a US keyboard, and may not
correspond to the character that you mean to send if you want to emulate non-US keyboard.

For usage example, see the ``keyboard`` documentation in this library.
"""

ConsumerControlCode = ConsumerControlCode
"""
The contents of the ConsumerControlCode module are available as a property of MacroPad.
This includes the available USB HID Consumer Control Device constants. This list is not
exhaustive.

For usage example, see the ``consumer_control`` documentation in this library.
"""

Mouse = Mouse
"""
The contents of the Mouse module are available as a property of MacroPad. This includes the
``LEFT_BUTTON``, ``MIDDLE_BUTTON``, and ``RIGHT_BUTTON`` constants. The rest of the
functionality of the ``Mouse`` module should be used through ``macropad.mouse``.

For usage example, see the ``mouse`` documentation in this library.
"""

@property
def pixels(self) -> Optional[_PixelMapLite]:
"""Sequence-like object representing the twelve NeoPixel LEDs in a 3 x 4 grid on the
Expand Down Expand Up @@ -501,7 +524,7 @@ def keyboard_layout(self) -> adafruit_hid.keyboard_layout_base.KeyboardLayoutBas
"""
if self._keyboard_layout is None:
# This will need to be updated if we add more layouts. Currently there is only US.
self._keyboard_layout = KeyboardLayoutUS(self.keyboard)
self._keyboard_layout = self._layout_class(self.keyboard)
return self._keyboard_layout

@property
Expand Down
45 changes: 45 additions & 0 deletions examples/macropad_keyboard_layout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# SPDX-FileCopyrightText: Copyright (c) 2021 Kattni Rembor for Adafruit Industries
#
# SPDX-License-Identifier: Unlicense
"""
International layout demo for MacroPad.
"""
import time
from keyboard_layout_win_fr import KeyboardLayout
from keycode_win_fr import Keycode
from adafruit_macropad import MacroPad

macropad = MacroPad(
layout_class=KeyboardLayout,
keycode_class=Keycode,
)

keycodes = [
"https://adafruit.com/",
"https://adafru.it/discord",
"https://circuitpython.org",
Keycode.A,
Keycode.D,
Keycode.A,
Keycode.F,
Keycode.R,
Keycode.U,
Keycode.I,
Keycode.T,
Keycode.PERIOD,
# Keycode.C, Keycode.O, Keycode.M,
]

while True:
key_event = macropad.keys.events.get()
if key_event:
keycode = keycodes[key_event.key_number]
if key_event.pressed:
if isinstance(keycode, int):
macropad.keyboard.press(keycode)
else:
macropad.keyboard_layout.write(keycode)
else:
if isinstance(keycode, int):
macropad.keyboard.release(keycode)
time.sleep(0.05)