mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 23:48:12 +00:00
trezor/ui: extract styles
This commit is contained in:
parent
e9b66dab7e
commit
f2e53ab2eb
@ -12,83 +12,54 @@ from trezor import res
|
|||||||
|
|
||||||
display = Display()
|
display = Display()
|
||||||
|
|
||||||
|
# for desktop platforms, we need to refresh the display after each frame
|
||||||
if sys.platform != 'trezor':
|
if sys.platform != 'trezor':
|
||||||
loop.after_step_hook = display.refresh
|
loop.after_step_hook = display.refresh
|
||||||
|
|
||||||
|
# font styles
|
||||||
def rgbcolor(r: int, g: int, b: int) -> int:
|
|
||||||
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3)
|
|
||||||
|
|
||||||
|
|
||||||
LIGHT_RED = rgbcolor(0xFF, 0x00, 0x00)
|
|
||||||
# RED E4572E
|
|
||||||
RED = rgbcolor(0xE4, 0x57, 0x2E)
|
|
||||||
# ACTIVE DARK RED A64022
|
|
||||||
ACTIVE_RED = rgbcolor(0xA6, 0x40, 0x22)
|
|
||||||
PINK = rgbcolor(0xE9, 0x1E, 0x63)
|
|
||||||
PURPLE = rgbcolor(0x9C, 0x27, 0xB0)
|
|
||||||
DEEP_PURPLE = rgbcolor(0x67, 0x3A, 0xB7)
|
|
||||||
INDIGO = rgbcolor(0x3F, 0x51, 0xB5)
|
|
||||||
BLUE = rgbcolor(0x21, 0x96, 0xF3)
|
|
||||||
LIGHT_BLUE = rgbcolor(0x03, 0xA9, 0xF4)
|
|
||||||
CYAN = rgbcolor(0x00, 0xBC, 0xD4)
|
|
||||||
TEAL = rgbcolor(0x00, 0x96, 0x88)
|
|
||||||
|
|
||||||
# GREEN 4CC148
|
|
||||||
GREEN = rgbcolor(0x4C, 0xC1, 0x48)
|
|
||||||
# ACTIVE DARK GREEN 1A8C14
|
|
||||||
ACTIVE_GREEN = rgbcolor(0x1A, 0x8C, 0x14)
|
|
||||||
|
|
||||||
LIGHT_GREEN = rgbcolor(0x87, 0xCE, 0x26)
|
|
||||||
LIME = rgbcolor(0xCD, 0xDC, 0x39)
|
|
||||||
YELLOW = rgbcolor(0xFF, 0xEB, 0x3B)
|
|
||||||
AMBER = rgbcolor(0xFF, 0xC1, 0x07)
|
|
||||||
ORANGE = rgbcolor(0xFF, 0x98, 0x00)
|
|
||||||
DEEP_ORANGE = rgbcolor(0xFF, 0x57, 0x22)
|
|
||||||
BROWN = rgbcolor(0x79, 0x55, 0x48)
|
|
||||||
LIGHT_GREY = rgbcolor(0xDA, 0xDD, 0xD8)
|
|
||||||
GREY = rgbcolor(0x9E, 0x9E, 0x9E)
|
|
||||||
DARK_GREY = rgbcolor(0x3E, 0x3E, 0x3E)
|
|
||||||
BLUE_GRAY = rgbcolor(0x60, 0x7D, 0x8B)
|
|
||||||
BLACK = rgbcolor(0x00, 0x00, 0x00)
|
|
||||||
WHITE = rgbcolor(0xFA, 0xFA, 0xFA)
|
|
||||||
|
|
||||||
BLACKISH = rgbcolor(0x20, 0x20, 0x20)
|
|
||||||
MONO = Display.FONT_MONO
|
|
||||||
NORMAL = Display.FONT_NORMAL
|
NORMAL = Display.FONT_NORMAL
|
||||||
BOLD = Display.FONT_BOLD
|
BOLD = Display.FONT_BOLD
|
||||||
|
MONO = Display.FONT_MONO
|
||||||
# radius for buttons and other elements
|
|
||||||
BTN_RADIUS = const(2)
|
|
||||||
|
|
||||||
BACKLIGHT_NORMAL = const(60)
|
|
||||||
BACKLIGHT_DIM = const(5)
|
|
||||||
BACKLIGHT_NONE = const(2)
|
|
||||||
BACKLIGHT_MAX = const(255)
|
|
||||||
|
|
||||||
# display width and height
|
# display width and height
|
||||||
SCREEN = const(240)
|
SCREEN = const(240)
|
||||||
|
|
||||||
# icons
|
|
||||||
ICON_RESET = 'trezor/res/header_icons/reset.toig'
|
|
||||||
ICON_WIPE = 'trezor/res/header_icons/wipe.toig'
|
|
||||||
ICON_RECOVERY = 'trezor/res/header_icons/recovery.toig'
|
|
||||||
|
|
||||||
|
|
||||||
def contains(pos: tuple, area: tuple) -> bool:
|
|
||||||
x, y = pos
|
|
||||||
ax, ay, aw, ah = area
|
|
||||||
return ax <= x <= ax + aw and ay <= y <= ay + ah
|
|
||||||
|
|
||||||
|
|
||||||
def lerpi(a: int, b: int, t: float) -> int:
|
def lerpi(a: int, b: int, t: float) -> int:
|
||||||
return int(a + t * (b - a))
|
return int(a + t * (b - a))
|
||||||
|
|
||||||
|
|
||||||
|
def rgb(r: int, g: int, b: int) -> int:
|
||||||
|
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3)
|
||||||
|
|
||||||
|
|
||||||
def blend(ca: int, cb: int, t: float) -> int:
|
def blend(ca: int, cb: int, t: float) -> int:
|
||||||
return rgbcolor(lerpi((ca >> 8) & 0xF8, (cb >> 8) & 0xF8, t),
|
return rgb(
|
||||||
lerpi((ca >> 3) & 0xFC, (cb >> 3) & 0xFC, t),
|
lerpi((ca >> 8) & 0xF8, (cb >> 8) & 0xF8, t),
|
||||||
lerpi((ca << 3) & 0xF8, (cb << 3) & 0xF8, t))
|
lerpi((ca >> 3) & 0xFC, (cb >> 3) & 0xFC, t),
|
||||||
|
lerpi((ca << 3) & 0xF8, (cb << 3) & 0xF8, t))
|
||||||
|
|
||||||
|
|
||||||
|
from trezor.ui.style import *
|
||||||
|
|
||||||
|
|
||||||
|
def contains(area: tuple, pos: tuple) -> bool:
|
||||||
|
x, y = pos
|
||||||
|
ax, ay, aw, ah = area
|
||||||
|
return ax <= x <= ax + aw and ay <= y <= ay + ah
|
||||||
|
|
||||||
|
|
||||||
|
def rotate(pos: tuple) -> tuple:
|
||||||
|
r = display.orientation()
|
||||||
|
if r == 0:
|
||||||
|
return pos
|
||||||
|
x, y = pos
|
||||||
|
if r == 90:
|
||||||
|
return (y, 240 - x)
|
||||||
|
if r == 180:
|
||||||
|
return (240 - x, 240 - y)
|
||||||
|
if r == 270:
|
||||||
|
return (240 - y, x)
|
||||||
|
|
||||||
|
|
||||||
def pulse(delay):
|
def pulse(delay):
|
||||||
@ -119,19 +90,6 @@ async def backlight_slide(val, delay=20000):
|
|||||||
await sleep
|
await sleep
|
||||||
|
|
||||||
|
|
||||||
def rotate(pos: tuple) -> tuple:
|
|
||||||
r = display.orientation()
|
|
||||||
if r == 0:
|
|
||||||
return pos
|
|
||||||
x, y = pos
|
|
||||||
if r == 90:
|
|
||||||
return (y, 240 - x)
|
|
||||||
if r == 180:
|
|
||||||
return (240 - x, 240 - y)
|
|
||||||
if r == 270:
|
|
||||||
return (240 - y, x)
|
|
||||||
|
|
||||||
|
|
||||||
def header(title, icon=ICON_RESET, fg=BLACK, bg=BLACK):
|
def header(title, icon=ICON_RESET, fg=BLACK, bg=BLACK):
|
||||||
display.bar(0, 0, 240, 32, bg)
|
display.bar(0, 0, 240, 32, bg)
|
||||||
if icon is not None:
|
if icon is not None:
|
||||||
@ -140,7 +98,6 @@ def header(title, icon=ICON_RESET, fg=BLACK, bg=BLACK):
|
|||||||
|
|
||||||
|
|
||||||
class Widget:
|
class Widget:
|
||||||
|
|
||||||
def render(self):
|
def render(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -3,79 +3,11 @@ from micropython import const
|
|||||||
from trezor import io
|
from trezor import io
|
||||||
from trezor import ui
|
from trezor import ui
|
||||||
|
|
||||||
from trezor.ui import display
|
|
||||||
from trezor.ui import contains
|
from trezor.ui import contains
|
||||||
|
from trezor.ui import display
|
||||||
from trezor.ui import rotate
|
from trezor.ui import rotate
|
||||||
from trezor.ui import Widget
|
from trezor.ui import Widget
|
||||||
|
|
||||||
|
|
||||||
DEFAULT_BUTTON = {
|
|
||||||
'bg-color': ui.BLACK,
|
|
||||||
'fg-color': ui.WHITE,
|
|
||||||
'text-style': ui.NORMAL,
|
|
||||||
'border-color': ui.BLACK,
|
|
||||||
'radius': ui.BTN_RADIUS,
|
|
||||||
}
|
|
||||||
DEFAULT_BUTTON_ACTIVE = {
|
|
||||||
'bg-color': ui.GREY,
|
|
||||||
'fg-color': ui.BLACK,
|
|
||||||
'text-style': ui.BOLD,
|
|
||||||
'border-color': ui.GREY,
|
|
||||||
'radius': ui.BTN_RADIUS,
|
|
||||||
}
|
|
||||||
DEFAULT_BUTTON_DISABLED = {
|
|
||||||
'bg-color': ui.BLACK,
|
|
||||||
'fg-color': ui.GREY,
|
|
||||||
'text-style': ui.NORMAL,
|
|
||||||
'border-color': ui.BLACK,
|
|
||||||
'radius': ui.BTN_RADIUS,
|
|
||||||
}
|
|
||||||
|
|
||||||
CANCEL_BUTTON = {
|
|
||||||
'bg-color': ui.RED,
|
|
||||||
'fg-color': ui.WHITE,
|
|
||||||
'text-style': ui.BOLD,
|
|
||||||
'border-color': ui.RED,
|
|
||||||
'radius': ui.BTN_RADIUS,
|
|
||||||
}
|
|
||||||
CANCEL_BUTTON_ACTIVE = {
|
|
||||||
'bg-color': ui.ACTIVE_RED,
|
|
||||||
'fg-color': ui.WHITE,
|
|
||||||
'text-style': ui.BOLD,
|
|
||||||
'border-color': ui.ACTIVE_RED,
|
|
||||||
'radius': ui.BTN_RADIUS,
|
|
||||||
}
|
|
||||||
|
|
||||||
CONFIRM_BUTTON = {
|
|
||||||
'bg-color': ui.GREEN,
|
|
||||||
'fg-color': ui.WHITE,
|
|
||||||
'text-style': ui.BOLD,
|
|
||||||
'border-color': ui.GREEN,
|
|
||||||
'radius': ui.BTN_RADIUS,
|
|
||||||
}
|
|
||||||
CONFIRM_BUTTON_ACTIVE = {
|
|
||||||
'bg-color': ui.ACTIVE_GREEN,
|
|
||||||
'fg-color': ui.WHITE,
|
|
||||||
'text-style': ui.BOLD,
|
|
||||||
'border-color': ui.ACTIVE_GREEN,
|
|
||||||
'radius': ui.BTN_RADIUS,
|
|
||||||
}
|
|
||||||
|
|
||||||
CLEAR_BUTTON = {
|
|
||||||
'bg-color': ui.BLACK,
|
|
||||||
'fg-color': ui.WHITE,
|
|
||||||
'text-style': ui.NORMAL,
|
|
||||||
'border-color': ui.BLACK,
|
|
||||||
'radius': ui.BTN_RADIUS,
|
|
||||||
}
|
|
||||||
CLEAR_BUTTON_ACTIVE = {
|
|
||||||
'bg-color': ui.BLACK,
|
|
||||||
'fg-color': ui.GREY,
|
|
||||||
'text-style': ui.NORMAL,
|
|
||||||
'border-color': ui.BLACK,
|
|
||||||
'radius': ui.BTN_RADIUS,
|
|
||||||
}
|
|
||||||
|
|
||||||
BTN_CLICKED = const(1)
|
BTN_CLICKED = const(1)
|
||||||
|
|
||||||
BTN_STARTED = const(1)
|
BTN_STARTED = const(1)
|
||||||
@ -93,9 +25,9 @@ class Button(Widget):
|
|||||||
absolute=False):
|
absolute=False):
|
||||||
self.area = area
|
self.area = area
|
||||||
self.content = content
|
self.content = content
|
||||||
self.normal_style = normal_style or DEFAULT_BUTTON
|
self.normal_style = normal_style or ui.BTN_DEFAULT
|
||||||
self.active_style = active_style or DEFAULT_BUTTON_ACTIVE
|
self.active_style = active_style or ui.BTN_DEFAULT_ACTIVE
|
||||||
self.disabled_style = disabled_style or DEFAULT_BUTTON_DISABLED
|
self.disabled_style = disabled_style or ui.BTN_DEFAULT_DISABLED
|
||||||
self.absolute = absolute
|
self.absolute = absolute
|
||||||
self.state = BTN_DIRTY
|
self.state = BTN_DIRTY
|
||||||
|
|
||||||
@ -114,33 +46,33 @@ class Button(Widget):
|
|||||||
return
|
return
|
||||||
state = self.state & ~BTN_DIRTY
|
state = self.state & ~BTN_DIRTY
|
||||||
if state & BTN_DISABLED:
|
if state & BTN_DISABLED:
|
||||||
style = self.disabled_style
|
s = self.disabled_style
|
||||||
elif state & BTN_ACTIVE:
|
elif state & BTN_ACTIVE:
|
||||||
style = self.active_style
|
s = self.active_style
|
||||||
else:
|
else:
|
||||||
style = self.normal_style
|
s = self.normal_style
|
||||||
ax, ay, aw, ah = self.area
|
ax, ay, aw, ah = self.area
|
||||||
tx = ax + aw // 2
|
tx = ax + aw // 2
|
||||||
ty = ay + ah // 2 + 8
|
ty = ay + ah // 2 + 8
|
||||||
display.bar_radius(ax, ay, aw, ah,
|
display.bar_radius(ax, ay, aw, ah,
|
||||||
style['border-color'],
|
s['border-color'],
|
||||||
ui.BLACK,
|
ui.BLACK,
|
||||||
style['radius'])
|
s['radius'])
|
||||||
display.bar_radius(ax + 1, ay + 1, aw - 2, ah - 2,
|
display.bar_radius(ax + 1, ay + 1, aw - 2, ah - 2,
|
||||||
style['bg-color'],
|
s['bg-color'],
|
||||||
style['border-color'],
|
s['border-color'],
|
||||||
style['radius'])
|
s['radius'])
|
||||||
|
|
||||||
if isinstance(self.content, str):
|
if isinstance(self.content, str):
|
||||||
display.text_center(tx, ty, self.content,
|
display.text_center(tx, ty, self.content,
|
||||||
style['text-style'],
|
s['text-style'],
|
||||||
style['fg-color'],
|
s['fg-color'],
|
||||||
style['bg-color'])
|
s['bg-color'])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
display.icon(ax, ay, self.content,
|
display.icon(ax, ay, self.content,
|
||||||
style['fg-color'],
|
s['fg-color'],
|
||||||
style['bg-color'])
|
s['bg-color'])
|
||||||
|
|
||||||
self.state = state
|
self.state = state
|
||||||
|
|
||||||
@ -150,10 +82,10 @@ class Button(Widget):
|
|||||||
if not self.absolute:
|
if not self.absolute:
|
||||||
pos = rotate(pos)
|
pos = rotate(pos)
|
||||||
if event == io.TOUCH_START:
|
if event == io.TOUCH_START:
|
||||||
if contains(pos, self.area):
|
if contains(self.area, pos):
|
||||||
self.state = BTN_STARTED | BTN_DIRTY | BTN_ACTIVE
|
self.state = BTN_STARTED | BTN_DIRTY | BTN_ACTIVE
|
||||||
elif event == io.TOUCH_MOVE and self.state & BTN_STARTED:
|
elif event == io.TOUCH_MOVE and self.state & BTN_STARTED:
|
||||||
if contains(pos, self.area):
|
if contains(self.area, pos):
|
||||||
if not self.state & BTN_ACTIVE:
|
if not self.state & BTN_ACTIVE:
|
||||||
self.state = BTN_STARTED | BTN_DIRTY | BTN_ACTIVE
|
self.state = BTN_STARTED | BTN_DIRTY | BTN_ACTIVE
|
||||||
else:
|
else:
|
||||||
@ -161,5 +93,5 @@ class Button(Widget):
|
|||||||
self.state = BTN_STARTED | BTN_DIRTY
|
self.state = BTN_STARTED | BTN_DIRTY
|
||||||
elif event == io.TOUCH_END and self.state & BTN_STARTED:
|
elif event == io.TOUCH_END and self.state & BTN_STARTED:
|
||||||
self.state = BTN_DIRTY
|
self.state = BTN_DIRTY
|
||||||
if contains(pos, self.area):
|
if contains(self.area, pos):
|
||||||
return BTN_CLICKED
|
return BTN_CLICKED
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
from micropython import const
|
from micropython import const
|
||||||
from trezor import loop
|
from trezor import loop
|
||||||
|
from trezor import ui
|
||||||
from trezor.ui import Widget
|
from trezor.ui import Widget
|
||||||
from .button import Button, BTN_CLICKED, BTN_STARTED
|
from trezor.ui.button import Button, BTN_CLICKED, BTN_STARTED
|
||||||
from .button import CONFIRM_BUTTON, CONFIRM_BUTTON_ACTIVE
|
from trezor.ui.loader import Loader
|
||||||
from .button import CANCEL_BUTTON, CANCEL_BUTTON_ACTIVE
|
|
||||||
from .loader import Loader
|
|
||||||
|
|
||||||
CONFIRMED = const(1)
|
CONFIRMED = const(1)
|
||||||
CANCELLED = const(2)
|
CANCELLED = const(2)
|
||||||
@ -16,16 +15,16 @@ class ConfirmDialog(Widget):
|
|||||||
self.content = content
|
self.content = content
|
||||||
if cancel is not None:
|
if cancel is not None:
|
||||||
self.confirm = Button((121, 240 - 48, 119, 48), confirm,
|
self.confirm = Button((121, 240 - 48, 119, 48), confirm,
|
||||||
normal_style=CONFIRM_BUTTON,
|
normal_style=ui.BTN_CONFIRM,
|
||||||
active_style=CONFIRM_BUTTON_ACTIVE)
|
active_style=ui.BTN_CONFIRM_ACTIVE)
|
||||||
self.cancel = Button((0, 240 - 48, 119, 48), cancel,
|
self.cancel = Button((0, 240 - 48, 119, 48), cancel,
|
||||||
normal_style=CANCEL_BUTTON,
|
normal_style=ui.BTN_CANCEL,
|
||||||
active_style=CANCEL_BUTTON_ACTIVE)
|
active_style=ui.BTN_CANCEL_ACTIVE)
|
||||||
else:
|
else:
|
||||||
self.cancel = None
|
self.cancel = None
|
||||||
self.confirm = Button((0, 240 - 48, 240, 48), confirm,
|
self.confirm = Button((0, 240 - 48, 240, 48), confirm,
|
||||||
normal_style=CONFIRM_BUTTON,
|
normal_style=ui.BTN_CONFIRM,
|
||||||
active_style=CONFIRM_BUTTON_ACTIVE)
|
active_style=ui.BTN_CONFIRM_ACTIVE)
|
||||||
|
|
||||||
def render(self):
|
def render(self):
|
||||||
self.confirm.render()
|
self.confirm.render()
|
||||||
@ -35,7 +34,6 @@ class ConfirmDialog(Widget):
|
|||||||
def touch(self, event, pos):
|
def touch(self, event, pos):
|
||||||
if self.confirm.touch(event, pos) == BTN_CLICKED:
|
if self.confirm.touch(event, pos) == BTN_CLICKED:
|
||||||
return CONFIRMED
|
return CONFIRMED
|
||||||
|
|
||||||
if self.cancel is not None:
|
if self.cancel is not None:
|
||||||
if self.cancel.touch(event, pos) == BTN_CLICKED:
|
if self.cancel.touch(event, pos) == BTN_CLICKED:
|
||||||
return CANCELLED
|
return CANCELLED
|
||||||
@ -53,8 +51,8 @@ class HoldToConfirmDialog(Widget):
|
|||||||
def __init__(self, content, hold='Hold to confirm', *args, **kwargs):
|
def __init__(self, content, hold='Hold to confirm', *args, **kwargs):
|
||||||
self.content = content
|
self.content = content
|
||||||
self.button = Button((0, 240 - 48, 240, 48), hold,
|
self.button = Button((0, 240 - 48, 240, 48), hold,
|
||||||
normal_style=CONFIRM_BUTTON,
|
normal_style=ui.BTN_CONFIRM,
|
||||||
active_style=CONFIRM_BUTTON_ACTIVE)
|
active_style=ui.BTN_CONFIRM_ACTIVE)
|
||||||
self.loader = Loader(*args, **kwargs)
|
self.loader = Loader(*args, **kwargs)
|
||||||
|
|
||||||
def render(self):
|
def render(self):
|
||||||
|
@ -1,20 +1,7 @@
|
|||||||
from trezor import ui, res, loop, io
|
from trezor import ui, res, loop, io
|
||||||
from trezor.crypto import bip39
|
from trezor.crypto import bip39
|
||||||
from trezor.ui import display
|
from trezor.ui import display
|
||||||
from trezor.ui.button import Button, BTN_CLICKED, CLEAR_BUTTON, CLEAR_BUTTON_ACTIVE
|
from trezor.ui.button import Button, BTN_CLICKED
|
||||||
|
|
||||||
KEY_BUTTON = {
|
|
||||||
'bg-color': ui.BLACKISH,
|
|
||||||
'fg-color': ui.WHITE,
|
|
||||||
'text-style': ui.MONO,
|
|
||||||
'border-color': ui.BLACK,
|
|
||||||
}
|
|
||||||
KEY_BUTTON_ACTIVE = {
|
|
||||||
'bg-color': ui.GREY,
|
|
||||||
'fg-color': ui.BLACK,
|
|
||||||
'text-style': ui.MONO,
|
|
||||||
'border-color': ui.GREY,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def cell_area(i, n_x=3, n_y=3, start_x=0, start_y=40, end_x=240, end_y=240 - 48, spacing=0):
|
def cell_area(i, n_x=3, n_y=3, start_x=0, start_y=40, end_x=240, end_y=240 - 48, spacing=0):
|
||||||
@ -29,8 +16,8 @@ def key_buttons():
|
|||||||
keys = ['abc', 'def', 'ghi', 'jkl', 'mno', 'pqr', 'stu', 'vwx', 'yz']
|
keys = ['abc', 'def', 'ghi', 'jkl', 'mno', 'pqr', 'stu', 'vwx', 'yz']
|
||||||
# keys = [' ', 'abc', 'def', 'ghi', 'jkl', 'mno', 'pqrs', 'tuv', 'wxyz']
|
# keys = [' ', 'abc', 'def', 'ghi', 'jkl', 'mno', 'pqrs', 'tuv', 'wxyz']
|
||||||
return [Button(cell_area(i), k,
|
return [Button(cell_area(i), k,
|
||||||
normal_style=KEY_BUTTON,
|
normal_style=ui.BTN_KEY,
|
||||||
active_style=KEY_BUTTON_ACTIVE) for i, k in enumerate(keys)]
|
active_style=ui.BTN_KEY_ACTIVE) for i, k in enumerate(keys)]
|
||||||
|
|
||||||
|
|
||||||
def compute_mask(text):
|
def compute_mask(text):
|
||||||
@ -56,8 +43,8 @@ class KeyboardMultiTap(ui.Widget):
|
|||||||
self.sugg_button = Button((5, 5, 240 - 35, 30), '')
|
self.sugg_button = Button((5, 5, 240 - 35, 30), '')
|
||||||
self.bs_button = Button((240 - 35, 5, 30, 30),
|
self.bs_button = Button((240 - 35, 5, 30, 30),
|
||||||
res.load('trezor/res/pin_close.toig'),
|
res.load('trezor/res/pin_close.toig'),
|
||||||
normal_style=CLEAR_BUTTON,
|
normal_style=ui.BTN_CLEAR,
|
||||||
active_style=CLEAR_BUTTON_ACTIVE)
|
active_style=ui.BTN_CLEAR_ACTIVE)
|
||||||
|
|
||||||
def render(self):
|
def render(self):
|
||||||
|
|
||||||
@ -172,8 +159,8 @@ class KeyboardZooming(ui.Widget):
|
|||||||
self.key_buttons = key_buttons()
|
self.key_buttons = key_buttons()
|
||||||
self.bs_button = Button((240 - 35, 5, 30, 30),
|
self.bs_button = Button((240 - 35, 5, 30, 30),
|
||||||
res.load('trezor/res/pin_close.toig'),
|
res.load('trezor/res/pin_close.toig'),
|
||||||
normal_style=CLEAR_BUTTON,
|
normal_style=ui.BTN_CLEAR,
|
||||||
active_style=CLEAR_BUTTON_ACTIVE)
|
active_style=ui.BTN_CLEAR_ACTIVE)
|
||||||
|
|
||||||
def render(self):
|
def render(self):
|
||||||
self.render_input()
|
self.render_input()
|
||||||
@ -208,8 +195,8 @@ class KeyboardZooming(ui.Widget):
|
|||||||
if btn.touch(event, pos) == BTN_CLICKED:
|
if btn.touch(event, pos) == BTN_CLICKED:
|
||||||
self.content += btn.content
|
self.content += btn.content
|
||||||
self.zoom_buttons = None
|
self.zoom_buttons = None
|
||||||
for btn in self.key_buttons:
|
for b in self.key_buttons:
|
||||||
btn.taint()
|
b.taint()
|
||||||
self.bs_button.taint()
|
self.bs_button.taint()
|
||||||
break
|
break
|
||||||
|
|
||||||
@ -217,8 +204,8 @@ class KeyboardZooming(ui.Widget):
|
|||||||
for btn in self.key_buttons:
|
for btn in self.key_buttons:
|
||||||
if btn.touch(event, pos) == BTN_CLICKED:
|
if btn.touch(event, pos) == BTN_CLICKED:
|
||||||
self.zoom_buttons = zoom_buttons(btn.content, self.uppercase)
|
self.zoom_buttons = zoom_buttons(btn.content, self.uppercase)
|
||||||
for btn in self.zoom_buttons:
|
for b in self.zoom_buttons:
|
||||||
btn.taint()
|
b.taint()
|
||||||
self.bs_button.taint()
|
self.bs_button.taint()
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -4,27 +4,13 @@ from trezor import loop
|
|||||||
from trezor import ui
|
from trezor import ui
|
||||||
|
|
||||||
|
|
||||||
DEFAULT_LOADER = {
|
|
||||||
'bg-color': ui.BLACK,
|
|
||||||
'fg-color': ui.WHITE,
|
|
||||||
'icon': None,
|
|
||||||
'icon-fg-color': None,
|
|
||||||
}
|
|
||||||
DEFAULT_LOADER_ACTIVE = {
|
|
||||||
'bg-color': ui.BLACK,
|
|
||||||
'fg-color': ui.ACTIVE_GREEN,
|
|
||||||
'icon': None,
|
|
||||||
'icon-fg-color': None,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Loader(ui.Widget):
|
class Loader(ui.Widget):
|
||||||
|
|
||||||
def __init__(self, target_ms=1000, normal_style=None, active_style=None):
|
def __init__(self, target_ms=1000, normal_style=None, active_style=None):
|
||||||
self.target_ms = target_ms
|
self.target_ms = target_ms
|
||||||
self.start_ticks_ms = None
|
self.start_ticks_ms = None
|
||||||
self.normal_style = normal_style or DEFAULT_LOADER
|
self.normal_style = normal_style or ui.LDR_DEFAULT
|
||||||
self.active_style = active_style or DEFAULT_LOADER_ACTIVE
|
self.active_style = active_style or ui.LDR_DEFAULT_ACTIVE
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.start_ticks_ms = utime.ticks_ms()
|
self.start_ticks_ms = utime.ticks_ms()
|
||||||
@ -42,18 +28,18 @@ class Loader(ui.Widget):
|
|||||||
def render(self):
|
def render(self):
|
||||||
progress = min(utime.ticks_ms() - self.start_ticks_ms, self.target_ms)
|
progress = min(utime.ticks_ms() - self.start_ticks_ms, self.target_ms)
|
||||||
if progress == self.target_ms:
|
if progress == self.target_ms:
|
||||||
style = self.active_style
|
s = self.active_style
|
||||||
else:
|
else:
|
||||||
style = self.normal_style
|
s = self.normal_style
|
||||||
if style['icon'] is None:
|
if s['icon'] is None:
|
||||||
ui.display.loader(
|
ui.display.loader(
|
||||||
progress, -8, style['fg-color'], style['bg-color'])
|
progress, -8, s['fg-color'], s['bg-color'])
|
||||||
elif style['icon-fg-color'] is None:
|
elif s['icon-fg-color'] is None:
|
||||||
ui.display.loader(
|
ui.display.loader(
|
||||||
progress, -8, style['fg-color'], style['bg-color'], style['icon'])
|
progress, -8, s['fg-color'], s['bg-color'], s['icon'])
|
||||||
else:
|
else:
|
||||||
ui.display.loader(
|
ui.display.loader(
|
||||||
progress, -8, style['fg-color'], style['bg-color'], style['icon'], style['icon-fg-color'])
|
progress, -8, s['fg-color'], s['bg-color'], s['icon'], s['icon-fg-color'])
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
sleep = loop.sleep(1000000 // 60) # 60 fps
|
sleep = loop.sleep(1000000 // 60) # 60 fps
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from micropython import const
|
from micropython import const
|
||||||
from trezor import ui, res
|
from trezor import ui
|
||||||
from trezor.crypto import random
|
from trezor.crypto import random
|
||||||
from trezor.ui import display
|
from trezor.ui import display
|
||||||
from trezor.ui.button import Button, BTN_CLICKED
|
from trezor.ui.button import Button, BTN_CLICKED
|
||||||
@ -54,14 +54,6 @@ class PinMatrix(ui.Widget):
|
|||||||
for btn in self.pin_buttons:
|
for btn in self.pin_buttons:
|
||||||
btn.render()
|
btn.render()
|
||||||
|
|
||||||
# vertical border bars
|
|
||||||
# display.bar(79, 48, 2, 143, ui.blend(ui.BLACK, ui.WHITE, 0.25))
|
|
||||||
# display.bar(158, 48, 2, 143, ui.blend(ui.BLACK, ui.WHITE, 0.25))
|
|
||||||
|
|
||||||
# horizontal border bars
|
|
||||||
# display.bar(0, 95, 240, 2, ui.blend(ui.BLACK, ui.WHITE, 0.25))
|
|
||||||
# display.bar(0, 142, 240, 2, ui.blend(ui.BLACK, ui.WHITE, 0.25))
|
|
||||||
|
|
||||||
def touch(self, event, pos):
|
def touch(self, event, pos):
|
||||||
for btn in self.pin_buttons:
|
for btn in self.pin_buttons:
|
||||||
if btn.touch(event, pos) == BTN_CLICKED:
|
if btn.touch(event, pos) == BTN_CLICKED:
|
||||||
|
137
src/trezor/ui/style.py
Normal file
137
src/trezor/ui/style.py
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
from micropython import const
|
||||||
|
from trezor.ui import rgb
|
||||||
|
from trezor.ui import NORMAL, BOLD, MONO
|
||||||
|
|
||||||
|
# radius for buttons and other elements
|
||||||
|
RADIUS = const(2)
|
||||||
|
|
||||||
|
# backlight brightness
|
||||||
|
BACKLIGHT_NORMAL = const(60)
|
||||||
|
BACKLIGHT_DIM = const(5)
|
||||||
|
BACKLIGHT_NONE = const(2)
|
||||||
|
BACKLIGHT_MAX = const(255)
|
||||||
|
|
||||||
|
# colors
|
||||||
|
LIGHT_RED = rgb(0xFF, 0x00, 0x00)
|
||||||
|
RED = rgb(0xE4, 0x57, 0x2E) # RED E4572E
|
||||||
|
ACTIVE_RED = rgb(0xA6, 0x40, 0x22) # ACTIVE DARK RED A64022
|
||||||
|
PINK = rgb(0xE9, 0x1E, 0x63)
|
||||||
|
PURPLE = rgb(0x9C, 0x27, 0xB0)
|
||||||
|
DEEP_PURPLE = rgb(0x67, 0x3A, 0xB7)
|
||||||
|
INDIGO = rgb(0x3F, 0x51, 0xB5)
|
||||||
|
BLUE = rgb(0x21, 0x96, 0xF3)
|
||||||
|
LIGHT_BLUE = rgb(0x03, 0xA9, 0xF4)
|
||||||
|
CYAN = rgb(0x00, 0xBC, 0xD4)
|
||||||
|
TEAL = rgb(0x00, 0x96, 0x88)
|
||||||
|
GREEN = rgb(0x4C, 0xC1, 0x48) # GREEN 4CC148
|
||||||
|
ACTIVE_GREEN = rgb(0x1A, 0x8C, 0x14) # ACTIVE DARK GREEN 1A8C14
|
||||||
|
LIGHT_GREEN = rgb(0x87, 0xCE, 0x26)
|
||||||
|
LIME = rgb(0xCD, 0xDC, 0x39)
|
||||||
|
YELLOW = rgb(0xFF, 0xEB, 0x3B)
|
||||||
|
AMBER = rgb(0xFF, 0xC1, 0x07)
|
||||||
|
ORANGE = rgb(0xFF, 0x98, 0x00)
|
||||||
|
DEEP_ORANGE = rgb(0xFF, 0x57, 0x22)
|
||||||
|
BROWN = rgb(0x79, 0x55, 0x48)
|
||||||
|
LIGHT_GREY = rgb(0xDA, 0xDD, 0xD8)
|
||||||
|
GREY = rgb(0x9E, 0x9E, 0x9E)
|
||||||
|
DARK_GREY = rgb(0x3E, 0x3E, 0x3E)
|
||||||
|
BLUE_GRAY = rgb(0x60, 0x7D, 0x8B)
|
||||||
|
BLACK = rgb(0x00, 0x00, 0x00)
|
||||||
|
WHITE = rgb(0xFA, 0xFA, 0xFA)
|
||||||
|
BLACKISH = rgb(0x20, 0x20, 0x20)
|
||||||
|
|
||||||
|
# icons
|
||||||
|
ICON_RESET = 'trezor/res/header_icons/reset.toig'
|
||||||
|
ICON_WIPE = 'trezor/res/header_icons/wipe.toig'
|
||||||
|
ICON_RECOVERY = 'trezor/res/header_icons/recovery.toig'
|
||||||
|
|
||||||
|
# buttons
|
||||||
|
BTN_DEFAULT = {
|
||||||
|
'bg-color': BLACK,
|
||||||
|
'fg-color': WHITE,
|
||||||
|
'text-style': NORMAL,
|
||||||
|
'border-color': BLACK,
|
||||||
|
'radius': RADIUS,
|
||||||
|
}
|
||||||
|
BTN_DEFAULT_ACTIVE = {
|
||||||
|
'bg-color': GREY,
|
||||||
|
'fg-color': BLACK,
|
||||||
|
'text-style': BOLD,
|
||||||
|
'border-color': GREY,
|
||||||
|
'radius': RADIUS,
|
||||||
|
}
|
||||||
|
BTN_DEFAULT_DISABLED = {
|
||||||
|
'bg-color': BLACK,
|
||||||
|
'fg-color': GREY,
|
||||||
|
'text-style': NORMAL,
|
||||||
|
'border-color': BLACK,
|
||||||
|
'radius': RADIUS,
|
||||||
|
}
|
||||||
|
BTN_CANCEL = {
|
||||||
|
'bg-color': RED,
|
||||||
|
'fg-color': WHITE,
|
||||||
|
'text-style': BOLD,
|
||||||
|
'border-color': RED,
|
||||||
|
'radius': RADIUS,
|
||||||
|
}
|
||||||
|
BTN_CANCEL_ACTIVE = {
|
||||||
|
'bg-color': ACTIVE_RED,
|
||||||
|
'fg-color': WHITE,
|
||||||
|
'text-style': BOLD,
|
||||||
|
'border-color': ACTIVE_RED,
|
||||||
|
'radius': RADIUS,
|
||||||
|
}
|
||||||
|
BTN_CONFIRM = {
|
||||||
|
'bg-color': GREEN,
|
||||||
|
'fg-color': WHITE,
|
||||||
|
'text-style': BOLD,
|
||||||
|
'border-color': GREEN,
|
||||||
|
'radius': RADIUS,
|
||||||
|
}
|
||||||
|
BTN_CONFIRM_ACTIVE = {
|
||||||
|
'bg-color': ACTIVE_GREEN,
|
||||||
|
'fg-color': WHITE,
|
||||||
|
'text-style': BOLD,
|
||||||
|
'border-color': ACTIVE_GREEN,
|
||||||
|
'radius': RADIUS,
|
||||||
|
}
|
||||||
|
BTN_CLEAR = {
|
||||||
|
'bg-color': BLACK,
|
||||||
|
'fg-color': WHITE,
|
||||||
|
'text-style': NORMAL,
|
||||||
|
'border-color': BLACK,
|
||||||
|
'radius': RADIUS,
|
||||||
|
}
|
||||||
|
BTN_CLEAR_ACTIVE = {
|
||||||
|
'bg-color': BLACK,
|
||||||
|
'fg-color': GREY,
|
||||||
|
'text-style': NORMAL,
|
||||||
|
'border-color': BLACK,
|
||||||
|
'radius': RADIUS,
|
||||||
|
}
|
||||||
|
BTN_KEY = {
|
||||||
|
'bg-color': BLACKISH,
|
||||||
|
'fg-color': WHITE,
|
||||||
|
'text-style': MONO,
|
||||||
|
'border-color': BLACK,
|
||||||
|
}
|
||||||
|
BTN_KEY_ACTIVE = {
|
||||||
|
'bg-color': GREY,
|
||||||
|
'fg-color': BLACK,
|
||||||
|
'text-style': MONO,
|
||||||
|
'border-color': GREY,
|
||||||
|
}
|
||||||
|
|
||||||
|
# loader
|
||||||
|
LDR_DEFAULT = {
|
||||||
|
'bg-color': BLACK,
|
||||||
|
'fg-color': WHITE,
|
||||||
|
'icon': None,
|
||||||
|
'icon-fg-color': None,
|
||||||
|
}
|
||||||
|
LDR_DEFAULT_ACTIVE = {
|
||||||
|
'bg-color': BLACK,
|
||||||
|
'fg-color': ACTIVE_GREEN,
|
||||||
|
'icon': None,
|
||||||
|
'icon-fg-color': None,
|
||||||
|
}
|
@ -52,7 +52,7 @@ class Swipe(ui.Widget):
|
|||||||
else:
|
else:
|
||||||
ui.display.backlight(self.light_target)
|
ui.display.backlight(self.light_target)
|
||||||
|
|
||||||
elif event == io.TOUCH_START and contains(pos, self.area):
|
elif event == io.TOUCH_START and contains(self.area, pos):
|
||||||
self.start_time = temp_time
|
self.start_time = temp_time
|
||||||
self.start_pos = pos
|
self.start_pos = pos
|
||||||
self.light_origin = ui.BACKLIGHT_NORMAL
|
self.light_origin = ui.BACKLIGHT_NORMAL
|
||||||
|
Loading…
Reference in New Issue
Block a user