Exemplo n.º 1
0
async def alert(count: int = 3) -> None:
    short_sleep = loop.sleep(20000)
    long_sleep = loop.sleep(80000)
    for i in range(count * 2):
        if i % 2 == 0:
            display.backlight(style.BACKLIGHT_MAX)
            await short_sleep
        else:
            display.backlight(style.BACKLIGHT_DIM)
            await long_sleep
    display.backlight(style.BACKLIGHT_NORMAL)
Exemplo n.º 2
0
async def alert(count: int = 3):
    short_sleep = loop.sleep(20000)
    long_sleep = loop.sleep(80000)
    current = display.backlight()
    for i in range(count * 2):
        if i % 2 == 0:
            display.backlight(BACKLIGHT_MAX)
            yield short_sleep
        else:
            display.backlight(BACKLIGHT_NORMAL)
            yield long_sleep
    display.backlight(current)
Exemplo n.º 3
0
async def _alert(count: int) -> None:
    short_sleep = loop.sleep(20)
    long_sleep = loop.sleep(80)
    for i in range(count * 2):
        if i % 2 == 0:
            display.backlight(style.BACKLIGHT_MAX)
            await short_sleep
        else:
            display.backlight(style.BACKLIGHT_DIM)
            await long_sleep
    display.backlight(style.BACKLIGHT_NORMAL)
    global _alert_in_progress
    _alert_in_progress = False
