Skip to content

Commit

Permalink
Merge pull request #8 from mchilli/flip-rotation
Browse files Browse the repository at this point in the history
flip rotation, brightness setting
  • Loading branch information
mchilli committed Oct 25, 2023
2 parents 969e7fb + 992f4df commit 03f2f15
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 76 deletions.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@ This is an [Adafruit MacroPad](https://www.adafruit.com/product/5128) script tha
- Make groups to organize your macros
- Groups can store more macros or groups
- Define encoder macros for different groups
- Set a display timeout to prevent burn-in
- Select a keyboard layout suitable for your language
- You can use a Unicode Font (but this increases the font loading time)
- Choose colors for every single macro or group
- You can have an almost infinite number of pages
- Save your configurations locally by downloading it as a JSON file

- Device settings:
- Choose a keyboard layout suitable for your language
- Set a display timeout to prevent burn-in
- Use a Unicode Font **(increases the font loading time)**
- Flip the rotation of the device by 180 degrees
- Adjust the LCD and LED brightness

#### Installation:

Flash circuitpython on to your macropad, following this [guide](https://learn.adafruit.com/adafruit-macropad-rp2040/circuitpython).
Expand Down
102 changes: 45 additions & 57 deletions circuitpython/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,56 +25,58 @@

SETTINGSFILE = "settings.json" # The file in which the settings are saved
MACROFILE = "macros.json" # The file in which the macros are saved
SLEEPTIME = 2 # Time in seconds until the display turns off
KEYBOARDLAYOUT = "us" # Supported keyboard layouts: br, cz, da, de, es, fr, hu, it, po, sw, tr, uk, us
USEUNICODEFONT = False # Use a unicode bitmap font, which will increas the initial load time!

SETTINGS = {
"sleeptime": 2, # Time in seconds until the display turns off
"keyboardlayout": "us", # Supported keyboard layouts: br, cz, da, de, es, fr, hu, it, po, sw, tr, uk, us
"useunicodefont": False, # Use a unicode bitmap font, which will increas the initial load time!
"fliprotation": False, # Flips the rotation of the device by 180 degrees
"brightness": 0.1 # Set the LCD and LED Brightness
}

try:
with open(SETTINGSFILE, "r") as f:
settings = json.load(f)
if "sleeptime" in settings:
SLEEPTIME = settings["sleeptime"]
if "keyboardlayout" in settings:
KEYBOARDLAYOUT = settings["keyboardlayout"]
if "useunicodefont" in settings:
USEUNICODEFONT = settings["useunicodefont"]
for key in SETTINGS:
if key in settings:
SETTINGS[key] = settings[key]
except Exception:
pass

if KEYBOARDLAYOUT == "br":
if SETTINGS["keyboardlayout"] == "br":
from adafruit_hid.keyboard_layout_win_br import KeyboardLayout
from adafruit_hid.keycode_win_br import Keycode
elif KEYBOARDLAYOUT == "cz":
elif SETTINGS["keyboardlayout"] == "cz":
from adafruit_hid.keyboard_layout_win_cz import KeyboardLayout
from adafruit_hid.keycode_win_cz import Keycode
elif KEYBOARDLAYOUT == "da":
elif SETTINGS["keyboardlayout"] == "da":
from adafruit_hid.keyboard_layout_win_da import KeyboardLayout
from adafruit_hid.keycode_win_da import Keycode
elif KEYBOARDLAYOUT == "de":
elif SETTINGS["keyboardlayout"] == "de":
from adafruit_hid.keyboard_layout_win_de import KeyboardLayout
from adafruit_hid.keycode_win_de import Keycode
elif KEYBOARDLAYOUT == "es":
elif SETTINGS["keyboardlayout"] == "es":
from adafruit_hid.keyboard_layout_win_es import KeyboardLayout
from adafruit_hid.keycode_win_es import Keycode
elif KEYBOARDLAYOUT == "fr":
elif SETTINGS["keyboardlayout"] == "fr":
from adafruit_hid.keyboard_layout_win_fr import KeyboardLayout
from adafruit_hid.keycode_win_fr import Keycode
elif KEYBOARDLAYOUT == "hu":
elif SETTINGS["keyboardlayout"] == "hu":
from adafruit_hid.keyboard_layout_win_hu import KeyboardLayout
from adafruit_hid.keycode_win_hu import Keycode
elif KEYBOARDLAYOUT == "it":
elif SETTINGS["keyboardlayout"] == "it":
from adafruit_hid.keyboard_layout_win_it import KeyboardLayout
from adafruit_hid.keycode_win_it import Keycode
elif KEYBOARDLAYOUT == "po":
elif SETTINGS["keyboardlayout"] == "po":
from adafruit_hid.keyboard_layout_win_po import KeyboardLayout
from adafruit_hid.keycode_win_po import Keycode
elif KEYBOARDLAYOUT == "sw":
elif SETTINGS["keyboardlayout"] == "sw":
from adafruit_hid.keyboard_layout_win_sw import KeyboardLayout
from adafruit_hid.keycode_win_sw import Keycode
elif KEYBOARDLAYOUT == "tr":
elif SETTINGS["keyboardlayout"] == "tr":
from adafruit_hid.keyboard_layout_win_tr import KeyboardLayout
from adafruit_hid.keycode_win_tr import Keycode
elif KEYBOARDLAYOUT == "uk":
elif SETTINGS["keyboardlayout"] == "uk":
from adafruit_hid.keyboard_layout_win_uk import KeyboardLayout
from adafruit_hid.keycode_win_uk import Keycode
else:
Expand All @@ -85,44 +87,31 @@
class MacroApp():
""" Main Class """
def __init__(self) -> None:
self.macropad = MacroPad(layout_class=KeyboardLayout)
self.macropad = MacroPad(layout_class=KeyboardLayout, rotation=180 if SETTINGS["fliprotation"] else 0)
self.macropad.display.auto_refresh = False
self.macropad.display.brightness = 0.1
self.macropad.display.brightness = SETTINGS["brightness"]
self.macropad.pixels.auto_write = False
self.macropad.pixels.brightness = 0.1
self.macropad.pixels.brightness = SETTINGS["brightness"]

self.readonly = storage.getmount('/').readonly
self.serial_data = usb_cdc.data
self.serial_last_state = False

self.settings = self._init_settings()
self.macros = self._init_macros()
self.keys = self._init_keys()
self.toolbar = self._init_toolbar()
self.encoder = Encoder(self.macropad)

self.show_homescreen()

def _init_settings(self) -> dict:
""" initiate the settings json file
Returns:
dict: the json file as a dict
"""
try:
with open(SETTINGSFILE, "r") as f:
return json.load(f)
except OSError:
return {
"keyboardlayout": KEYBOARDLAYOUT,
"sleeptime": SLEEPTIME,
"useunicodefont": USEUNICODEFONT
}

def _save_settings(self) -> None:
""" store the settings in the settingsfile
def _save_settings(self, new_settings) -> None:
""" store the new settings in the settingsfile
"""
if self.readonly:
return False
with open(SETTINGSFILE, "w") as f:
f.write(json.dumps(self.settings, separators=(",", ":")))
f.write(json.dumps(new_settings, separators=(",", ":")))
return True

def _init_macros(self) -> list[dict]:
""" initiate the macro json file
Expand All @@ -148,8 +137,11 @@ def _init_macros(self) -> list[dict]:
def _save_macros(self) -> None:
""" store the macros in the macrofile
"""
if self.readonly:
return False
with open(MACROFILE, "w") as f:
f.write(json.dumps(self.macros, separators=(",", ":")))
return True

def _init_keys(self) -> list[Key]:
""" Initiate the keys and a display group for each key
Expand All @@ -162,7 +154,7 @@ def _init_keys(self) -> list[Key]:

for i in range(self.macropad.keys.key_count):
label = Label(
font=load_font("/fonts/6x12.pcf") if USEUNICODEFONT else terminalio.FONT,
font=load_font("/fonts/6x12.pcf") if SETTINGS["useunicodefont"] else terminalio.FONT,
text="",
padding_top=1,
padding_bottom=2,
Expand Down Expand Up @@ -293,7 +285,7 @@ def run_macro(self, item:dict, *args) -> None:
if 'sys' in key:
method = getattr(System, key['sys'], None)
if method:
method(self.macropad)
method(self)

self.macropad.keyboard.release_all()
self.macropad.mouse.release_all()
Expand Down Expand Up @@ -396,7 +388,7 @@ def _handle_serial_data(self, payload:str) -> dict:

if command == 'get_settings':
response['ACK'] = 'settings'
response['CONTENT'] = self.settings
response['CONTENT'] = SETTINGS
return response

elif command == 'set_settings':
Expand All @@ -405,12 +397,10 @@ def _handle_serial_data(self, payload:str) -> dict:
return response

content = payload['content']
self.settings = content

try:
self._save_settings()
if self._save_settings(content):
response['ACK'] = 'Settings are set'
except OSError as e:
else:
response['ERR'] = 'Cannot set settings because USB storage is enabled'

return response
Expand All @@ -434,10 +424,9 @@ def _handle_serial_data(self, payload:str) -> dict:
return response

elif command == 'save_macros':
try:
self._save_macros()
if self._save_macros():
response['ACK'] = 'Macros stored'
except OSError as e:
else:
response['ERR'] = 'Cannot store macros because USB storage is enabled'

return response
Expand Down Expand Up @@ -486,7 +475,7 @@ def start(self) -> None:
"""
self.sleep_timer = time.monotonic()
while True:
if not self.macropad.display_sleep and time.monotonic() - self.sleep_timer > SLEEPTIME:
if not self.macropad.display_sleep and time.monotonic() - self.sleep_timer > SETTINGS["sleeptime"]:
self.macropad.display_sleep = True

self.macropad.display.refresh()
Expand All @@ -495,8 +484,7 @@ def start(self) -> None:
if self.serial_last_state != self.serial_data.connected:
self.serial_last_state = self.serial_data.connected
if self.serial_data.connected:
readonly = storage.getmount('/').readonly
self._send_serial_data({'ACK': 'usbenabled', 'CONTENT': readonly })
self._send_serial_data({'ACK': 'usbenabled', 'CONTENT': self.readonly })

if self.serial_data.connected:
if self.serial_data.in_waiting > 0:
Expand Down
33 changes: 17 additions & 16 deletions circuitpython/utils/system.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,34 @@
import microcontroller
import supervisor
from adafruit_macropad import MacroPad

USBENABLEDFILE = "usbenabled"

class System():
def enable_usb(macropad:MacroPad=None) -> None:
def enable_usb(app=None) -> None:
try:
with open(USBENABLEDFILE, "a") as f: pass
System.hard_reset()
except Exception:
pass

def soft_reset(macropad:MacroPad=None) -> None:
def soft_reset(app=None) -> None:
supervisor.reload()

def hard_reset(macropad:MacroPad=None) -> None:
def hard_reset(app=None) -> None:
microcontroller.reset()

def decrease_brightness(macropad:MacroPad=None) -> None:
if macropad.display.brightness > 0:
brightness = round(macropad.display.brightness * 10)
macropad.display.brightness = (brightness - 1) / 10
macropad.pixels.brightness = (brightness - 1) / 10
macropad.pixels.show()
def decrease_brightness(app=None) -> None:
if app.macropad.display.brightness > 0:
brightness = (round(app.macropad.display.brightness * 10) - 1) / 10
app.macropad.display.brightness = brightness
app.macropad.pixels.brightness = brightness
app.macropad.pixels.show()
app.settings["brightness"] = brightness

def increase_brightness(macropad:MacroPad=None) -> None:
if macropad.display.brightness < 1:
brightness = round(macropad.display.brightness * 10)
macropad.display.brightness = (brightness + 1) / 10
macropad.pixels.brightness = (brightness + 1) / 10
macropad.pixels.show()
def increase_brightness(app=None) -> None:
if app.macropad.display.brightness < 1:
brightness = (round(app.macropad.display.brightness * 10) + 1) / 10
app.macropad.display.brightness = brightness
app.macropad.pixels.brightness = brightness
app.macropad.pixels.show()
app.settings["brightness"] = brightness
47 changes: 47 additions & 0 deletions webui/js/modules/classes/Dialogs.js
Original file line number Diff line number Diff line change
Expand Up @@ -1536,6 +1536,46 @@ export class SettingsDialog extends BaseDialog {
})),
],
}),
utils.create({
attributes: {
class: 'dialog-input-shorten',
},
children: [
utils.create({
text: 'Flip Rotation: ',
}),
(DOM.fliprotation = utils.create({
type: 'input',
attributes: {
type: 'checkbox',
},
})),
],
}),
utils.create({
attributes: {
class: 'dialog-input-shorten',
},
children: [
utils.create({
text: 'LCD/LED Brightness: ',
}),
(DOM.brightness = utils.create({
type: 'input',
attributes: {
type: 'range',
min: 0,
max: 1,
step: 0.1,
},
events: {
input: (event) => {
event.target.title = event.target.value;
},
},
})),
],
}),
],
}),
utils.create({
Expand Down Expand Up @@ -1578,6 +1618,8 @@ export class SettingsDialog extends BaseDialog {
DOM.keyboardlayout.disabled = this.readonly;
DOM.sleeptime.disabled = this.readonly;
DOM.useunicodefont.disabled = this.readonly;
DOM.fliprotation.disabled = this.readonly;
DOM.brightness.disabled = this.readonly;

return DOM;
}
Expand All @@ -1597,6 +1639,8 @@ export class SettingsDialog extends BaseDialog {
this.settings.keyboardlayout = this.DOM.keyboardlayout.value;
this.settings.sleeptime = parseInt(this.DOM.sleeptime.value);
this.settings.useunicodefont = this.DOM.useunicodefont.checked;
this.settings.fliprotation = this.DOM.fliprotation.checked;
this.settings.brightness = parseFloat(this.DOM.brightness.value);

this.resolve({ dialogInstance: this, settings: this.settings });
this._removeFromParent(this.DOM.container);
Expand All @@ -1615,6 +1659,9 @@ export class SettingsDialog extends BaseDialog {

this.DOM.sleeptime.value = this.settings.sleeptime;
this.DOM.useunicodefont.checked = this.settings.useunicodefont;
this.DOM.fliprotation.checked = this.settings.fliprotation;
this.DOM.brightness.value = this.settings.brightness;
this.DOM.brightness.title = this.settings.brightness;
}
}

Expand Down

0 comments on commit 03f2f15

Please sign in to comment.