1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-18 20:38:10 +00:00

refactor(core): put property key+value on the same screen

This commit is contained in:
matejcik 2021-06-16 13:18:08 +02:00 committed by matejcik
parent 3c4eb04346
commit 41c5d773e2
2 changed files with 71 additions and 22 deletions

View File

@ -15,7 +15,7 @@ if False:
from ..common.text import TextContent from ..common.text import TextContent
_PAGINATED_LINE_WIDTH = const(204) PAGINATED_LINE_WIDTH = const(204)
WAS_PAGED = object() WAS_PAGED = object()
@ -283,7 +283,7 @@ def paginate_text(
else: else:
pages: list[ui.Component] = [] pages: list[ui.Component] = []
span.reset( span.reset(
text, 0, font, break_words=break_words, line_width=_PAGINATED_LINE_WIDTH text, 0, font, break_words=break_words, line_width=PAGINATED_LINE_WIDTH
) )
while span.has_more_content(): while span.has_more_content():
# advance to first line of the page # advance to first line of the page
@ -295,7 +295,7 @@ def paginate_text(
new_lines=False, new_lines=False,
content_offset=0, content_offset=0,
char_offset=span.start, char_offset=span.start,
line_width=_PAGINATED_LINE_WIDTH, line_width=PAGINATED_LINE_WIDTH,
break_words=break_words, break_words=break_words,
render_page_overflow=False, render_page_overflow=False,
) )
@ -310,6 +310,9 @@ def paginate_text(
return Paginated(pages) return Paginated(pages)
PAGEBREAK = 0, ""
def paginate_paragraphs( def paginate_paragraphs(
para: Iterable[tuple[int, str]], para: Iterable[tuple[int, str]],
header: str, header: str,
@ -321,15 +324,16 @@ def paginate_paragraphs(
span = Span("", 0, ui.NORMAL, break_words=break_words) span = Span("", 0, ui.NORMAL, break_words=break_words)
lines = 0 lines = 0
content: list[TextContent] = [] content: list[TextContent] = []
for font, text in para: for item in para:
span.reset(text, 0, font, break_words=break_words) if item is PAGEBREAK:
continue
span.reset(item[1], 0, item[0], break_words=break_words)
lines += span.count_lines() lines += span.count_lines()
# we'll need this for multipage too # we'll need this for multipage too
if content: if content:
content.append("\n") content.append("\n")
content.append(font) content.extend(item)
content.append(text)
if lines <= TEXT_MAX_LINES: if lines <= TEXT_MAX_LINES:
result = Text( result = Text(
@ -339,19 +343,27 @@ def paginate_paragraphs(
new_lines=False, new_lines=False,
break_words=break_words, break_words=break_words,
) )
for font, text in para: result.content = content
if len(result.content) != 0:
result.content.append("\n")
result.content.append(font)
result.content.append(text)
return confirm(result) return confirm(result)
else: else:
pages: list[ui.Component] = [] pages: list[ui.Component] = []
lines_left = 0 lines_left = 0
for i, (font, text) in enumerate(para): content_ctr = 0
page: Text | None = None
for item in para:
if item is PAGEBREAK:
if page is not None:
page.max_lines -= lines_left
lines_left = 0
continue
span.reset( span.reset(
text, 0, font, break_words=break_words, line_width=_PAGINATED_LINE_WIDTH item[1],
0,
item[0],
break_words=break_words,
line_width=PAGINATED_LINE_WIDTH,
) )
while span.has_more_content(): while span.has_more_content():
@ -362,9 +374,9 @@ def paginate_paragraphs(
header_icon=header_icon, header_icon=header_icon,
icon_color=icon_color, icon_color=icon_color,
new_lines=False, new_lines=False,
content_offset=i * 3 + 1, # font, _text_, newline content_offset=content_ctr * 3 + 1, # font, _text_, newline
char_offset=span.start, char_offset=span.start,
line_width=_PAGINATED_LINE_WIDTH, line_width=PAGINATED_LINE_WIDTH,
render_page_overflow=False, render_page_overflow=False,
break_words=break_words, break_words=break_words,
) )
@ -374,5 +386,7 @@ def paginate_paragraphs(
else: else:
lines_left -= 1 lines_left -= 1
content_ctr += 1
pages[-1] = confirm(pages[-1]) pages[-1] = confirm(pages[-1])
return Paginated(pages) return Paginated(pages)

View File

@ -11,7 +11,7 @@ from ..components.common import break_path_to_lines
from ..components.common.confirm import is_confirmed, raise_if_cancelled from ..components.common.confirm import is_confirmed, raise_if_cancelled
from ..components.tt.button import ButtonCancel, ButtonDefault from ..components.tt.button import ButtonCancel, ButtonDefault
from ..components.tt.confirm import Confirm, HoldToConfirm from ..components.tt.confirm import Confirm, HoldToConfirm
from ..components.tt.scroll import Paginated, paginate_paragraphs, paginate_text from ..components.tt.scroll import Paginated, paginate_paragraphs, paginate_text, PAGINATED_LINE_WIDTH, PAGEBREAK
from ..components.tt.text import Span, Text from ..components.tt.text import Span, Text
from ..constants.tt import ( from ..constants.tt import (
MONO_ADDR_PER_LINE, MONO_ADDR_PER_LINE,
@ -577,6 +577,9 @@ async def confirm_hex(
await raise_if_cancelled(interact(ctx, content, br_type, br_code)) await raise_if_cancelled(interact(ctx, content, br_type, br_code))
_SCREEN_FULL_THRESHOLD = const(2)
# TODO keep name and value on the same page if possible # TODO keep name and value on the same page if possible
async def confirm_properties( async def confirm_properties(
ctx: wire.GenericContext, ctx: wire.GenericContext,
@ -588,12 +591,44 @@ async def confirm_properties(
hold: bool = False, hold: bool = False,
br_code: ButtonRequestType = ButtonRequestType.ConfirmOutput, br_code: ButtonRequestType = ButtonRequestType.ConfirmOutput,
) -> None: ) -> None:
span = Span()
para = [] para = []
for p in props: used_lines = 0
if p[0] is not None: for key, val in props:
para.append((ui.NORMAL, p[0])) span.reset(key or "", 0, ui.NORMAL, line_width=PAGINATED_LINE_WIDTH)
if p[1] is not None: key_lines = span.count_lines()
para.append((ui.BOLD, p[1])) span.reset(val or "", 0, ui.BOLD, line_width=PAGINATED_LINE_WIDTH)
val_lines = span.count_lines()
remaining_lines = TEXT_MAX_LINES - used_lines
used_lines = (used_lines + key_lines + val_lines) % TEXT_MAX_LINES
if key_lines + val_lines > remaining_lines:
if remaining_lines <= _SCREEN_FULL_THRESHOLD:
# there are only 2 remaining lines, don't try to fit and put everything
# on next page
para.append(PAGEBREAK)
used_lines = (key_lines + val_lines) % TEXT_MAX_LINES
elif val_lines > 0 and key_lines >= remaining_lines:
# more than 2 remaining lines so try to fit something -- but won't fit
# at least one line of value
para.append(PAGEBREAK)
used_lines = (key_lines + val_lines) % TEXT_MAX_LINES
elif key_lines + val_lines <= TEXT_MAX_LINES:
# Whole property won't fit to the page, but it will fit on a page
# by itself
para.append(PAGEBREAK)
used_lines = (key_lines + val_lines) % TEXT_MAX_LINES
# else:
# None of the above. Continue fitting on the same page.
if key:
para.append((ui.NORMAL, key))
if val:
para.append((ui.BOLD, val))
content = paginate_paragraphs( content = paginate_paragraphs(
para, title, icon, icon_color, confirm=HoldToConfirm if hold else Confirm para, title, icon, icon_color, confirm=HoldToConfirm if hold else Confirm
) )