Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SPACE, DEL icons to Keyboard; various UI consistency tweaks #664

Merged
merged 5 commits into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 9 additions & 18 deletions l10n/messages.pot
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: seedsigner 0.8.5-rc1\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2025-01-15 10:45-0600\n"
"POT-Creation-Date: 2025-01-19 10:20-0600\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
Expand Down Expand Up @@ -36,16 +36,6 @@ msgstr ""
msgid "sats"
msgstr ""

#. The abbreviated label for the special key <del> on a standard keyboard.
#: src/seedsigner/gui/keyboard.py
msgid "del"
msgstr ""

#. The abbreviated label for the special key <space> on a standard keyboard.
#: src/seedsigner/gui/keyboard.py
msgid "space"
msgstr ""

#: src/seedsigner/gui/toast.py
msgid ""
"You can remove\n"
Expand Down Expand Up @@ -215,7 +205,7 @@ msgstr ""
msgid "OK"
msgstr ""

#: src/seedsigner/gui/screens/screen.py src/seedsigner/views/psbt_views.py
#: src/seedsigner/gui/screens/screen.py
msgid "Caution"
msgstr ""

Expand Down Expand Up @@ -901,18 +891,16 @@ msgstr ""

#. Variable is either "change" or "self-transfer".
#: src/seedsigner/views/psbt_views.py
msgid ""
"PSBT's {} address could not be verified with your multisig wallet "
"descriptor."
msgid "PSBT's {} address could not be verified from wallet descriptor."
msgstr ""

#. Variable is either "change" or "self-transfer".
#: src/seedsigner/views/psbt_views.py
msgid "Suspicious PSBT"
msgid "PSBT's {} address could not be generated from your seed."
msgstr ""

#. Variable is either "change" or "self-transfer".
#: src/seedsigner/views/psbt_views.py
msgid "PSBT's {} address could not be generated from your seed."
msgid "Suspicious PSBT"
msgstr ""

#: src/seedsigner/views/psbt_views.py
Expand Down Expand Up @@ -1459,10 +1447,13 @@ msgstr ""
msgid "Back to Main Menu"
msgstr ""

#. The network setting (mainnet/testnet/regtest) doesn't match the provided
#. derivation path
#: src/seedsigner/views/view.py
msgid "Network Mismatch"
msgstr ""

#. Button option to alter a setting
#: src/seedsigner/views/view.py
msgid "Change Setting"
msgstr ""
Expand Down
20 changes: 5 additions & 15 deletions src/seedsigner/gui/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,9 @@ class SeedSignerIconConstants:

# Messaging icons
INFO = "\ue912"
ERROR = "\ue913"
SUCCESS = "\ue914"
WARNING = "\ue915"
SUCCESS = "\ue913"
WARNING = "\ue914"
ERROR = "\ue915"

# Informational icons
ADDRESS = "\ue916"
Expand All @@ -241,8 +241,9 @@ class SeedSignerIconConstants:
DELETE = "\ue922"
SPACE = "\ue923"

# Must be updated whenever new icons are added. See usage in `Icon` class below.
MIN_VALUE = SCAN
MAX_VALUE = QRCODE
MAX_VALUE = SPACE



