mirror of
https://github.com/SeedSigner/seedsigner.git
synced 2026-10-05 15:08:25 +00:00
Merge pull request #625 from alvroble/messaging_toasts
[Enhancement] Messaging toast refactor
This commit is contained in:
+110
-6
@@ -13,6 +13,7 @@ logger = logging.getLogger(__name__)
|
||||
class ToastOverlay(BaseComponent):
|
||||
icon_name: str = None
|
||||
color: str = GUIConstants.NOTIFICATION_COLOR
|
||||
font_color: str = GUIConstants.NOTIFICATION_COLOR
|
||||
label_text: str = None
|
||||
height: int = GUIConstants.ICON_TOAST_FONT_SIZE + 2*GUIConstants.EDGE_PADDING
|
||||
font_size: int = 19
|
||||
@@ -21,34 +22,43 @@ class ToastOverlay(BaseComponent):
|
||||
def __post_init__(self):
|
||||
super().__post_init__()
|
||||
|
||||
icon_delta_x = 0
|
||||
if self.icon_name:
|
||||
self.icon = Icon(
|
||||
image_draw=self.image_draw,
|
||||
canvas=self.canvas,
|
||||
screen_x=self.outline_thickness + 2*GUIConstants.EDGE_PADDING, # Push the icon further from the left edge than strictly necessary
|
||||
screen_x=self.outline_thickness + GUIConstants.EDGE_PADDING, # Push the icon further from the left edge than strictly necessary
|
||||
icon_name=self.icon_name,
|
||||
icon_size=GUIConstants.ICON_TOAST_FONT_SIZE,
|
||||
icon_color=self.color
|
||||
)
|
||||
self.icon.screen_y = self.canvas_height - self.height + int((self.height - self.icon.height)/2)
|
||||
icon_delta_x = self.icon.width + self.icon.screen_x
|
||||
|
||||
self.label = TextArea(
|
||||
image_draw=self.image_draw,
|
||||
canvas=self.canvas,
|
||||
text=self.label_text,
|
||||
font_size=self.font_size,
|
||||
font_color=self.color,
|
||||
font_color=self.font_color,
|
||||
edge_padding=0,
|
||||
is_text_centered=False,
|
||||
auto_line_break=True,
|
||||
width=self.canvas_width - self.icon.screen_x - self.icon.width - GUIConstants.COMPONENT_PADDING - self.outline_thickness,
|
||||
screen_x=self.icon.screen_x + self.icon.width + GUIConstants.COMPONENT_PADDING,
|
||||
width=self.canvas_width - icon_delta_x - 2 * GUIConstants.COMPONENT_PADDING - 2 * self.outline_thickness,
|
||||
screen_x=icon_delta_x + GUIConstants.COMPONENT_PADDING,
|
||||
allow_text_overflow=False,
|
||||
height_ignores_below_baseline=True,
|
||||
)
|
||||
|
||||
# Vertically center the message within the toast (for single- or multi-line
|
||||
if self.label.height > GUIConstants.ICON_FONT_SIZE:
|
||||
self.height = self.label.height + GUIConstants.EDGE_PADDING * 2
|
||||
|
||||
# Vertically center the message and icon within the toast (for single- or multi-line
|
||||
# messages).
|
||||
self.label.screen_y = self.canvas_height - self.height + self.outline_thickness + int((self.height - 2*self.outline_thickness - self.label.height)/2)
|
||||
|
||||
if self.icon_name:
|
||||
self.icon.screen_y = self.canvas_height - self.height + int((self.height - self.icon.height)/2)
|
||||
|
||||
|
||||
def render(self):
|
||||
# Render the toast's solid background
|
||||
@@ -61,7 +71,9 @@ class ToastOverlay(BaseComponent):
|
||||
)
|
||||
|
||||
# Draw the toast visual elements
|
||||
if self.icon_name:
|
||||
self.icon.render()
|
||||
|
||||
self.label.render()
|
||||
|
||||
self.renderer.show_image()
|
||||
@@ -125,6 +137,7 @@ class BaseToastOverlayManagerThread(BaseThread):
|
||||
def run(self):
|
||||
logger.info(f"{self.__class__.__name__}: started")
|
||||
start = time.time()
|
||||
time.sleep(0.2)
|
||||
while time.time() - start < self.activation_delay:
|
||||
if self.hw_inputs.has_any_input():
|
||||
# User has pressed a button, cancel the toast
|
||||
@@ -237,3 +250,94 @@ class SDCardStateChangeToastManagerThread(BaseToastOverlayManagerThread):
|
||||
icon_name=SeedSignerIconConstants.MICROSD,
|
||||
label_text=self.message,
|
||||
)
|
||||
|
||||
|
||||
"""****************************************************************************
|
||||
Messaging toasts
|
||||
****************************************************************************"""
|
||||
|
||||
|
||||
class DefaultToast(BaseToastOverlayManagerThread):
|
||||
def __init__(self, label_text="This is a notification toast", activation_delay=0, duration=3):
|
||||
# Note: activation_delay is configurable so the screenshot generator can get the
|
||||
# toast to immediately render.
|
||||
self.label_text = label_text
|
||||
super().__init__(
|
||||
activation_delay=activation_delay, # seconds
|
||||
duration=duration # seconds
|
||||
)
|
||||
|
||||
|
||||
def instantiate_toast(self) -> ToastOverlay:
|
||||
body_font_size = GUIConstants.get_body_font_size()
|
||||
return ToastOverlay(
|
||||
label_text=self.label_text,
|
||||
color=GUIConstants.BODY_FONT_COLOR,
|
||||
font_color=GUIConstants.BODY_FONT_COLOR,
|
||||
font_size=body_font_size,
|
||||
)
|
||||
|
||||
|
||||
|
||||
class InfoToast(DefaultToast):
|
||||
def instantiate_toast(self) -> ToastOverlay:
|
||||
body_font_size = GUIConstants.get_body_font_size()
|
||||
return ToastOverlay(
|
||||
icon_name=SeedSignerIconConstants.INFO,
|
||||
label_text=self.label_text,
|
||||
color=GUIConstants.INFO_COLOR,
|
||||
font_color=GUIConstants.BODY_FONT_COLOR,
|
||||
font_size=body_font_size,
|
||||
)
|
||||
|
||||
|
||||
|
||||
class SuccessToast(DefaultToast):
|
||||
def instantiate_toast(self) -> ToastOverlay:
|
||||
body_font_size = GUIConstants.get_body_font_size()
|
||||
return ToastOverlay(
|
||||
icon_name=SeedSignerIconConstants.SUCCESS,
|
||||
label_text=self.label_text,
|
||||
color=GUIConstants.SUCCESS_COLOR,
|
||||
font_color=GUIConstants.BODY_FONT_COLOR,
|
||||
font_size=body_font_size,
|
||||
)
|
||||
|
||||
|
||||
|
||||
class WarningToast(DefaultToast):
|
||||
def instantiate_toast(self) -> ToastOverlay:
|
||||
body_font_size = GUIConstants.get_body_font_size()
|
||||
return ToastOverlay(
|
||||
icon_name=SeedSignerIconConstants.WARNING,
|
||||
label_text=self.label_text,
|
||||
color=GUIConstants.WARNING_COLOR,
|
||||
font_color=GUIConstants.BODY_FONT_COLOR,
|
||||
font_size=body_font_size,
|
||||
)
|
||||
|
||||
|
||||
|
||||
class DireWarningToast(DefaultToast):
|
||||
def instantiate_toast(self) -> ToastOverlay:
|
||||
body_font_size = GUIConstants.get_body_font_size()
|
||||
return ToastOverlay(
|
||||
icon_name=SeedSignerIconConstants.WARNING,
|
||||
label_text=self.label_text,
|
||||
color=GUIConstants.DIRE_WARNING_COLOR,
|
||||
font_color=GUIConstants.BODY_FONT_COLOR,
|
||||
font_size=body_font_size,
|
||||
)
|
||||
|
||||
|
||||
|
||||
class ErrorToast(DefaultToast):
|
||||
def instantiate_toast(self) -> ToastOverlay:
|
||||
body_font_size = GUIConstants.get_body_font_size()
|
||||
return ToastOverlay(
|
||||
icon_name=SeedSignerIconConstants.ERROR,
|
||||
label_text=self.label_text,
|
||||
color=GUIConstants.ERROR_COLOR,
|
||||
font_color=GUIConstants.BODY_FONT_COLOR,
|
||||
font_size=body_font_size,
|
||||
)
|
||||
@@ -27,6 +27,7 @@ from seedsigner.controller import Controller
|
||||
from seedsigner.gui.renderer import Renderer
|
||||
from seedsigner.gui.screens.seed_screens import SeedAddPassphraseScreen
|
||||
from seedsigner.gui.toast import RemoveSDCardToastManagerThread, SDCardStateChangeToastManagerThread
|
||||
from seedsigner.gui.toast import DefaultToast, InfoToast, SuccessToast, WarningToast, ErrorToast, DireWarningToast
|
||||
from seedsigner.hardware.microsd import MicroSD
|
||||
from seedsigner.helpers import embit_utils
|
||||
from seedsigner.models.decode_qr import DecodeQR
|
||||
@@ -243,6 +244,12 @@ def generate_screenshots(locale):
|
||||
ScreenshotConfig(MainMenuView, screenshot_name='MainMenuView_SDCardStateChangeToast_removed', toast_thread=SDCardStateChangeToastManagerThread(action=MicroSD.ACTION__REMOVED, activation_delay=0, duration=0)),
|
||||
ScreenshotConfig(MainMenuView, screenshot_name='MainMenuView_SDCardStateChangeToast_inserted', toast_thread=SDCardStateChangeToastManagerThread(action=MicroSD.ACTION__INSERTED, activation_delay=0, duration=0)),
|
||||
ScreenshotConfig(MainMenuView, screenshot_name='MainMenuView_RemoveSDCardToast', toast_thread=RemoveSDCardToastManagerThread(activation_delay=0, duration=0)),
|
||||
ScreenshotConfig(MainMenuView, screenshot_name='MainMenuView_DefaultToast', toast_thread=DefaultToast("This is a default text toast!", activation_delay=0, duration=0)),
|
||||
ScreenshotConfig(MainMenuView, screenshot_name='MainMenuView_InfoToast', toast_thread=InfoToast("This is an info toast!", activation_delay=0, duration=0)),
|
||||
ScreenshotConfig(MainMenuView, screenshot_name='MainMenuView_SuccessToast', toast_thread=SuccessToast("This is a success toast!", activation_delay=0, duration=0)),
|
||||
ScreenshotConfig(MainMenuView, screenshot_name='MainMenuView_WarningToast', toast_thread=WarningToast("This is a warning toast!", activation_delay=0, duration=0)),
|
||||
ScreenshotConfig(MainMenuView, screenshot_name='MainMenuView_DireWarningToast', toast_thread=DireWarningToast("This is a dire warning toast!", activation_delay=0, duration=0)),
|
||||
ScreenshotConfig(MainMenuView, screenshot_name='MainMenuView_ErrorToast', toast_thread=ErrorToast("This is an error toast!", activation_delay=0, duration=0)),
|
||||
ScreenshotConfig(PowerOptionsView),
|
||||
ScreenshotConfig(RestartView),
|
||||
ScreenshotConfig(PowerOffView),
|
||||
|
||||
Reference in New Issue
Block a user