Files

135 lines
4.8 KiB
Python

import terminalio
import json
from time import monotonic_ns
from adafruit_display_text.bitmap_label import Label
from adafruit_displayio_layout.layouts.grid_layout import GridLayout
from adafruit_hid.keycode import Keycode
from macropad_os import App
from macropad_os.app_utils import rgb_from_int, Macro, MacroSet
from rainbowio import colorwheel
COLOR_UPDATE_RATE = 33000000 # .033 seconds
JSON_FILE_LOCATION = "./macropad_apps/json/"
PROFILE_NAME = "profileName"
SORT_ORDER = "sortOrder"
KEY_KEYS = ["key1", "key2", "key3", "key4", "key5", "key6", "key7", "key8", "key9", "key10", "key11", "key12"]
REQUIRED_KEYS = KEY_KEYS.copy()
REQUIRED_KEYS.extend(x for x in [PROFILE_NAME, SORT_ORDER])
class JsonApp(App):
def __init__(self, macropad, config, json_file):
super().__init__(macropad, config)
self.json_file = json_file
self.wheel_offset = 0
self.labels = []
self.title = ""
self.last_color_update = 0
self.active_macro = 0
self.name = "JSON_APP"
self.json_dict = JsonApp.read_json_file(self.json_file)
self.macros = JsonApp.get_macroset_from_dict(self.json_dict)
self.title = self.json_dict[PROFILE_NAME]
self.sort_order = self.json_dict[SORT_ORDER]
@staticmethod
def create_macro_from_dict(key_dict) -> Macro:
print(f"Creating macro for {key_dict}")
name = key_dict["text"]
values = key_dict["values"]
codes = []
for value in values:
if isinstance(value, str):
value_mod = 1
if value[0] is '-':
value_mod = -1
value = value[1:]
if hasattr(Keycode, value):
keycode = getattr(Keycode, value)
codes.append(keycode * value_mod)
else:
codes.append(value)
if isinstance(value, int) or isinstance(value, float) or isinstance(value, dict) or isinstance(value, list):
# TODO: Add validation for lists and dictionaries
codes.append(value)
print(name, codes)
return Macro(name, *codes)
@staticmethod
def get_macroset_from_dict(json_dict: {}) -> MacroSet:
key_macros = []
for key in KEY_KEYS:
key_macros.append(JsonApp.create_macro_from_dict(json_dict[key]))
return MacroSet(key_macros=key_macros, encoder_up=Macro("Test"), encoder_down=Macro("Test"))
@staticmethod
def read_json_file(json_file) -> {}:
try:
f = open(json_file, "r")
json_dict = json.load(f)
print(json_dict)
for key in REQUIRED_KEYS:
if key not in json_dict:
raise ValueError(f"JSON FOR FILE - {json_file} IS INVALID - KEY MISSING {key}")
return json_dict
except Exception as e:
print(e)
def on_start(self):
print("on start from the app!")
self.set_layout(GridLayout(x=0, y=9, width=128, height=54, grid_size=(3, 4), cell_padding=1))
self.set_title(self.title)
for i in range(12):
self.labels.append(
Label(terminalio.FONT, text=self.macros.get_macro_from_key(i).name))
for index in range(12):
x = index % 3
y = index // 3
self._layout.add_content(self.labels[index], grid_position=(x, y), cell_size=(1, 1))
self.register_on_key_pressed(self.process_keys_pressed_callback)
self.register_on_key_released(self.process_keys_released_callback)
self.register_on_encoder_changed(self.process_enbcoder_changed)
def on_resume(self):
print("resume from the debug app!")
def on_pause(self):
print("Pausing")
def on_stop(self):
print("Stopping")
def on_loop(self):
self.update_key_colors()
def update_key_colors(self):
self.wheel_offset += 1
colors = []
last_update_ago = monotonic_ns() - self.last_color_update
if last_update_ago > COLOR_UPDATE_RATE:
self.last_color_update = monotonic_ns()
for pixel in range(12):
(r, g, b) = rgb_from_int(colorwheel((pixel / 12 * 256) + self.wheel_offset))
colors.append((r, g, b))
self.set_colors(colors)
def process_keys_pressed_callback(self, key_event):
print(f"KEY PRESSED - {key_event}")
print(self.macros)
macro = self.macros.get_macro_from_key(key_event)
print(macro)
print(macro.name)
print(macro.codes)
self.press_macro(self.macros.get_macro_from_key(key_event))
def process_keys_released_callback(self, key_event):
self.release_macro(self.macros.get_macro_from_key(key_event))
def process_enbcoder_changed(self, key_event):
print(key_event)