import utime from micropython import const from trezor import loop, res, ui _TARGET_MS = const(1000) _SHRINK_BY = const(2) class Loader(ui.Widget): def __init__(self, style=ui.LDR_DEFAULT): self.target_ms = _TARGET_MS self.normal_style = style['normal'] or ui.LDR_DEFAULT['normal'] self.active_style = style['active'] or ui.LDR_DEFAULT['active'] self.start_ms = None self.stop_ms = None def start(self): self.start_ms = utime.ticks_ms() self.stop_ms = None def stop(self): if self.start_ms is not None and self.stop_ms is None: diff_ms = utime.ticks_ms() - self.start_ms else: diff_ms = 0 self.stop_ms = utime.ticks_ms() return diff_ms >= self.target_ms def is_active(self): return self.start_ms is not None def render(self): target = self.target_ms start = self.start_ms stop = self.stop_ms now = utime.ticks_ms() if stop is None: r = min(now - start, target) else: r = max(stop - start + (stop - now) * _SHRINK_BY, 0) if r == 0: self.start_ms = None self.stop_ms = None if r == target: s = self.active_style else: s = self.normal_style if s['icon'] is None: ui.display.loader( r, -24, s['fg-color'], s['bg-color']) elif s['icon-fg-color'] is None: ui.display.loader( r, -24, s['fg-color'], s['bg-color'], res.load(s['icon'])) else: ui.display.loader( r, -24, s['fg-color'], s['bg-color'], res.load(s['icon']), s['icon-fg-color']) 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