Beispiel #1
0
class StopwatchApp(ZeroApp):
    def __init__(self, i, o):
        super(StopwatchApp, self).__init__(i, o)
        self.menu_name = "Stopwatch"
        self.counter = Chronometer()
        self.refresher = None
        self.__instructions = [
            "", "UP/ENTER to start/pause", "RIGHT : restart", "DOWN : reset"
        ]

    def on_start(self):
        self.refresher = Refresher(
            self.refresh_function, self.i, self.o, .1, {
                "KEY_UP": self.counter.toggle,
                "KEY_RIGHT": self.counter.start,
                "KEY_ENTER": self.counter.toggle,
                "KEY_DOWN": self.counter.stop
            })
        self.refresher.activate()

    def refresh_function(self):
        self.counter.update()
        text_rows = [
            "{} {}".format(self.get_char(), round(self.counter.elapsed,
                                                  2)).center(self.o.cols)
        ]
        text_rows.extend([
            instruction.center(self.o.cols)
            for instruction in self.__instructions
        ])
        return text_rows

    def get_char(self):
        return "|>" if self.counter.active else "||"
Beispiel #2
0
class Throbber(LoadingIndicator, CenteredTextRenderer):
    """A throbber is a circular LoadingIndicator, similar to those used on websites
    or in smartphones. Suitable for graphical displays and looks great on them!"""
    def __init__(self, i, o, *args, **kwargs):
        self._current_angle = 0
        self._current_range = 0  # range or width of the throbber
        self.rotation_speed = 360  # degree per second
        # We use a counter to make the rotation speed independent of the refresh-rate
        self.counter = Chronometer()
        self.start_time = 0
        self.message = kwargs.pop("message", None)
        LoadingIndicator.__init__(self,
                                  i,
                                  o,
                                  refresh_interval=0.01,
                                  *args,
                                  **kwargs)

    def activate(self):
        self.start_time = time()
        self.counter.start()
        return Refresher.activate(self)

    @to_be_foreground
    def refresh(self):
        self.update_throbber_angle()
        c = canvas(self.o.device)
        c.__enter__()
        draw = c.draw
        self.draw_throbber(c, draw)
        if self.message:
            self.draw_message(draw)
        self.o.display_image(c.image)

    def draw_message(self, draw):
        # type: (ImageDraw) -> None
        bounds = self.get_centered_text_bounds(draw, self.message,
                                               self.o.device.size)

        draw.text((bounds.left, 0), self.message,
                  fill=True)  # Drawn top-centered (with margin)

    def draw_throbber(self, c, draw):
        c.__enter__()
        x, y = c.device.size
        radius = min(x, y) / 4
        draw.arc((x / 2 - radius, y / 2 - radius, x / 2 + 1 + radius,
                  y / 2 + radius),
                 start=(self._current_angle - self._current_range / 2) % 360,
                 end=(self._current_angle + self._current_range / 2) % 360,
                 fill=True)

    def update_throbber_angle(self):
        self.counter.update()
        self._current_angle += self.rotation_speed * self.counter.elapsed
        time_since_activation = time() - self.start_time
        self._current_range = cos(time_since_activation * math.pi) / 2 + 0.5
        self._current_range = (self._current_range * 170) + 10
        self.counter.restart()