Exemplo n.º 4
0
 def __iter__(self):
     sleep = loop.sleep(1000000 // 30)  # 30 fps
     ui.display.bar(0, 32, 240, 240 - 80, ui.BG)  # clear
     while self.is_active():
         self.render()
         yield sleep
     ui.display.bar(0, 32, 240, 240 - 80, ui.BG)  # clear
Exemplo n.º 5
0
 def __iter__(self):
     sleep = loop.sleep(1000000 // 30)  # 30 fps
     ui.display.bar(0, 32, ui.WIDTH, ui.HEIGHT - 83, ui.BG)  # clear
     while self.is_active():
         self.render()
         yield sleep
     ui.display.bar(0, 32, ui.WIDTH, ui.HEIGHT - 83, ui.BG)  # clear
Exemplo n.º 6
0
    async def __iter__(self):
        timeout = loop.sleep(1000 * 1000 * 1)
        touch = loop.select(io.TOUCH)
        wait_timeout = loop.wait(touch, timeout)
        wait_touch = loop.wait(touch)
        content = None

        self.back.taint()
        self.input.taint()

        while content is None:
            self.render()
            if self.pbutton is not None:
                wait = wait_timeout
            else:
                wait = wait_touch
            result = await wait
            if touch in wait.finished:
                event, *pos = result
                content = self.touch(event, pos)
            else:
                if self.input.word:
                    # just reset the pending state
                    self.edit(self.input.content)
                else:
                    # invalid character, backspace it
                    self.edit(self.input.content[:-1])
        return content
Exemplo n.º 7
0
async def memory_stats(interval):
    import micropython
    import gc

    sleep = loop.sleep(interval * 1000 * 1000)
    while True:
        micropython.mem_info()
        gc.collect()
        await sleep
Exemplo n.º 8
0
async def animate_swipe():
    time_delay = const(40000)
    draw_delay = const(200000)

    sleep = loop.sleep(time_delay)
    for t in ui.pulse(draw_delay):
        fg = ui.blend(ui.GREY, ui.DARK_GREY, t)
        ui.display.icon(110, 210, res.load(ui.ICON_SWIPE), fg, ui.BG)
        await sleep
Exemplo n.º 9
0
 def handle_rendering(self) -> loop.Task:  # type: ignore
     backlight_fade(style.BACKLIGHT_DIM)
     display.clear()
     self.dispatch(RENDER, 0, 0)
     display.refresh()
     backlight_fade(style.BACKLIGHT_NORMAL)
     sleep = loop.sleep(_RENDER_DELAY_US)
     while True:
         self.dispatch(RENDER, 0, 0)
         yield sleep
Exemplo n.º 10
0
async def animate_swipe():
    time_delay = const(40000)
    draw_delay = const(200000)

    ui.display.text_center(130, 220, 'Swipe', ui.BOLD, ui.GREY, ui.BG)

    sleep = loop.sleep(time_delay)
    icon = res.load(ui.ICON_SWIPE)
    for t in ui.pulse(draw_delay):
        fg = ui.blend(ui.GREY, ui.DARK_GREY, t)
        ui.display.icon(70, 205, icon, fg, ui.BG)
        yield sleep
Exemplo n.º 11
0
 def __iter__(self):
     timeout = loop.sleep(1000 * 1000 * 1)
     touch = loop.select(io.TOUCH)
     wait = loop.wait(touch, timeout)
     while True:
         self.render()
         result = yield wait
         if touch in wait.finished:
             event, *pos = result
             self.touch(event, pos)
         elif self.zoom_buttons:
             self.zoom_buttons = None
             for btn in self.key_buttons:
                 btn.taint()
Exemplo n.º 12
0
 def __iter__(self):
     timeout = loop.sleep(1000 * 1000 * 1)
     touch = loop.select(io.TOUCH)
     wait = loop.wait(touch, timeout)
     while True:
         self.render()
         result = yield wait
         if touch in wait.finished:
             event, *pos = result
             self.touch(event, pos)
         else:
             self.pending_button = None
             self.pending_index = 0
             self._update_suggestion()
             self._update_buttons()
Exemplo n.º 13
0
    async def handle_input(self) -> None:
        touch = loop.wait(io.TOUCH)
        timeout = loop.sleep(1000)
        race_touch = loop.race(touch)
        race_timeout = loop.race(touch, timeout)

        while True:
            if self.pending_button is not None:
                race = race_timeout
            else:
                race = race_touch
            result = await race

            if touch in race.finished:
                event, x, y = result
                self.dispatch(event, x, y)
            else:
                self.on_timeout()
Exemplo n.º 14
0
    async def handle_input(self):
        touch = loop.wait(io.TOUCH)
        timeout = loop.sleep(1000 * 1000 * 1)
        spawn_touch = loop.spawn(touch)
        spawn_timeout = loop.spawn(touch, timeout)

        while True:
            if self.pending_button is not None:
                spawn = spawn_timeout
            else:
                spawn = spawn_touch
            result = await spawn

            if touch in spawn.finished:
                event, x, y = result
                self.dispatch(event, x, y)
            else:
                self.on_timeout()
Exemplo n.º 15
0
 async def enter_text(self):
     timeout = loop.sleep(1000 * 1000 * 1)
     touch = loop.wait(io.TOUCH)
     wait_timeout = loop.spawn(touch, timeout)
     wait_touch = loop.spawn(touch)
     content = None
     while content is None:
         self.render()
         if self.pbutton is not None:
             wait = wait_timeout
         else:
             wait = wait_touch
         result = await wait
         if touch in wait.finished:
             event, *pos = result
             content = self.touch(event, pos)
         else:
             # disable the pending buttons
             self.edit(self.input.content)
     return content
Exemplo n.º 16
0
 def handle_rendering(self) -> loop.Task:  # type: ignore
     """Task that is rendering the layout in a busy loop."""
     # Before the first render, we dim the display.
     backlight_fade(style.BACKLIGHT_DIM)
     # Clear the screen of any leftovers, make sure everything is marked for
     # repaint (we can be running the same layout instance multiple times)
     # and paint it.
     display.clear()
     self.dispatch(REPAINT, 0, 0)
     self.dispatch(RENDER, 0, 0)
     # Display is usually refreshed after every loop step, but here we are
     # rendering everything synchronously, so refresh it manually and turn
     # the brightness on again.
     refresh()
     backlight_fade(style.BACKLIGHT_NORMAL)
     sleep = loop.sleep(_RENDER_DELAY_US)
     while True:
         # Wait for a couple of ms and render the layout again.  Because
         # components use re-paint marking, they do not really draw on the
         # display needlessly.  Using `yield` instead of `await` to avoid allocations.
         # TODO: remove the busy loop
         yield sleep
         self.dispatch(RENDER, 0, 0)
Exemplo n.º 17
0
 def handle_timeout(self):
     yield loop.sleep(self.time_ms * 1000)
     raise ui.Result(None)
Exemplo n.º 18
0
 def handle_timeout(self) -> loop.Task:  # type: ignore
     yield loop.sleep(self.time_ms)
     raise ui.Result(None)
Exemplo n.º 19
0
async def backlight_slide(val: int, delay: int = 20000, step: int = 1):
    sleep = loop.sleep(delay)
    current = display.backlight()
    for i in range(current, val, -step if current > val else step):
        display.backlight(i)
        await sleep
Exemplo n.º 20
0
 def __iter__(self):
     sleep = loop.sleep(1000000 // 60)  # 60 fps
     while self.is_active():
         self.render()
         yield sleep
Exemplo n.º 21
0
class Layout(Component):
    """
    Abstract class.

    Layouts are top-level components.  Only one layout can be running at the
    same time.  Layouts provide asynchronous interface, so a running task can
    wait for the layout to complete.  Layouts complete when a `Result` is
    raised, usually from some of the child components.
    """

    BACKLIGHT_LEVEL = style.BACKLIGHT_NORMAL
    RENDER_SLEEP = loop.sleep(_RENDER_DELAY_MS)  # type: loop.Syscall

    async def __iter__(self) -> ResultValue:
        """
        Run the layout and wait until it completes.  Returns the result value.
        Usually not overridden.
        """
        if __debug__:
            # we want to call notify_layout_change() when the rendering is done;
            # but only the first time the layout is awaited. Here we indicate that we
            # are being awaited, and in handle_rendering() we send the appropriate event
            self.should_notify_layout_change = True

        value = None
        try:
            # If any other layout is running (waiting on the layout channel),
            # we close it with the Cancelled exception, and wait until it is
            # closed, just to be sure.
            if layout_chan.takers:
                await layout_chan.put(Cancelled())
            # Now, no other layout should be running.  In a loop, we create new
            # layout tasks and execute them in parallel, while waiting on the
            # layout channel.  This allows other layouts to cancel us, and the
            # layout tasks to trigger restart by exiting (new tasks are created
            # and we continue, because we are in a loop).
            while True:
                await loop.race(layout_chan.take(), *self.create_tasks())
        except Result as result:
            # Result exception was raised, this means this layout is complete.
            value = result.value
        return value

    def __await__(self) -> Generator[Any, Any, ResultValue]:
        return self.__iter__()  # type: ignore

    def create_tasks(self) -> Tuple[loop.Task, ...]:
        """
        Called from `__iter__`.  Creates and returns a sequence of tasks that
        run this layout.  Tasks are executed in parallel.  When one of them
        returns, the others are closed and `create_tasks` is called again.

        Usually overridden to add another tasks to the list."""
        return self.handle_input(), self.handle_rendering()

    def handle_input(self) -> loop.Task:  # type: ignore
        """Task that is waiting for the user input."""
        touch = loop.wait(io.TOUCH)
        while True:
            # Using `yield` instead of `await` to avoid allocations.
            event, x, y = yield touch
            workflow.idle_timer.touch()
            self.dispatch(event, x, y)
            # We dispatch a render event right after the touch.  Quick and dirty
            # way to get the lowest input-to-render latency.
            self.dispatch(RENDER, 0, 0)

    def handle_rendering(self) -> loop.Task:  # type: ignore
        """Task that is rendering the layout in a busy loop."""
        # Before the first render, we dim the display.
        backlight_fade(style.BACKLIGHT_DIM)
        # Clear the screen of any leftovers, make sure everything is marked for
        # repaint (we can be running the same layout instance multiple times)
        # and paint it.
        display.clear()
        self.dispatch(REPAINT, 0, 0)
        self.dispatch(RENDER, 0, 0)

        if __debug__ and self.should_notify_layout_change:
            # notify about change and do not notify again until next await.
            # (handle_rendering might be called multiple times in a single await,
            # because of the endless loop in __iter__)
            self.should_notify_layout_change = False
            notify_layout_change(self)

        # Display is usually refreshed after every loop step, but here we are
        # rendering everything synchronously, so refresh it manually and turn
        # the brightness on again.
        refresh()
        backlight_fade(self.BACKLIGHT_LEVEL)
        sleep = self.RENDER_SLEEP
        while True:
            # Wait for a couple of ms and render the layout again.  Because
            # components use re-paint marking, they do not really draw on the
            # display needlessly.  Using `yield` instead of `await` to avoid allocations.
            # TODO: remove the busy loop
            yield sleep
            self.dispatch(RENDER, 0, 0)