reformatting the default_app structure and worked on options menu.

This commit is contained in:
Lucas
2022-04-30 23:14:42 -04:00
parent 43104ac2d2
commit d8feab1636
10 changed files with 35 additions and 31 deletions
+4
View File
@@ -0,0 +1,4 @@
from .abstract_app import App
from .app_state import AppState, InvalidStateUpdateError
from .app_router import AppRouter
from macropad_os.default_apps.debug_app import DebugApp
+82
View File
@@ -0,0 +1,82 @@
import displayio
from .app_state import AppState, InvalidStateUpdateError
DISPLAY = displayio.Group()
class App(object):
def __init__(self, macropad, config):
print("app created")
self.macropad = macropad
self.config = config
self.name = "app"
self.state = AppState.STOPPED
self.display_group = DISPLAY
def start(self):
print("Start from base class ")
if self.state is not AppState.STOPPED:
raise InvalidStateUpdateError(f"Start called but the current app state is {self.state}")
self.state = AppState.STARTING
self._on_start()
self.on_start()
self.state = AppState.PAUSED
def _on_start(self):
pass
def on_start(self):
raise NotImplementedError("on_start not implemented")
def resume(self):
if self.state is not AppState.PAUSED:
raise InvalidStateUpdateError(f"Resume called but the current app state is {self.state}")
self.state = AppState.RESUMING
self._on_resume()
self.on_resume()
self.state = AppState.RUNNING
def _on_resume(self):
pass
def on_resume(self):
raise NotImplementedError("on_resume not implemented")
def pause(self):
if self.state is not AppState.RUNNING:
raise InvalidStateUpdateError(f"Pause called but the current app state is {self.state}")
self.state = AppState.PAUSING
self._on_pause()
self.on_pause()
self.state = AppState.PAUSED
def _on_pause(self):
self.macropad.keyboard.release_all()
self.macropad.consumer_control.release()
self.macropad.mouse.release_all()
self.macropad.stop_tone()
self.macropad.pixels.show()
# self.macropad.display.refresh()
def on_pause(self):
raise NotImplementedError("on_pause not implemented")
def loop(self):
raise NotImplementedError("Not implemented")
def stop(self):
if self.state is not AppState.PAUSED:
raise InvalidStateUpdateError(f"Stop called but the current app state is {self.state}")
self.state = AppState.STOPPING
self._on_stop()
self.on_stop()
self.state = AppState.STOPPED
def _on_stop(self):
pass
def on_stop(self):
raise NotImplementedError("on_stop not implemented.")
+67
View File
@@ -0,0 +1,67 @@
import time
from .app_state import AppState
from app.options.options_app import OptionsApp
class AppRouter(object):
def __init__(self, macropad, config, apps):
print("app router")
self.macropad = macropad
self.app_index = 0
self.apps = apps
self.options = OptionsApp(macropad, config)
self.current_app = apps[self.app_index]
self.config = config
self.encoder_state = False
self.options_time = 500000000 # .5 seconds in nanoseconds
self.click_time = 0
def swap_to_app(self, app):
"""
TODO: Calculate the size of the stack and the max size of hte stack and then fully close apps if need be.
:param app:
:return:
"""
print("Pausing current app")
self.current_app.pause()
print("Selecting new app")
self.current_app = app
if self.current_app.state is AppState.STOPPED:
print("Starting new app")
self.current_app.start()
if self.current_app.state is AppState.PAUSED:
print("Starting new app")
self.current_app.resume()
print(time.monotonic_ns())
def start(self):
self.current_app.start()
self.current_app.resume()
while True:
# detect if the current app is what should be running
# stop current app and start new one if not
self.current_app.loop()
# any other finite state machine logic that comes up
if self.macropad.encoder_switch_debounced.pressed and not self.encoder_state:
self.macropad.play_tone(1000, .1)
self.encoder_state = True
self.click_time = time.monotonic_ns()
elif self.macropad.encoder_switch_debounced.released and self.encoder_state:
self.encoder_state = False
if self.current_app is self.options:
print("Moving from options to the last opened app.")
else:
self.app_index += 1
print("Moving to the next app on the list. ")
self.swap_to_app(self.apps[self.app_index % len(self.apps)])
print("released encoder")
if self.encoder_state and self.click_time:
self.release_time = time.monotonic_ns()
if (time.monotonic_ns() - self.click_time) > self.options_time:
self.macropad.play_tone(1000, .1)
self.swap_to_app(self.options)
self.encoder_state = False
self.macropad.encoder_switch_debounced.update()
+12
View File
@@ -0,0 +1,12 @@
class InvalidStateUpdateError(Exception):
pass
class AppState(object):
STARTING = "starting"
RESUMING = "resuming"
RUNNING = "running"
PAUSING = "pausing"
PAUSED = "paused"
STOPPING = "stopping"
STOPPED = "stopped"
@@ -0,0 +1 @@
from light_patterns import *
@@ -0,0 +1,20 @@
arrows_with_enter = [
(0, 0, 0), (0, 0, 0), (0, 0, 0),
(0, 0, 0), (0, 0, 100), (0, 0, 0),
(0, 0, 100), (100, 0, 0), (0, 0, 100),
(0, 0, 0), (0, 0, 100), (0, 0, 0)
]
up_down_enter = [
(0, 0, 0), (0, 0, 0), (0, 0, 0),
(0, 0, 0), (0, 0, 100), (0, 0, 0),
(0, 0, 0), (100, 0, 0), (0, 0, 0),
(0, 0, 0), (0, 0, 100), (0, 0, 0)
]
arrows_yes_no = [
(0, 0, 0), (0, 0, 0), (0, 0, 0),
(0, 0, 0), (0, 0, 100), (0, 0, 0),
(0, 0, 0), (100, 0, 0), (0, 0, 0),
(0, 100, 0), (0, 0, 100), (100, 0, 0)
]
+91
View File
@@ -0,0 +1,91 @@
import terminalio
from adafruit_display_text import bitmap_label as label
from adafruit_displayio_layout.layouts.grid_layout import GridLayout
from rainbowio import colorwheel
from macropad_os.abstract_app import App
def rgb_from_int(rgb):
blue = rgb & 255
green = (rgb >> 8) & 255
red = (rgb >> 16) & 255
return red, green, blue
class DebugApp(App):
def __init__(self, macropad, config, name):
super().__init__(macropad, config)
self.name = name
self.tones = [196, 220, 246, 262, 294, 330, 349, 392, 440, 494, 523, 587]
self.wheel_offset = 0
self.send_keyboard_inputs = 0
self.lit_keys = [False] * 12
self.labels = []
self.layout = GridLayout(x=0, y=9, width=128, height=54, grid_size=(4, 4), cell_padding=1)
self.title = label.Label(
y=4,
font=terminalio.FONT,
color=0x0,
text=f" {self.name} MENU ",
background_color=0xFFFFFF,
)
def on_start(self):
print("on start from the app!")
self.lit_keys = [False] * 12
self.macropad.display.show(self.display_group)
for _ in range(12):
self.labels.append(label.Label(terminalio.FONT, text=""))
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))
def on_resume(self):
print("resume from the debug app!")
print(id(self.display_group))
print(self.display_group)
self.display_group.append(self.title)
self.display_group.append(self.layout)
self.macropad.display.show(self.display_group)
def on_pause(self):
print("Pausing")
self.display_group.remove(self.title)
self.display_group.remove(self.layout)
def on_stop(self):
print("Stopping")
def loop(self):
self.process_key_presses()
self.light_keys()
self.light_keys()
def process_key_presses(self):
key_event = self.macropad.keys.events.get()
if key_event:
if key_event.pressed:
self.labels[key_event.key_number].text = "KEY{}".format(key_event.key_number)
print(self.macropad.keys)
self.lit_keys[key_event.key_number] = not self.lit_keys[key_event.key_number]
self.macropad.stop_tone()
self.macropad.start_tone(self.tones[key_event.key_number])
else:
self.labels[key_event.key_number].text = ""
self.macropad.stop_tone()
def light_keys(self):
self.wheel_offset += 1
for pixel in range(12):
if self.lit_keys[pixel]:
(r, g, b) = rgb_from_int(colorwheel((pixel / 12 * 256) + self.wheel_offset))
self.macropad.pixels[pixel] = (r * .1, g * .1, b * .1)
else:
self.macropad.pixels[pixel] = 0
+67
View File
@@ -0,0 +1,67 @@
import terminalio
from adafruit_display_text import label
from adafruit_displayio_layout.layouts.grid_layout import GridLayout
from common.light_patterns import arrows_yes_no
from ..abstract_app import App
class OptionsApp(App):
def __init__(self, macropad, config):
super().__init__(macropad, config)
self.send_keyboard_inputs = 0
self.labels = []
self.layout = GridLayout(x=0, y=9, width=128, height=54, grid_size=(4, 4), cell_padding=1)
self.key_colors = arrows_yes_no
self.title = label.Label(
y=4,
font=terminalio.FONT,
color=0x0,
text=f" OPTIONS MENU ",
background_color=0xFFFFFF,
)
def on_start(self):
print("on start from the app!")
self.lit_keys = [False] * 4
for _ in range(4):
self.labels.append(label.Label(terminalio.FONT, text=""))
for index in range(4):
x = 0
y = index
self.layout.add_content(self.labels[index], grid_position=(x, y), cell_size=(3, 1))
def on_resume(self):
print("resume from the options app!")
self.display_group.append(self.title)
self.display_group.append(self.layout)
self.macropad.display.show(self.display_group)
def on_pause(self):
print("Pausing")
self.display_group.remove(self.title)
self.display_group.remove(self.layout)
def on_stop(self):
print("Stopping")
def loop(self):
self.process_key_presses()
self.light_keys()
def process_key_presses(self):
key_event = self.macropad.keys.events.get()
if key_event:
if key_event.key_number < 12:
if key_event.pressed:
self.macropad.stop_tone()
self.macropad.start_tone(200)
else:
self.macropad.stop_tone()
def light_keys(self):
for pixel in range(12):
print(pixel)
self.macropad.pixels[pixel] = self.key_colors[pixel]