Expand Down Expand Up @@ -280,17 +281,6 @@ def calc_text_centering(font: ImageFont,



def load_icon(icon_name: str, load_selected_variant: bool = False):
icon_url = os.path.join(pathlib.Path(__file__).parent.resolve(), "..", "resources", "icons", icon_name)
icon = Image.open(icon_url + ".png").convert("RGB")
if not load_selected_variant:
return icon
else:
icon_selected = Image.open(icon_url + "_selected.png").convert("RGB")
return (icon, icon_selected)



def load_image(image_name: str) -> Image.Image:
image_url = os.path.join(pathlib.Path(__file__).parent.resolve(), "..", "resources", "img", image_name)
image = Image.open(image_url).convert("RGB")
Expand Down
61 changes: 32 additions & 29 deletions src/seedsigner/gui/keyboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from typing import Tuple
from gettext import gettext as _

from seedsigner.gui.components import Fonts, GUIConstants
from seedsigner.gui.components import Fonts, GUIConstants, SeedSignerIconConstants
from seedsigner.hardware.buttons import HardwareButtonsConstants


Expand All @@ -30,58 +30,55 @@ class Keyboard:
ENTER_RIGHT = "enter_right"

REGULAR_KEY_FONT = "regular"
COMPACT_KEY_FONT = "compact"
ICON_KEY_FONT = GUIConstants.ICON_FONT_NAME__SEEDSIGNER

# TRANSLATOR_NOTE: The abbreviated label for the special key <del> on a standard keyboard.
del_label = _("del")
KEY_BACKSPACE = {
"code": "DEL",
"letter": del_label,
"font": COMPACT_KEY_FONT,
"letter": SeedSignerIconConstants.DELETE,
"font": ICON_KEY_FONT,
"size": 2,
}
# TRANSLATOR_NOTE: The abbreviated label for the special key <space> on a standard keyboard.
space_label = _("space")

KEY_SPACE = {
"code": "SPACE",
"letter": space_label,
"font": COMPACT_KEY_FONT,
"letter": SeedSignerIconConstants.SPACE,
"font": ICON_KEY_FONT,
"size": 1,
}
KEY_SPACE_2 = {
"code": "SPACE",
"letter": space_label,
"font": COMPACT_KEY_FONT,
"letter": SeedSignerIconConstants.SPACE,
"font": ICON_KEY_FONT,
"size": 2,
}
KEY_SPACE_3 = {
"code": "SPACE",
"letter": space_label,
"font": COMPACT_KEY_FONT,
"letter": SeedSignerIconConstants.SPACE,
"font": ICON_KEY_FONT,
"size": 3,
}
KEY_SPACE_4 = {
"code": "SPACE",
"letter": space_label,
"font": COMPACT_KEY_FONT,
"letter": SeedSignerIconConstants.SPACE,
"font": ICON_KEY_FONT,
"size": 4,
}
KEY_SPACE_5 = {
"code": "SPACE",
"letter": space_label,
"font": COMPACT_KEY_FONT,
"letter": SeedSignerIconConstants.SPACE,
"font": ICON_KEY_FONT,
"size": 5,
}
KEY_CURSOR_LEFT = {
"code": "CURSOR_LEFT",
"letter": "<",
"font": REGULAR_KEY_FONT,
"letter": SeedSignerIconConstants.CHEVRON_LEFT,
"font": ICON_KEY_FONT,
"size": 1,
}
KEY_CURSOR_RIGHT = {
"code": "CURSOR_RIGHT",
"letter": ">",
"font": REGULAR_KEY_FONT,
"letter": SeedSignerIconConstants.CHEVRON_RIGHT,
"font": ICON_KEY_FONT,
"size": 1,
}
KEY_PREVIOUS_PAGE = {
Expand Down Expand Up @@ -123,9 +120,11 @@ def __post_init__(self):

def render_key(self):
font = self.keyboard.font
text_height = self.keyboard.text_height
if self.is_additional_key:
if Keyboard.ADDITIONAL_KEYS[self.code]["font"] == Keyboard.COMPACT_KEY_FONT:
font = self.keyboard.additonal_key_compact_font
if Keyboard.ADDITIONAL_KEYS[self.code]["font"] == Keyboard.ICON_KEY_FONT:
font = self.keyboard.icon_key_font
text_height = self.keyboard.icon_key_height

outline_color = "#333"
if not self.is_active:
Expand Down Expand Up @@ -159,15 +158,12 @@ def render_key(self):
radius=4
)

# Fixed-width fonts will all have same height, ignoring below baseline (e.g. "Q" or "q")
(left, top, right, bottom) = font.getbbox("X", anchor="ls")
text_height = -1 * top
self.keyboard.draw.text(
(
self.screen_x + int(self.keyboard.key_width * self.size / 2),
self.screen_y + self.keyboard.key_height - int((self.keyboard.key_height - text_height)/2)
),
_(self.letter),
self.letter,
fill=font_color,
font=font,
anchor="ms"
Expand Down Expand Up @@ -217,8 +213,15 @@ def __init__(self,

# Set up the rendering and state params
self.active_keys = list(self.charset)
self.icon_key_font = Fonts.get_font(GUIConstants.ICON_FONT_NAME__SEEDSIGNER, 26)

# Fixed-width fonts will all have same height, ignoring below baseline (e.g. "Q" or "q")
(left, top, right, bottom) = self.font.getbbox("X", anchor="ls")
self.text_height = -1 * top

(left, top, right, bottom) = self.icon_key_font.getbbox(SeedSignerIconConstants.DELETE + SeedSignerIconConstants.SPACE, anchor="ls")
self.icon_key_height = -1 * top

self.additonal_key_compact_font = Fonts.get_font("RobotoCondensed-Bold", 18)
self.x_start = rect[0]
self.y_start = rect[1]
self.x_gap = 2
Expand Down
21 changes: 19 additions & 2 deletions src/seedsigner/gui/screens/screen.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ def __post_init__(self):
if len(self.button_data) == 1:
button_list_height = button_height
else:
button_list_height = (len(self.button_data) * button_height) + (GUIConstants.COMPONENT_PADDING * (len(self.button_data) - 1))
button_list_height = (len(self.button_data) * button_height) + (GUIConstants.LIST_ITEM_PADDING * (len(self.button_data) - 1))

if self.is_bottom_list:
button_list_y = self.canvas_height - (button_list_height + GUIConstants.EDGE_PADDING)
Expand Down Expand Up @@ -1013,21 +1013,38 @@ def __post_init__(self):

@dataclass
class WarningScreen(WarningEdgesMixin, LargeIconStatusScreen):
"""
Exclamation point icon + yellow WARNING color
"""
title: str = _mft("Caution")
status_icon_name: str = SeedSignerIconConstants.WARNING
status_color: str = "yellow"
status_color: str = GUIConstants.WARNING_COLOR
status_headline: str = _mft("Privacy Leak!") # The colored text under the alert icon
button_data: list = field(default_factory=lambda: [ButtonOption("I Understand")])



@dataclass
class DireWarningScreen(WarningScreen):
"""
Exclamation point icon + orange DIRE_WARNING color
"""
status_headline: str = _mft("Classified Info!") # The colored text under the alert icon
status_color: str = GUIConstants.DIRE_WARNING_COLOR



@dataclass
class ErrorScreen(WarningScreen):
"""
X icon + red ERROR color
"""
title: str = _mft("Error")
status_icon_name: str = SeedSignerIconConstants.ERROR
status_color: str = GUIConstants.ERROR_COLOR



@dataclass
class ResetScreen(BaseTopNavScreen):
def __post_init__(self):
Expand Down
13 changes: 6 additions & 7 deletions src/seedsigner/gui/screens/settings_screens.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from typing import List

from seedsigner.helpers.l10n import mark_for_translation as _mft
from seedsigner.gui.components import Button, CheckboxButton, CheckedSelectionButton, FontAwesomeIconConstants, Fonts, GUIConstants, Icon, IconButton, IconTextLine, TextArea
from seedsigner.gui.components import Button, CheckboxButton, CheckedSelectionButton, FontAwesomeIconConstants, Fonts, GUIConstants, Icon, IconButton, IconTextLine, SeedSignerIconConstants, TextArea
from seedsigner.gui.screens.scan_screens import ScanScreen
from seedsigner.gui.screens.screen import BaseScreen, BaseTopNavScreen, ButtonListScreen, ButtonOption
from seedsigner.hardware.buttons import HardwareButtonsConstants
Expand Down Expand Up @@ -82,7 +82,7 @@ def __post_init__(self):
self.components.append(self.joystick_click_button)

self.joystick_up_button = IconButton(
icon_name=FontAwesomeIconConstants.ANGLE_UP,
icon_name=SeedSignerIconConstants.CHEVRON_UP,
icon_size=GUIConstants.ICON_INLINE_FONT_SIZE,
width=input_button_width,
height=input_button_height,
Expand All @@ -93,7 +93,7 @@ def __post_init__(self):
self.components.append(self.joystick_up_button)

self.joystick_down_button = IconButton(
icon_name=FontAwesomeIconConstants.ANGLE_DOWN,
icon_name=SeedSignerIconConstants.CHEVRON_DOWN,
icon_size=GUIConstants.ICON_INLINE_FONT_SIZE,
width=input_button_width,
height=input_button_height,
Expand All @@ -104,9 +104,8 @@ def __post_init__(self):
self.components.append(self.joystick_down_button)

self.joystick_left_button = IconButton(
text=FontAwesomeIconConstants.ANGLE_LEFT,
font_name=GUIConstants.ICON_FONT_NAME__FONT_AWESOME,
font_size=GUIConstants.ICON_INLINE_FONT_SIZE,
icon_name=SeedSignerIconConstants.CHEVRON_LEFT,
icon_size=GUIConstants.ICON_INLINE_FONT_SIZE,
width=input_button_width,
height=input_button_height,
screen_x=dpad_center_x - input_button_width - GUIConstants.COMPONENT_PADDING,
Expand All @@ -116,7 +115,7 @@ def __post_init__(self):
self.components.append(self.joystick_left_button)

self.joystick_right_button = IconButton(
icon_name=FontAwesomeIconConstants.ANGLE_RIGHT,
icon_name=SeedSignerIconConstants.CHEVRON_RIGHT,
icon_size=GUIConstants.ICON_INLINE_FONT_SIZE,
width=input_button_width,
height=input_button_height,
Expand Down
2 changes: 1 addition & 1 deletion src/seedsigner/gui/screens/tools_screens.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ def __post_init__(self):
self.rows = 3
self.cols = 3
self.keyboard_font_name = GUIConstants.ICON_FONT_NAME__FONT_AWESOME
self.keyboard_font_size = None # Force auto-scaling to Key height
self.keyboard_font_size = 36
self.keys_charset = "".join([
FontAwesomeIconConstants.DICE_ONE,
FontAwesomeIconConstants.DICE_TWO,
Expand Down
6 changes: 2 additions & 4 deletions src/seedsigner/views/psbt_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -460,16 +460,14 @@ def __init__(self, is_change: bool = True, is_multisig: bool = False):

def run(self):
if self.is_multisig:
title = _("Caution")
# TRANSLATOR_NOTE: Variable is either "change" or "self-transfer".
text = _("PSBT's {} address could not be verified with your multisig wallet descriptor.").format(_("change") if self.is_change else _("self-transfer"))
text = _("PSBT's {} address could not be verified from wallet descriptor.").format(_("change") if self.is_change else _("self-transfer"))
else:
title = _("Suspicious PSBT")
# TRANSLATOR_NOTE: Variable is either "change" or "self-transfer".
text = _("PSBT's {} address could not be generated from your seed.").format(_("change") if self.is_change else _("self-transfer"))

DireWarningScreen(
title=title,
title=_("Suspicious PSBT"),
status_headline=_("Address Verification Failed"),
text=text,
button_data=[ButtonOption("Discard PSBT")],
Expand Down
Loading
Loading