caps NFC/QR

This commit is contained in:
Peter D. Gray 2023-12-07 11:14:13 -05:00
parent ec62c80ccc
commit 28ea702901
No known key found for this signature in database
GPG Key ID: A2DCD558C2BE5D7C
5 changed files with 32 additions and 27 deletions

View File

@ -18,6 +18,7 @@ TEXT_PALETTES = [
# same, but w/o byte swapping, packing (useful for simulator)
#TEXT_PALETTE = [0x0000, 0x0840, 0x18a0, 0x2900, 0x3940, 0x49a0, 0x5a00, 0x6a60, 0x7aa0, 0x8b00, 0x9b60, 0xabc0, 0xbc00, 0xdcc0, 0xed00, 0xfd60]
COL_TEXT = const(0xfd60) # text foreground colour
COL_DARK_TEXT = const(0xa380) # "dark" pallette text foreground colour
CELL_W = const(9)
CELL_H = const(22)
@ -166,7 +167,7 @@ class FontIosevka:
'': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xff\xff\xff\x00?\xff\xff\xf0\x03\xff\xff\xff\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x00\x03\xff\xf3\x00',
'': b'\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x0f\xff\xff\xf3\x00\xff\xff\xff0\x0f\xff\xff\xf3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
'': b'\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x00\x03\xff\xff\xff\x00?\xff\xff\xf0\x03\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
'\x0e': b'\x00\x0f\xff\xff\xff\xff\xff\xf0\x00\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x04\xde`\x00\x0f\xf0\x00\x00\x00\x0c\xdc\xe0\x00\x0f\xf0\x00\x00\x00\r\xb3P\x00\x0f\xff\xae\xd2\x00.\xc2\x10~\xff\xff\xc7\xf9\x04\xff\xff\x82\xfc\x8f\xff`\xdc\x01^\xc5%\xf5\x0f\xff`\xdc\x00\x0e\xb0\x06\xf4\x0f\xff`\xdc\x00\x0e\xb0\x05\xf5\x0f\xff`\xdc\x00\x0e\xb0\x02\xfc\x8f\xff`\xdc\x00\x0e\xb0\x00~\xff\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x00\x0f\xff\xff\xff\xff\xff\xf0\x00',
'\x11': b'\x00\x0f\xff\xff\xff\xff\xff\xf0\x00\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\t\xfb\xdc\x00\x9f\x8f\x90\x0f\xf0?\xc7\xfc\x00\x9f\x9c\xf0\x0f\xf0_P\xdc\x00\x9f! \x0f\xf0o@\xdc\x00\x9f\x10\x00\x0f\xf0_P\xdc\x00\x9f\x10\x00\x0f\xf0?\xc8\xfc\x00\x9f\x10\x00\x0f\xf0\t\xfb\xdc\x00\x9f\x10\x00\x0f\xf0\x00\x00\xdc\x00\x00\x00\x00\x0f\xf0\x00\x00\xdc\x00\x00\x00\x00\x0f\xf0\x00\x00\xdc\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x00\x0f\xff\xff\xff\xff\xff\xf0\x00',
'\t': b'\x00\x0f\xff\xff\xff\xff\xff\xf0\x00\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\rP\x00\x00\x02\xa0\x00\x0f\xf0\rP\x00\x00\x00\x99\x00\x0f\xf0\rb""",\x80\x0f\xf0\r\xff\xff\xff\xff\xff\xf4\x0f\xf0\r\x85UUU\\\xa0\x0f\xf0\rP\x00\x00\x00\x8a\x00\x0f\xf0\rP\x00\x00\x02\xb0\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x00\x0f\xff\xff\xff\xff\xff\xf0\x00',
'\x0e': b'\x00\x0f\xff\xff\xff\xff\xff\xf0\x00\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf6\xf1\x8d\x01\xff\xfd\x0b\xfdO\xf6\xf6\x8d\x01\xf73_\\\xcf\xf6\xfb\x8d\x01\xf5\x00~\x01/\xf6\xed\x9d\x01\xff\xf4~\x00\x0f\xf6\xf9\xcd\x01\xf71~\x00\x0f\xf6\xf3\xfd\x01\xf5\x00~\x01/\xf6\xf0\xdd\x01\xf5\x00_\\\xcf\xf6\xf0\x8d\x01\xf5\x00\x0b\xfdO\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x00\x0f\xff\xff\xff\xff\xff\xf0\x00',
'\x11': b'\x00\x0f\xff\xff\xff\xff\xff\xf0\x00\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\xaf\xd4\x06\xff\xd4\x00\x0f\xf0\x05\xf5\xbd\x06\xf3\xbc\x00\x0f\xf0\x07\xe0~\x06\xf0~\x00\x0f\xf0\x07\xe0~\x06\xf0\xad\x00\x0f\xf0\x07\xe0~\x06\xff\xf6\x00\x0f\xf0\x07\xe0~\x06\xf9\xe1\x00\x0f\xf0\x07\xe1\x8e\x06\xf1\xe7\x00\x0f\xf0\x02\xed\xe9\x06\xf0\x9d\x00\x0f\xf0\x00-\xc0\x00\x00\x00\x00\x0f\xf0\x00\x07\xfa\x00\x00\x00\x00\x0f\xf0\x00\x00"\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x00\x0f\xff\xff\xff\xff\xff\xf0\x00',
'\t': b'\x00\x0f\xff\xff\xff\xff\xff\xf0\x00\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x0e \x00\x00\x83\x00\x00\x0f\xf0\x0e \x00\x00-\x10\x00\x0f\xf0\x0e \x00\x00\x05\xc0\x00\x0f\xf0\x0e\xff\xff\xff\xff\xf6\x00\x0f\xf0\x0eC339\x90\x00\x0f\xf0\x0e \x00\x00f\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x00\x0f\xff\xff\xff\xff\xff\xf0\x00',
}

