ui: reduce flicker in buttons, text, and pin dialog

pull/25/head
Jan Pochyla 6 years ago
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…
Cancel
Save