mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-18 04:18:10 +00:00
ui: reduce flicker in buttons, text, and pin dialog
This commit is contained in:
parent
faa665a80b
commit
dd5eba8da9
@ -159,6 +159,11 @@ def grid(
|
||||
|
||||
|
||||
class Widget:
|
||||
tainted = True
|
||||
|
||||
def taint(self):
|
||||
self.tainted = True
|
||||
|
||||
def render(self):
|
||||
pass
|
||||
|
||||
@ -173,21 +178,3 @@ class Widget:
|
||||
event, *pos = yield touch
|
||||
result = self.touch(event, pos)
|
||||
return result
|
||||
|
||||
|
||||
class LazyWidget(Widget):
|
||||
render_next_frame = True
|
||||
|
||||
def taint(self):
|
||||
self.render_next_frame = True
|
||||
|
||||
def __iter__(self):
|
||||
touch = loop.wait(io.TOUCH)
|
||||
result = None
|
||||
while result is None:
|
||||
if self.render_next_frame:
|
||||
self.render()
|
||||
self.render_next_frame = False
|
||||
event, *pos = yield touch
|
||||
result = self.touch(event, pos)
|
||||
return result
|
||||
|
@ -1,7 +1,7 @@
|
||||
from micropython import const
|
||||
|
||||
from trezor import io, ui
|
||||
from trezor.ui import LazyWidget, contains, display, rotate
|
||||
from trezor.ui import Widget, contains, display, rotate
|
||||
|
||||
# button events
|
||||
BTN_CLICKED = const(1)
|
||||
@ -17,7 +17,7 @@ ICON = const(16) # icon size in pixels
|
||||
BORDER = const(4) # border size in pixels
|
||||
|
||||
|
||||
class Button(LazyWidget):
|
||||
class Button(Widget):
|
||||
def __init__(self, area: tuple, content: str, style: dict = ui.BTN_KEY):
|
||||
self.area = area
|
||||
self.content = content
|
||||
@ -29,14 +29,16 @@ class Button(LazyWidget):
|
||||
def enable(self):
|
||||
if self.state == BTN_DISABLED:
|
||||
self.state = BTN_INITIAL
|
||||
self.render_next_frame = True
|
||||
self.tainted = True
|
||||
|
||||
def disable(self):
|
||||
if self.state != BTN_DISABLED:
|
||||
self.state = BTN_DISABLED
|
||||
self.render_next_frame = True
|
||||
self.tainted = True
|
||||
|
||||
def render(self):
|
||||
if not self.tainted:
|
||||
return
|
||||
state = self.state
|
||||
if state == BTN_DISABLED:
|
||||
s = self.disabled_style
|
||||
@ -47,6 +49,7 @@ class Button(LazyWidget):
|
||||
ax, ay, aw, ah = self.area
|
||||
self.render_background(s, ax, ay, aw, ah)
|
||||
self.render_content(s, ax, ay, aw, ah)
|
||||
self.tainted = False
|
||||
|
||||
def render_background(self, s, ax, ay, aw, ah):
|
||||
radius = s["radius"]
|
||||
@ -89,20 +92,21 @@ class Button(LazyWidget):
|
||||
if event == io.TOUCH_START:
|
||||
if contains(self.area, pos):
|
||||
self.state = BTN_ACTIVE
|
||||
self.render_next_frame = True
|
||||
self.tainted = True
|
||||
|
||||
elif event == io.TOUCH_MOVE:
|
||||
if contains(self.area, pos):
|
||||
if state == BTN_FOCUSED:
|
||||
self.state = BTN_ACTIVE
|
||||
self.render_next_frame = True
|
||||
self.tainted = True
|
||||
else:
|
||||
if state == BTN_ACTIVE:
|
||||
self.state = BTN_FOCUSED
|
||||
self.render_next_frame = True
|
||||
self.tainted = True
|
||||
|
||||
elif event == io.TOUCH_END:
|
||||
self.state = BTN_INITIAL
|
||||
self.render_next_frame = True
|
||||
if state == BTN_ACTIVE and contains(self.area, pos):
|
||||
return BTN_CLICKED
|
||||
if state != BTN_INITIAL:
|
||||
self.state = BTN_INITIAL
|
||||
self.tainted = True
|
||||
if state == BTN_ACTIVE and contains(self.area, pos):
|
||||
return BTN_CLICKED
|
||||
|
@ -79,8 +79,7 @@ class HoldToConfirmDialog(Widget):
|
||||
self.loader.start()
|
||||
return _STARTED
|
||||
if was_active and not is_active:
|
||||
if isinstance(self.content, ui.LazyWidget):
|
||||
self.content.taint()
|
||||
self.content.taint()
|
||||
if self.loader.stop():
|
||||
return CONFIRMED
|
||||
else:
|
||||
|
@ -35,6 +35,13 @@ class PinMatrix(ui.Widget):
|
||||
self.onchange = None
|
||||
|
||||
def render(self):
|
||||
# pin matrix buttons
|
||||
for btn in self.pin_buttons:
|
||||
btn.render()
|
||||
|
||||
if not self.tainted:
|
||||
return
|
||||
|
||||
# clear canvas under input line
|
||||
display.bar(0, 0, ui.WIDTH, 45, ui.BG)
|
||||
|
||||
@ -52,9 +59,7 @@ class PinMatrix(ui.Widget):
|
||||
# input line with header label
|
||||
display.text_center(ui.WIDTH // 2, 36, self.label, ui.BOLD, ui.GREY, ui.BG)
|
||||
|
||||
# pin matrix buttons
|
||||
for btn in self.pin_buttons:
|
||||
btn.render()
|
||||
self.tainted = False
|
||||
|
||||
def touch(self, event, pos):
|
||||
for btn in self.pin_buttons:
|
||||
@ -64,6 +69,7 @@ class PinMatrix(ui.Widget):
|
||||
break
|
||||
|
||||
def change(self, pin):
|
||||
self.tainted = True
|
||||
self.pin = pin
|
||||
for btn in self.pin_buttons:
|
||||
if len(self.pin) == self.maxlength:
|
||||
|
@ -106,7 +106,7 @@ def render_text(words: list, new_lines: bool, max_lines: int) -> None:
|
||||
offset_x += SPACE
|
||||
|
||||
|
||||
class Text(ui.LazyWidget):
|
||||
class Text(ui.Widget):
|
||||
def __init__(
|
||||
self,
|
||||
header_text: str,
|
||||
@ -121,6 +121,7 @@ class Text(ui.LazyWidget):
|
||||
self.max_lines = max_lines
|
||||
self.new_lines = new_lines
|
||||
self.content = []
|
||||
self.tainted = True
|
||||
|
||||
def normal(self, *content):
|
||||
self.content.append(ui.NORMAL)
|
||||
@ -142,7 +143,10 @@ class Text(ui.LazyWidget):
|
||||
self.content.append(BR)
|
||||
|
||||
def render(self):
|
||||
if not self.tainted:
|
||||
return
|
||||
ui.header(
|
||||
self.header_text, self.header_icon, ui.TITLE_GREY, ui.BG, self.icon_color
|
||||
)
|
||||
render_text(self.content, self.new_lines, self.max_lines)
|
||||
self.tainted = False
|
||||
|
Loading…
Reference in New Issue
Block a user