View File

@ -58,8 +58,8 @@ NUM_CHARS = len(CHARSET)
# use a different glyph for these unicode values
# - useful for multi-codepoint sequences, which we want to encode as single char
REMAPS = {
KEY_NFC: 'nfc',
KEY_QR: 'qr',
KEY_NFC: 'NFC',
KEY_QR: 'QR',
KEY_TAB: '',
}
@ -100,7 +100,7 @@ def make_palette(shades, col, darken=1.0):
def doit(out_fname='font_iosevka.py', cls_name='FontIosevka'):
font = ImageFont.truetype(FONT, FONT_SIZE)
font2 = ImageFont.truetype(FONT, FONT_SIZE-5)
keycap_font = ImageFont.truetype(FONT, FONT_SIZE-7) # see KEY_NFC
left, top, right, bottom = font.getbbox("|")
char_h = bottom - top
@ -153,13 +153,13 @@ def doit(out_fname='font_iosevka.py', cls_name='FontIosevka'):
if ch in KEYCAP_SYMBOLS:
if ch == KEY_NFC:
x_shift += 0
x_shift += 1
elif ch == KEY_QR:
x_shift += 2
x_shift += 3
else:
x_shift += 3
this_y += 3
draw.text((x_shift, y_offset + this_y), REMAPS.get(ch, ch), 'white', font2)
this_y += 5
draw.text((x_shift, y_offset + this_y), REMAPS.get(ch, ch), 'white', keycap_font)
# add a border
draw.rounded_rectangle( ( 0,0, (CELL_W*2)-1, CELL_H-1), 4, outline='white')
@ -249,7 +249,7 @@ def doit(out_fname='font_iosevka.py', cls_name='FontIosevka'):
BRAND_TEXT_COLOUR = (255, 176, 0) # amber phospher colour #ffb000
pal_nums, pal_vals, text_pal = make_palette(shades, BRAND_TEXT_COLOUR)
_, pal_vals_inv, text_pal_inv = make_palette([255-i for i in shades], BRAND_TEXT_COLOUR)
_, _, text_pal_dark = make_palette(shades, BRAND_TEXT_COLOUR, 0.66)
pal_dark_nums, _, text_pal_dark = make_palette(shades, BRAND_TEXT_COLOUR, 0.66)
with open(out_fname, 'w') as fp:
tmpl = open('template.py').read()
@ -266,6 +266,7 @@ TEXT_PALETTES = [
# same, but w/o byte swapping, packing (useful for simulator)
#TEXT_PALETTE = [{pal_vals}]
COL_TEXT = const(0x{pal_nums[15]:04x}) # text foreground colour
COL_DARK_TEXT = const(0x{pal_dark_nums[15]:04x}) # "dark" pallette text foreground colour
CELL_W = const({CELL_W})
CELL_H = const({CELL_H})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -169,8 +169,7 @@ FileMgmtMenu = [
MenuItem('Batch Sign PSBT', predicate=has_secrets, f=batch_sign),
MenuItem('List Files', f=list_files),
MenuItem('Verify Sig File', f=verify_sig_file),
MenuItem('NFC File Share', predicate=nfc_enabled, f=nfc_share_file,
shortcut=KEY_NFC),
MenuItem('NFC File Share', predicate=nfc_enabled, f=nfc_share_file, shortcut=KEY_NFC),
MenuItem('Clone Coldcard', predicate=has_secrets, f=clone_write_data),
MenuItem('Format SD Card', f=wipe_sd_card),
MenuItem('Format RAM Disk', predicate=vdisk_enabled, f=wipe_vdisk),
@ -320,7 +319,7 @@ ImportWallet = [
MenuItem("18 Words", menu=start_seed_import, arg=18),
MenuItem("24 Words", menu=start_seed_import, arg=24),
MenuItem('Scan QR Code', predicate=lambda: version.has_qr,
shortcut=charcodes.KEY_QR, f=scan_any_qr, arg=(True, False)),
shortcut=KEY_QR, f=scan_any_qr, arg=(True, False)),
MenuItem("Restore Backup", f=restore_everything),
MenuItem("Clone Coldcard", menu=clone_start),
MenuItem("Import XPRV", f=import_xprv, arg=False), # ephemeral=False
@ -346,21 +345,22 @@ EmptyWallet = [
]
# In operation, normal system, after a good PIN received.
# - key shortcuts in place for all items that will be shown on Q
NormalSystem = [
# xxxxxxxxxxxxxxxx
MenuItem('Ready To Sign', f=ready2sign),
MenuItem('Ready To Sign', f=ready2sign, shortcut='r'),
MenuItem('Scan Any QR Code', predicate=lambda: version.has_qr,
shortcut=charcodes.KEY_QR, f=scan_any_qr, arg=(False, True)),
MenuItem('Passphrase', f=start_b39_pw, predicate=bip39_passphrase_active),
shortcut=KEY_QR, f=scan_any_qr, arg=(False, True)),
MenuItem('Passphrase', f=start_b39_pw, predicate=bip39_passphrase_active, shortcut='p'),
MenuItem('Start HSM Mode', f=start_hsm_menu_item, predicate=hsm_policy_available),
MenuItem("Address Explorer", f=address_explore, shortcut='x'),
MenuItem('Type Passwords', f=password_entry,
MenuItem('Type Passwords', f=password_entry, shortcut='t',
predicate=lambda: settings.get("emu", False) and has_secrets()),
MenuItem('Seed Vault', menu=make_seed_vault_menu,
MenuItem('Seed Vault', menu=make_seed_vault_menu, shortcut='v',
predicate=lambda: settings.master_get('seedvault') and has_secrets()),
MenuItem('Secure Logout', f=logout_now, predicate=lambda: not version.has_battery),
MenuItem('Advanced/Tools', menu=AdvancedNormalMenu, shortcut='t'),
MenuItem('Settings', menu=SettingsMenu),
MenuItem('Settings', menu=SettingsMenu, shortcut='s'),
]
# Shown until unit is put into a numbered bag

View File

@ -10,7 +10,7 @@ from utils import xfp2str
from ucollections import namedtuple
# the one font: fixed-width (except for a few double-width chars)
from font_iosevka import CELL_W, CELL_H, TEXT_PALETTES, COL_TEXT
from font_iosevka import CELL_W, CELL_H, TEXT_PALETTES, COL_TEXT, COL_DARK_TEXT
from font_iosevka import FontIosevka
@ -408,14 +408,17 @@ class Display:
raise NotImplementedError
def scroll_bar(self, fraction):
# along right edge
# Immediately draw bar along right edge.
# - length means nothing, just vert position
# MAYBE TODO: make this internal, part of show and make fraction a var?
# XXX not showing at all?!?
self.gpu.take_spi()
self.dis.fill_rect(WIDTH-5, 0, 5, HEIGHT, 0)
mm = HEIGHT-6
pos = min(int(mm*fraction), mm)
self.dis.fill_rect(WIDTH-2, pos, 1, 16, 1)
bw = 2 # bar width, height
bh = ACTIVE_H // 4
self.dis.fill_rect(WIDTH-bw, TOP_MARGIN, bw, ACTIVE_H, COL_DARK_TEXT)
pos = int((ACTIVE_H-bh)*fraction)
if pos+bh > ACTIVE_H:
pos = ACTIVE_H - bh
self.dis.fill_rect(WIDTH-bw, TOP_MARGIN+pos, bw, bh, COL_TEXT)
def fullscreen(self, msg, percent=None):
# show a simple message "fullscreen".