def learn_about_5_buttons(self): c = Canvas(self.o) c.centered_text( "Let's go through\nthe main buttons\nand their meanings") GraphicsPrinter(c.get_image(), self.i, self.o, 5, invert=False) c.clear() c.centered_text("Press the buttons\nto test\nThen ENTER\nto continue") GraphicsPrinter(c.get_image(), self.i, self.o, 5, invert=False) c.clear() # First, show the left/right/up/down buttons # TODO: different behaviour for ZP and emulator? c.text("Enter", (48, 22)) c.text("Continue", (39, 30)) c.text("Left", (2, 18)) c.text("Back", (2, 26)) c.text("Cancel", (2, 34)) c.text("Right", (92, 22)) c.text("Option", (90, 30)) c.text("Up", (56, 5)) c.text("Down", (52, "-18")) image = c.get_image() def process_key(key, state): # invert/deinvert areas on the canvas when buttons are pressed/released # on drivers that don't support key states, will toggle inversion on every press # on drivers that support key states, will "highlight" the buttons pressed print(key, state) if state != KEY_HELD: if key == "KEY_UP": c.invert_rect((64 - 20, 2, 64 + 20, 22)) elif key == "KEY_DOWN": c.invert_rect((64 - 20, "-2", 64 + 20, "-22")) elif key == "KEY_LEFT": c.invert_rect((2, 32 - 15, 38, 32 + 15)) elif key == "KEY_RIGHT": c.invert_rect(("-2", 32 - 10, "-40", 32 + 10)) keys = ["KEY_UP", "KEY_DOWN", "KEY_LEFT", "KEY_RIGHT"] keymap = {"KEY_ENTER": "deactivate"} for key in keys: cb = cb_needs_key_state(lambda st, x=key: process_key(x, st)) keymap[key] = cb Refresher(c.get_image, self.i, self.o, override_left=False, keymap=keymap).activate() return True
class KeyboardFallbackApp(ZeroApp): do_not_activate_events = ["usb_keyboard_connected"] def __init__(self, *args, **kwargs): ZeroApp.__init__(self, *args, **kwargs) self.active = Event() self.pop_on_event = Event() self.pop_on_event.set() self.c = Canvas(self.o) device_manager.register_monitor_callback(self.process_dm_event) self.i.set_streaming(self.deactivate) self.state = None self.status_image = "No image" self.r = Refresher(self.get_status_image, self.i, self.o, name="Keyboard fallback status refresher") def deactivate(self, keyname, *args, **kwargs): # Upon receiving *any* key when active, it's our hint from the user # to not appear again ;-P # Unless the keyboard was just connected, of course if self.state == "usb_keyboard_connected": self.r.deactivate() self.context.signal_background() else: self.pop_on_event.clear() def go_into_foreground(self): if not self.pop_on_event.isSet(): return False return self.context.request_switch() def process_dm_event(self, event): self.c.clear() self.state = event if not self.context.is_active() and self.pop_on_event.isSet() \ and event not in self.do_not_activate_events: if not self.go_into_foreground(): return if event == "usb_keyboard_connected": self.c.centered_text("USB kb connected") elif event == "custom_i2c_disconnected": self.c.centered_text("Keypad not found!") try: dcdc = USB_DCDC() dcdc.on() except: logger.exception("Can't turn the ZP USB DC-DC on!") elif event == "looking_for_usb_keyboard": self.c.centered_text("Keypad not found!", ch=16) self.c.centered_text("Looking for USB kb") elif event == "usb_keyboard_found": self.c.centered_text("USB keyboard found") elif event == "usb_keyboard_disconnected": self.c.centered_text("USB kb disconnected!") self.status_image = self.c.get_image() if self.state == "usb_keyboard_connected": sleep(2) if self.state == "usb_keyboard_connected": self.r.deactivate() self.context.signal_background() def set_context(self, c): self.context = c c.set_target(self.show_status) def get_status_image(self): return self.status_image def show_status(self): self.r.activate()