feat: Adding support for json apps. Updated Macropad_os.py to automatically load in the python and json apps at launch.
This commit is contained in:
@@ -10,31 +10,14 @@ default_config = Config("default_config.json").load()
|
|||||||
config = Config("config.json").load(default_config)
|
config = Config("config.json").load(default_config)
|
||||||
|
|
||||||
PYTHON_APP_FOLDER = "./macropad_apps/python"
|
PYTHON_APP_FOLDER = "./macropad_apps/python"
|
||||||
|
JSON_APP_FOLDER = "./macropad_apps/json"
|
||||||
|
|
||||||
apps = []
|
ar = MacropadOS(
|
||||||
|
macropad,
|
||||||
files = os.listdir(PYTHON_APP_FOLDER)
|
config,
|
||||||
files.sort()
|
python_apps=PYTHON_APP_FOLDER,
|
||||||
|
json_apps=JSON_APP_FOLDER
|
||||||
app_classes = []
|
)
|
||||||
for filename in files:
|
|
||||||
if filename.endswith('.py') and not filename.startswith('._'):
|
|
||||||
try:
|
|
||||||
print(filename)
|
|
||||||
module = __import__(PYTHON_APP_FOLDER + '/' + filename[:-3])
|
|
||||||
classes = [getattr(module, a) for a in dir(module)
|
|
||||||
if isinstance(getattr(module, a), type)]
|
|
||||||
for cls in classes:
|
|
||||||
if issubclass(cls, App) and cls.__name__ != "App":
|
|
||||||
app_classes.append(cls)
|
|
||||||
print(app_classes)
|
|
||||||
except (SyntaxError, ImportError, AttributeError, KeyError, NameError, IndexError, TypeError) as err:
|
|
||||||
print("ERROR in", filename)
|
|
||||||
import traceback
|
|
||||||
|
|
||||||
traceback.print_exception(err, err, err.__traceback__)
|
|
||||||
|
|
||||||
ar = MacropadOS(macropad, config, apps=app_classes)
|
|
||||||
# sc = SerialComms(config)
|
# sc = SerialComms(config)
|
||||||
# _thread.start_new_thread(sc.run, (sc))
|
# _thread.start_new_thread(sc.run, (sc))
|
||||||
ar.start()
|
ar.start()
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
{
|
|
||||||
"profileName" : "",
|
|
||||||
"sortOrder" : 99,
|
|
||||||
|
|
||||||
"key1" : {
|
|
||||||
"text" : [""],
|
|
||||||
"value" : [""]
|
|
||||||
},
|
|
||||||
"key2" : {
|
|
||||||
"text" : [""],
|
|
||||||
"value" : [""]
|
|
||||||
},
|
|
||||||
"key3" : {
|
|
||||||
"text" : [""],
|
|
||||||
"value" : [""]
|
|
||||||
},
|
|
||||||
"key4" : {
|
|
||||||
"text" : [""],
|
|
||||||
"value" : [""]
|
|
||||||
},
|
|
||||||
"key5" : {
|
|
||||||
"text" : [""],
|
|
||||||
"value" : [""]
|
|
||||||
},
|
|
||||||
"key6" : {
|
|
||||||
"text" : [""],
|
|
||||||
"value" : [""]
|
|
||||||
},
|
|
||||||
"key7" : {
|
|
||||||
"text" : [""],
|
|
||||||
"value" : [""]
|
|
||||||
},
|
|
||||||
"key8" : {
|
|
||||||
"text" : [""],
|
|
||||||
"value" : [""]
|
|
||||||
},
|
|
||||||
"key9" : {
|
|
||||||
"text" : [""],
|
|
||||||
"value" : [""]
|
|
||||||
},
|
|
||||||
"key10" : {
|
|
||||||
"text" : [""],
|
|
||||||
"value" : [""]
|
|
||||||
},
|
|
||||||
"key11" : {
|
|
||||||
"text" : [""],
|
|
||||||
"value" : [""]
|
|
||||||
},
|
|
||||||
"key12" : {
|
|
||||||
"text" : [""],
|
|
||||||
"value" : [""]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,54 +1,53 @@
|
|||||||
{
|
{
|
||||||
"profileName" : "Gamepad",
|
"profileName" : "Gamepad Json",
|
||||||
"sortOrder" : 1,
|
"sortOrder" : 1,
|
||||||
|
|
||||||
"key1" : {
|
"key1" : {
|
||||||
"text" : ["ESC"],
|
"text" : "ESC",
|
||||||
"value" : ["ESCAPE"]
|
"values" : ["ESCAPE"]
|
||||||
},
|
},
|
||||||
"key2" : {
|
"key2" : {
|
||||||
"text" : ["Tab"],
|
"text" : "Tab",
|
||||||
"value" : ["TAB"]
|
"values" : ["TAB"]
|
||||||
},
|
},
|
||||||
"key3" : {
|
"key3" : {
|
||||||
"text" : ["R"],
|
"text" : "R",
|
||||||
"value" : ["R"]
|
"values" : ["R"]
|
||||||
},
|
},
|
||||||
"key4" : {
|
"key4" : {
|
||||||
"text" : ["Q"],
|
"text" : "Q",
|
||||||
"value" : ["Q"]
|
"values" : ["Q"]
|
||||||
},
|
},
|
||||||
"key5" : {
|
"key5" : {
|
||||||
"text" : ["W"],
|
"text" : "W",
|
||||||
"value" : ["W"]
|
"values" : ["W"]
|
||||||
},
|
},
|
||||||
"key6" : {
|
"key6" : {
|
||||||
"text" : ["E"],
|
"text" : "E",
|
||||||
"value" : ["E"]
|
"values" : ["E"]
|
||||||
},
|
},
|
||||||
"key7" : {
|
"key7" : {
|
||||||
"text" : ["A"],
|
"text" : "A",
|
||||||
"value" : ["A"]
|
"values" : ["A"]
|
||||||
},
|
},
|
||||||
"key8" : {
|
"key8" : {
|
||||||
"text" : ["S"],
|
"text" : "S",
|
||||||
"value" : ["S"]
|
"values" : ["S"]
|
||||||
},
|
},
|
||||||
"key9" : {
|
"key9" : {
|
||||||
"text" : ["D"],
|
"text" : "D",
|
||||||
"value" : ["D"]
|
"values" : ["D"]
|
||||||
},
|
},
|
||||||
"key10" : {
|
"key10" : {
|
||||||
"text" : ["Shift"],
|
"text" : "Shift",
|
||||||
"value" : [""]
|
"values" : ["SHIFT"]
|
||||||
},
|
},
|
||||||
"key11" : {
|
"key11" : {
|
||||||
"text" : ["C"],
|
"text" : "C",
|
||||||
"value" : ["C"]
|
"values" : ["C"]
|
||||||
},
|
},
|
||||||
"key12" : {
|
"key12" : {
|
||||||
"text" : ["Space"],
|
"text" : "Space",
|
||||||
"value" : ["SPACEBAR"]
|
"values" : ["SPACEBAR"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,53 +1,52 @@
|
|||||||
{
|
{
|
||||||
"profileName" : "NumPad",
|
"profileName" : "Numpad Json",
|
||||||
"sortOrder" : 0,
|
"sortOrder" : 0,
|
||||||
|
|
||||||
"key1" : {
|
"key1" : {
|
||||||
"text" : ["7"],
|
"text" : "7",
|
||||||
"value" : ["SEVEN"]
|
"values" : ["SEVEN"]
|
||||||
},
|
},
|
||||||
"key2" : {
|
"key2" : {
|
||||||
"text" : ["8"],
|
"text" : "8",
|
||||||
"value" : ["EIGHT"]
|
"values" : ["EIGHT"]
|
||||||
},
|
},
|
||||||
"key3" : {
|
"key3" : {
|
||||||
"text" : ["9"],
|
"text" : "9",
|
||||||
"value" : ["NINE"]
|
"values" : ["NINE"]
|
||||||
},
|
},
|
||||||
"key4" : {
|
"key4" : {
|
||||||
"text" : ["4"],
|
"text" : "4",
|
||||||
"value" : ["FOUR"]
|
"values" : ["FOUR"]
|
||||||
},
|
},
|
||||||
"key5" : {
|
"key5" : {
|
||||||
"text" : ["5"],
|
"text" : "5",
|
||||||
"value" : ["FIVE"]
|
"values" : ["FIVE"]
|
||||||
},
|
},
|
||||||
"key6" : {
|
"key6" : {
|
||||||
"text" : ["6"],
|
"text" : "6",
|
||||||
"value" : ["SIX"]
|
"values" : ["SIX"]
|
||||||
},
|
},
|
||||||
"key7" : {
|
"key7" : {
|
||||||
"text" : ["1"],
|
"text" : "1",
|
||||||
"value" : ["ONE"]
|
"values" : ["ONE"]
|
||||||
},
|
},
|
||||||
"key8" : {
|
"key8" : {
|
||||||
"text" : ["2"],
|
"text" : "2",
|
||||||
"value" : ["TWO"]
|
"values" : ["TWO"]
|
||||||
},
|
},
|
||||||
"key9" : {
|
"key9" : {
|
||||||
"text" : ["3"],
|
"text" : "3",
|
||||||
"value" : ["THREE"]
|
"values" : ["THREE"]
|
||||||
},
|
},
|
||||||
"key10" : {
|
"key10" : {
|
||||||
"text" : ["0"],
|
"text" : "0",
|
||||||
"value" : ["ZERO"]
|
"values" : ["ZERO"]
|
||||||
},
|
},
|
||||||
"key11" : {
|
"key11" : {
|
||||||
"text" : ["."],
|
"text" : ".",
|
||||||
"value" : ["PERIOD"]
|
"values" : ["PERIOD"]
|
||||||
},
|
},
|
||||||
"key12" : {
|
"key12" : {
|
||||||
"text" : ["ENT"],
|
"text" : "ENT",
|
||||||
"value" : ["RETURN"]
|
"values" : ["RETURN"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"profileName" : "",
|
||||||
|
"sortOrder" : 99,
|
||||||
|
|
||||||
|
"key1" : {
|
||||||
|
"text" : "",
|
||||||
|
"values" : [""]
|
||||||
|
},
|
||||||
|
"key2" : {
|
||||||
|
"text" : "",
|
||||||
|
"values" : [""]
|
||||||
|
},
|
||||||
|
"key3" : {
|
||||||
|
"text" : "",
|
||||||
|
"values" : [""]
|
||||||
|
},
|
||||||
|
"key4" : {
|
||||||
|
"text" : "",
|
||||||
|
"values" : [""]
|
||||||
|
},
|
||||||
|
"key5" : {
|
||||||
|
"text" : "",
|
||||||
|
"values" : [""]
|
||||||
|
},
|
||||||
|
"key6" : {
|
||||||
|
"text" : "",
|
||||||
|
"values" : [""]
|
||||||
|
},
|
||||||
|
"key7" : {
|
||||||
|
"text" : "",
|
||||||
|
"values" : [""]
|
||||||
|
},
|
||||||
|
"key8" : {
|
||||||
|
"text" : "",
|
||||||
|
"values" : [""]
|
||||||
|
},
|
||||||
|
"key9" : {
|
||||||
|
"text" : "",
|
||||||
|
"values" : [""]
|
||||||
|
},
|
||||||
|
"key10" : {
|
||||||
|
"text" : "",
|
||||||
|
"values" : [""]
|
||||||
|
},
|
||||||
|
"key11" : {
|
||||||
|
"text" : "",
|
||||||
|
"values" : [""]
|
||||||
|
},
|
||||||
|
"key12" : {
|
||||||
|
"text" : "",
|
||||||
|
"values" : [""]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -16,14 +16,12 @@ COLOR_UPDATE_RATE = 33000000 # .033 seconds
|
|||||||
class NumpadApp(App):
|
class NumpadApp(App):
|
||||||
def __init__(self, macropad, config):
|
def __init__(self, macropad, config):
|
||||||
super().__init__(macropad, config)
|
super().__init__(macropad, config)
|
||||||
self.name = "Numpad"
|
self.name = "NumpadApp"
|
||||||
self.wheel_offset = 0
|
self.wheel_offset = 0
|
||||||
self.lit_keys = [False] * 12
|
|
||||||
self.labels = []
|
self.labels = []
|
||||||
self.title = "Numpad"
|
self.title = "Numpad"
|
||||||
self.modifier_pressed = False
|
self.modifier_pressed = False
|
||||||
self.last_color_update = 0
|
self.last_color_update = 0
|
||||||
self.modifier_pressed = False
|
|
||||||
self.macros = MacroSet(
|
self.macros = MacroSet(
|
||||||
[
|
[
|
||||||
Macro("7", Keycode.SEVEN), Macro("8", Keycode.EIGHT), Macro("9", Keycode.NINE),
|
Macro("7", Keycode.SEVEN), Macro("8", Keycode.EIGHT), Macro("9", Keycode.NINE),
|
||||||
@@ -36,7 +34,7 @@ class NumpadApp(App):
|
|||||||
encoder_down=Macro("-", Keycode.KEYPAD_MINUS),
|
encoder_down=Macro("-", Keycode.KEYPAD_MINUS),
|
||||||
)
|
)
|
||||||
self.mod_macros = MacroSet([
|
self.mod_macros = MacroSet([
|
||||||
Macro("<", Keycode.SHIFT, Keycode.COMMA), Macro(">", Keycode.SHIFT, Keycode.PERIOD), Macro("&", Keycode.SHIFT, Keycode.SEVEN),
|
Macro("<", Keycode.SHIFT, Keycode.COMMA), Macro(">", Keycode.SHIFT, Keycode.PERIOD), Macro("BACKSP", Keycode.BACKSPACE),
|
||||||
|
|
||||||
Macro("(", Keycode.SHIFT, Keycode.NINE), Macro(")", Keycode.SHIFT, Keycode.ZERO),Macro("%", Keycode.SHIFT, Keycode.FIVE),
|
Macro("(", Keycode.SHIFT, Keycode.NINE), Macro(")", Keycode.SHIFT, Keycode.ZERO),Macro("%", Keycode.SHIFT, Keycode.FIVE),
|
||||||
|
|
||||||
@@ -62,7 +60,6 @@ class NumpadApp(App):
|
|||||||
print("on start from the app!")
|
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_layout(GridLayout(x=0, y=9, width=128, height=54, grid_size=(3, 4), cell_padding=1))
|
||||||
self.set_title(self.title)
|
self.set_title(self.title)
|
||||||
self.lit_keys = [True] * 12
|
|
||||||
for i in range(12):
|
for i in range(12):
|
||||||
self.labels.append(Label(terminalio.FONT, text=self.active_macros.get_macro_from_key(i).name))
|
self.labels.append(Label(terminalio.FONT, text=self.active_macros.get_macro_from_key(i).name))
|
||||||
for index in range(12):
|
for index in range(12):
|
||||||
@@ -93,11 +90,8 @@ class NumpadApp(App):
|
|||||||
if last_update_ago > COLOR_UPDATE_RATE:
|
if last_update_ago > COLOR_UPDATE_RATE:
|
||||||
self.last_color_update = monotonic_ns()
|
self.last_color_update = monotonic_ns()
|
||||||
for pixel in range(12):
|
for pixel in range(12):
|
||||||
if self.lit_keys[pixel]:
|
(r, g, b) = rgb_from_int(colorwheel((pixel / 12 * 256) + self.wheel_offset))
|
||||||
(r, g, b) = rgb_from_int(colorwheel((pixel / 12 * 256) + self.wheel_offset))
|
colors.append((r, g, b))
|
||||||
colors.append((r, g, b))
|
|
||||||
else:
|
|
||||||
colors.append((0, 0, 0))
|
|
||||||
self.set_colors(colors)
|
self.set_colors(colors)
|
||||||
|
|
||||||
def process_keys_pressed_callback(self, key_event):
|
def process_keys_pressed_callback(self, key_event):
|
||||||
|
|||||||
@@ -143,12 +143,13 @@ class App(object):
|
|||||||
|
|
||||||
def _stop_tone_for_key(self, key_number):
|
def _stop_tone_for_key(self, key_number):
|
||||||
self.macropad.stop_tone()
|
self.macropad.stop_tone()
|
||||||
self._pressed_keys.remove(key_number)
|
if key_number in self._pressed_keys:
|
||||||
if self._pressed_keys and self.config.key_tone_enabled():
|
self._pressed_keys.remove(key_number)
|
||||||
if key_number in self._key_tones:
|
if self._pressed_keys and self.config.key_tone_enabled():
|
||||||
self.macropad.start_tone(self._key_tones[self._pressed_keys[0]])
|
if key_number in self._key_tones:
|
||||||
else:
|
self.macropad.start_tone(self._key_tones[self._pressed_keys[0]])
|
||||||
self.macropad.start_tone(self.config.key_tone_hz())
|
else:
|
||||||
|
self.macropad.start_tone(self.config.key_tone_hz())
|
||||||
|
|
||||||
def _process_wheel_changes(self) -> None:
|
def _process_wheel_changes(self) -> None:
|
||||||
encoder = self.macropad.encoder
|
encoder = self.macropad.encoder
|
||||||
|
|||||||
@@ -1,23 +1,29 @@
|
|||||||
import time
|
import time, os
|
||||||
|
|
||||||
|
from . import App
|
||||||
from .app_state import AppState
|
from .app_state import AppState
|
||||||
|
|
||||||
from macropad_os.system_apps import OptionsApp, DebugApp
|
from macropad_os.system_apps import OptionsApp, DebugApp, JsonApp
|
||||||
|
|
||||||
|
|
||||||
class MacropadOS(object):
|
class MacropadOS(object):
|
||||||
def __init__(self, macropad, config, apps):
|
def __init__(self, macropad, config, python_apps: str, json_apps: str):
|
||||||
print("app router")
|
print("app router")
|
||||||
self.macropad = macropad
|
self.macropad = macropad
|
||||||
self.app_index = 0
|
self.app_index = 0
|
||||||
self.apps = [a(macropad, config) for a in apps]
|
|
||||||
self.options = OptionsApp(macropad, config)
|
self.options = OptionsApp(macropad, config)
|
||||||
self.current_app = self.apps[self.app_index]
|
|
||||||
self.config = config
|
self.config = config
|
||||||
self.encoder_state = False
|
self.encoder_state = False
|
||||||
self.options_time = 500000000 # .5 seconds in nanoseconds
|
self.options_time = 500000000 # .5 seconds in nanoseconds
|
||||||
self.click_time = 0
|
self.click_time = 0
|
||||||
self.debug_app = DebugApp(macropad, config, "DEBUG APP")
|
self.debug_app = DebugApp(macropad, config, "DEBUG APP")
|
||||||
self.debug_app_active = self.config.debug_app_enabled()
|
self.debug_app_active = self.config.debug_app_enabled()
|
||||||
|
self.python_apps_location = python_apps
|
||||||
|
self.json_apps_location = json_apps
|
||||||
|
self.apps: [App] = []
|
||||||
|
self.load_python_apps()
|
||||||
|
self.load_json_apps()
|
||||||
|
self.current_app = self.apps[self.app_index]
|
||||||
if self.debug_app_active:
|
if self.debug_app_active:
|
||||||
self.apps.append(self.debug_app)
|
self.apps.append(self.debug_app)
|
||||||
|
|
||||||
@@ -38,6 +44,39 @@ class MacropadOS(object):
|
|||||||
print("Starting new app")
|
print("Starting new app")
|
||||||
self.current_app.resume()
|
self.current_app.resume()
|
||||||
|
|
||||||
|
def load_python_apps(self):
|
||||||
|
app_classes = []
|
||||||
|
for filename in sorted(os.listdir(self.python_apps_location)):
|
||||||
|
if filename.endswith('.py') and not filename.startswith('._'):
|
||||||
|
try:
|
||||||
|
print(filename)
|
||||||
|
module = __import__(self.python_apps_location + '/' + filename[:-3])
|
||||||
|
classes = [getattr(module, a) for a in dir(module)
|
||||||
|
if isinstance(getattr(module, a), type)]
|
||||||
|
for cls in classes:
|
||||||
|
if issubclass(cls, App) and cls.__name__ != "App":
|
||||||
|
app_classes.append(cls)
|
||||||
|
print(app_classes)
|
||||||
|
except (SyntaxError, ImportError, AttributeError, KeyError, NameError, IndexError, TypeError) as err:
|
||||||
|
print("ERROR in", filename)
|
||||||
|
import traceback
|
||||||
|
traceback.print_exception(err, err, err.__traceback__)
|
||||||
|
self.apps.extend(a(self.macropad, self.config) for a in app_classes)
|
||||||
|
|
||||||
|
def load_json_apps(self):
|
||||||
|
json_apps = []
|
||||||
|
for filename in sorted(os.listdir(self.json_apps_location)):
|
||||||
|
if filename.endswith('.json'):
|
||||||
|
json_apps.append(
|
||||||
|
JsonApp(
|
||||||
|
self.macropad,
|
||||||
|
self.config,
|
||||||
|
self.json_apps_location + "/" + filename
|
||||||
|
)
|
||||||
|
)
|
||||||
|
json_apps.sort(key=lambda x: x.sort_order)
|
||||||
|
self.apps.extend(json_apps)
|
||||||
|
|
||||||
def start(self) -> None:
|
def start(self) -> None:
|
||||||
print(self.current_app)
|
print(self.current_app)
|
||||||
self.current_app.start()
|
self.current_app.start()
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
from .debug_app import DebugApp
|
from .debug_app import DebugApp
|
||||||
from .options_app import OptionsApp
|
from .options_app import OptionsApp
|
||||||
|
from .json_app import JsonApp
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
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)
|
||||||
Reference in New Issue
Block a user