From 40abf591d7d225686af059bf9ce3668c49c3fb3f Mon Sep 17 00:00:00 2001 From: Easy <86452817+easyuxd@users.noreply.github.com> Date: Thu, 3 Aug 2023 16:43:42 -0700 Subject: [PATCH 01/24] Icon font update - Renamed `seedsigner-glyphs.otf` to `seedsigner-icons.otf` - Updated `seedsigner-icons.otf` - Renamed `SeedSignerCustomIconConstants` to `SeedSignerIconConstants` - Updated `SeedSignerCustomIconConstants` names and Unicode values in src/seedsigner/gui/components.py --- src/seedsigner/gui/components.py | 75 +++--- src/seedsigner/gui/screens/psbt_screens.py | 4 +- src/seedsigner/gui/screens/screen.py | 12 +- src/seedsigner/gui/screens/seed_screens.py | 10 +- src/seedsigner/gui/screens/tools_screens.py | 8 +- .../resources/fonts/seedsigner-glyphs.otf | Bin 11808 -> 0 bytes .../resources/fonts/seedsigner-icons.otf | Bin 0 -> 26948 bytes src/seedsigner/views/psbt_views.py | 6 +- src/seedsigner/views/seed_views.py | 18 +- src/seedsigner/views/settings_views.py | 4 +- src/seedsigner/views/tools_views.py | 8 +- src/seedsigner/views/view.py | 10 +- tests/screenshot_generator/README.md | 8 + tests/screenshot_generator/__init__.py | 0 tests/screenshot_generator/conftest.py | 11 + tests/screenshot_generator/generator.py | 221 ++++++++++++++++++ tests/screenshot_generator/utils.py | 53 +++++ 17 files changed, 375 insertions(+), 73 deletions(-) delete mode 100644 src/seedsigner/resources/fonts/seedsigner-glyphs.otf create mode 100644 src/seedsigner/resources/fonts/seedsigner-icons.otf create mode 100644 tests/screenshot_generator/README.md create mode 100644 tests/screenshot_generator/__init__.py create mode 100644 tests/screenshot_generator/conftest.py create mode 100644 tests/screenshot_generator/generator.py create mode 100644 tests/screenshot_generator/utils.py diff --git a/src/seedsigner/gui/components.py b/src/seedsigner/gui/components.py index 429890f9e..340923187 100644 --- a/src/seedsigner/gui/components.py +++ b/src/seedsigner/gui/components.py @@ -28,7 +28,7 @@ class GUIConstants: REGTEST_COLOR = "#00caf1" ICON_FONT_NAME__FONT_AWESOME = "Font_Awesome_6_Free-Solid-900" - ICON_FONT_NAME__SEEDSIGNER = "seedsigner-glyphs" + ICON_FONT_NAME__SEEDSIGNER = "seedsigner-icons" ICON_FONT_SIZE = 22 ICON_INLINE_FONT_SIZE = 24 ICON_LARGE_BUTTON_SIZE = 36 @@ -69,10 +69,6 @@ class FontAwesomeIconConstants: ANGLE_RIGHT = "\uf105" ANGLE_UP = "\uf106" CAMERA = "\uf030" - CARET_DOWN = "\uf0d7" - CARET_LEFT = "\uf0d9" - CARET_RIGHT = "\uf0da" - CARET_UP = "\uf0d8" CHEVRON_UP = "\uf077" CHEVRON_DOWN = "\uf078" SOLID_CIRCLE_CHECK = "\uf058" @@ -85,46 +81,59 @@ class FontAwesomeIconConstants: DICE_FOUR = "\uf524" DICE_FIVE = "\uf523" DICE_SIX = "\uf526" - GEAR = "\uf013" - KEY = "\uf084" KEYBOARD = "\uf11c" LOCK = "\uf023" MAP = "\uf279" PAPER_PLANE = "\uf1d8" PEN = "\uf304" - PLUS = "+" - POWER_OFF = "\uf011" ROTATE_RIGHT = "\uf2f9" - SCREWDRIVER_WRENCH = "\uf7d9" + SDCARD = "\uf7c2" SQUARE = "\uf0c8" SQUARE_CARET_DOWN = "\uf150" SQUARE_CARET_LEFT = "\uf191" SQUARE_CARET_RIGHT = "\uf152" SQUARE_CARET_UP = "\uf151" SQUARE_CHECK = "\uf14a" - TRIANGLE_EXCLAMATION = "\uf071" UNLOCK = "\uf09c" - QRCODE = "\uf029" X = "\u0058" - SDCARD = "\uf7c2" -class SeedSignerCustomIconConstants: - LARGE_CHEVRON_LEFT = "\ue900" - SMALL_CHEVRON_RIGHT = "\ue901" - PAGE_UP = "\ue903" - PAGE_DOWN = "\ue902" - PLUS = "\ue904" - CIRCLE_CHECK = "\ue907" - CIRCLE_EXCLAMATION = "\ue908" - CIRCLE_X = "\ue909" - FINGERPRINT = "\ue90a" - PATH = "\ue90b" - BITCOIN_LOGO_STRAIGHT = "\ue90c" - BITCOIN_LOGO_TILTED = "\ue90d" +class SeedSignerIconConstants: + SCAN = "\ue900" + SEEDS = "\ue901" + SETTINGS = "\ue902" + TOOLS = "\ue903" + + BACK = "\ue904" + CHEVRON_DOWN = "\ue905" + CHEVRON_LEFT = "\ue906" + CHEVRON_RIGHT = "\ue907" + CHEVRON_UP = "\ue908" + CLOSE = "\ue909" + PAGE_DOWN = "\ue90a" + PAGE_UP = "\ue90b" + PLUS = "\ue90c" + POWER = "\ue90d" + + ERROR = "\ue90e" + SUCCESS = "\ue90f" + WARNING = "\ue910" + + ADDRESS = "\ue911" + CHANGE = "\ue912" + DERIVATION = "\ue913" + FEE = "\ue914" + FINGERPRINT = "\ue915" + PASSPHRASE = "\ue916" + + BITCOIN = "\ue917" + BITCOIN_ALT = "\ue918" + BRIGHTNESS = "\ue919" + MICROSD = "\ue91a" + QRCODE = "\ue91b" - MIN_VALUE = LARGE_CHEVRON_LEFT - MAX_VALUE = BITCOIN_LOGO_TILTED + MIN_VALUE = BACK + MAX_VALUE = BITCOIN_ALT @@ -425,7 +434,7 @@ def render(self): class Icon(BaseComponent): screen_x: int = 0 screen_y: int = 0 - icon_name: str = SeedSignerCustomIconConstants.BITCOIN_LOGO_TILTED + icon_name: str = SeedSignerIconConstants.BITCOIN_ALT icon_size: int = GUIConstants.ICON_FONT_SIZE icon_color: str = GUIConstants.BODY_FONT_COLOR @@ -859,7 +868,7 @@ def __post_init__(self): btc_icon = Icon( image_draw=draw, canvas=self.paste_image, - icon_name=SeedSignerCustomIconConstants.BITCOIN_LOGO_TILTED, + icon_name=SeedSignerIconConstants.BITCOIN_ALT, icon_color=btc_color, icon_size=self.icon_size, screen_x=0, @@ -947,7 +956,7 @@ def __post_init__(self): btc_icon = Icon( image_draw=draw, canvas=self.paste_image, - icon_name=SeedSignerCustomIconConstants.BITCOIN_LOGO_TILTED, + icon_name=SeedSignerIconConstants.BITCOIN_ALT, icon_color=btc_color, icon_size=self.icon_size, screen_x=0, @@ -1279,7 +1288,7 @@ def __post_init__(self): if self.show_back_button: self.left_button = IconButton( - icon_name=SeedSignerCustomIconConstants.LARGE_CHEVRON_LEFT, + icon_name=SeedSignerIconConstants.BACK, icon_size=GUIConstants.ICON_INLINE_FONT_SIZE, screen_x=GUIConstants.EDGE_PADDING, screen_y=GUIConstants.EDGE_PADDING, @@ -1289,7 +1298,7 @@ def __post_init__(self): if self.show_power_button: self.right_button = IconButton( - icon_name=FontAwesomeIconConstants.POWER_OFF, + icon_name=SeedSignerIconConstants.POWER, icon_size=GUIConstants.ICON_INLINE_FONT_SIZE, screen_x=self.width - GUIConstants.TOP_NAV_BUTTON_SIZE - GUIConstants.EDGE_PADDING, screen_y=GUIConstants.EDGE_PADDING, diff --git a/src/seedsigner/gui/screens/psbt_screens.py b/src/seedsigner/gui/screens/psbt_screens.py index 1ca904c09..ad378fc39 100644 --- a/src/seedsigner/gui/screens/psbt_screens.py +++ b/src/seedsigner/gui/screens/psbt_screens.py @@ -655,7 +655,7 @@ def __post_init__(self): # Adjust the vertical spacing screen_y -= GUIConstants.COMPONENT_PADDING self.components.append(IconTextLine( - icon_name=SeedSignerCustomIconConstants.FINGERPRINT, + icon_name=SeedSignerIconConstants.FINGERPRINT, icon_color="blue", value_text=f"""{"Multisig" if self.is_multisig else self.fingerprint}: {"Change" if self.is_change_derivation_path else "Addr"} #{self.derivation_path_addr_index}""", is_text_centered=False, @@ -665,7 +665,7 @@ def __post_init__(self): if self.is_change_addr_verified: self.components.append(IconTextLine( - icon_name=SeedSignerCustomIconConstants.CIRCLE_CHECK, + icon_name=SeedSignerIconConstants.SUCCESS, icon_color="#00dd00", value_text="Address verified!", is_text_centered=False, diff --git a/src/seedsigner/gui/screens/screen.py b/src/seedsigner/gui/screens/screen.py index ea08a4f50..0e3ea6516 100644 --- a/src/seedsigner/gui/screens/screen.py +++ b/src/seedsigner/gui/screens/screen.py @@ -692,7 +692,7 @@ def add_brightness_tips(self, image: Image.Image) -> None: canvas=rectangle, screen_x=GUIConstants.EDGE_PADDING*2 + 1, screen_y=GUIConstants.COMPONENT_PADDING + 4, # +4 fudge factor to account for where the chevron is drawn relative to baseline - icon_name=FontAwesomeIconConstants.CHEVRON_UP, + icon_name=SeedSignerIconConstants.CHEVRON_UP, icon_size=GUIConstants.BODY_FONT_SIZE, ) chevron_up_icon.render() @@ -702,7 +702,7 @@ def add_brightness_tips(self, image: Image.Image) -> None: canvas=rectangle, screen_x=chevron_up_icon.screen_x, screen_y=chevron_up_icon.screen_y + chevron_up_icon.icon_size + GUIConstants.BODY_LINE_SPACING, - icon_name=FontAwesomeIconConstants.CHEVRON_DOWN, + icon_name=SeedSignerIconConstants.CHEVRON_DOWN, icon_size=chevron_up_icon.icon_size, ) chevron_down_icon.render() @@ -824,7 +824,7 @@ def _run(self): @dataclass class LargeIconStatusScreen(ButtonListScreen): title: str = "Success!" - status_icon_name: str = SeedSignerCustomIconConstants.CIRCLE_CHECK + status_icon_name: str = SeedSignerIconConstants.SUCCESS status_icon_size: int = GUIConstants.ICON_PRIMARY_SCREEN_SIZE status_color: str = GUIConstants.SUCCESS_COLOR status_headline: str = "Success!" # The colored text under the large icon @@ -948,7 +948,7 @@ def __post_init__(self): @dataclass class WarningScreen(WarningEdgesMixin, LargeIconStatusScreen): title: str = "Caution" - status_icon_name: str = SeedSignerCustomIconConstants.CIRCLE_EXCLAMATION + status_icon_name: str = SeedSignerIconConstants.WARNING status_color: str = "yellow" status_headline: str = "Privacy Leak!" # The colored text under the alert icon @@ -1242,7 +1242,7 @@ def _render(self): if self.action == MicroSD.ACTION__REMOVED: self.toast = ToastOverlay( - icon_name=FontAwesomeIconConstants.SDCARD, + icon_name=SeedSignerIconConstants.MICROSD, color=GUIConstants.NOTIFICATION_COLOR, label_text="MicroSD removed" ) @@ -1250,7 +1250,7 @@ def _render(self): elif self.action == MicroSD.ACTION__INSERTED: self.toast = ToastOverlay( - icon_name=FontAwesomeIconConstants.SDCARD, + icon_name=SeedSignerIconConstants.MICROSD, color=GUIConstants.NOTIFICATION_COLOR, label_text="MicroSD inserted" ) diff --git a/src/seedsigner/gui/screens/seed_screens.py b/src/seedsigner/gui/screens/seed_screens.py index 74f0cacf0..3e4213eba 100644 --- a/src/seedsigner/gui/screens/seed_screens.py +++ b/src/seedsigner/gui/screens/seed_screens.py @@ -421,7 +421,7 @@ def __post_init__(self): super().__post_init__() self.fingerprint_icontl = IconTextLine( - icon_name=SeedSignerCustomIconConstants.FINGERPRINT, + icon_name=SeedSignerIconConstants.FINGERPRINT, icon_color="blue", icon_size=GUIConstants.ICON_FONT_SIZE + 12, label_text="fingerprint", @@ -441,7 +441,7 @@ class SeedOptionsScreen(ButtonListScreen): has_passphrase: bool = False def __post_init__(self): - self.top_nav_icon_name = SeedSignerCustomIconConstants.FINGERPRINT + self.top_nav_icon_name = SeedSignerIconConstants.FINGERPRINT self.top_nav_icon_color = "blue" self.title = self.fingerprint self.is_button_text_centered = False @@ -584,7 +584,7 @@ def __post_init__(self): # Set up the fingerprint and passphrase displays self.fingerprint_line = IconTextLine( - icon_name=SeedSignerCustomIconConstants.FINGERPRINT, + icon_name=SeedSignerIconConstants.FINGERPRINT, icon_color="blue", label_text="Fingerprint", value_text=self.fingerprint, @@ -594,7 +594,7 @@ def __post_init__(self): self.components.append(self.fingerprint_line) self.derivation_line = IconTextLine( - icon_name=SeedSignerCustomIconConstants.PATH, + icon_name=SeedSignerIconConstants.DERIVATION, label_text="Derivation", value_text=self.derivation_path, screen_x=GUIConstants.COMPONENT_PADDING, @@ -1009,7 +1009,7 @@ def __post_init__(self): super().__post_init__() self.components.append(IconTextLine( - icon_name=SeedSignerCustomIconConstants.FINGERPRINT, + icon_name=SeedSignerIconConstants.FINGERPRINT, icon_color="blue", label_text="changes fingerprint", value_text=f"{self.fingerprint_without} >> {self.fingerprint_with}", diff --git a/src/seedsigner/gui/screens/tools_screens.py b/src/seedsigner/gui/screens/tools_screens.py index 65ffcc3db..e27e49493 100644 --- a/src/seedsigner/gui/screens/tools_screens.py +++ b/src/seedsigner/gui/screens/tools_screens.py @@ -362,7 +362,7 @@ def __post_init__(self): )) self.components.append(IconTextLine( - icon_name=SeedSignerCustomIconConstants.FINGERPRINT, + icon_name=SeedSignerIconConstants.FINGERPRINT, icon_color="blue", label_text="fingerprint", value_text=self.fingerprint, @@ -386,7 +386,7 @@ def __post_init__(self): if self.fingerprint: self.components.append(IconTextLine( - icon_name=SeedSignerCustomIconConstants.FINGERPRINT, + icon_name=SeedSignerIconConstants.FINGERPRINT, icon_color="blue", label_text="Fingerprint", value_text=self.fingerprint, @@ -396,7 +396,7 @@ def __post_init__(self): if self.script_type != SettingsConstants.CUSTOM_DERIVATION: self.components.append(IconTextLine( - icon_name=SeedSignerCustomIconConstants.PATH, + icon_name=SeedSignerIconConstants.DERIVATION, label_text="Derivation", value_text=SettingsDefinition.get_settings_entry(attr_name=SettingsConstants.SETTING__SCRIPT_TYPES).get_selection_option_display_name_by_value(value=self.script_type), screen_x=GUIConstants.EDGE_PADDING, @@ -404,7 +404,7 @@ def __post_init__(self): )) else: self.components.append(IconTextLine( - icon_name=SeedSignerCustomIconConstants.PATH, + icon_name=SeedSignerIconConstants.DERIVATION, label_text="Derivation", value_text=self.custom_derivation_path, screen_x=GUIConstants.EDGE_PADDING, diff --git a/src/seedsigner/resources/fonts/seedsigner-glyphs.otf b/src/seedsigner/resources/fonts/seedsigner-glyphs.otf deleted file mode 100644 index 63a0008cdca20b42e9f41981c9b8b46f5dc3c058..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11808 zcmds-dyv%CmB(+-Owas=$MAkEjyei4+O7&}`N+D_XaaGojIQt-LTQzYI)#8d6i|ta zG>$xf!iX?FqDBc?YPYUQWveW$wRAU?&DNStC2l%~jZqA~@EKI-85_L&`JVgh=@zz3 z^v|8CIemWjo_o%@=XKBh^;|e(#)WRM%ezK5`Mjx9J1*II;aumkMlD{nWGQ;`)6@s(a2X(fFP?b$uP+;R)?PQbNt5p7tB-$R z;4^k(TJnwad5&CzM)_e)<8%Hw4e6&PZ=4KIL927N7tXE%?mOIWDt%sL48~@i})6bJ98dbhr+CYIFaTj%M5lHz~y%T#K8U;*E@7 zo8nF2kED1O&%Kc1&2B`dA;kx|37NmcQkkY!Mvg{Yz#CkfJ1xZ<8UId-H-X=h;#vIr zbc#1K{&I>Ba;IiSyXmfr-z)i?>*lzH;Mckn+%$K!TkaOStK1UjrgwE+IeqS&grl>$2T+}E1rYh2T~hIE}x29Rkc2&x7Bj91>t-?|4-IFGmvQIz9q0OT z4SmNq_Kj&uhBPKanvNLcTCeLoDM<#9AuT%}Xm82)`)qq=#ISY>N_%GVh;}!m{g`nh z-3ak%AtlG)=7}yxNS@)&Ch0G5Gu$NvPM5pRt(~JBnzC%++{u$C>*HHzPM#b-(x;Qd z(<$NO)bMe7_&6hcoEbj85kAfhALoUSZxZ>3?D3ER{GVByS%*c|XEtP#%&nP?nN69V z%x#&?ncFj4GF#nn?WV!CQZ&bBRyI7{G%fp^mSxddt);=4anBug@{uzp{j@Dfnv$fY z`q8&FJeIfi%@~ukB)uEGYmMU`@1jC6z|G)syk$$&*IF)Ty=yKM8EVNDylW~H!2}xP zxE_o0&by2zV3v3{vQSL!@xEWfL*w|SDukE!f6BXLdE)&(J$#x2l;P(0$8mQRep2f6 zzEAW0ngT?Xmn;8O<}YXzCR`S+jLtO{iruJXFjHa;JcEp6dCCR3-hWsq-W1@C3~S`Q z0YVm4_u>1rLG7|0Lo2g^6xtl^mwmdotTubCH46r~KA535YU@8Pn0fUE??1`A^=sCz zVT;;VMWQQlyf&&VuFTJ-qfD*!{(!_Xw?4o%T8u%x-;1g@+b+{xx0r(PbB1BUtyq5$ z#G7yRE*rVm3cVP=Gdf-ve8^|({pVF4VZm6jRm`~YvfaKCODDuJ_6X2MWmZup+Y;y`vq>XRpl^VpbFG>ZM+I!u ze{NY4h}tdQ4a*ho^losWcuy5(C2EA3M1lP%!ln0L0sOn-F&a>Zy;&ev25I(>kbA$! zBJ2YZ;ouOC13_6RuJ-;T5#!_Nz;`N-AGoOeI02zCIf8^Kb#C_leLY(O)vyn=7mLzA znWP|3^8MbbPW~P7ke&gP?*0wP7oZx!kB|~0??a$n-&lp%VWrumyXuT_<_t4c)pWrb z!JLN}*-T&W42$|hoo22SN4Xbgn7gqw2_2NESF5UQP(E1@oS_ZXZ?d-CnlTP`h77md zOd24DR;e2>JkBWNj7rrRa*#O#hsgz@Hq|gWBP931&IrNqe}zglkdj9evvqKWf~^{S zArM1QDnO&QzODU_QoHYD#h@G-RdAn5HsuQi>#!!x?#mSt??1+{m96EiEwHsfZdHZ- z{FQr4ak4U58OS_OL4ZlA0|-b-5RxFJvb8x#Ooxp?s?{yBM`MW&2w{PqoT+@!Hf(FA zDoV3yHV~DO(qh|Ur3Cz$l^80yGa;`fz|3ZLIvB_*fkak9N?Ci6#B|sQq|m`DLuD#=Dr%%KZhw`*<-r^uYkQ?wPwy5=4`*-+2HBP* z2meb0gBtafDv^%3==CY()#cR`uP?rKOLxyIIe6`=?(V4aVCBJVclWBba>lBjZsM$d z8}rI%t6lhlruf1kx|*W_V-ZMX67gWJ_5FIZh^b+!8H(Q!J61s~c0>_UpoWQ)tHsXh z%4qH7&jv%yrGMc*Lc*l#D`12ApC9_s7moeUIA&jE8k@m9v0_q&viKlU2BL=8Av87L zDnmfDB`Oas53TUWIm5~=w#ow0D0>4{h)5n-OpGSIMh3A0FRX_{HExZ$iTV7H{cPBo z78SU3(?RYkIsP&6_{l0Lx5k=04LjzlOHEP!XSC~#LZ9K z{5Z!(j+OocOk-KH+N9*S-?*I>HH7R3~r*=V<14I;90cJ`g?=kmsrtQl04=DOiNTFU8-?d z{?JnEkQSNF0WyMpmiI<;(v9p8XNJ6gF^&n30Dl{I(hHW%jR7)3B*C09SxMf1NUWHUztJyqbAi+&(?Ur-!aqyG{JRYI7hEsrMKc01%u+Sc( z>nmd|QR(5me@o4ce^ce$nu^z@S`D)cz-xAJ|55SaUorhk@qGFNk?s`N8m8-)-zl2G zaXfz`p@$oZ&0G;bu;Tz(q0vus#mz~yF~J}uR=6Cj?CR#kpbmpr=M-a_Aaclbi#4&K zGwmcoxpoAYGScNx)}%;$C>_7TQc8E>vDDh_nwRICVRlOxS5U2@w~6=|uepXCV4S34 z-fdObEU}|CZ)cq{Nta7wb?-yzl&vx%!vOa)HM~#^5Mr$uQXr3xNLf8_c-YZ&-vQXfiz$DEmA1uPW4;V^Wi=?RYUhC>H&6dInxvJU9WmY2u z&21Jc0froKS?-maH*O(?2~COs0UIDmg1@^d1C~r&1HFGudEcP7HaW zxDA)Ev4>TLNbe3Uql~4SsbP9~;f}%DKS{P@IkCV|#^>HD97Fz_Qx)}z#XeA@;Y9>8 zzh|^SaZt1*OUM#AFmk*9e z;1%t64=ntvnt4|8$< zK8K>HQ_D*G0WA#k@UL5=dKfsu8yN{t(tzR%1_-%O#nut^_&;c_(rh<;H%9e@PJlKS<9JCGj>;7m-97*A`L|P~v_Nr^a5Q3} zTZor9=B^!Jf3CQ$JBhlX0p%=an9F*Akl&tcK^_}oOop1E__yLha)q8;Y4(pKn4JHf z%sNtrsbb5>1G(%Ct>zrP#@=m(kPGi&$S_r8eJl=ALW5#Qx|W5Di|PddUAO_>1vV_0 zM)=zjZR8ficF!@4ZK$rO+KRpRFG~wGZvGY6scc3*Mg) zV`atgr&^0g2~$zkuzt;|uF6gc<;~<-HEV!ru!r>)W*NgcbSOc&0o ziNfqa-Zi(CKka|Xs+zglctoX6Qc9A-o2mg!Nt36b>LuE=Y1z<0>C7VJ=qwa@2hq^*i*s<4}))`th?~WJE1Y*kNay%YYDE@O59w!^* z1g6CClhL<-nO$YAmZkR{skO|cW;esw9W_MKW#Oote>B^h8rzOQE6vtr5?dG)71B5K z3Tx}Bu+pk%K_$=K){=l4NG-9X_((g@1v$KN1X4?ZZZ=Ry<+*wpWGQ6_lvP_xE-EnZZ4VbmS=${^f}?B{dZijBTe_oUEvqI+OKHO_ zld->d6AQ&Fo{0YT>v$6XtjY%q92E9S1rmb5NjF9CL<`EP`+KRPL`LYq6fNQVs~Tpl z86>^7I%@mm?C_P1_dnAftVI8ZbfZqrTsAXx`U@ISV}CHP3ECGUWr_E;*x0}@F}6UB z>Xeyjm+YC_yw^&1M3tpZU5bF+9YBLv-AtA}YpMXn)15A!?rVgVLE~wo#`oE6&jy}a zX(#z1z$OrDq+?T-DI2lnC=c9`WHM9v%j}+%>SY?%bT!Pj!lt&RTMRt4@nD3gvSFVc zTGq{QM9`ze@egSYaA1IZfnrz5m!uX^9lbu|)E3JwSoA5|d zoSAvY>R-`B)BG8HADH|-l}JwpDVrnBn08&F3+p8=?A-=XsUvwRX_jOkqElr9OjUEp zF-5Z-6HT+U4x7yQT}}IE;XG-NW-uHTavuEjqkLQ zv%!9seJY4of3`LBJnDMuvEfRt!^v|UaA}d2#_HQwKa`%3Bc$XWEi}yDPthY^v-uv* zw;>w0lP@Y1zfS@gY}Du|(|R0fR#{LOldNu8Q)w{kHCG`f3|qDD>UhzBB8rD_K-REf zIaC^M8>MdG0${2VqxSt-Sfg*!QcPdy7{~CP76y&-l{3dANm3blTe3OH>Z`x@62f$v zs)n#opoWbo#rHvUq~#9K3KVCdD!d()NV|w;e;?Bn{cY%K`+2ZLY z<=xYmEsg_(43=)Brj+<{KP+2?!jeL)m9SkweSj~`J$%Vp%E?^g3xsDdhxlG<+=1e0 z<_PaZWDfDg9O5Z+U|USVDOo<Lxn6G>8sOsZBZev(ZQB*!b=_&46aAvH z^Nd>pSl)3qWYhtK3teAH^8i(ijnM-;JMUU{YF4iSFd8;vkynErJW|7~r)?~CA~(x) zI8IHD{#OBsoIc9@AiEATE#gj&W%V;Frc+?Tacjh~MR?nR^z`7ZVK!R|OcUbMPV=Ff zR}Ukr@h&64CMiHvr4>en>7q(E22pjjy@kS5$vci`Do%juDPr5E67)o?H)hu}U#Qll zB)aB8RGwTYuH>F*l@EKbi+KA4s~gVw*PHGuF;AzPMq-S>KNOgwsNHP)B%puc|BgEZ34$ZE+5-90@YaKCTO9(pBOD>HS7bewbJpH z)>=zB+}?b1z_`ZNuIIw)JxVsY3qTkwH1%?6P9Xd zU>Z^uAoiIgdM2TK!)t&qGE!;CeQe%i^8!2V$Jh_3%KA%_S*t9Dq?XwFRg-_WLpi;uX8W!k2OPFP~q%BoY| zt@d`HgHGx=*LuOU{hb;5gU|#Y^I2U@YbzQse^z^gaeC5O53K(5Gi|EM#j|Mx9E=dU z4>49_T@S1ofx9|o+Fzj68V`eTZunLcgy)QjIW{k%D| zY55$3riHoTD`5(Q!{??>oBNe1Ab$g?zhTN`V^Qpi!Exc}aAY_tgvnDczGV8G+2f8r zk}rP)*^`ajr4XFP0xpLs;ZpGPY5Rw;0Qd=$%BL8qrH>5Z5va+V_q}DMd7lrC@cvpLuXhYz7=i_KM1#npN4-8_l7@&&Ed(gWA5zfNAZt; zOyuLF9?c3agu)=;~($wk7NDgIRALBe;n^0ANG%r_{T^6<757Dl7F0R9}~6u zNykt0^(Ojy6MemjzTQM%Z=$a^(bt>k>rM3aCi;34KZ4ix6?xz9*kER9W*O>Po>`HJ zGuLERX0FYw%B;?GWUkAs$#iDAGS_F;X10HK+$by%-@TMFIry6Cy)I0+*(aF+%SX$$G(7ELiShHY1GHrG8rjwUqO3OO2l z1yS=As#vdjZH0Ip!-~Eh!$d}7>#!E}LTOzbz0#C~BjGCvhcG62HP?M(l02QyJ6xM2 z59PY!bE1Qr<13OxyD$!IXMKTK*N`jXXm{txxH(B)7UASIcDOfuN3S-=cdSjq!9`XN z`xf9t&^ZeO#Irbs<#n*DJs3l_uT<2Gc1-&hr|}iWcaC;ruSYyeK}ijJO})NJanDw@^)`s`U0%s!Jnl8w|E{i-y&_0BubZhmN_ zU~gkiTW^#YIzP~Q$DQXi_rAA$yP5azWp2rXS{u*3#5~#IBJ=S0j_8$Ui&Pq70jW=r zvcT1%UYvPdY(6iREYNAJxo}+=wB6#&@fFb#GTdi17qiD(B^F3sRe?kD`6V0U==r)x zl4G!zOsQ5ek0j<33TKLf4Be|}Qrd$fysgNcgh66eYlaqiw?}W7slz;aOD1e!V@wLk z=U3a#x++k+4ntr!39ZDaZEs7`#so9PKq~F3G-?uZx#T46Lz?4r7Fnja#Bzs2*S<1J zlE@mO^19NzI_nwSvvKFkvXw9vMsI0P!v6U@#sMS`Y0LX6-fYhmNSA8crnVY3M7>X| zcYt~yFLaZwfE}~Z{Uc_6EK3r~bx)x~=%2NZ8ulkqcvKy~$>--rTaL@7_9Dj!{j~jE z&`%Og+bK}Pb{Cnpt1T?WN09I_$NcKk%qB|PcV>(1E;)Fz(|7?U$!_)2>Vs@%Ig~@T z_T7jwP^@Xm5HzobDJ_M5x$dQ_qR;#+yL1&pbBt;Pn4gA5jhDwdmRN7G8fdnVdWz~D zrg0CecmK94T1OgJDvxxlz2fi+GC$_gvU%f$tSt)@vU4OG@w; zn#5!c!)}t$U%k5#PBeeZ{56<>EF|>PNK<#eLII!Pd-UORvRAbea@4h3R!K2(O$F}A zvtdi?rF?!(^o6^jBn*?vv2y=H_X^XTLkJ=p#X@7MEBf&t84nj7f>3H=lD>nb{8ccU z(iWE6#OT_SPG+E7O7UrqCp*Nj}C}J!bQYlNk*w(cf>*ws)nQupk-=-Phwt1{(`lTz^r5 z!!^;}h|93F(ef)CUjv&CVHR)9Ly)KtZ9XT98P_ubIcYa-tHbDUwhP@Wqm7TS4%65g z8+7IO-M*1AhD}TZWmbP|S{u8>Jfllaser4P2)ZIzU{Q3#dsxa0&ef=1Sxu_Yiu^1V zg(llxu7LVcR->n#FxZW5_ol*1!~=i_n3e_UOkS zagkGB$i3vBD=ddObXQDvq>C?(zJR#2_+lg_N@cC%lTv8=Zwps-L?6B*i|=dO6(+Q_ zzS0)WUp$|zC6s+iB4!8{YJ89+;usP!Q7nq1FPHwCCEmj@vG0=Z>G6QQzt$yS1B49{ zILHF9hW?Obs=jfeNv8FoRcwY&NFJ~VC^*9>*oeMBl#(qBnyP@y=ydkOMWT>cutZ(O zzH5m*3F3ob`-`62TjTit6R*7Ty2Z#IU!iiai1kvg8+tDo55QDv+o75enhivs`n&Rb zO2@hmQu8R~*wgM@;j6$xw?lNK);&2a+KdKAh@Rc%>)E0dS#)|l8U|;iRfB4EBZf0y z6Fy7h%Pl7Nj2PLjo;_M%dojP{@+FtEh!ps8QM#l6g3Zz?wv{phE#_$iM2G+$QfZKMqfFqb+Js6>cUcLT!F6@CsSxBtKi@`{ZfS_ z(IYWBTxBh5JS3z6l_4}&hcK{zF~4-p;wTLq5~&v{(66qgshtJ%Wm%KB z6Ky>_U7VD?+QNDEkL{UQ-%4^ zE{l7>N^+GbDyNcFD6X-Xha~kpB1mDbU`%wcib_Y6j>zIi&R5o4ygHO=OxB6R^ln6V ziF|t0(Rn{zUN&w_Rd|e^JdMD&bk&lT?Qwg&WckviQTd4S5!t0nmoK5AedUr>OIIyj zy}Tpth*z&%RpDgS%GESg6kA&7kt$9fD&EgZnFtU%GRtG)&7O~JzBwS{TBEm08ldlSPX zj-*HSZV4I?l^-tOTY9+sTj#1Bq02pc#F5=sSQxHh89K;1x~HKoi5H}lwrd@(A5ycg zU<*^@f8MmN2~4i+O&1y0vXn!!gOsz5sJDNqCrd2n8l`;=R^c%nh>|6eE>di#6$$N- zq^`JT$;u_vVFVnrM;Q{{Ql4455KEMsyOrYRvRL{Yu2?NIGa0woAc6kU2`ig6YFH;U zBo+pubeo2})ncY5d#Yj>VXt~{jipiPbLBHipDUe_T_w{M-G*E`)+=z$7se$?Mm<%A z;!fzOMckwpKUK_>vctTJqD*3dOu~73Ng9mJxb1Gtu-&9h@}{C@c}7`ssaQW4i>PPG z@+HJTo?}Y ze5075!9Jvf*kx_gR;;d9+cJ|QPUnIxeHPK;Jjm7~g~MxJuUz>7@>C*9<(Xn%^(B+4 z6k{Za98&?+BnXB8k)z3q5OHC7#_Pmr`2@Kj#U(3Dj&XZ5c;|#VF{+sm#{eUeioT)= zkwlE1n4qTRq;UGti=fdpM-sbYy(rVLtpMsU1%SR{yk>R1fLvsXX4og9{4Do1F4}rw zzlo3F3a&UUQNiRNVnhDns$T74bgz&YtC-9q$5{6d6QlP@5NQN|{-<8l)*_H_18 zU^ScTDNx{gEP&fNgt%JC-<|=Y(o7k7)gnE+;Z9@|)o%_VU$$t5^Td>NEbs9W$8uqs z+nHE}QFzNC%~mY*sBDvBL=L!=h=$&BoM;PX~^_^CzYKbP%YXNYc~5&O-NsSh+^= zzE1^HzO*#Ayr8@Q>#dw)-g=fN4J&6XC8=bNH^fxUmLjc+CgG*E&w|o|a$Bh_T_K$% zPHM9>)@Iczq#9-&)LkqP`>;M|pi&$37nT+xuDze-W4)BKq7LC8B&9}p^J7#+B2jr^ zc_EKv=B6v`<*dQmdcI6yRoYe_%S5|QHb)tlV}Wvh^4H9`9Kw!TEgdnEjXG4T^!+t6 z1&54P!lb~Xyd;!IrDscHb;F`C9-51QtgMV0%PN?9%&aU@`bmqF!3^>{JrT9r1izHg zy@F$}7%{Q;l4UHyR!l{}IyyASx9n(ZVU#juS-XY5sQhwyT>0hFI4&CeB8I+e75X&C zcr_a44DwWHI(@CDaO>Ro1*P3`*ky|)J?@gL!|k$A`%;DDd-Y?e_V1Wvq8p(u<26Dt z6HGCP%@yM=X2K>ONz5+tJTh<DjeHN_;mizr56$)PJo(y3KrUlQc zWNV7A8AA;duVJ8>l04ZA3QZ$w6@Io)PVVd$$o@OJsJ44LcWxj=Rc{~5HX13rp6njd zYS%`Hb5z%DTe-8;*<2BRf7!-f%wi9(!h{Xw>H&dTDcuKHhp1^Vj}SV`olP;PKx<<4 zH=ku43|SN}Vi|o4#;!45+k#=nDwm$zRhOVnaMntwSEl;cXR%d;Dr=LQBM-mg7FoZQ zsbP|e57BT|DzT5ZoMkuW5MHaRuTGwtS$vh?6#~OR7V=0}!?@VJ9PVFGHTq1mMN3JE zt0smrsV}gOoyB~be;DR>!y20|P{kOgGjn&mAu2)JpCxJd*L`Rj-1CgGFwaoSW*gY> zw(?2Je7ajn?@~q-(D|Q4k_h*u3RKmT+=p2u$?r@L|EdPFlwWGEauWiAJ%mJ8Jo^X!bqb92xAptMJ60(w5phv z3-8Kx&%N6y0>x4|PK3hy#AtZ823yg_INQ$us6cHs9IjSvUvJz*UDn5evsjtc=N^&J zfDjiErCTplRux(;9#*MQ7Wz`Uw%lnrG9 z(-aZAtHg9$>r2>TwydaX=b}t4DSjN-?7nxsZ#KJUN9mN-aV@8gJg8-G&k?0fZ;m2?K-Rtk`4IaptuIY}BxygrCtnk}CBbdfw21&|bEo zkkTMad=0|vx+_a0QiYXfh8m`~OepY)Q;7y60iv+I1>`EUE)#^vx-tzj=~GNDT8^XI zCB{w-*dtO_;EP@zR@T=fKbe}Jo`sy0w@XdBHn8`j{NaV(lydAvvtxaIfvuA)ACv@= zhZXS~)VHa|EM5evK7e38d7 zL^af51v!wYc(9HX;ZP)XO>=xRnqVJcR1wOGb^gj|4YQy=GFKpQj<5>1RfC9?Fe1JP z$My`Q9vdW3ivMr#u$MboIsWu<6i_R^UC#*o&lVjnh(5v6qJS#qQ{W#6)7gux373my&blpv0D;sYM%>X(K-~pVJDuqMh^=VL3g61Z^_aP+ zJ=`+?*+;!#KsiAe%LTVR(sSr#Zx}5OpT~itIc7*na=!+*ipgKo=V7>lokft(LGX`- z?m6i#Jjq}Yty!_OtC6rr$9 zI^~j&=aCNW)s7d`NHz!mDlsQVt{6gNsBv{ZC(3b@<{DFB}QHe zOodm&%wBdwK(B-|#C%-CLT^xUKe*4%RoVwqeP*n?~Gfnu-Q<5Qx}CCsH} zln(LXBKla>Ci0p8P>1EhKcI7VtymC zMv1^yobJXeZoC4Ci&d*nD>*(YU0k|HSziuP@!yiRW&XP>53vfyd%nBXLnewnT49Z3 zew%A%R>QDRWq%8Vmi_B6d!}d>F7oykZ&JhTW`@m^)%p_%(x3(EDO~}ZM+Nwk!xfls zG0$&E%oqvpJZT=7*L!b>%^|E65D^{&Q<(ayF0P?jq2s!a>xgS=w%00~#f^N>?LJEa z;|QYq-3in%aT9oBrAx7aR2Z8NE?e8a7H_n-!jNVftEsYVC+5%OmzNbX%+rx$J%*cN zXAqkot!R$tvt9X%uHp!of>$$HV-&!wcpJQH$j)4A%#UzjfC8inn+*pNRM`8C2vMPK zgiMNi$Zu5OOKKfdgr;oXB&7Vc=JHf4#-YUGb%|(BXJWV4S(whY3I%*i zHsQjlVFNWqPNN`v6*0`#u$;mrFT$sGbx3{@@8qEk7A0V6v?D*um)#^_!K~Fe*z- zM8qi2Ho)L04YF)UbXmX7f{a7Fiq56Cs#@nF8c42=S7ulAev$~IuaHTSBD7TdCy6L| zTMe^b0!)X$dZdzMmP=SKuoIz32!fKEX@pxCi3w1{wkY)Qkiy=k^SGh+>I|Eas`FtM z!6NlBBeew$F;}<2DF!K?dpUU(_f{lod3$A6?2wsYZS5=z1?d}8B+V$kl7BDC#;#A> zE}BghWIC3rFe05*lNXDsKB4!J4ldHbgUj!)`2GrR-C)39{$L<6Ps8mY2N>J8lbW?zh?I#+ zZ#OGY(!HNXTS%;6oC3{4MkBk$*r-%MZ{_<(+PAm@bt`K(3tN zmz8d}lPMwHH0G9#>27<-~cAo#ke9@r~cD_&^*jc5`PNdr(oOkf`LWq6$U_;P)` zHhag+BplB;{eCeCCjmTKRj~U!sD_V=mXWDpClP>n_`#|lQ7?I}9y?ZFN9HI0$Vxgc z{PyhpcT+&AG3}JgZf>^c2R*gcobuXb{_` zLR&v?{k+s4RIhnKZ}Vht`thOVeJjv|nk7fY{Ib*zIQi6L4fa~CWfR;q znpM^#X8VeyNc8qTm4xQ^ixsSm_yn7tQQ#~3zysOy(q#E?K2L0WTyntZ44X-{iYSw< zMF^<|_h$n&>=pG=lX{`1FjkM@12bcDI9}f&fO~c=ix@XZFe!?Cz-#Jdh;E{&cm;Fp zJmk8O1P11?(u#5UOFM{*sMJpc@xfK@lb#&pox+$&*^!zSW-l|Bls%(l)MXjP+o1IN zULVb?3C*$UArT#|*`^qdCRD5k=(|K6#)>hCDU4HF4U;(i#aIbi!PG@=Au~Y*x1DFV z|Ir6Oh(awv0ovH5glx2{ULeoFKdjJ~>Sb8bEPL6&zP6|hL(!`*Le14{7{+yNmx+TX zU_a3B#^Sj5;GRQbGEO*Fj9CJhBo&*B9Hll~OITSxSkiKwW1BFn_?u!NMewM{4_Zf-&igQb<3NdPST=O zqm@TR@3A`i==|g^dtkKjCmZb-S7`xb6$#>w$WEFg$%ip=*>^}KFkwH1=EmtrGRIw1 z{?LnhC-xlGlqCPgY2i%FSG@dQK=Keamun6g&SN>gTgmyLx@(xZ)8@87IsUss_x!U6 zTE8)?h9qKNlm1-qeMrdmVT;^t<)}j*jftWa42NmeKk?O{2N^b2>iNC)F;cydHH zH1FpkocxO|X`H`U%;WINJt|%5F;2vuXp%oLoCI~B&3!=YQ8mo83eMree}Y@&6n{sa z%!>OKS?f8C94?|Y>}heDu? z)M0wS!Q*y%2dnpw)~lshMG1?0Jg+dZ(|T+drn;C0-EQb`AZR~mAhXGy`4Hre4?Z~b z@S1ofVIl~<%&x~M?kh?co^i&j&92VJ%YSx?8*8g!y~X?wV!QYSVo}%XHvnT<)IUf; zW9*GB8Ka#%?A}lHpBxo{h4>R9*(+nXWu`IL{XG?ld56BL*RY4Hf1s#=QR%;<(B1JP z-eUQ?-D9na^oTXM$R3``=@lhzMjR5&a_r|hIgD9`Ws?Tz+5G|6odk5d@5rdlZpdqx zxiM~z{K}?HAQBZtjg;?mRp8KmajZ(g1S;xSq=gqyUrl+vI^JhNYiW(TxC}+{1|5H0 ztPYd8TR|s+cH%NSwL>;;!(4=CR=Uw4w=PnFS0v~uBF0z|!p+bR-Mp->^$JlHt_P7L z@_HXfQQ=2i?jCOEvO~p@RrMId4U{?!-q?nI? zsG1w`V$DS{Y~pRw#2O||xg`_ZV5FufIS`4Mu;p;s;%fJA^+RM8WSh?2MC@1a&~1O3 z!H^`TW(*>1k}Le{0{`2vR_Jy}^`3)|GF>u4`?-Yb20zrQmh$s*4YT0GZ5WqV{WOr# zRE&vB54N?)oglUH*V}e<>ZayOj($YjLRA;@k0Ee^Az61+{;3X?53-KmcF=Rv z#W%tI*c?miT31D29QAyt$uaNI;G6izXK8S3-BC&Oyl%9~^gxahOI-L8EEY$bntDf! zjN|y%Iw=vz$kM*nvAg)A-ut?{sa;7q)f{8zwHEM>8{7*RBs<;BmHxB+DQQQJzcu zute27H;(w>TAb~fU3v%akd#;K&~`luTl6I-ed`jt8gXbQ_OQhCKa_5e-Fq+}3PkvY%>n2bE4iQ|&iog-mavV_1Jf#6)k*S7k*|-~&*>aKC1x6my47w}t!lPsZ`Al(V3K3~ zp-SZTXw&wNnD-*gn_tVWjME~UNSPK+sP1)`7N>V*9GzJ{n(eHNsfN{HT6T#1v<7ea zxFn_jP3e~RXSa4E@3%ZwBG`S8VMLj^sR?d{1)1qALSb9D(%fQI1wIB9ZFa6D0ObW4 z8*Z+h%0ws&D{VDQ0jF}fB*HDewUx)KKQDA&@`dSk>H*#-GWSdN6ia8%IUDict1as| zWtT9@t)EW|fL}1!xB82Gew~p5-diYe*#)8RrAI0A_`hgzU7PsD%#jGZhC;tB{M72K z^hSeK{>5pB_wud}7s^^e_>DiMu&1a5zEkVJLxjh-g*&nCeBNOaCP@{y;n?N@t;qtlwXRf zo$r59D7bv1^7PViX8Nd%UU|2kV9d8b;qbz*vmAv&wCS<@*XHSuB4GBIlO^o%)@9cI187%5@{=R)2NVOh0E@}6*N7=LyRjVl6(xW&TH zl=&+X7R>Ir4*fKg zm_MFWCiTQ_<=#O|v;gBr5$+r}q8x*I;lti~wp#%|kWxGG49rS`2nIc*T3oFGdn__c zy0g&gLAA4VUF%&jcb-~)m;mL=8-R5%B)%)Y%Z{~7D6%uliia?(4l8Q@uwwqqSl1r< zmb?H_W+@+CZkJxG(hh7`|xe}r`+XBEL*qzrXRwMxk z02MUtVN7+rsT10M&!O6>x{6v8j1&%>8(_+v@hPhQnnMlK@_yj1?w4I>H4<4Mkw*!Q z{^9#F5ow{nk8Mpb3j?MBfxE8%vNHm5V|8DSJLUXr{=q$A#W*n5qA&IQ_trR$$5mb< z&}lx6t5(4J!CT@tjEBH>IJYzi|NV{sW|q;!4y$?{>MuW7sY9KH5`SXXzK z3ay8<>^@=SAuWSw#T0=yJ6l9^YBF3+LOgMmOIgdk|MYH-8Kce2#n=0{y`WnizXT9s@e}AWjQGwlrIlxU+TC{cRv855sTOWyk z68}Xf`Bpnt4Q~q@Ec-bmcuL|C2B`sYRE$eQ;!<;*El(?NY%Lx0{_-)+rRgJ6WJZb% z-g!c4L+g9CKGICRIKq(92_yCW*m9@0KVx5er`zwG_VR}puOTh{DD-XpVuYVWa*`+d zvPb<0Bs8K1|Gi5j8P$MwwB+=o7k+m7*1vhtQ+%VQlo>~JPi^JTbWGMAu z$e(%7OzStdUr)o2^#-1P-Dzq{&yUaiZ~tO+Z+|dKW$}P)^)NB;h*b5izxs>O_iL~U z4$h2~5^)kI_q)?4OF9eK(=PPuz-dcH8; z4r5-*ZxypUX-?ABU&Y=l;$o4rxUBzYSpNW|Oi|A@{hd}y-EOCK;FCE9b8MOM-5K9a zA9LJ0BggxAc$c!1$j2TYO+vu&1WZAQsPw@{W z=s~r*0;@r#(9P;w@_C2G(M51aJ?5OkH3^DC!Cf(@ce2gx#vxE;l{RqmckR)NLw{mz zO4T)+4+FCNo$*~rBfkHHY=<&Bsf}bE8>Wg+?0Bj0X{nRqB zGn|%L42B1pLZ5O>1yZoGNnAza$Z#q5nqdV}pQ6dW_Nkl(giHuwApZ^JzkdAJn11sA zfB*}B{`|V_`mF!|0%=I)pL9w-a|HiejW1`Il$puDA*>E3@^3e-m46q7GYzk_-NT(+ F_zxD5lGgwL literal 0 HcmV?d00001 diff --git a/src/seedsigner/views/psbt_views.py b/src/seedsigner/views/psbt_views.py index fc5b4763d..0e3e3576f 100644 --- a/src/seedsigner/views/psbt_views.py +++ b/src/seedsigner/views/psbt_views.py @@ -21,7 +21,7 @@ class PSBTSelectSeedView(View): - SCAN_SEED = ("Scan a seed", FontAwesomeIconConstants.QRCODE) + SCAN_SEED = ("Scan a seed", SeedSignerIconConstants.QRCODE) TYPE_12WORD = ("Enter 12-word seed", FontAwesomeIconConstants.KEYBOARD) TYPE_24WORD = ("Enter 24-word seed", FontAwesomeIconConstants.KEYBOARD) button_data = [] @@ -41,7 +41,7 @@ def run(self): # Doesn't look like this seed can sign the current PSBT button_str += " (?)" - self.button_data.append((button_str, SeedSignerCustomIconConstants.FINGERPRINT, "blue")) + self.button_data.append((button_str, SeedSignerIconConstants.FINGERPRINT, "blue")) self.button_data.append(self.SCAN_SEED) self.button_data.append(self.TYPE_12WORD) @@ -531,7 +531,7 @@ def run(self): # Just a WarningScreen here; only use DireWarningScreen for true security risks. selected_menu_num = WarningScreen( title="PSBT Error", - status_icon_name=SeedSignerCustomIconConstants.CIRCLE_EXCLAMATION, + status_icon_name=SeedSignerIconConstants.WARNING, status_headline="Signing Failed", text="Signing with this seed did not add a valid signature.", button_data=["Select Diff Seed"], diff --git a/src/seedsigner/views/seed_views.py b/src/seedsigner/views/seed_views.py index 41491d47d..28781ae19 100644 --- a/src/seedsigner/views/seed_views.py +++ b/src/seedsigner/views/seed_views.py @@ -49,7 +49,7 @@ def run(self): button_data = [] for seed in self.seeds: - button_data.append((seed["fingerprint"], SeedSignerCustomIconConstants.FINGERPRINT, "blue")) + button_data.append((seed["fingerprint"], SeedSignerIconConstants.FINGERPRINT, "blue")) button_data.append("Load a seed") selected_menu_num = self.run_screen( @@ -74,10 +74,10 @@ def run(self): Loading seeds, passphrases, etc ****************************************************************************""" class LoadSeedView(View): - SEED_QR = (" Scan a SeedQR", FontAwesomeIconConstants.QRCODE) + SEED_QR = (" Scan a SeedQR", SeedSignerIconConstants.QRCODE) TYPE_12WORD = ("Enter 12-word seed", FontAwesomeIconConstants.KEYBOARD) TYPE_24WORD = ("Enter 24-word seed", FontAwesomeIconConstants.KEYBOARD) - CREATE = (" Create a seed", FontAwesomeIconConstants.PLUS) + CREATE = (" Create a seed", SeedSignerIconConstants.PLUS) def run(self): button_data = [ @@ -340,11 +340,11 @@ def run(self): Views for actions on individual seeds: ****************************************************************************""" class SeedOptionsView(View): - SCAN_PSBT = ("Scan PSBT", FontAwesomeIconConstants.QRCODE) + SCAN_PSBT = ("Scan PSBT", SeedSignerIconConstants.QRCODE) VERIFY_ADDRESS = "Verify Addr" EXPORT_XPUB = "Export Xpub" EXPLORER = "Address Explorer" - BACKUP = ("Backup Seed", None, None, None, SeedSignerCustomIconConstants.SMALL_CHEVRON_RIGHT) + BACKUP = ("Backup Seed", None, None, None, SeedSignerIconConstants.CHEVRON_RIGHT) BIP85_CHILD_SEED = "BIP-85 Child Seed" DISCARD = ("Discard Seed", None, None, "red") @@ -1354,7 +1354,7 @@ def __init__(self, seed_num: int): def run(self): - SCAN = ("Confirm SeedQR", FontAwesomeIconConstants.QRCODE) + SCAN = ("Confirm SeedQR", SeedSignerIconConstants.QRCODE) DONE = "Done" button_data = [SCAN, DONE] @@ -1529,7 +1529,7 @@ class SeedSingleSigAddressVerificationSelectSeedView(View): def run(self): seeds = self.controller.storage.seeds - SCAN_SEED = ("Scan a seed", FontAwesomeIconConstants.QRCODE) + SCAN_SEED = ("Scan a seed", SeedSignerIconConstants.QRCODE) TYPE_12WORD = ("Enter 12-word seed", FontAwesomeIconConstants.KEYBOARD) TYPE_24WORD = ("Enter 24-word seed", FontAwesomeIconConstants.KEYBOARD) button_data = [] @@ -1538,7 +1538,7 @@ def run(self): for seed in seeds: button_str = seed.get_fingerprint(self.settings.get_value(SettingsConstants.SETTING__NETWORK)) - button_data.append((button_str, SeedSignerCustomIconConstants.FINGERPRINT, "blue")) + button_data.append((button_str, SeedSignerIconConstants.FINGERPRINT, "blue")) text = "Select seed to verify" button_data.append(SCAN_SEED) @@ -1784,7 +1784,7 @@ def run(self): class LoadMultisigWalletDescriptorView(View): def run(self): - SCAN = ("Scan Descriptor", FontAwesomeIconConstants.QRCODE) + SCAN = ("Scan Descriptor", SeedSignerIconConstants.QRCODE) CANCEL = "Cancel" button_data = [SCAN, CANCEL] selected_menu_num = seed_screens.LoadMultisigWalletDescriptorScreen( diff --git a/src/seedsigner/views/settings_views.py b/src/seedsigner/views/settings_views.py index bc02281b2..b3f6275bc 100644 --- a/src/seedsigner/views/settings_views.py +++ b/src/seedsigner/views/settings_views.py @@ -40,7 +40,7 @@ def run(self): title = "Settings" # Set up the next nested level of menuing - button_data.append(("Advanced", None, None, None, SeedSignerCustomIconConstants.SMALL_CHEVRON_RIGHT)) + button_data.append(("Advanced", None, None, None, SeedSignerIconConstants.CHEVRON_RIGHT)) next_destination = Destination(SettingsMenuView, view_args={"visibility": SettingsConstants.VISIBILITY__ADVANCED}) button_data.append(self.IO_TEST) @@ -50,7 +50,7 @@ def run(self): title = "Advanced" # So far there are no real Developer options; disabling for now - # button_data.append(("Developer Options", None, None, None, SeedSignerCustomIconConstants.SMALL_CHEVRON_RIGHT)) + # button_data.append(("Developer Options", None, None, None, SeedSignerIconConstants.CHEVRON_RIGHT)) # next_destination = Destination(SettingsMenuView, view_args={"visibility": SettingsConstants.VISIBILITY__DEVELOPER}) next_destination = None diff --git a/src/seedsigner/views/tools_views.py b/src/seedsigner/views/tools_views.py index 6cd0c0bd0..af53c1065 100644 --- a/src/seedsigner/views/tools_views.py +++ b/src/seedsigner/views/tools_views.py @@ -425,8 +425,8 @@ def run(self): Address Explorer Views ****************************************************************************""" class ToolsAddressExplorerSelectSourceView(View): - SCAN_SEED = ("Scan a seed", FontAwesomeIconConstants.QRCODE) - SCAN_DESCRIPTOR = ("Scan wallet descriptor", FontAwesomeIconConstants.QRCODE) + SCAN_SEED = ("Scan a seed", SeedSignerIconConstants.QRCODE) + SCAN_DESCRIPTOR = ("Scan wallet descriptor", SeedSignerIconConstants.QRCODE) TYPE_12WORD = ("Enter 12-word seed", FontAwesomeIconConstants.KEYBOARD) TYPE_24WORD = ("Enter 24-word seed", FontAwesomeIconConstants.KEYBOARD) @@ -436,7 +436,7 @@ def run(self): button_data = [] for seed in seeds: button_str = seed.get_fingerprint(self.settings.get_value(SettingsConstants.SETTING__NETWORK)) - button_data.append((button_str, SeedSignerCustomIconConstants.FINGERPRINT, "blue")) + button_data.append((button_str, SeedSignerIconConstants.FINGERPRINT, "blue")) button_data = button_data + [self.SCAN_SEED, self.SCAN_DESCRIPTOR, self.TYPE_12WORD, self.TYPE_24WORD] selected_menu_num = self.run_screen( @@ -630,7 +630,7 @@ def run(self): end_digits = -4 button_data.append(f"{cur_index}:{address[:8]}...{address[end_digits:]}") - button_data.append(("Next {}".format(addrs_per_screen), None, None, None, SeedSignerCustomIconConstants.SMALL_CHEVRON_RIGHT)) + button_data.append(("Next {}".format(addrs_per_screen), None, None, None, SeedSignerIconConstants.CHEVRON_RIGHT)) selected_menu_num = self.run_screen( ButtonListScreen, diff --git a/src/seedsigner/views/view.py b/src/seedsigner/views/view.py index de4bac713..57cdeace1 100644 --- a/src/seedsigner/views/view.py +++ b/src/seedsigner/views/view.py @@ -137,10 +137,10 @@ def __ne__(self, obj): # ######################################################################################### class MainMenuView(View): - SCAN = ("Scan", FontAwesomeIconConstants.QRCODE) - SEEDS = ("Seeds", FontAwesomeIconConstants.KEY) - TOOLS = ("Tools", FontAwesomeIconConstants.SCREWDRIVER_WRENCH) - SETTINGS = ("Settings", FontAwesomeIconConstants.GEAR) + SCAN = ("Scan", SeedSignerIconConstants.SCAN) + SEEDS = ("Seeds", SeedSignerIconConstants.SEEDS) + TOOLS = ("Tools", SeedSignerIconConstants.TOOLS) + SETTINGS = ("Settings", SeedSignerIconConstants.SETTINGS) def run(self): button_data = [self.SCAN, self.SEEDS, self.TOOLS, self.SETTINGS] @@ -176,7 +176,7 @@ def run(self): class PowerOptionsView(View): RESET = ("Restart", FontAwesomeIconConstants.ROTATE_RIGHT) - POWER_OFF = ("Power Off", FontAwesomeIconConstants.POWER_OFF) + POWER_OFF = ("Power Off", SeedSignerIconConstants.POWER) def run(self): button_data = [self.RESET, self.POWER_OFF] diff --git a/tests/screenshot_generator/README.md b/tests/screenshot_generator/README.md new file mode 100644 index 000000000..b4ccb83b5 --- /dev/null +++ b/tests/screenshot_generator/README.md @@ -0,0 +1,8 @@ +# Screenshot Generator + +From the project root, run: +``` +pytest tests/screenshot_generator/generator.py --locale en +``` + +By default it writes the screenshots to a dir that's parallel to the project root: `seedsigner-screenshots/`. diff --git a/tests/screenshot_generator/__init__.py b/tests/screenshot_generator/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/screenshot_generator/conftest.py b/tests/screenshot_generator/conftest.py new file mode 100644 index 000000000..43f690b84 --- /dev/null +++ b/tests/screenshot_generator/conftest.py @@ -0,0 +1,11 @@ +import pytest + + + +def pytest_addoption(parser): + parser.addoption("--locale", action="store", default=None) + + +@pytest.fixture(scope='session') +def target_locale(request): + return request.config.option.locale diff --git a/tests/screenshot_generator/generator.py b/tests/screenshot_generator/generator.py new file mode 100644 index 000000000..0315ab16e --- /dev/null +++ b/tests/screenshot_generator/generator.py @@ -0,0 +1,221 @@ +import embit +import os +import pathlib +import pytest +from mock import Mock, patch + +from seedsigner.controller import Controller +from seedsigner.gui.renderer import Renderer +from seedsigner.hardware.buttons import HardwareButtons +from seedsigner.hardware.camera import Camera +from seedsigner.models.decode_qr import DecodeQR +from seedsigner.models.qr_type import QRType +from seedsigner.models.seed import Seed +from seedsigner.models.settings import Settings +from seedsigner.models.settings_definition import SettingsConstants, SettingsDefinition +from seedsigner.views import (main_menu_views, psbt_views, scan_views, seed_views, + settings_views, tools_views) +from seedsigner.views.view import View + +from .utils import ScreenshotComplete, ScreenshotRenderer + + + +def test_generate_screenshots(target_locale): + """ + The `Renderer` class is mocked so that calls in the normal code are ignored + (necessary to avoid having it trying to wire up hardware dependencies). + + When the `Renderer` instance is needed, we patch in our own test-only + `ScreenshotRenderer`. + """ + # Disable hardware dependencies by essentially wiping out this class + HardwareButtons.get_instance = Mock() + Camera.get_instance = Mock() + + # Prep the ScreenshotRenderer that will be patched over the normal Renderer + screenshot_root = "/Users/kdmukai/dev/seedsigner-screenshots" + ScreenshotRenderer.configure_instance() + screenshot_renderer: ScreenshotRenderer = ScreenshotRenderer.get_instance() + + # Replace the core `Singleton` calls so that only our ScreenshotRenderer is used. + Renderer.configure_instance = Mock() + Renderer.get_instance = Mock(return_value=screenshot_renderer) + + controller = Controller.get_instance() + + # Set up some test data that we'll need in the `Controller` for certain Views + mnemonic_12 = "forum undo fragile fade shy sign arrest garment culture tube off merit".split() + mnemonic_24 = "attack pizza motion avocado network gather crop fresh patrol unusual wild holiday candy pony ranch winter theme error hybrid van cereal salon goddess expire".split() + mnemonic_12b = ["abandon"] * 11 + ["about"] + seed_12 = Seed(mnemonic=mnemonic_12, passphrase="cap*BRACKET3stove", wordlist_language_code=SettingsConstants.WORDLIST_LANGUAGE__ENGLISH) + seed_12b = Seed(mnemonic=mnemonic_12b, wordlist_language_code=SettingsConstants.WORDLIST_LANGUAGE__ENGLISH) + seed_24 = Seed(mnemonic=mnemonic_24, passphrase="some-PASS*phrase9", wordlist_language_code=SettingsConstants.WORDLIST_LANGUAGE__ENGLISH) + controller.storage.seeds.append(seed_12) + controller.storage.seeds.append(seed_12b) + controller.storage.set_pending_seed(seed_24) + + # Load a PSBT into memory + BASE64_PSBT_1 = """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""" + decoder = DecodeQR() + decoder.add_data(BASE64_PSBT_1) + controller.psbt = decoder.get_psbt() + controller.psbt_seed = seed_12b + + # Multisig wallet descriptor for the multisig in the above PSBT + MULTISIG_WALLET_DESCRIPTOR = """wsh(sortedmulti(1,[22bde1a9/48h/1h/0h/2h]tpubDFfsBrmpj226ZYiRszYi2qK6iGvh2vkkghfGB2YiRUVY4rqqedHCFEgw12FwDkm7rUoVtq9wLTKc6BN2sxswvQeQgp7m8st4FP8WtP8go76/{0,1}/*,[73c5da0a/48h/1h/0h/2h]tpubDFH9dgzveyD8zTbPUFuLrGmCydNvxehyNdUXKJAQN8x4aZ4j6UZqGfnqFrD4NqyaTVGKbvEW54tsvPTK2UoSbCC1PJY8iCNiwTL3RWZEheQ/{0,1}/*))#3jhtf6yx""" + controller.multisig_wallet_descriptor = embit.descriptor.Descriptor.from_string(MULTISIG_WALLET_DESCRIPTOR) + + # Parse the main `babel/messages.pot` for overall stats + messages_source_path = os.path.join(pathlib.Path(__file__).parent.resolve().parent.resolve().parent.resolve(), "babel", "messages.pot") + with open(messages_source_path, 'r') as messages_source_file: + num_source_messages = messages_source_file.read().count("msgid \"") - 1 + + def screencap_view(view_cls: View, view_name: str, view_args: dict={}): + screenshot_renderer.set_screenshot_filename(f"{view_name}.png") + try: + print(f"Running {view_name}") + view_cls(**view_args).run() + except ScreenshotComplete: + # Slightly hacky way to exit ScreenshotRenderer as expected + pass + print(f"Completed {view_name}") + except Exception as e: + # Something else went wrong + print(repr(e)) + raise e + + # Automatically populate all Settings options Views + settings_views_list = [] + settings_views_list.append(settings_views.SettingsMenuView) + for settings_entry in SettingsDefinition.settings_entries: + if settings_entry.visibility == SettingsConstants.VISIBILITY__HIDDEN: + continue + settings_views_list.append((settings_views.SettingsEntryUpdateSelectionView, dict(attr_name=settings_entry.attr_name), f"SettingsEntryUpdateSelectionView_{settings_entry.attr_name}")) + settings_views_list.append(settings_views.IOTestView) + settings_views_list.append(settings_views.DonateView) + + + screenshot_sections = { + "Main Menu Views": [ + main_menu_views.MainMenuView, + main_menu_views.PowerOffView, + (scan_views.SettingsUpdatedView, dict(config_name="Keith's Settings")), + ], + "Seed Views": [ + seed_views.SeedsMenuView, + seed_views.LoadSeedView, + seed_views.SeedMnemonicEntryView, + seed_views.SeedMnemonicInvalidView, + seed_views.SeedFinalizeView, + seed_views.SeedPassphraseWarningView, + seed_views.SeedAddPassphraseView, + seed_views.SeedReviewPassphraseView, + (seed_views.SeedOptionsView, dict(seed_num=0)), + (seed_views.SeedBackupView, dict(seed_num=0)), + (seed_views.SeedWordsWarningView, dict(seed_num=0)), + (seed_views.SeedWordsView, dict(seed_num=0)), + (seed_views.SeedWordsView, dict(seed_num=0, page_index=2), "SeedWordsView_2"), + (seed_views.SeedTranscribeSeedQRFormatView, dict(seed_num=0)), + (seed_views.SeedTranscribeSeedQRWarningView, dict(seed_num=0)), + (seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed_num=0, seedqr_format=QRType.SEED__SEEDQR, num_modules=25), "SeedTranscribeSeedQRWholeQRView_12_Standard"), + (seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed_num=0, seedqr_format=QRType.SEED__COMPACTSEEDQR, num_modules=21), "SeedTranscribeSeedQRWholeQRView_12_Compact"), + + # Screenshot doesn't render properly due to how the transparency mask is pre-rendered + # (seed_views.SeedTranscribeSeedQRZoomedInView, dict(seed_num=0, seedqr_format=QRType.SEED__SEEDQR)), + + (seed_views.SeedTranscribeSeedQRConfirmQRPromptView, dict(seed_num=0)), + + # Screenshot can't render live preview screens + # (seed_views.SeedTranscribeSeedQRConfirmScanView, dict(seed_num=0)), + + seed_views.LoadMultisigWalletDescriptorView, + seed_views.MultisigWalletDescriptorView, + ], + "PSBT Views": [ + psbt_views.PSBTSelectSeedView, + psbt_views.PSBTOverviewView, + psbt_views.PSBTUnsupportedScriptTypeWarningView, + psbt_views.PSBTNoChangeWarningView, + psbt_views.PSBTMathView, + (psbt_views.PSBTAddressDetailsView, dict(address_num=0)), + + # TODO: Render Multisig change w/ and w/out the multisig wallet descriptor onboard + (psbt_views.PSBTChangeDetailsView, dict(change_address_num=0)), + (psbt_views.PSBTAddressVerificationFailedView, dict(is_change=True, is_multisig=False), "PSBTAddressVerificationFailedView_singlesig_change"), + (psbt_views.PSBTAddressVerificationFailedView, dict(is_change=False, is_multisig=False), "PSBTAddressVerificationFailedView_singlesig_selftransfer"), + (psbt_views.PSBTAddressVerificationFailedView, dict(is_change=True, is_multisig=True), "PSBTAddressVerificationFailedView_multisig_change"), + (psbt_views.PSBTAddressVerificationFailedView, dict(is_change=False, is_multisig=True), "PSBTAddressVerificationFailedView_multisig_selftransfer"), + psbt_views.PSBTFinalizeView, + psbt_views.PSBTSelectCoordinatorView, + psbt_views.PSBTSigningErrorView, + ], + "Tools Views": [ + tools_views.ToolsMenuView, + tools_views.ToolsDiceEntropyMnemonicLengthView, + (tools_views.ToolsDiceEntropyEntryView, dict(total_rolls=50)), + ], + "Settings Views": settings_views_list, + } + + + locales = [] + if target_locale is None: + locales = SettingsConstants.ALL_LOCALES + else: + locales = [locale_tuple for locale_tuple in SettingsConstants.ALL_LOCALES if locale_tuple[0] == target_locale] + + if not locales: + raise Exception(f"Invalid locale: {target_locale}") + + for locale, display_name in locales: + Settings.get_instance().set_value(SettingsConstants.SETTING__LOCALE, value=locale) + screenshot_renderer.set_screenshot_path(os.path.join(screenshot_root, locale)) + + locale_readme = f"""# SeedSigner Screenshots: {display_name}\n""" + + # Report the translation progress + if locale != SettingsConstants.LOCALE__ENGLISH: + translated_messages_path = os.path.join(pathlib.Path(__file__).parent.resolve().parent.resolve().parent.resolve(), "src", "seedsigner", "resources", "babel", locale, "LC_MESSAGES", "messages.po") + with open(translated_messages_path, 'r') as translation_file: + locale_translations = translation_file.read() + num_locale_translations = locale_translations.count("msgid \"") - locale_translations.count("""msgstr ""\n\n""") - 1 + + locale_readme += f"## Translation progress: {num_locale_translations / num_source_messages:.1%}\n\n" + locale_readme += "---\n\n" + + for section_name, screenshot_list in screenshot_sections.items(): + locale_readme += "\n\n---\n\n" + locale_readme += f"## {section_name}\n\n" + locale_readme += """""" + locale_readme += f"""
""" + for screenshot in screenshot_list: + if type(screenshot) == tuple: + if len(screenshot) == 2: + view_cls, view_args = screenshot + view_name = view_cls.__name__ + elif len(screenshot) == 3: + view_cls, view_args, view_name = screenshot + else: + view_cls = screenshot + view_args = {} + view_name = view_cls.__name__ + + screencap_view(view_cls, view_name, view_args) + locale_readme += """""" + locale_readme += f"""""" + locale_readme += """
{view_name}

""" + + locale_readme += "
" + + with open(os.path.join(screenshot_renderer.screenshot_path, "README.md"), 'w') as readme_file: + readme_file.write(locale_readme) + + # Write the main README; ensure it writes all locales, not just the one that may + # have been specified for this run. + main_readme = """# SeedSigner Screenshots \n\n""" + for locale, display_name in SettingsConstants.ALL_LOCALES: + main_readme += f"* [{display_name}]({locale}/README.md)\n" + + with open(os.path.join(screenshot_root, "README.md"), 'w') as readme_file: + readme_file.write(main_readme) diff --git a/tests/screenshot_generator/utils.py b/tests/screenshot_generator/utils.py new file mode 100644 index 000000000..26d232a46 --- /dev/null +++ b/tests/screenshot_generator/utils.py @@ -0,0 +1,53 @@ +import os +from PIL import Image, ImageDraw +from seedsigner.gui.renderer import Renderer + + +class ScreenshotComplete(Exception): + pass + + +class ScreenshotRenderer(Renderer): + screenshot_path: str = None + screenshot_filename: str = None + + @classmethod + def configure_instance(cls): + # Instantiate the one and only Renderer instance + renderer = cls.__new__(cls) + cls._instance = renderer + + # Hard-coding output values for now + renderer.canvas_width = 240 + renderer.canvas_height = 240 + + renderer.canvas = Image.new('RGB', (renderer.canvas_width, renderer.canvas_height)) + renderer.draw = ImageDraw.Draw(renderer.canvas) + + + def set_screenshot_filename(self, filename:str): + self.screenshot_filename = filename + + + def set_screenshot_path(self, path): + if not os.path.exists(path): + os.makedirs(path) + self.screenshot_path = path + + + def show_image(self, image=None, alpha_overlay=None, is_background_thread: bool = False): + if is_background_thread: + return + + if alpha_overlay: + if image == None: + image = self.canvas + image = Image.alpha_composite(image, alpha_overlay) + + if image: + # Always write to the current canvas, rather than trying to replace it + self.canvas.paste(image) + + self.canvas.save(os.path.join(self.screenshot_path, self.screenshot_filename)) + raise ScreenshotComplete() + From 78683e727187c909a28cef6ba7179721b7ab5f16 Mon Sep 17 00:00:00 2001 From: Easy <86452817+easyuxd@users.noreply.github.com> Date: Thu, 3 Aug 2023 21:16:32 -0700 Subject: [PATCH 02/24] SeedSignerIconConstants --- src/seedsigner/gui/components.py | 2 +- src/seedsigner/gui/screens/psbt_screens.py | 2 +- src/seedsigner/gui/screens/screen.py | 2 +- src/seedsigner/gui/screens/seed_screens.py | 2 +- src/seedsigner/gui/screens/tools_screens.py | 2 +- src/seedsigner/views/psbt_views.py | 2 +- src/seedsigner/views/seed_views.py | 2 +- src/seedsigner/views/settings_views.py | 2 +- src/seedsigner/views/tools_views.py | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/seedsigner/gui/components.py b/src/seedsigner/gui/components.py index 340923187..cef7ab88e 100644 --- a/src/seedsigner/gui/components.py +++ b/src/seedsigner/gui/components.py @@ -441,7 +441,7 @@ class Icon(BaseComponent): def __post_init__(self): super().__post_init__() - if SeedSignerCustomIconConstants.MIN_VALUE <= self.icon_name and self.icon_name <= SeedSignerCustomIconConstants.MAX_VALUE: + if SeedSignerIconConstants.MIN_VALUE <= self.icon_name and self.icon_name <= SeedSignerIconConstants.MAX_VALUE: self.icon_font = Fonts.get_font(GUIConstants.ICON_FONT_NAME__SEEDSIGNER, self.icon_size, file_extension="otf") else: self.icon_font = Fonts.get_font(GUIConstants.ICON_FONT_NAME__FONT_AWESOME, self.icon_size, file_extension="otf") diff --git a/src/seedsigner/gui/screens/psbt_screens.py b/src/seedsigner/gui/screens/psbt_screens.py index ad378fc39..be495e1b7 100644 --- a/src/seedsigner/gui/screens/psbt_screens.py +++ b/src/seedsigner/gui/screens/psbt_screens.py @@ -7,7 +7,7 @@ from seedsigner.models.threads import BaseThread from .screen import ButtonListScreen, WarningScreen -from ..components import (BtcAmount, Button, Icon, FontAwesomeIconConstants, IconTextLine, FormattedAddress, GUIConstants, Fonts, SeedSignerCustomIconConstants, TextArea, +from ..components import (BtcAmount, Button, Icon, FontAwesomeIconConstants, IconTextLine, FormattedAddress, GUIConstants, Fonts, SeedSignerIconConstants, TextArea, calc_bezier_curve, linear_interp) diff --git a/src/seedsigner/gui/screens/screen.py b/src/seedsigner/gui/screens/screen.py index 0e3ea6516..447a40c15 100644 --- a/src/seedsigner/gui/screens/screen.py +++ b/src/seedsigner/gui/screens/screen.py @@ -11,7 +11,7 @@ from seedsigner.models.settings import SettingsConstants from ..components import (FontAwesomeIconConstants, GUIConstants, BaseComponent, Button, Icon, IconButton, - LargeIconButton, SeedSignerCustomIconConstants, TopNav, TextArea, load_image, ToastOverlay, + LargeIconButton, SeedSignerIconConstants, TopNav, TextArea, load_image, ToastOverlay, Fonts) from seedsigner.hardware.buttons import HardwareButtonsConstants, HardwareButtons diff --git a/src/seedsigner/gui/screens/seed_screens.py b/src/seedsigner/gui/screens/seed_screens.py index 3e4213eba..e1f53c0cc 100644 --- a/src/seedsigner/gui/screens/seed_screens.py +++ b/src/seedsigner/gui/screens/seed_screens.py @@ -15,7 +15,7 @@ from .screen import RET_CODE__BACK_BUTTON, BaseScreen, BaseTopNavScreen, ButtonListScreen, KeyboardScreen, WarningEdgesMixin from ..components import (Button, FontAwesomeIconConstants, Fonts, FormattedAddress, IconButton, - IconTextLine, SeedSignerCustomIconConstants, TextArea, GUIConstants, + IconTextLine, SeedSignerIconConstants, TextArea, GUIConstants, calc_text_centering) from seedsigner.gui.keyboard import Keyboard, TextEntryDisplay diff --git a/src/seedsigner/gui/screens/tools_screens.py b/src/seedsigner/gui/screens/tools_screens.py index e27e49493..680bdd71d 100644 --- a/src/seedsigner/gui/screens/tools_screens.py +++ b/src/seedsigner/gui/screens/tools_screens.py @@ -3,7 +3,7 @@ from PIL.Image import Image from seedsigner.gui.keyboard import Keyboard, TextEntryDisplay from seedsigner.hardware.camera import Camera -from seedsigner.gui.components import FontAwesomeIconConstants, Fonts, FormattedAddress, GUIConstants, IconTextLine, SeedSignerCustomIconConstants, TextArea +from seedsigner.gui.components import FontAwesomeIconConstants, Fonts, FormattedAddress, GUIConstants, IconTextLine, SeedSignerIconConstants, TextArea from seedsigner.gui.screens.screen import RET_CODE__BACK_BUTTON, BaseScreen, BaseTopNavScreen, ButtonListScreen, KeyboardScreen from seedsigner.hardware.buttons import HardwareButtonsConstants diff --git a/src/seedsigner/views/psbt_views.py b/src/seedsigner/views/psbt_views.py index 0e3e3576f..4dc39cef7 100644 --- a/src/seedsigner/views/psbt_views.py +++ b/src/seedsigner/views/psbt_views.py @@ -6,7 +6,7 @@ from embit.networks import NETWORKS from seedsigner.controller import Controller -from seedsigner.gui.components import FontAwesomeIconConstants, SeedSignerCustomIconConstants +from seedsigner.gui.components import FontAwesomeIconConstants, SeedSignerIconConstants from seedsigner.models.encode_qr import EncodeQR from seedsigner.models.psbt_parser import PSBTParser from seedsigner.models.qr_type import QRType diff --git a/src/seedsigner/views/seed_views.py b/src/seedsigner/views/seed_views.py index 28781ae19..772bec73b 100644 --- a/src/seedsigner/views/seed_views.py +++ b/src/seedsigner/views/seed_views.py @@ -9,7 +9,7 @@ from typing import List from seedsigner.controller import Controller -from seedsigner.gui.components import FontAwesomeIconConstants, SeedSignerCustomIconConstants +from seedsigner.gui.components import FontAwesomeIconConstants, SeedSignerIconConstants from seedsigner.helpers import embit_utils from seedsigner.gui.screens import (RET_CODE__BACK_BUTTON, ButtonListScreen, WarningScreen, DireWarningScreen, seed_screens) diff --git a/src/seedsigner/views/settings_views.py b/src/seedsigner/views/settings_views.py index b3f6275bc..ca9c36dcf 100644 --- a/src/seedsigner/views/settings_views.py +++ b/src/seedsigner/views/settings_views.py @@ -1,5 +1,5 @@ import logging -from seedsigner.gui.components import SeedSignerCustomIconConstants +from seedsigner.gui.components import SeedSignerIconConstants from .view import View, Destination, MainMenuView diff --git a/src/seedsigner/views/tools_views.py b/src/seedsigner/views/tools_views.py index af53c1065..4b5ae56aa 100644 --- a/src/seedsigner/views/tools_views.py +++ b/src/seedsigner/views/tools_views.py @@ -8,7 +8,7 @@ from PIL.ImageOps import autocontrast from seedsigner.controller import Controller from seedsigner.hardware.camera import Camera -from seedsigner.gui.components import FontAwesomeIconConstants, GUIConstants, SeedSignerCustomIconConstants +from seedsigner.gui.components import FontAwesomeIconConstants, GUIConstants, SeedSignerIconConstants from seedsigner.gui.screens import (RET_CODE__BACK_BUTTON, ButtonListScreen) from seedsigner.gui.screens.tools_screens import ToolsCalcFinalWordDoneScreen, ToolsCalcFinalWordFinalizePromptScreen, ToolsCalcFinalWordScreen, ToolsCoinFlipEntryScreen, ToolsDiceEntropyEntryScreen, ToolsImageEntropyFinalImageScreen, ToolsImageEntropyLivePreviewScreen, ToolsAddressExplorerAddressTypeScreen from seedsigner.helpers import embit_utils, mnemonic_generation From 550f576d80c96e7c9e97d8e4d3f84209a95983c5 Mon Sep 17 00:00:00 2001 From: Easy <86452817+easyuxd@users.noreply.github.com> Date: Thu, 3 Aug 2023 21:23:25 -0700 Subject: [PATCH 03/24] Define SeedSignerIconConstants --- src/seedsigner/views/view.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/seedsigner/views/view.py b/src/seedsigner/views/view.py index 57cdeace1..dcf352fc2 100644 --- a/src/seedsigner/views/view.py +++ b/src/seedsigner/views/view.py @@ -2,6 +2,7 @@ from typing import Type from seedsigner.gui.components import FontAwesomeIconConstants +from seedsigner.gui.components import SeedSignerIconConstants from seedsigner.gui.screens import RET_CODE__POWER_BUTTON, RET_CODE__BACK_BUTTON from seedsigner.gui.screens.screen import BaseScreen, DireWarningScreen, LargeButtonScreen, PowerOffScreen, PowerOffNotRequiredScreen, ResetScreen, WarningScreen from seedsigner.models.threads import BaseThread From 5ffd5120431f99787a7da7e9338198dc2bad1973 Mon Sep 17 00:00:00 2001 From: Easy <86452817+easyuxd@users.noreply.github.com> Date: Thu, 3 Aug 2023 21:26:13 -0700 Subject: [PATCH 04/24] Update view.py --- src/seedsigner/views/view.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/seedsigner/views/view.py b/src/seedsigner/views/view.py index dcf352fc2..756147f53 100644 --- a/src/seedsigner/views/view.py +++ b/src/seedsigner/views/view.py @@ -1,8 +1,7 @@ from dataclasses import dataclass from typing import Type -from seedsigner.gui.components import FontAwesomeIconConstants -from seedsigner.gui.components import SeedSignerIconConstants +from seedsigner.gui.components import FontAwesomeIconConstants, SeedSignerIconConstants from seedsigner.gui.screens import RET_CODE__POWER_BUTTON, RET_CODE__BACK_BUTTON from seedsigner.gui.screens.screen import BaseScreen, DireWarningScreen, LargeButtonScreen, PowerOffScreen, PowerOffNotRequiredScreen, ResetScreen, WarningScreen from seedsigner.models.threads import BaseThread From 5c90e9e17ca3ea6a007bb68ef84ec411f60b3d28 Mon Sep 17 00:00:00 2001 From: Easy <86452817+easyuxd@users.noreply.github.com> Date: Thu, 3 Aug 2023 22:09:16 -0700 Subject: [PATCH 05/24] Update seedsigner-icons.otf --- .../resources/fonts/seedsigner-icons.otf | Bin 26948 -> 27056 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/seedsigner/resources/fonts/seedsigner-icons.otf b/src/seedsigner/resources/fonts/seedsigner-icons.otf index a54b4c59032b3c75e742d8fe2f85abec9f9f6b89..c21c964cb723ad51d6f641224b8becf131d7cfb2 100644 GIT binary patch delta 1722 zcmZXVQA-q26vxlHJI=(S^(Vfe@606_KumnnaEd1y)qFJ`_Pd1V*!@tHKhw zZuw$gpxGBUeNd{m@By)?uxp#IQ^I?y7?mctvIluEibpurk+zoB7}aA%eU0g+XtX{! zQ;mnu_??Z%AKuen1?RC|$FDB_xc~XSCH)zEAEZZ{Bi5lW-|y^g-k@*@$3&}Z=N3wT zbE|Wqio12wliEb!^pgY22RkC44tE^+akTfCb0T%}XY^yk#WTOozqnAm^z_<%`|Inc zZoa&A<92&*aJpCD*l#_mN$Em3rkNTP6tJ^G6ksT5nmbqanD<<1XAL*+tY}F=8hg2R zHZ8B3E&YP1BqZV%^SK>JQ%M?KR{&01$#R zmmp+aqR4e}g}fR`%G*^6?xMS*$!*UR@;$?Nm3@)8f92$RWJ!v)QSHnW+G?zno{}39 zK3cE~e0FTe1B<&2XT@FAJn%pO5N=+9AC+FP0FHYSW69<-a1TA8E9S6kriE>w2XtUy` zx=aAgXX1Q5TCytd1PwwwQbdY4>q~L=trQ3kI0Yns7W)o%+e9&8X#=#S(jhdj=jD$0 z`-FP7iF@P5kP-DNF}&r68=S7eA4OrKlgTLt(O{*cZ9Lhuvj zS5EaVBM;!>>5Q|0K2d~)DoV8!c{^lhlhAn1nRTb!SuKfv^S*G|kF{0S8t<}%RMYug zj9Eg0Ru)O|ZfUxR6P8uVA|!F@$0 e2E@}Jj<>Xieg7RYg?PlEM4&cMONmURFZvJNleV=0 delta 1583 zcmai!&r4KM6vxlZ_?lOW{UD{n(!xq7q`(LXtwlN#A*OkijFO0AQUVt(iWYB>oEhh- zGolpqV-;;?HkF%#iWbrzU<_@FT;#4rMfN72cKe=tM;%d!;hj0}ob%4T_jAuV&pvpj zrag779UZMyNMZ8PkyF87MQu&pERj)9bR`xHcCDs%;w=|5LEI8eL zW^c=zbKB0(c7M5efAW%luC)6_iR~Y>rJN7baAYJhBBdK9Nj@Q>k_u93)9rKm4Jj8= zX=RmiQHaEl@@W}Q+L8<*AUCNX78?Vp@pnbrtqFXT5z1qa={PC>vIV)3i({9x1Xf`W zuWdT*ZkN;UbQy^RA_SWQxmfb@D}TjWQj&)~%R8_qkcTaPA;y0cm0G_uojBke?@-R; zD=7o%2zG%i(q*xtEe6ujs5-3a_PTs-6`%!jGKR=dWJvLf587t2BeTsws8bKao)MrJ z$+2?rO@lrla+prP+h^ol$bZ0JvTh_Q70*KZ1uRv;_#r4N#g@((E3oT4cGCPs|jQUf(g~sLH!V2gsEs>qA3t>Wb zRf2t7);byA4S6BZFDdT)R9Z`~IHoz&Ma+9fPl1g(9 zAvhmobQA$7c+*8oyWnbYn_<0}^8e=^Eo{@TR)WyldKW2)GK>>jBo9Zbv9Y3g+3U-6 zVxWMf>GbkoQ-pIu`NM>XqUVa5Ge(#;s1Y+ZSyI{9bU1JJ>S@fAn8=F<@4|D41YPqG Metr1Sc Date: Fri, 4 Aug 2023 10:01:23 -0700 Subject: [PATCH 06/24] jdlcdl's modified screenshot_generator --- src/seedsigner/gui/components.py | 4 +- tests/screenshot_generator/README.md | 4 +- tests/screenshot_generator/generator.py | 153 +++++++++++++----------- 3 files changed, 86 insertions(+), 75 deletions(-) diff --git a/src/seedsigner/gui/components.py b/src/seedsigner/gui/components.py index cef7ab88e..60d055e21 100644 --- a/src/seedsigner/gui/components.py +++ b/src/seedsigner/gui/components.py @@ -132,8 +132,8 @@ class SeedSignerIconConstants: MICROSD = "\ue91a" QRCODE = "\ue91b" - MIN_VALUE = BACK - MAX_VALUE = BITCOIN_ALT + MIN_VALUE = SCAN + MAX_VALUE = QRCODE diff --git a/tests/screenshot_generator/README.md b/tests/screenshot_generator/README.md index b4ccb83b5..cfb1048b7 100644 --- a/tests/screenshot_generator/README.md +++ b/tests/screenshot_generator/README.md @@ -2,7 +2,7 @@ From the project root, run: ``` -pytest tests/screenshot_generator/generator.py --locale en +pytest tests/screenshot_generator/generator.py ``` -By default it writes the screenshots to a dir that's parallel to the project root: `seedsigner-screenshots/`. +By default it writes the screenshots to a dir that's parallel to the project root: `seedsigner-screenshots`. diff --git a/tests/screenshot_generator/generator.py b/tests/screenshot_generator/generator.py index 0315ab16e..d6784dc0a 100644 --- a/tests/screenshot_generator/generator.py +++ b/tests/screenshot_generator/generator.py @@ -2,6 +2,7 @@ import os import pathlib import pytest +import shutil from mock import Mock, patch from seedsigner.controller import Controller @@ -13,8 +14,8 @@ from seedsigner.models.seed import Seed from seedsigner.models.settings import Settings from seedsigner.models.settings_definition import SettingsConstants, SettingsDefinition -from seedsigner.views import (main_menu_views, psbt_views, scan_views, seed_views, - settings_views, tools_views) +from seedsigner.views import (MainMenuView, PowerOptionsView, RestartView, NotYetImplementedView, UnhandledExceptionView, + psbt_views, scan_views, seed_views, settings_views, tools_views) from seedsigner.views.view import View from .utils import ScreenshotComplete, ScreenshotRenderer @@ -34,7 +35,7 @@ def test_generate_screenshots(target_locale): Camera.get_instance = Mock() # Prep the ScreenshotRenderer that will be patched over the normal Renderer - screenshot_root = "/Users/kdmukai/dev/seedsigner-screenshots" + screenshot_root = "/home/pi/seedsigner-screenshots" ScreenshotRenderer.configure_instance() screenshot_renderer: ScreenshotRenderer = ScreenshotRenderer.get_instance() @@ -54,6 +55,7 @@ def test_generate_screenshots(target_locale): controller.storage.seeds.append(seed_12) controller.storage.seeds.append(seed_12b) controller.storage.set_pending_seed(seed_24) + UnhandledExceptionViewFood = ["IndexError", "line 1, in some_buggy_code.py", "list index out of range"] # Load a PSBT into memory BASE64_PSBT_1 = """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""" @@ -66,11 +68,6 @@ def test_generate_screenshots(target_locale): MULTISIG_WALLET_DESCRIPTOR = """wsh(sortedmulti(1,[22bde1a9/48h/1h/0h/2h]tpubDFfsBrmpj226ZYiRszYi2qK6iGvh2vkkghfGB2YiRUVY4rqqedHCFEgw12FwDkm7rUoVtq9wLTKc6BN2sxswvQeQgp7m8st4FP8WtP8go76/{0,1}/*,[73c5da0a/48h/1h/0h/2h]tpubDFH9dgzveyD8zTbPUFuLrGmCydNvxehyNdUXKJAQN8x4aZ4j6UZqGfnqFrD4NqyaTVGKbvEW54tsvPTK2UoSbCC1PJY8iCNiwTL3RWZEheQ/{0,1}/*))#3jhtf6yx""" controller.multisig_wallet_descriptor = embit.descriptor.Descriptor.from_string(MULTISIG_WALLET_DESCRIPTOR) - # Parse the main `babel/messages.pot` for overall stats - messages_source_path = os.path.join(pathlib.Path(__file__).parent.resolve().parent.resolve().parent.resolve(), "babel", "messages.pot") - with open(messages_source_path, 'r') as messages_source_file: - num_source_messages = messages_source_file.read().count("msgid \"") - 1 - def screencap_view(view_cls: View, view_name: str, view_args: dict={}): screenshot_renderer.set_screenshot_filename(f"{view_name}.png") try: @@ -88,9 +85,15 @@ def screencap_view(view_cls: View, view_name: str, view_args: dict={}): # Automatically populate all Settings options Views settings_views_list = [] settings_views_list.append(settings_views.SettingsMenuView) + # so we get a choice for transcribe seed qr format + controller.settings.set_value( + attr_name=SettingsConstants.SETTING__COMPACT_SEEDQR, + value=SettingsConstants.OPTION__ENABLED + ) for settings_entry in SettingsDefinition.settings_entries: if settings_entry.visibility == SettingsConstants.VISIBILITY__HIDDEN: continue + settings_views_list.append((settings_views.SettingsEntryUpdateSelectionView, dict(attr_name=settings_entry.attr_name), f"SettingsEntryUpdateSelectionView_{settings_entry.attr_name}")) settings_views_list.append(settings_views.IOTestView) settings_views_list.append(settings_views.DonateView) @@ -98,9 +101,14 @@ def screencap_view(view_cls: View, view_name: str, view_args: dict={}): screenshot_sections = { "Main Menu Views": [ - main_menu_views.MainMenuView, - main_menu_views.PowerOffView, - (scan_views.SettingsUpdatedView, dict(config_name="Keith's Settings")), + MainMenuView, + PowerOptionsView, + RestartView, + #PowerOffView # this test is too real; pi will power-off + NotYetImplementedView, + (UnhandledExceptionView, dict(error=UnhandledExceptionViewFood)), + (settings_views.SettingsIngestSettingsQRView, dict(data="settings::v1 name=factory_reset")) + ], "Seed Views": [ seed_views.SeedsMenuView, @@ -108,14 +116,28 @@ def screencap_view(view_cls: View, view_name: str, view_args: dict={}): seed_views.SeedMnemonicEntryView, seed_views.SeedMnemonicInvalidView, seed_views.SeedFinalizeView, - seed_views.SeedPassphraseWarningView, seed_views.SeedAddPassphraseView, seed_views.SeedReviewPassphraseView, + (seed_views.SeedOptionsView, dict(seed_num=0)), (seed_views.SeedBackupView, dict(seed_num=0)), + (seed_views.SeedExportXpubSigTypeView, dict(seed_num=0)), + (seed_views.SeedExportXpubScriptTypeView, dict(seed_num=0, sig_type="msig")), + (seed_views.SeedExportXpubCustomDerivationView, dict(seed_num=0, sig_type="ss", script_type="")), + (seed_views.SeedExportXpubCoordinatorView, dict(seed_num=0, sig_type="ss", script_type="nat")), + (seed_views.SeedExportXpubWarningView, dict(seed_num=0, sig_type="msig", script_type="nes", coordinator="spd", custom_derivation="")), + (seed_views.SeedExportXpubDetailsView, dict(seed_num=0, sig_type="ss", script_type="nat", coordinator="bw", custom_derivation="")), + #SeedExportXpubQRDisplayView, (seed_views.SeedWordsWarningView, dict(seed_num=0)), (seed_views.SeedWordsView, dict(seed_num=0)), (seed_views.SeedWordsView, dict(seed_num=0, page_index=2), "SeedWordsView_2"), + (seed_views.SeedBIP85ApplicationModeView, dict(seed_num=0)), + (seed_views.SeedBIP85SelectChildIndexView, dict(seed_num=0, num_words=24)), + (seed_views.SeedBIP85InvalidChildIndexView, dict(seed_num=0, num_words=12)), + (seed_views.SeedWordsBackupTestPromptView, dict(seed_num=0)), + (seed_views.SeedWordsBackupTestView, dict(seed_num=0)), + (seed_views.SeedWordsBackupTestMistakeView, dict(seed_num=0, cur_index=7, wrong_word="unlucky")), + (seed_views.SeedWordsBackupTestSuccessView, dict(seed_num=0)), (seed_views.SeedTranscribeSeedQRFormatView, dict(seed_num=0)), (seed_views.SeedTranscribeSeedQRWarningView, dict(seed_num=0)), (seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed_num=0, seedqr_format=QRType.SEED__SEEDQR, num_modules=25), "SeedTranscribeSeedQRWholeQRView_12_Standard"), @@ -129,8 +151,15 @@ def screencap_view(view_cls: View, view_name: str, view_args: dict={}): # Screenshot can't render live preview screens # (seed_views.SeedTranscribeSeedQRConfirmScanView, dict(seed_num=0)), + #(seed_views.AddressVerificationStartView, dict(address=, script_type="nat", network="M")), + #seed_views.AddressVerificationSigTypeView, + #seed_views.SeedSingleSigAddressVerificationSelectSeedView, + #seed_views.SeedAddressVerificationView, + #seed_views.AddressVerificationSuccessView, + seed_views.LoadMultisigWalletDescriptorView, seed_views.MultisigWalletDescriptorView, + (seed_views.SeedDiscardView, dict(seed_num=0)), ], "PSBT Views": [ psbt_views.PSBTSelectSeedView, @@ -147,75 +176,57 @@ def screencap_view(view_cls: View, view_name: str, view_args: dict={}): (psbt_views.PSBTAddressVerificationFailedView, dict(is_change=True, is_multisig=True), "PSBTAddressVerificationFailedView_multisig_change"), (psbt_views.PSBTAddressVerificationFailedView, dict(is_change=False, is_multisig=True), "PSBTAddressVerificationFailedView_multisig_selftransfer"), psbt_views.PSBTFinalizeView, - psbt_views.PSBTSelectCoordinatorView, + #PSBTSignedQRDisplayView psbt_views.PSBTSigningErrorView, ], "Tools Views": [ tools_views.ToolsMenuView, + #ToolsImageEntropyLivePreviewView + #ToolsImageEntropyFinalImageView + tools_views.ToolsImageEntropyMnemonicLengthView, tools_views.ToolsDiceEntropyMnemonicLengthView, (tools_views.ToolsDiceEntropyEntryView, dict(total_rolls=50)), + tools_views.ToolsCalcFinalWordNumWordsView, + tools_views.ToolsCalcFinalWordFinalizePromptView, + tools_views.ToolsCalcFinalWordCoinFlipsView, + #(tools_views.ToolsCalcFinalWordShowFinalWordView, dict(coin_flips=3)), + #tools_views.ToolsCalcFinalWordDoneView, + tools_views.ToolsAddressExplorerSelectSourceView, + tools_views.ToolsAddressExplorerAddressTypeView, + tools_views.ToolsAddressExplorerAddressListView, + #tools_views.ToolsAddressExplorerAddressView, ], "Settings Views": settings_views_list, } - locales = [] - if target_locale is None: - locales = SettingsConstants.ALL_LOCALES - else: - locales = [locale_tuple for locale_tuple in SettingsConstants.ALL_LOCALES if locale_tuple[0] == target_locale] - - if not locales: - raise Exception(f"Invalid locale: {target_locale}") - - for locale, display_name in locales: - Settings.get_instance().set_value(SettingsConstants.SETTING__LOCALE, value=locale) - screenshot_renderer.set_screenshot_path(os.path.join(screenshot_root, locale)) - - locale_readme = f"""# SeedSigner Screenshots: {display_name}\n""" - - # Report the translation progress - if locale != SettingsConstants.LOCALE__ENGLISH: - translated_messages_path = os.path.join(pathlib.Path(__file__).parent.resolve().parent.resolve().parent.resolve(), "src", "seedsigner", "resources", "babel", locale, "LC_MESSAGES", "messages.po") - with open(translated_messages_path, 'r') as translation_file: - locale_translations = translation_file.read() - num_locale_translations = locale_translations.count("msgid \"") - locale_translations.count("""msgstr ""\n\n""") - 1 - - locale_readme += f"## Translation progress: {num_locale_translations / num_source_messages:.1%}\n\n" - locale_readme += "---\n\n" - - for section_name, screenshot_list in screenshot_sections.items(): - locale_readme += "\n\n---\n\n" - locale_readme += f"## {section_name}\n\n" - locale_readme += """""" - locale_readme += f"""
""" - for screenshot in screenshot_list: - if type(screenshot) == tuple: - if len(screenshot) == 2: - view_cls, view_args = screenshot - view_name = view_cls.__name__ - elif len(screenshot) == 3: - view_cls, view_args, view_name = screenshot - else: - view_cls = screenshot - view_args = {} - view_name = view_cls.__name__ - - screencap_view(view_cls, view_name, view_args) - locale_readme += """""" - locale_readme += f"""""" - locale_readme += """
{view_name}

""" - - locale_readme += "
" + screenshot_renderer.set_screenshot_path(screenshot_root) - with open(os.path.join(screenshot_renderer.screenshot_path, "README.md"), 'w') as readme_file: - readme_file.write(locale_readme) + readme = f"""# SeedSigner Screenshots\n""" - # Write the main README; ensure it writes all locales, not just the one that may - # have been specified for this run. - main_readme = """# SeedSigner Screenshots \n\n""" - for locale, display_name in SettingsConstants.ALL_LOCALES: - main_readme += f"* [{display_name}]({locale}/README.md)\n" - - with open(os.path.join(screenshot_root, "README.md"), 'w') as readme_file: - readme_file.write(main_readme) + for section_name, screenshot_list in screenshot_sections.items(): + readme += "\n\n---\n\n" + readme += f"## {section_name}\n\n" + readme += """""" + readme += f"""
""" + for screenshot in screenshot_list: + if type(screenshot) == tuple: + if len(screenshot) == 2: + view_cls, view_args = screenshot + view_name = view_cls.__name__ + elif len(screenshot) == 3: + view_cls, view_args, view_name = screenshot + else: + view_cls = screenshot + view_args = {} + view_name = view_cls.__name__ + + screencap_view(view_cls, view_name, view_args) + readme += """""" + readme += f"""""" + readme += """
{view_name}

""" + + readme += "
" + + with open(os.path.join(screenshot_renderer.screenshot_path, "README.md"), 'w') as readme_file: + readme_file.write(readme) From f083d40657b385006ac2bf62022401bdc8afc30d Mon Sep 17 00:00:00 2001 From: Easy <86452817+easyuxd@users.noreply.github.com> Date: Fri, 4 Aug 2023 10:33:04 -0700 Subject: [PATCH 07/24] Update psbt_views.py --- src/seedsigner/views/psbt_views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/seedsigner/views/psbt_views.py b/src/seedsigner/views/psbt_views.py index 4dc39cef7..ed402768a 100644 --- a/src/seedsigner/views/psbt_views.py +++ b/src/seedsigner/views/psbt_views.py @@ -12,7 +12,7 @@ from seedsigner.models.qr_type import QRType from seedsigner.models.settings import SettingsConstants from seedsigner.gui.screens.psbt_screens import PSBTOverviewScreen, PSBTMathScreen, PSBTAddressDetailsScreen, PSBTChangeDetailsScreen, PSBTFinalizeScreen -from seedsigner.gui.screens.screen import (RET_CODE__BACK_BUTTON, ButtonListScreen, DireWarningScreen, QRDisplayScreen) +from seedsigner.gui.screens.screen import (RET_CODE__BACK_BUTTON, ButtonListScreen, WarningScreen, DireWarningScreen, QRDisplayScreen) from .view import BackStackView, MainMenuView, NotYetImplementedView, View, Destination From da5a7ef3e402887645e21fb5d1070c19cef2c6a5 Mon Sep 17 00:00:00 2001 From: Easy <86452817+easyuxd@users.noreply.github.com> Date: Fri, 4 Aug 2023 17:41:40 -0700 Subject: [PATCH 08/24] Icon tweaks, Large button size --- src/seedsigner/gui/components.py | 2 +- .../resources/fonts/seedsigner-icons.otf | Bin 27056 -> 27828 bytes tests/screenshot_generator/generator.py | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/seedsigner/gui/components.py b/src/seedsigner/gui/components.py index 60d055e21..4a3f36058 100644 --- a/src/seedsigner/gui/components.py +++ b/src/seedsigner/gui/components.py @@ -31,7 +31,7 @@ class GUIConstants: ICON_FONT_NAME__SEEDSIGNER = "seedsigner-icons" ICON_FONT_SIZE = 22 ICON_INLINE_FONT_SIZE = 24 - ICON_LARGE_BUTTON_SIZE = 36 + ICON_LARGE_BUTTON_SIZE = 48 ICON_PRIMARY_SCREEN_SIZE = 50 TOP_NAV_TITLE_FONT_NAME = "OpenSans-SemiBold" diff --git a/src/seedsigner/resources/fonts/seedsigner-icons.otf b/src/seedsigner/resources/fonts/seedsigner-icons.otf index c21c964cb723ad51d6f641224b8becf131d7cfb2..ef31dc41ffc2ad0a0070c5e5d4daf9404b1d5686 100644 GIT binary patch delta 4546 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 delta 3594 zcmZWsYm8OZ6<*hQ-3gQdEilS;pk;K1;{y|;5<{y^b!=nR81J6M8bv~lLo1GL)qsPZ zt2lx^MIEk`Hsb^1E1VNE(oz4Yv55&k{L%P2I_MyvV;OvbfXrM5SpB}W@8wR~5WchS z-fOS5_FCUwd(SJ|GcSLTS#(W4e~nC$g4D=)zwGFk_lu!?y-3|+k!6QEI`UUNv8ZvQ z$nsx_NbZWuF7J>tAj$Ic`W7u{t9fM_hJp2EuI&i{^sr_O^bh!DYcju*>&Ke_fLE;mHMqCPuDj09m$uD*5xu!HRVL6=Q2BH zNr^U(56>OlP_frQK@5V`Sbyq%RWjs3GUT zGuORVL0XeGj?#n7cP_ip=2U(}AGT^noJ1-fn}WDkWon#+o3K^dwB79IYH@B=8Fiu{ zs{1giheP7`P*rN_DB)0mUHpez8RO3pLRFf8YyHBxXhk+s{RkUU-R@lft;mjZz?lK` zcRBZhE%m4}m&?B5j#_CC-Uf&vLOYWK;|zBJ%vO-2(m*xZ^~=0OQ!>+azMwJ(Iq@Iw zSLSjR^auI}ie|ZNZ;L7emmGa@Gh7OZ`}ZPuEvLFpp9z`G>BF2wNw63xlj#^^BA=`v z(@SrgEbCcA$f!eKr6#^Ite1|*$wo_dcG}pEvB$xk;+nxN=MFcAs7UO+~kwb#c6t3Gw!}>P!tM74OU+R{r?xgN# zMglML_jaQPl|F!e7TmSPC^AwICx1}+iE|!%1|yYoG5sQv6~N`}6wAJ$<|#B)l|~s_ zBWJ-U1mTgRAR$(o>i+^w>S&Ne-P!2I;*$QQ{Y&8j*7XxumllBTbne+dsx;Hm*Umj> z_45dgAi2*@j_MB#D$5neDAhAxM;KHsN$5FI%W1IVuRz+PrjCJQ4_ozAj|NFEmT`E3 zP?bui&-ExXlLp4rs~)$EAEzG>2fv{qLbZ=c8y!wNRYJ5C)z2|6CsU~^eSryS4wCLI zIJ~Dg*R%OvE2~Ey)k@9}+txjf)99&bIY@R7#zXTEu`2*MAH5h^@%qC-44|eS!78ev z(kf@OR%9N~xVDd4`dOTK>|YicpQ7$^aZ#*l>2V;cESSv%8AmFvXVU{I5pru@caqe| zY4FLyJRb@?j<2hJOI-v8%1{HrseYMatgRrw$3Ei3qbIVQR*)sIjUpPKO|(V~-*Iw1 z;vWY8@!3H`N8)6;=L$D@KMou$>-Pn@edX;d(G>%@9p%toYJc5<3GSqQ}-|;DIuQT^_GN3J+4)$qX#=Oc8?u| z1K+|Alhmy|MkR*RO1-LdG<7dWDrXpVz^z9Tw8R#8^`FPtievOjGBT7IwAx0Pg$|6X z4gi|q+8{s&4q7PA36htn~j5vACga|l(*DmydfO&ww#x(jT;3wkF@2g7JXYX*7-dOQpCtDwAIN9f!lhO`-1 z029JTf_{pJh+PhNl;DDlmLh3(L_kLz4gx6pUD|z~ zVI6LbfZ;ScS3D~}2g%CC$j!cjJa;$WA~E`cIfdd+^UVFY#>YZdcrqZwO&*C{A!lKPd>dI*iZ^aobaC zCnK?hd=7$*-@6(I;C>u*To3*VD)$Zk^c{o}cg@Do3+sC<;JpD-UK1cN?!+UHNr?0` zGIz!pztvfEY`1(ai0`pJ>=C(TIP+5%ZN-z3c?368Mr`e(o(roIYvPX{OES44Bs6Yc zbg9sP)~z`)|L-{Yo83guEO`d)p1ndpg<*edA(LR0MTlhMD5RJ^SP(o;aoc-TIUT$8 zuS9S&>O-h}F4(Q!p;Ise8 Date: Fri, 4 Aug 2023 18:21:38 -0700 Subject: [PATCH 09/24] Fingerprint icon, color --- src/seedsigner/gui/screens/seed_screens.py | 2 ++ .../resources/fonts/seedsigner-icons.otf | Bin 27828 -> 27240 bytes src/seedsigner/views/psbt_views.py | 2 +- src/seedsigner/views/seed_views.py | 2 +- src/seedsigner/views/tools_views.py | 2 +- 5 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/seedsigner/gui/screens/seed_screens.py b/src/seedsigner/gui/screens/seed_screens.py index e1f53c0cc..b76b09a6e 100644 --- a/src/seedsigner/gui/screens/seed_screens.py +++ b/src/seedsigner/gui/screens/seed_screens.py @@ -595,6 +595,7 @@ def __post_init__(self): self.derivation_line = IconTextLine( icon_name=SeedSignerIconConstants.DERIVATION, + icon_color="blue", label_text="Derivation", value_text=self.derivation_path, screen_x=GUIConstants.COMPONENT_PADDING, @@ -604,6 +605,7 @@ def __post_init__(self): self.xpub_line = IconTextLine( icon_name=FontAwesomeIconConstants.X, + icon_color="blue", label_text="Xpub", value_text=f"{self.xpub[:18]}...", font_name=GUIConstants.FIXED_WIDTH_FONT_NAME, diff --git a/src/seedsigner/resources/fonts/seedsigner-icons.otf b/src/seedsigner/resources/fonts/seedsigner-icons.otf index ef31dc41ffc2ad0a0070c5e5d4daf9404b1d5686..5e480af0a83982eb6cde3c0bf63a54ff267e99e7 100644 GIT binary patch delta 2850 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 Sn& Date: Fri, 4 Aug 2023 18:26:56 -0700 Subject: [PATCH 10/24] Update seed_views.py --- src/seedsigner/views/seed_views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/seedsigner/views/seed_views.py b/src/seedsigner/views/seed_views.py index 7f127d9c8..cc11e4a9f 100644 --- a/src/seedsigner/views/seed_views.py +++ b/src/seedsigner/views/seed_views.py @@ -49,7 +49,7 @@ def run(self): button_data = [] for seed in self.seeds: - button_data.append((seed["fingerprint"], SeedSignerIconConstants.FINGERPRINT, "blue")) + button_data.append((seed["fingerprint"], SeedSignerIconConstants.FINGERPRINT)) button_data.append("Load a seed") selected_menu_num = self.run_screen( From 4bfbcab98e762079131532747c8b8cb7482f33b4 Mon Sep 17 00:00:00 2001 From: Easy <86452817+easyuxd@users.noreply.github.com> Date: Fri, 4 Aug 2023 18:33:20 -0700 Subject: [PATCH 11/24] Blue icon color --- src/seedsigner/gui/screens/psbt_screens.py | 2 +- src/seedsigner/gui/screens/seed_screens.py | 12 ++++++------ src/seedsigner/gui/screens/tools_screens.py | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/seedsigner/gui/screens/psbt_screens.py b/src/seedsigner/gui/screens/psbt_screens.py index be495e1b7..84022a479 100644 --- a/src/seedsigner/gui/screens/psbt_screens.py +++ b/src/seedsigner/gui/screens/psbt_screens.py @@ -656,7 +656,7 @@ def __post_init__(self): screen_y -= GUIConstants.COMPONENT_PADDING self.components.append(IconTextLine( icon_name=SeedSignerIconConstants.FINGERPRINT, - icon_color="blue", + icon_color="0084ff", value_text=f"""{"Multisig" if self.is_multisig else self.fingerprint}: {"Change" if self.is_change_derivation_path else "Addr"} #{self.derivation_path_addr_index}""", is_text_centered=False, screen_x=GUIConstants.EDGE_PADDING, diff --git a/src/seedsigner/gui/screens/seed_screens.py b/src/seedsigner/gui/screens/seed_screens.py index b76b09a6e..7e04a26ec 100644 --- a/src/seedsigner/gui/screens/seed_screens.py +++ b/src/seedsigner/gui/screens/seed_screens.py @@ -422,7 +422,7 @@ def __post_init__(self): self.fingerprint_icontl = IconTextLine( icon_name=SeedSignerIconConstants.FINGERPRINT, - icon_color="blue", + icon_color="0084ff", icon_size=GUIConstants.ICON_FONT_SIZE + 12, label_text="fingerprint", value_text=self.fingerprint, @@ -442,7 +442,7 @@ class SeedOptionsScreen(ButtonListScreen): def __post_init__(self): self.top_nav_icon_name = SeedSignerIconConstants.FINGERPRINT - self.top_nav_icon_color = "blue" + self.top_nav_icon_color = "0084ff" self.title = self.fingerprint self.is_button_text_centered = False self.is_bottom_list = True @@ -585,7 +585,7 @@ def __post_init__(self): # Set up the fingerprint and passphrase displays self.fingerprint_line = IconTextLine( icon_name=SeedSignerIconConstants.FINGERPRINT, - icon_color="blue", + icon_color="0084ff", label_text="Fingerprint", value_text=self.fingerprint, screen_x=GUIConstants.COMPONENT_PADDING, @@ -595,7 +595,7 @@ def __post_init__(self): self.derivation_line = IconTextLine( icon_name=SeedSignerIconConstants.DERIVATION, - icon_color="blue", + icon_color="0084ff", label_text="Derivation", value_text=self.derivation_path, screen_x=GUIConstants.COMPONENT_PADDING, @@ -605,7 +605,7 @@ def __post_init__(self): self.xpub_line = IconTextLine( icon_name=FontAwesomeIconConstants.X, - icon_color="blue", + icon_color="0084ff", label_text="Xpub", value_text=f"{self.xpub[:18]}...", font_name=GUIConstants.FIXED_WIDTH_FONT_NAME, @@ -1012,7 +1012,7 @@ def __post_init__(self): self.components.append(IconTextLine( icon_name=SeedSignerIconConstants.FINGERPRINT, - icon_color="blue", + icon_color="0084ff", label_text="changes fingerprint", value_text=f"{self.fingerprint_without} >> {self.fingerprint_with}", is_text_centered=True, diff --git a/src/seedsigner/gui/screens/tools_screens.py b/src/seedsigner/gui/screens/tools_screens.py index 680bdd71d..ad9611a35 100644 --- a/src/seedsigner/gui/screens/tools_screens.py +++ b/src/seedsigner/gui/screens/tools_screens.py @@ -363,7 +363,7 @@ def __post_init__(self): self.components.append(IconTextLine( icon_name=SeedSignerIconConstants.FINGERPRINT, - icon_color="blue", + icon_color="0084ff", label_text="fingerprint", value_text=self.fingerprint, is_text_centered=True, @@ -387,7 +387,7 @@ def __post_init__(self): if self.fingerprint: self.components.append(IconTextLine( icon_name=SeedSignerIconConstants.FINGERPRINT, - icon_color="blue", + icon_color="0084ff", label_text="Fingerprint", value_text=self.fingerprint, screen_x=GUIConstants.EDGE_PADDING, From 403b3866be8cd6c4babdcda7c9e3309b0ea79821 Mon Sep 17 00:00:00 2001 From: Easy <86452817+easyuxd@users.noreply.github.com> Date: Fri, 4 Aug 2023 18:42:29 -0700 Subject: [PATCH 12/24] Blue myself --- src/seedsigner/gui/screens/psbt_screens.py | 2 +- src/seedsigner/gui/screens/seed_screens.py | 12 ++++++------ src/seedsigner/gui/screens/tools_screens.py | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/seedsigner/gui/screens/psbt_screens.py b/src/seedsigner/gui/screens/psbt_screens.py index 84022a479..0a2cca3fc 100644 --- a/src/seedsigner/gui/screens/psbt_screens.py +++ b/src/seedsigner/gui/screens/psbt_screens.py @@ -656,7 +656,7 @@ def __post_init__(self): screen_y -= GUIConstants.COMPONENT_PADDING self.components.append(IconTextLine( icon_name=SeedSignerIconConstants.FINGERPRINT, - icon_color="0084ff", + icon_color="#0084ff", value_text=f"""{"Multisig" if self.is_multisig else self.fingerprint}: {"Change" if self.is_change_derivation_path else "Addr"} #{self.derivation_path_addr_index}""", is_text_centered=False, screen_x=GUIConstants.EDGE_PADDING, diff --git a/src/seedsigner/gui/screens/seed_screens.py b/src/seedsigner/gui/screens/seed_screens.py index 7e04a26ec..4c556a975 100644 --- a/src/seedsigner/gui/screens/seed_screens.py +++ b/src/seedsigner/gui/screens/seed_screens.py @@ -422,7 +422,7 @@ def __post_init__(self): self.fingerprint_icontl = IconTextLine( icon_name=SeedSignerIconConstants.FINGERPRINT, - icon_color="0084ff", + icon_color="#0084ff", icon_size=GUIConstants.ICON_FONT_SIZE + 12, label_text="fingerprint", value_text=self.fingerprint, @@ -442,7 +442,7 @@ class SeedOptionsScreen(ButtonListScreen): def __post_init__(self): self.top_nav_icon_name = SeedSignerIconConstants.FINGERPRINT - self.top_nav_icon_color = "0084ff" + self.top_nav_icon_color = "#0084ff" self.title = self.fingerprint self.is_button_text_centered = False self.is_bottom_list = True @@ -585,7 +585,7 @@ def __post_init__(self): # Set up the fingerprint and passphrase displays self.fingerprint_line = IconTextLine( icon_name=SeedSignerIconConstants.FINGERPRINT, - icon_color="0084ff", + icon_color="#0084ff", label_text="Fingerprint", value_text=self.fingerprint, screen_x=GUIConstants.COMPONENT_PADDING, @@ -595,7 +595,7 @@ def __post_init__(self): self.derivation_line = IconTextLine( icon_name=SeedSignerIconConstants.DERIVATION, - icon_color="0084ff", + icon_color="#0084ff", label_text="Derivation", value_text=self.derivation_path, screen_x=GUIConstants.COMPONENT_PADDING, @@ -605,7 +605,7 @@ def __post_init__(self): self.xpub_line = IconTextLine( icon_name=FontAwesomeIconConstants.X, - icon_color="0084ff", + icon_color="#0084ff", label_text="Xpub", value_text=f"{self.xpub[:18]}...", font_name=GUIConstants.FIXED_WIDTH_FONT_NAME, @@ -1012,7 +1012,7 @@ def __post_init__(self): self.components.append(IconTextLine( icon_name=SeedSignerIconConstants.FINGERPRINT, - icon_color="0084ff", + icon_color="#0084ff", label_text="changes fingerprint", value_text=f"{self.fingerprint_without} >> {self.fingerprint_with}", is_text_centered=True, diff --git a/src/seedsigner/gui/screens/tools_screens.py b/src/seedsigner/gui/screens/tools_screens.py index ad9611a35..1ac5f3337 100644 --- a/src/seedsigner/gui/screens/tools_screens.py +++ b/src/seedsigner/gui/screens/tools_screens.py @@ -363,7 +363,7 @@ def __post_init__(self): self.components.append(IconTextLine( icon_name=SeedSignerIconConstants.FINGERPRINT, - icon_color="0084ff", + icon_color="#0084ff", label_text="fingerprint", value_text=self.fingerprint, is_text_centered=True, @@ -387,7 +387,7 @@ def __post_init__(self): if self.fingerprint: self.components.append(IconTextLine( icon_name=SeedSignerIconConstants.FINGERPRINT, - icon_color="0084ff", + icon_color="#0084ff", label_text="Fingerprint", value_text=self.fingerprint, screen_x=GUIConstants.EDGE_PADDING, From 9ec31a23052dd56ef176312f67c40fad33fc57e0 Mon Sep 17 00:00:00 2001 From: Jean Do Date: Sat, 5 Aug 2023 13:36:56 -0400 Subject: [PATCH 13/24] tweaks for new easyuxd screenshots --- tests/screenshot_generator/generator.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/screenshot_generator/generator.py b/tests/screenshot_generator/generator.py index 3a0edb05f..178d84f1f 100644 --- a/tests/screenshot_generator/generator.py +++ b/tests/screenshot_generator/generator.py @@ -62,7 +62,7 @@ def test_generate_screenshots(target_locale): decoder = DecodeQR() decoder.add_data(BASE64_PSBT_1) controller.psbt = decoder.get_psbt() - controller.psbt_seed = seed_24 + controller.psbt_seed = seed_12b # Multisig wallet descriptor for the multisig in the above PSBT MULTISIG_WALLET_DESCRIPTOR = """wsh(sortedmulti(1,[22bde1a9/48h/1h/0h/2h]tpubDFfsBrmpj226ZYiRszYi2qK6iGvh2vkkghfGB2YiRUVY4rqqedHCFEgw12FwDkm7rUoVtq9wLTKc6BN2sxswvQeQgp7m8st4FP8WtP8go76/{0,1}/*,[73c5da0a/48h/1h/0h/2h]tpubDFH9dgzveyD8zTbPUFuLrGmCydNvxehyNdUXKJAQN8x4aZ4j6UZqGfnqFrD4NqyaTVGKbvEW54tsvPTK2UoSbCC1PJY8iCNiwTL3RWZEheQ/{0,1}/*))#3jhtf6yx""" @@ -162,7 +162,7 @@ def screencap_view(view_cls: View, view_name: str, view_args: dict={}): (seed_views.SeedDiscardView, dict(seed_num=0)), ], "PSBT Views": [ - psbt_views.PSBTSelectSeedView, + psbt_views.PSBTSelectSeedView, # this will fail, be rerun below psbt_views.PSBTOverviewView, psbt_views.PSBTUnsupportedScriptTypeWarningView, psbt_views.PSBTNoChangeWarningView, @@ -208,7 +208,7 @@ def screencap_view(view_cls: View, view_name: str, view_args: dict={}): readme += "\n\n---\n\n" readme += f"## {section_name}\n\n" readme += """""" - readme += f"""
""" + readme += f"""
\n""" for screenshot in screenshot_list: if type(screenshot) == tuple: if len(screenshot) == 2: @@ -222,11 +222,15 @@ def screencap_view(view_cls: View, view_name: str, view_args: dict={}): view_name = view_cls.__name__ screencap_view(view_cls, view_name, view_args) - readme += """""" + readme += """
""" readme += f"""""" - readme += """
{view_name}

""" + readme += """
\n""" readme += "" + # many screens don't work, leaving a missing image, re-run here for now + controller.psbt_seed = None + screencap_view(psbt_views.PSBTSelectSeedView, 'PSBTSelectSeedView', {}) + with open(os.path.join(screenshot_renderer.screenshot_path, "README.md"), 'w') as readme_file: readme_file.write(readme) From 045f6ca4d793adbbe0f2e3fc271701095bbc92b1 Mon Sep 17 00:00:00 2001 From: kdmukai Date: Mon, 7 Aug 2023 09:21:17 -0500 Subject: [PATCH 14/24] Edits to enable running in local dev --- .gitignore | 1 + tests/__init__.py | 0 tests/screenshot_generator/generator.py | 24 ++++++++++++++---------- tests/screenshot_generator/utils.py | 2 ++ 4 files changed, 17 insertions(+), 10 deletions(-) create mode 100644 tests/__init__.py diff --git a/.gitignore b/.gitignore index dcf343d8c..f2fbb160e 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ src/seedsigner/models/settings_definition.json .idea *.mo .coverage +seedsigner-screenshots \ No newline at end of file diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/screenshot_generator/generator.py b/tests/screenshot_generator/generator.py index 3a0edb05f..b4a1d6af5 100644 --- a/tests/screenshot_generator/generator.py +++ b/tests/screenshot_generator/generator.py @@ -1,9 +1,17 @@ import embit import os -import pathlib -import pytest -import shutil -from mock import Mock, patch +import sys +from mock import Mock, patch, MagicMock + +# Prevent importing modules w/Raspi hardware dependencies. +# These must precede any SeedSigner imports. +sys.modules['seedsigner.hardware.ST7789'] = MagicMock() +sys.modules['seedsigner.gui.screens.screensaver'] = MagicMock() +sys.modules['seedsigner.views.screensaver'] = MagicMock() +sys.modules['seedsigner.hardware.buttons'] = MagicMock() +sys.modules['seedsigner.hardware.camera'] = MagicMock() +sys.modules['seedsigner.hardware.microsd'] = MagicMock() + from seedsigner.controller import Controller from seedsigner.gui.renderer import Renderer @@ -18,7 +26,7 @@ psbt_views, scan_views, seed_views, settings_views, tools_views) from seedsigner.views.view import View -from .utils import ScreenshotComplete, ScreenshotRenderer +from tests.screenshot_generator.utils import ScreenshotComplete, ScreenshotRenderer @@ -30,12 +38,8 @@ def test_generate_screenshots(target_locale): When the `Renderer` instance is needed, we patch in our own test-only `ScreenshotRenderer`. """ - # Disable hardware dependencies by essentially wiping out this class - HardwareButtons.get_instance = Mock() - Camera.get_instance = Mock() - # Prep the ScreenshotRenderer that will be patched over the normal Renderer - screenshot_root = "/home/pi/seedsigner-screenshots" + screenshot_root = os.path.join(os.getcwd(), "seedsigner-screenshots") ScreenshotRenderer.configure_instance() screenshot_renderer: ScreenshotRenderer = ScreenshotRenderer.get_instance() diff --git a/tests/screenshot_generator/utils.py b/tests/screenshot_generator/utils.py index 26d232a46..703bbf61a 100644 --- a/tests/screenshot_generator/utils.py +++ b/tests/screenshot_generator/utils.py @@ -3,10 +3,12 @@ from seedsigner.gui.renderer import Renderer + class ScreenshotComplete(Exception): pass + class ScreenshotRenderer(Renderer): screenshot_path: str = None screenshot_filename: str = None From b269f8fa86e7018398dff56ba39ebae8243eeef8 Mon Sep 17 00:00:00 2001 From: kdmukai Date: Mon, 7 Aug 2023 09:21:48 -0500 Subject: [PATCH 15/24] Update README.md --- tests/screenshot_generator/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/screenshot_generator/README.md b/tests/screenshot_generator/README.md index cfb1048b7..f25b163db 100644 --- a/tests/screenshot_generator/README.md +++ b/tests/screenshot_generator/README.md @@ -5,4 +5,4 @@ From the project root, run: pytest tests/screenshot_generator/generator.py ``` -By default it writes the screenshots to a dir that's parallel to the project root: `seedsigner-screenshots`. +Writes the screenshots to a dir in the project root: `seedsigner-screenshots`. From 3c89359f5192b7cf8542e4ac2f791f4e8fabcb6e Mon Sep 17 00:00:00 2001 From: Easy <86452817+easyuxd@users.noreply.github.com> Date: Mon, 7 Aug 2023 09:00:20 -0700 Subject: [PATCH 16/24] Comments for icon categories --- src/seedsigner/gui/components.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/seedsigner/gui/components.py b/src/seedsigner/gui/components.py index 4a3f36058..2e4fb8dfe 100644 --- a/src/seedsigner/gui/components.py +++ b/src/seedsigner/gui/components.py @@ -99,11 +99,13 @@ class FontAwesomeIconConstants: class SeedSignerIconConstants: + # Menu icons SCAN = "\ue900" SEEDS = "\ue901" SETTINGS = "\ue902" TOOLS = "\ue903" + # Utility icons BACK = "\ue904" CHEVRON_DOWN = "\ue905" CHEVRON_LEFT = "\ue906" @@ -115,10 +117,12 @@ class SeedSignerIconConstants: PLUS = "\ue90c" POWER = "\ue90d" + # Messaging icons ERROR = "\ue90e" SUCCESS = "\ue90f" WARNING = "\ue910" + # Informational icons ADDRESS = "\ue911" CHANGE = "\ue912" DERIVATION = "\ue913" @@ -126,6 +130,7 @@ class SeedSignerIconConstants: FINGERPRINT = "\ue915" PASSPHRASE = "\ue916" + # Misc icons BITCOIN = "\ue917" BITCOIN_ALT = "\ue918" BRIGHTNESS = "\ue919" From 2fe0f3fe2037fa3b56f89db609512930bd38ef96 Mon Sep 17 00:00:00 2001 From: Jean Do Date: Mon, 7 Aug 2023 19:12:38 -0400 Subject: [PATCH 17/24] test suite working --- tests/__init__.py | 0 tests/screenshot_generator/generator.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 tests/__init__.py diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/screenshot_generator/generator.py b/tests/screenshot_generator/generator.py index d5e31bbcb..037a79055 100644 --- a/tests/screenshot_generator/generator.py +++ b/tests/screenshot_generator/generator.py @@ -26,7 +26,7 @@ psbt_views, scan_views, seed_views, settings_views, tools_views) from seedsigner.views.view import View -from tests.screenshot_generator.utils import ScreenshotComplete, ScreenshotRenderer +from .utils import ScreenshotComplete, ScreenshotRenderer From 9368d23a8c0a0c23cdb12b0da5b92525b15bae64 Mon Sep 17 00:00:00 2001 From: Easy <86452817+easyuxd@users.noreply.github.com> Date: Mon, 7 Aug 2023 21:20:29 -0700 Subject: [PATCH 18/24] Icons v2.1, color edits --- src/seedsigner/gui/components.py | 81 ++++++++++-------- src/seedsigner/gui/screens/psbt_screens.py | 2 +- src/seedsigner/gui/screens/screen.py | 2 +- src/seedsigner/gui/screens/seed_screens.py | 2 +- .../resources/fonts/seedsigner-icons.otf | Bin 27240 -> 29196 bytes src/seedsigner/views/view.py | 2 +- 6 files changed, 47 insertions(+), 42 deletions(-) diff --git a/src/seedsigner/gui/components.py b/src/seedsigner/gui/components.py index 2e4fb8dfe..4c9ebb1fa 100644 --- a/src/seedsigner/gui/components.py +++ b/src/seedsigner/gui/components.py @@ -20,12 +20,12 @@ class GUIConstants: BACKGROUND_COLOR = "black" WARNING_COLOR = "#FFD60A" - DIRE_WARNING_COLOR = "red" - SUCCESS_COLOR = "#00dd00" - BITCOIN_ORANGE = "#ff9416" - ACCENT_COLOR = "orange" - TESTNET_COLOR = "#00f100" - REGTEST_COLOR = "#00caf1" + DIRE_WARNING_COLOR = "FF453A" + SUCCESS_COLOR = "#30D158" + BITCOIN_ORANGE = "#FF9416" + ACCENT_COLOR = "FF9F0A" + TESTNET_COLOR = "#00F100" + REGTEST_COLOR = "#00CAF1" ICON_FONT_NAME__FONT_AWESOME = "Font_Awesome_6_Free-Solid-900" ICON_FONT_NAME__SEEDSIGNER = "seedsigner-icons" @@ -71,7 +71,7 @@ class FontAwesomeIconConstants: CAMERA = "\uf030" CHEVRON_UP = "\uf077" CHEVRON_DOWN = "\uf078" - SOLID_CIRCLE_CHECK = "\uf058" + #SOLID_CIRCLE_CHECK = "\uf058" CIRCLE = "\uf111" CIRCLE_CHEVRON_RIGHT = "\uf138" DICE = "\uf522" @@ -86,14 +86,14 @@ class FontAwesomeIconConstants: MAP = "\uf279" PAPER_PLANE = "\uf1d8" PEN = "\uf304" - ROTATE_RIGHT = "\uf2f9" + #ROTATE_RIGHT = "\uf2f9" SDCARD = "\uf7c2" - SQUARE = "\uf0c8" + #SQUARE = "\uf0c8" SQUARE_CARET_DOWN = "\uf150" SQUARE_CARET_LEFT = "\uf191" SQUARE_CARET_RIGHT = "\uf152" SQUARE_CARET_UP = "\uf151" - SQUARE_CHECK = "\uf14a" + #SQUARE_CHECK = "\uf14a" UNLOCK = "\uf09c" X = "\u0058" @@ -107,35 +107,40 @@ class SeedSignerIconConstants: # Utility icons BACK = "\ue904" - CHEVRON_DOWN = "\ue905" - CHEVRON_LEFT = "\ue906" - CHEVRON_RIGHT = "\ue907" - CHEVRON_UP = "\ue908" - CLOSE = "\ue909" - PAGE_DOWN = "\ue90a" - PAGE_UP = "\ue90b" - PLUS = "\ue90c" - POWER = "\ue90d" + CHECK = "\ue905" + CHECKBOX = "\ue906" + CHECKBOX_SELECTED = "\ue907" + CHEVRON_DOWN = "\ue908" + CHEVRON_LEFT = "\ue909" + CHEVRON_RIGHT = "\ue90a" + CHEVRON_UP = "\ue90b" + CLOSE = "\ue90c" + PAGE_DOWN = "\ue90d" + PAGE_UP = "\ue90e" + PLUS = "\ue90f" + POWER = "\ue910" + RESTART = "\ue911" # Messaging icons - ERROR = "\ue90e" - SUCCESS = "\ue90f" - WARNING = "\ue910" + ERROR = "\ue912" + SUCCESS = "\ue913" + WARNING = "\ue914" # Informational icons - ADDRESS = "\ue911" - CHANGE = "\ue912" - DERIVATION = "\ue913" - FEE = "\ue914" - FINGERPRINT = "\ue915" - PASSPHRASE = "\ue916" + ADDRESS = "\ue915" + CHANGE = "\ue916" + DERIVATION = "\ue917" + FEE = "\ue918" + FINGERPRINT = "\ue919" + PASSPHRASE = "\ue91a" # Misc icons - BITCOIN = "\ue917" - BITCOIN_ALT = "\ue918" - BRIGHTNESS = "\ue919" - MICROSD = "\ue91a" - QRCODE = "\ue91b" + BITCOIN = "\ue91b" + BITCOIN_ALT = "\ue91c" + BRIGHTNESS = "\ue91d" + MICROSD = "\ue91e" + QRCODE = "\ue91f" + SDCARD = "\ue920" MIN_VALUE = SCAN MAX_VALUE = QRCODE @@ -1217,8 +1222,8 @@ class CheckedSelectionButton(Button): def __post_init__(self): self.is_text_centered = False - self.icon_name = FontAwesomeIconConstants.SOLID_CIRCLE_CHECK - self.icon_color = "#00dd00" + self.icon_name = SeedSignerIconConstants.CHECK + self.icon_color = GUIConstants.SUCCESS_COLOR super().__post_init__() if not self.is_checked: @@ -1236,10 +1241,10 @@ class CheckboxButton(Button): def __post_init__(self): self.is_text_centered = False if self.is_checked: - self.icon_name = FontAwesomeIconConstants.SQUARE_CHECK - self.icon_color = "#00dd00" + self.icon_name = SeedSignerIconConstants.CHECKBOX_SELECTED + self.icon_color = GUIConstants.SUCCESS_COLOR else: - self.icon_name = FontAwesomeIconConstants.SQUARE + self.icon_name = SeedSignerIconConstants.CHECKBOX self.icon_color = GUIConstants.BODY_FONT_COLOR super().__post_init__() diff --git a/src/seedsigner/gui/screens/psbt_screens.py b/src/seedsigner/gui/screens/psbt_screens.py index 0a2cca3fc..8cb0d50f0 100644 --- a/src/seedsigner/gui/screens/psbt_screens.py +++ b/src/seedsigner/gui/screens/psbt_screens.py @@ -666,7 +666,7 @@ def __post_init__(self): if self.is_change_addr_verified: self.components.append(IconTextLine( icon_name=SeedSignerIconConstants.SUCCESS, - icon_color="#00dd00", + icon_color=GUIConstants.SUCCESS_COLOR, value_text="Address verified!", is_text_centered=False, screen_x=GUIConstants.EDGE_PADDING, diff --git a/src/seedsigner/gui/screens/screen.py b/src/seedsigner/gui/screens/screen.py index 447a40c15..5289c92ad 100644 --- a/src/seedsigner/gui/screens/screen.py +++ b/src/seedsigner/gui/screens/screen.py @@ -1059,7 +1059,7 @@ def __post_init__(self): # Render the right button panel (only has a Key3 "Save" button) self.save_button = IconButton( - icon_name=FontAwesomeIconConstants.SOLID_CIRCLE_CHECK, + icon_name=SeedSignerIconConstants.CHECK, icon_color=GUIConstants.SUCCESS_COLOR, width=right_panel_buttons_width, screen_x=hw_button_x, diff --git a/src/seedsigner/gui/screens/seed_screens.py b/src/seedsigner/gui/screens/seed_screens.py index 4c556a975..e84488d85 100644 --- a/src/seedsigner/gui/screens/seed_screens.py +++ b/src/seedsigner/gui/screens/seed_screens.py @@ -795,7 +795,7 @@ def __post_init__(self): ) self.hw_button3 = IconButton( - icon_name=FontAwesomeIconConstants.SOLID_CIRCLE_CHECK, + icon_name=SeedSignerIconConstants.CHECK, icon_color=GUIConstants.SUCCESS_COLOR, width=self.right_panel_buttons_width, screen_x=hw_button_x, diff --git a/src/seedsigner/resources/fonts/seedsigner-icons.otf b/src/seedsigner/resources/fonts/seedsigner-icons.otf index 5e480af0a83982eb6cde3c0bf63a54ff267e99e7..b0035bd88b8051ed3cda3df98b6ccfc64451b8c2 100644 GIT binary patch delta 3055 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 Dr85$b diff --git a/src/seedsigner/views/view.py b/src/seedsigner/views/view.py index 756147f53..dc1b95ce7 100644 --- a/src/seedsigner/views/view.py +++ b/src/seedsigner/views/view.py @@ -175,7 +175,7 @@ def run(self): class PowerOptionsView(View): - RESET = ("Restart", FontAwesomeIconConstants.ROTATE_RIGHT) + RESET = ("Restart", SeedSignerIconConstants.RESTART) POWER_OFF = ("Power Off", SeedSignerIconConstants.POWER) def run(self): From 54ae0d78bf126f55441432eb39fb33d692521fca Mon Sep 17 00:00:00 2001 From: Easy <86452817+easyuxd@users.noreply.github.com> Date: Mon, 7 Aug 2023 21:38:04 -0700 Subject: [PATCH 19/24] Update components.py --- src/seedsigner/gui/components.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/seedsigner/gui/components.py b/src/seedsigner/gui/components.py index 4c9ebb1fa..c3fb120bd 100644 --- a/src/seedsigner/gui/components.py +++ b/src/seedsigner/gui/components.py @@ -20,10 +20,10 @@ class GUIConstants: BACKGROUND_COLOR = "black" WARNING_COLOR = "#FFD60A" - DIRE_WARNING_COLOR = "FF453A" + DIRE_WARNING_COLOR = "#FF453A" SUCCESS_COLOR = "#30D158" BITCOIN_ORANGE = "#FF9416" - ACCENT_COLOR = "FF9F0A" + ACCENT_COLOR = "#FF9F0A" TESTNET_COLOR = "#00F100" REGTEST_COLOR = "#00CAF1" From f6c1152d9dd4e90e53b523d7445f95a3b38ee994 Mon Sep 17 00:00:00 2001 From: Easy <86452817+easyuxd@users.noreply.github.com> Date: Mon, 7 Aug 2023 21:50:31 -0700 Subject: [PATCH 20/24] Update seedsigner-icons.otf --- .../resources/fonts/seedsigner-icons.otf | Bin 29196 -> 29192 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/seedsigner/resources/fonts/seedsigner-icons.otf b/src/seedsigner/resources/fonts/seedsigner-icons.otf index b0035bd88b8051ed3cda3df98b6ccfc64451b8c2..43f1ba310a54a826e4bb2acec66fc04d59d49563 100644 GIT binary patch delta 204 zcmeBq!r1YI(ZW9@#Giqip@D&!!NA$gO<_v-S}q0#Ru2Y-91AzM5Z^gYz0C{^g)l?hKUwhOo1~drYJLRnb=_?bMMj2{&;?yuMFHQAbExd-z!hT=#3AK zu`n*%yqxtcqxnC{G-*qjEpp28lN1@1CaGwvE>XAD?$rBW;A1FmwAd!p>7iSk`_&-r r;7?(F(T|fEli#N;Pj}h8n*ECySya8Cw?!Z{2K z3^ML6u5JvfKo&z`%R~z;Ch53|DawpHCU)4!xNMZ27te3=m4TZDB+u~Rd)yirz45^@ z7RKe9m$RN_H2*J|E^Q^VRZc~IvLchxWECCNrRsLtU3wo4d<`Xxme_8_hsvwsm|`tG`Uf!xC&CI*Jd4TV}<2pcAEDGUJs5z|D2 From 8bb6d2512fd1765701f154c3f406947e155c950c Mon Sep 17 00:00:00 2001 From: Easy <86452817+easyuxd@users.noreply.github.com> Date: Tue, 8 Aug 2023 11:20:26 -0700 Subject: [PATCH 21/24] Color constants clean-up --- src/seedsigner/gui/components.py | 18 +++++++----------- src/seedsigner/gui/screens/psbt_screens.py | 4 ++-- src/seedsigner/gui/screens/seed_screens.py | 14 +++++++------- src/seedsigner/gui/screens/tools_screens.py | 4 ++-- .../resources/fonts/seedsigner-icons.otf | Bin 29192 -> 29216 bytes 5 files changed, 18 insertions(+), 22 deletions(-) diff --git a/src/seedsigner/gui/components.py b/src/seedsigner/gui/components.py index c3fb120bd..c07df632e 100644 --- a/src/seedsigner/gui/components.py +++ b/src/seedsigner/gui/components.py @@ -22,8 +22,9 @@ class GUIConstants: WARNING_COLOR = "#FFD60A" DIRE_WARNING_COLOR = "#FF453A" SUCCESS_COLOR = "#30D158" - BITCOIN_ORANGE = "#FF9416" + INFO_COLOR = "#0084FF" ACCENT_COLOR = "#FF9F0A" + BITCOIN_ORANGE = "#FF9416" TESTNET_COLOR = "#00F100" REGTEST_COLOR = "#00CAF1" @@ -43,7 +44,7 @@ class GUIConstants: BODY_FONT_SIZE = 17 BODY_FONT_MAX_SIZE = TOP_NAV_TITLE_FONT_SIZE BODY_FONT_MIN_SIZE = 15 - BODY_FONT_COLOR = "#f8f8f8" + BODY_FONT_COLOR = "#FCFCFC" BODY_LINE_SPACING = COMPONENT_PADDING FIXED_WIDTH_FONT_NAME = "Inconsolata-Regular" @@ -54,12 +55,12 @@ class GUIConstants: BUTTON_FONT_NAME = "OpenSans-SemiBold" BUTTON_FONT_SIZE = 18 - BUTTON_FONT_COLOR = "#e8e8e8" - BUTTON_BACKGROUND_COLOR = "#2c2c2c" + BUTTON_FONT_COLOR = "#FCFCFC" + BUTTON_BACKGROUND_COLOR = "#2C2C2C" BUTTON_HEIGHT = 32 - BUTTON_SELECTED_FONT_COLOR = "black" + BUTTON_SELECTED_FONT_COLOR = BACKGROUND_COLOR - NOTIFICATION_COLOR = "#00f100" + NOTIFICATION_COLOR = "#00F100" @@ -71,7 +72,6 @@ class FontAwesomeIconConstants: CAMERA = "\uf030" CHEVRON_UP = "\uf077" CHEVRON_DOWN = "\uf078" - #SOLID_CIRCLE_CHECK = "\uf058" CIRCLE = "\uf111" CIRCLE_CHEVRON_RIGHT = "\uf138" DICE = "\uf522" @@ -86,14 +86,10 @@ class FontAwesomeIconConstants: MAP = "\uf279" PAPER_PLANE = "\uf1d8" PEN = "\uf304" - #ROTATE_RIGHT = "\uf2f9" - SDCARD = "\uf7c2" - #SQUARE = "\uf0c8" SQUARE_CARET_DOWN = "\uf150" SQUARE_CARET_LEFT = "\uf191" SQUARE_CARET_RIGHT = "\uf152" SQUARE_CARET_UP = "\uf151" - #SQUARE_CHECK = "\uf14a" UNLOCK = "\uf09c" X = "\u0058" diff --git a/src/seedsigner/gui/screens/psbt_screens.py b/src/seedsigner/gui/screens/psbt_screens.py index 8cb0d50f0..76686039d 100644 --- a/src/seedsigner/gui/screens/psbt_screens.py +++ b/src/seedsigner/gui/screens/psbt_screens.py @@ -656,7 +656,7 @@ def __post_init__(self): screen_y -= GUIConstants.COMPONENT_PADDING self.components.append(IconTextLine( icon_name=SeedSignerIconConstants.FINGERPRINT, - icon_color="#0084ff", + icon_color=GUIConstants.INFO_COLOR, value_text=f"""{"Multisig" if self.is_multisig else self.fingerprint}: {"Change" if self.is_change_derivation_path else "Addr"} #{self.derivation_path_addr_index}""", is_text_centered=False, screen_x=GUIConstants.EDGE_PADDING, @@ -685,7 +685,7 @@ def __post_init__(self): icon = Icon( icon_name=FontAwesomeIconConstants.PAPER_PLANE, - icon_color=GUIConstants.SUCCESS_COLOR, + icon_color=GUIConstants.INFO_COLOR, icon_size=GUIConstants.ICON_LARGE_BUTTON_SIZE, screen_y=self.top_nav.height + GUIConstants.COMPONENT_PADDING ) diff --git a/src/seedsigner/gui/screens/seed_screens.py b/src/seedsigner/gui/screens/seed_screens.py index e84488d85..98d715a30 100644 --- a/src/seedsigner/gui/screens/seed_screens.py +++ b/src/seedsigner/gui/screens/seed_screens.py @@ -422,7 +422,7 @@ def __post_init__(self): self.fingerprint_icontl = IconTextLine( icon_name=SeedSignerIconConstants.FINGERPRINT, - icon_color="#0084ff", + icon_color=GUIConstants.INFO_COLOR, icon_size=GUIConstants.ICON_FONT_SIZE + 12, label_text="fingerprint", value_text=self.fingerprint, @@ -442,7 +442,7 @@ class SeedOptionsScreen(ButtonListScreen): def __post_init__(self): self.top_nav_icon_name = SeedSignerIconConstants.FINGERPRINT - self.top_nav_icon_color = "#0084ff" + self.top_nav_icon_color = GUIConstants.INFO_COLOR self.title = self.fingerprint self.is_button_text_centered = False self.is_bottom_list = True @@ -510,7 +510,7 @@ def __post_init__(self): (number_box_x + int(number_box_width/2), baseline_y), font=number_font, text=str(self.page_index * words_per_page + index + 1), - fill="#0084ff", + fill=GUIConstants.INFO_COLOR, anchor="ms" # Middle (centered), baSeline ) @@ -585,7 +585,7 @@ def __post_init__(self): # Set up the fingerprint and passphrase displays self.fingerprint_line = IconTextLine( icon_name=SeedSignerIconConstants.FINGERPRINT, - icon_color="#0084ff", + icon_color=GUIConstants.INFO_COLOR, label_text="Fingerprint", value_text=self.fingerprint, screen_x=GUIConstants.COMPONENT_PADDING, @@ -595,7 +595,7 @@ def __post_init__(self): self.derivation_line = IconTextLine( icon_name=SeedSignerIconConstants.DERIVATION, - icon_color="#0084ff", + icon_color=GUIConstants.INFO_COLOR, label_text="Derivation", value_text=self.derivation_path, screen_x=GUIConstants.COMPONENT_PADDING, @@ -605,7 +605,7 @@ def __post_init__(self): self.xpub_line = IconTextLine( icon_name=FontAwesomeIconConstants.X, - icon_color="#0084ff", + icon_color=GUIConstants.INFO_COLOR, label_text="Xpub", value_text=f"{self.xpub[:18]}...", font_name=GUIConstants.FIXED_WIDTH_FONT_NAME, @@ -1012,7 +1012,7 @@ def __post_init__(self): self.components.append(IconTextLine( icon_name=SeedSignerIconConstants.FINGERPRINT, - icon_color="#0084ff", + icon_color=GUIConstants.INFO_COLOR, label_text="changes fingerprint", value_text=f"{self.fingerprint_without} >> {self.fingerprint_with}", is_text_centered=True, diff --git a/src/seedsigner/gui/screens/tools_screens.py b/src/seedsigner/gui/screens/tools_screens.py index 1ac5f3337..b2188e0dd 100644 --- a/src/seedsigner/gui/screens/tools_screens.py +++ b/src/seedsigner/gui/screens/tools_screens.py @@ -363,7 +363,7 @@ def __post_init__(self): self.components.append(IconTextLine( icon_name=SeedSignerIconConstants.FINGERPRINT, - icon_color="#0084ff", + icon_color=GUIConstants.INFO_COLOR, label_text="fingerprint", value_text=self.fingerprint, is_text_centered=True, @@ -387,7 +387,7 @@ def __post_init__(self): if self.fingerprint: self.components.append(IconTextLine( icon_name=SeedSignerIconConstants.FINGERPRINT, - icon_color="#0084ff", + icon_color=GUIConstants.INFO_COLOR, label_text="Fingerprint", value_text=self.fingerprint, screen_x=GUIConstants.EDGE_PADDING, diff --git a/src/seedsigner/resources/fonts/seedsigner-icons.otf b/src/seedsigner/resources/fonts/seedsigner-icons.otf index 43f1ba310a54a826e4bb2acec66fc04d59d49563..ef4292b28effe8af1de63336109fa6c4892e95c2 100644 GIT binary patch delta 269 zcmeBp!noiGqlJG+h(7~2LjwadgMqV~o5F;YoP7)otR4&uIRS2NA-;25*f%mT6mDQ( zV32Wladl%*1+o|lXH2xvWadA8Y+{NsZLw%#&Hn~ne-OAkG z204dtg)NKzoh+Hcp0+i;=|NjXj82GhT xb^m7&T(ufP{%2qV$pb|vACl{1x*9e)LR^vMkKG@;&H3_HLEK2Lo4lnk1OT>dW8we+ delta 240 zcmZ4Rgt6lZqlJG+h(7~2LjwadgMqV~o5GavwOkAgtR4&uITmhiA-;2*dYc&-3TH4d zFvz&OxVkZ@0$B`&4HGRinfU@|OiWQ`+%mDlM&{n5nf>wnHeVUISwIRH9(=Dn38ObY zIL5-bZ1Zx~GmIAE|0L6-EoHXIDa%h%WK^1@qOH0_-B!C(?}LGlp}5gvn^32RZgK8c zgS3M`h4n>0PG(GgpSC>RW%FwGFJhu+M7z6xXMWFQ{r~@SXz29+|9`GpJ!^8Art0LE ca^;gPw4_=7*!{8H+%9hw#Es;D$!7{f0BA;8Qvd(} From 092445b7bb7b24b0cb153e57ef5b72fa7d0c0350 Mon Sep 17 00:00:00 2001 From: Easy <86452817+easyuxd@users.noreply.github.com> Date: Tue, 8 Aug 2023 11:53:35 -0700 Subject: [PATCH 22/24] More color constants cleanup --- src/seedsigner/gui/components.py | 8 ++++---- src/seedsigner/gui/keyboard.py | 2 +- src/seedsigner/gui/screens/seed_screens.py | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/seedsigner/gui/components.py b/src/seedsigner/gui/components.py index c07df632e..6934c59a5 100644 --- a/src/seedsigner/gui/components.py +++ b/src/seedsigner/gui/components.py @@ -18,7 +18,7 @@ class GUIConstants: COMPONENT_PADDING = 8 LIST_ITEM_PADDING = 4 - BACKGROUND_COLOR = "black" + BACKGROUND_COLOR = "#0A0A0A" WARNING_COLOR = "#FFD60A" DIRE_WARNING_COLOR = "#FF453A" SUCCESS_COLOR = "#30D158" @@ -51,7 +51,7 @@ class GUIConstants: FIXED_WIDTH_EMPHASIS_FONT_NAME = "Inconsolata-SemiBold" LABEL_FONT_SIZE = BODY_FONT_MIN_SIZE - LABEL_FONT_COLOR = "#777" + LABEL_FONT_COLOR = "#B3B3B3" BUTTON_FONT_NAME = "OpenSans-SemiBold" BUTTON_FONT_SIZE = 18 @@ -516,7 +516,7 @@ def __post_init__(self): canvas=self.canvas, text=self.label_text, font_size=GUIConstants.BODY_FONT_SIZE - 2, - font_color="#666", + font_color=GUIConstants.LABEL_FONT_COLOR, edge_padding=0, is_text_centered=self.is_text_centered if not self.icon_name else False, auto_line_break=False, @@ -1279,7 +1279,7 @@ class TopNav(BaseComponent): icon_color: str = GUIConstants.BODY_FONT_COLOR font_name: str = GUIConstants.TOP_NAV_TITLE_FONT_NAME font_size: int = GUIConstants.TOP_NAV_TITLE_FONT_SIZE - font_color: str = "#fcfcfc" + font_color: str = GUIConstants.BODY_FONT_COLOR show_back_button: bool = True show_power_button: bool = False is_selected: bool = False diff --git a/src/seedsigner/gui/keyboard.py b/src/seedsigner/gui/keyboard.py index 7e1dc6c41..4c7317fe4 100644 --- a/src/seedsigner/gui/keyboard.py +++ b/src/seedsigner/gui/keyboard.py @@ -574,7 +574,7 @@ def render(self, cur_text=None, cursor_position=None): draw.text((self.text_offset, self.height - int(text_height/2)), self.cur_text[:-1], fill=GUIConstants.ACCENT_COLOR, font=self.font, anchor="ls") # Draw the highlighted cursor block - cursor_color = "#666" + cursor_color = GUIConstants.LABEL_FONT_COLOR draw.rectangle((cursor_block_offset, 1, cursor_block_offset + cursor_block_width, self.height - 1), fill=cursor_color) draw.text((cursor_block_offset + 1, self.height - int(text_height/2)), self.cur_text[-1], fill=GUIConstants.ACCENT_COLOR, font=self.font, anchor="ls") diff --git a/src/seedsigner/gui/screens/seed_screens.py b/src/seedsigner/gui/screens/seed_screens.py index 98d715a30..d1aaf3e3f 100644 --- a/src/seedsigner/gui/screens/seed_screens.py +++ b/src/seedsigner/gui/screens/seed_screens.py @@ -502,7 +502,7 @@ def __post_init__(self): for index, word in enumerate(self.words): draw.rounded_rectangle( (number_box_x, number_box_y, number_box_x + number_box_width, number_box_y + number_box_height), - fill="#202020", + fill=GUIConstants.BUTTON_BACKGROUND_COLOR, radius=5 * supersampling_factor ) baseline_y = number_box_y + number_box_height - int((number_box_height - number_height)/2) From 10202bdb0c0f406fd2f373ef9a8ddce68d11fc3f Mon Sep 17 00:00:00 2001 From: Easy <86452817+easyuxd@users.noreply.github.com> Date: Tue, 8 Aug 2023 12:00:33 -0700 Subject: [PATCH 23/24] Update components.py --- src/seedsigner/gui/components.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/seedsigner/gui/components.py b/src/seedsigner/gui/components.py index 6934c59a5..0f9ddda4d 100644 --- a/src/seedsigner/gui/components.py +++ b/src/seedsigner/gui/components.py @@ -18,7 +18,7 @@ class GUIConstants: COMPONENT_PADDING = 8 LIST_ITEM_PADDING = 4 - BACKGROUND_COLOR = "#0A0A0A" + BACKGROUND_COLOR = "black" WARNING_COLOR = "#FFD60A" DIRE_WARNING_COLOR = "#FF453A" SUCCESS_COLOR = "#30D158" From b16c0eedf1ff37d9fbe6211cfef2c9791963bae1 Mon Sep 17 00:00:00 2001 From: Easy <86452817+easyuxd@users.noreply.github.com> Date: Tue, 8 Aug 2023 12:16:44 -0700 Subject: [PATCH 24/24] Reverted cursor color --- src/seedsigner/gui/keyboard.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/seedsigner/gui/keyboard.py b/src/seedsigner/gui/keyboard.py index 4c7317fe4..7e1dc6c41 100644 --- a/src/seedsigner/gui/keyboard.py +++ b/src/seedsigner/gui/keyboard.py @@ -574,7 +574,7 @@ def render(self, cur_text=None, cursor_position=None): draw.text((self.text_offset, self.height - int(text_height/2)), self.cur_text[:-1], fill=GUIConstants.ACCENT_COLOR, font=self.font, anchor="ls") # Draw the highlighted cursor block - cursor_color = GUIConstants.LABEL_FONT_COLOR + cursor_color = "#666" draw.rectangle((cursor_block_offset, 1, cursor_block_offset + cursor_block_width, self.height - 1), fill=cursor_color) draw.text((cursor_block_offset + 1, self.height - int(text_height/2)), self.cur_text[-1], fill=GUIConstants.ACCENT_COLOR, font=self.font, anchor="ls")