Skip to content

Commit

Permalink
Menu class refactor, created class MenuItem
Browse files Browse the repository at this point in the history
  • Loading branch information
tadeubas committed Aug 28, 2024
1 parent 1b03495 commit 33a1bb0
Show file tree
Hide file tree
Showing 22 changed files with 285 additions and 264 deletions.
84 changes: 44 additions & 40 deletions src/krux/pages/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,8 @@ def load_method(self):
load_menu = Menu(
self.ctx,
[
(t("Load from camera"), lambda: None),
(
t("Load from SD card"),
None if not self.has_sd_card() else lambda: None,
),
MenuItem(t("Load from camera"), lambda: None),
MenuItemSD(t("Load from SD card"), lambda: None),
],
back_status=lambda: None,
)
Expand Down Expand Up @@ -425,12 +422,7 @@ def has_sd_card(self):
"""Checks if the device has a SD card inserted"""
self.ctx.display.clear()
self.ctx.display.draw_centered_text(t("Checking for SD card.."))
try:
# Check for SD hot-plug
with SDHandler():
return True
except:
return False
return SDHandler.sd_card_available()

def shutdown(self):
"""Handler for the 'shutdown' menu item"""
Expand Down Expand Up @@ -499,17 +491,15 @@ class Menu:
def __init__(
self,
ctx,
menu,
menu_list,
offset=None,
disable_statusbar=False,
back_label="Back",
back_status=lambda: MENU_EXIT,
):
self.ctx = ctx
self.menu = menu
if back_label:
back_label = t("Back") if back_label == "Back" else back_label
self.menu += [("< " + back_label, back_status)]
menu_list += [MenuItem.back(back_label, back_status)]

self.disable_statusbar = disable_statusbar
if offset is None:
Expand All @@ -521,16 +511,10 @@ def __init__(
self.menu_offset = offset
max_viewable = min(
self.ctx.display.max_menu_lines(self.menu_offset),
len(self.menu),
len(menu_list),
)
self.menu_view = ListView(self.menu, max_viewable)

def screensaver(self):
"""Loads and starts screensaver"""
from .screensaver import ScreenSaver

screen_saver = ScreenSaver(self.ctx)
screen_saver.start()
self.menu_view = ListView(menu_list, max_viewable)
self.back_index = len(menu_list) - 1

def run_loop(self, start_from_index=None):
"""Runs the menu loop until one of the menu items returns either a MENU_EXIT
Expand Down Expand Up @@ -603,14 +587,16 @@ def run_loop(self, start_from_index=None):
self.menu_view.move_backward()
elif btn is None and self.menu_offset == STATUS_BAR_HEIGHT:
# Activates screensaver if there's no info_box(other things draw on the screen)
self.screensaver()
from .screensaver import start_screen_saver

Check warning on line 590 in src/krux/pages/__init__.py

View check run for this annotation

Codecov / codecov/patch

src/krux/pages/__init__.py#L590

Added line #L590 was not covered by tests

start_screen_saver(self.ctx)

Check warning on line 592 in src/krux/pages/__init__.py

View check run for this annotation

Codecov / codecov/patch

src/krux/pages/__init__.py#L592

Added line #L592 was not covered by tests

def _clicked_item(self, selected_item_index):
if self.menu_view[selected_item_index][1] is None:
if not self.menu_view[selected_item_index].enabled():
return MENU_CONTINUE
try:
self.ctx.display.clear()
status = self.menu_view[selected_item_index][1]()
status = self.menu_view[selected_item_index].action()
if status != MENU_CONTINUE:
return status
except Exception as e:
Expand Down Expand Up @@ -731,7 +717,7 @@ def _draw_touch_menu(self, selected_item_index):
offset_y = 0
Page.y_keypad_map = [offset_y]
for menu_item in self.menu_view:
offset_y += len(self.ctx.display.to_lines(menu_item[0])) + 1
offset_y += len(self.ctx.display.to_lines(menu_item.label)) + 1
Page.y_keypad_map.append(offset_y)
height_multiplier = self.ctx.display.height()
height_multiplier -= self.menu_offset # Top offset
Expand All @@ -753,17 +739,15 @@ def _draw_touch_menu(self, selected_item_index):

# draw centralized strings in regions
for i, menu_item in enumerate(self.menu_view):
menu_item_lines = self.ctx.display.to_lines(menu_item[0])
menu_item_lines = self.ctx.display.to_lines(menu_item.label)
offset_y = Page.y_keypad_map[i + 1] - Page.y_keypad_map[i]
offset_y -= len(menu_item_lines) * FONT_HEIGHT
if i == len(self.menu_view) - 1:
# Compensate for the expanded last region
offset_y -= DEFAULT_PADDING
offset_y //= 2
offset_y += Page.y_keypad_map[i]
fg_color = (
theme.fg_color if menu_item[1] is not None else theme.disabled_color
)
fg_color = theme.fg_color if menu_item.enabled() else theme.disabled_color
if selected_item_index == i and self.ctx.input.buttons_active:
self.ctx.display.fill_rectangle(
0,
Expand All @@ -789,7 +773,7 @@ def _draw_menu(self, selected_item_index):
extra_lines = 0
for menu_item in self.menu_view:
# Count extra lines for multi-line menu items
extra_lines += len(self.ctx.display.to_lines(menu_item[0])) - 1
extra_lines += len(self.ctx.display.to_lines(menu_item.label)) - 1
if self.menu_offset > STATUS_BAR_HEIGHT:
offset_y = self.menu_offset + FONT_HEIGHT
else:
Expand All @@ -811,10 +795,8 @@ def _draw_menu(self, selected_item_index):
# Limit padding to font height
items_pad = min(items_pad, FONT_HEIGHT)
for i, menu_item in enumerate(self.menu_view):
fg_color = (
theme.fg_color if menu_item[1] is not None else theme.disabled_color
)
menu_item_lines = self.ctx.display.to_lines(menu_item[0])
fg_color = theme.fg_color if menu_item.enabled() else theme.disabled_color
menu_item_lines = self.ctx.display.to_lines(menu_item.label)
delta_y = len(menu_item_lines) * FONT_HEIGHT
delta_y += items_pad
if selected_item_index == i:
Expand All @@ -840,14 +822,36 @@ def _draw_menu(self, selected_item_index):
offset_y += delta_y


class MenuItem:
"""Handle items for the Menu"""

def __init__(self, text, action, enabled=lambda: True):
self.label = text
self.action = action
self.enabled = enabled

@staticmethod
def back(text="Back", action=lambda: MENU_EXIT):
"""Create a standard back MenuItem"""
text = t("Back") if text == "Back" else text
return MenuItem("< " + text, action)


class MenuItemSD(MenuItem):
"""Reusable MenuItem for the Menu that automatic disables when SD card not detected"""

def __init__(self, text, action):
super().__init__(text, action, SDHandler.sd_card_available)


def choose_len_mnemonic(ctx, double_mnemonic=False):
"""Reusable '12 or 24 words?" menu choice"""
items = [
(t("12 words"), lambda: 12),
(t("24 words"), lambda: 24),
MenuItem(t("12 words"), lambda: 12),
MenuItem(t("24 words"), lambda: 24),
]
if double_mnemonic:
items += [(t("Double mnemonic"), lambda: 48)]
items += [MenuItem(t("Double mnemonic"), lambda: 48)]
submenu = Menu(
ctx,
items,
Expand Down
25 changes: 11 additions & 14 deletions src/krux/pages/encryption_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
from . import (
Page,
Menu,
MenuItem,
MenuItemSD,
MENU_CONTINUE,
ESC_KEY,
LETTERS,
Expand All @@ -49,8 +51,8 @@ def encryption_key(self):
submenu = Menu(
self.ctx,
[
(t("Type Key"), self.load_key),
(t("Scan Key QR Code"), self.load_qr_encryption_key),
MenuItem(t("Type Key"), self.load_key),
MenuItem(t("Scan Key QR Code"), self.load_qr_encryption_key),
],
back_label=None,
)
Expand Down Expand Up @@ -102,16 +104,11 @@ def encrypt_menu(self):
"""Menu with mnemonic encryption output options"""

encrypt_outputs_menu = [
(t("Store on Flash"), self.store_mnemonic_on_memory),
(
t("Store on SD Card"),
(
None
if not self.has_sd_card()
else lambda: self.store_mnemonic_on_memory(True)
),
MenuItem(t("Store on Flash"), self.store_mnemonic_on_memory),
MenuItemSD(
t("Store on SD Card"), lambda: self.store_mnemonic_on_memory(True)
),
(t("Encrypted QR Code"), self.encrypted_qr_code),
MenuItem(t("Encrypted QR Code"), self.encrypted_qr_code),
]
submenu = Menu(self.ctx, encrypt_outputs_menu)
_, _ = submenu.run_loop()
Expand Down Expand Up @@ -239,7 +236,7 @@ def load_from_storage(self, remove_opt=False):

for mnemonic_id in mnemonics:
mnemonic_ids_menu.append(
(
MenuItem(
mnemonic_id + "(flash)",
lambda m_id=mnemonic_id: (
self._remove_encrypted_mnemonic(m_id)
Expand All @@ -250,7 +247,7 @@ def load_from_storage(self, remove_opt=False):
)
for mnemonic_id in sd_mnemonics:
mnemonic_ids_menu.append(
(
MenuItem(
mnemonic_id + "(SD card)",
lambda m_id=mnemonic_id: (
self._remove_encrypted_mnemonic(m_id, sd_card=True)
Expand All @@ -261,7 +258,7 @@ def load_from_storage(self, remove_opt=False):
)
submenu = Menu(self.ctx, mnemonic_ids_menu)
index, status = submenu.run_loop()
if index == len(submenu.menu) - 1:
if index == submenu.back_index:
return MENU_CONTINUE
return status

Expand Down
6 changes: 3 additions & 3 deletions src/krux/pages/file_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

import board
import gc
from . import Page, Menu, MENU_EXIT, MENU_CONTINUE
from . import Page, Menu, MenuItem, MENU_EXIT, MENU_CONTINUE
from ..sd_card import SDHandler
from ..krux_settings import t
from ..format import generate_thousands_separator, render_decimal_separator
Expand Down Expand Up @@ -61,7 +61,7 @@ def select_file(

if path != SD_ROOT_PATH:
items.append("..")
menu_items.append(("../", lambda: MENU_EXIT))
menu_items.append(MenuItem("../", lambda: MENU_EXIT))

# sorts by name ignorecase
dir_files = sorted(os.listdir(path), key=str.lower)
Expand Down Expand Up @@ -109,7 +109,7 @@ def select_file(
]
)
menu_items.append(
(
MenuItem(
display_filename,
lambda file=filename: select_file_handler(
path + "/" + file
Expand Down
24 changes: 13 additions & 11 deletions src/krux/pages/home_pages/addresses.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from .. import (
Page,
Menu,
MenuItem,
MENU_CONTINUE,
MENU_EXIT,
)
Expand All @@ -48,9 +49,9 @@ def addresses_menu(self):
submenu = Menu(
self.ctx,
[
(t("Scan Address"), self.pre_scan_address),
(t("Receive Addresses"), self.list_address_type),
(t("Change Addresses"), lambda: self.list_address_type(1)),
MenuItem(t("Scan Address"), self.pre_scan_address),
MenuItem(t("Receive Addresses"), self.list_address_type),
MenuItem(t("Change Addresses"), lambda: self.list_address_type(1)),
],
)
submenu.run_loop()
Expand All @@ -72,7 +73,7 @@ def list_address_type(self, addr_type=0):
items = []
if address_index >= max_addresses:
items.append(
(
MenuItem(
"%d..%d" % (address_index - max_addresses, address_index - 1),
lambda: MENU_EXIT,
)
Expand All @@ -87,7 +88,7 @@ def list_address_type(self, addr_type=0):
pos_str = str(address_index) + "." + THIN_SPACE
qr_title = pos_str + addr
items.append(
(
MenuItem(
self.fit_to_line(addr, pos_str, fixed_chars=3),
lambda address=addr, title=qr_title: self.show_address(
address, title
Expand All @@ -97,7 +98,7 @@ def list_address_type(self, addr_type=0):
address_index += 1

items.append(
(
MenuItem(
"%d..%d" % (address_index, address_index + max_addresses - 1),
lambda: MENU_EXIT,
)
Expand All @@ -108,13 +109,14 @@ def list_address_type(self, addr_type=0):
while stay_on_this_addr_menu:
index, _ = submenu.run_loop()

if index == len(submenu.menu) - 1: # Back
if index == submenu.back_index: # Back
del submenu, items
gc.collect()
return MENU_CONTINUE
if index == len(submenu.menu) - 2: # Next

if index == submenu.back_index - 1: # Next
stay_on_this_addr_menu = False
if index == 0 and address_index > max_addresses: # Prev
elif index == 0 and address_index > max_addresses: # Prev
stay_on_this_addr_menu = False
address_index -= 2 * max_addresses

Expand All @@ -134,8 +136,8 @@ def pre_scan_address(self):
submenu = Menu(
self.ctx,
[
(t("Receive"), self.scan_address),
(t("Change"), lambda: self.scan_address(1)),
MenuItem(t("Receive"), self.scan_address),
MenuItem(t("Change"), lambda: self.scan_address(1)),
],
)
submenu.run_loop()
Expand Down
Loading

0 comments on commit 33a1bb0

Please sign in to comment.