1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-22 15:38:11 +00:00

feat(core): restart loader from current position

On "hold to confirm" dialogs, when you hold your finger, lift it, and
quickly hold again, the progress bar jumps to the beginning. This commit
changes the behavior so the progress continues from its current position
of the reverse animation.
This commit is contained in:
Martin Milata 2021-01-27 19:05:30 +01:00
parent 06b9d1314d
commit 9b60cc0098
2 changed files with 20 additions and 13 deletions

View File

@ -32,6 +32,7 @@ class Homescreen(HomescreenBase):
style=LoaderNeutral,
target_ms=_LOADER_TOTAL_MS - _LOADER_DELAY_MS,
offset_y=-10,
reverse_speedup=3,
)
self.touch_ms: Optional[int] = None

View File

@ -44,6 +44,7 @@ if False:
_TARGET_MS = const(1000)
_OFFSET_Y = const(-24)
_REVERSE_SPEEDUP = const(2)
class Loader(ui.Component):
@ -52,6 +53,7 @@ class Loader(ui.Component):
style: LoaderStyleType = LoaderDefault,
target_ms: int = _TARGET_MS,
offset_y: int = _OFFSET_Y,
reverse_speedup: int = _REVERSE_SPEEDUP,
) -> None:
super().__init__()
self.normal_style = style.normal
@ -60,9 +62,13 @@ class Loader(ui.Component):
self.start_ms: Optional[int] = None
self.stop_ms: Optional[int] = None
self.offset_y = offset_y
self.reverse_speedup = reverse_speedup
def start(self) -> None:
self.start_ms = utime.ticks_ms()
if self.start_ms is not None and self.stop_ms is not None:
self.start_ms = utime.ticks_ms() - self.elapsed_ms()
else:
self.start_ms = utime.ticks_ms()
self.stop_ms = None
self.on_start()
@ -70,27 +76,27 @@ class Loader(ui.Component):
self.stop_ms = utime.ticks_ms()
def elapsed_ms(self) -> int:
if self.start_ms is None:
return 0
return utime.ticks_ms() - self.start_ms
def on_render(self) -> None:
target = self.target_ms
start = self.start_ms
stop = self.stop_ms
if start is None:
return
now = utime.ticks_ms()
if stop is None:
r = min(now - start, target)
if start is None:
return 0
elif stop is not None:
return max(stop - start + (stop - now) * self.reverse_speedup, 0)
else:
r = max(stop - start + (stop - now) * 2, 0)
return min(now - start, self.target_ms)
def on_render(self) -> None:
if self.start_ms is None:
return
target = self.target_ms
r = self.elapsed_ms()
if r != target:
s = self.normal_style
else:
s = self.active_style
progress = r * 1000 // target
progress = r * 1000 // target # scale to 0-1000
if s.icon is None:
display.loader(progress, False, self.offset_y, s.fg_color, s.bg_color)
else: