fix: hitting 'b' or 'h' in main menu raises exception
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
This commit is contained in:
@@ -21,8 +21,7 @@ class KlipperNoFirmwareErrorMenu(BaseMenu):
|
||||
super().__init__()
|
||||
|
||||
self.flash_options = FlashOptions()
|
||||
self.options = {"": self.go_back}
|
||||
self.default_options = self.go_back
|
||||
self.default_option = self.go_back
|
||||
self.footer_type = FooterType.BLANK
|
||||
self.input_label_txt = "Press ENTER to go back to [Advanced Menu]"
|
||||
|
||||
@@ -64,8 +63,7 @@ class KlipperNoBoardTypesErrorMenu(BaseMenu):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
self.options = {"": self.go_back}
|
||||
self.default_options = self.go_back
|
||||
self.default_option = self.go_back
|
||||
self.footer_type = FooterType.BLANK
|
||||
self.input_label_txt = "Press ENTER to go back to [Main Menu]"
|
||||
|
||||
|
||||
@@ -48,10 +48,10 @@ class KlipperFlashMethodMenu(BaseMenu):
|
||||
super().__init__()
|
||||
|
||||
self.previous_menu: BaseMenu = previous_menu
|
||||
self.help_menu = KlipperFlashMethodHelpMenu
|
||||
self.options = {
|
||||
"1": self.select_regular,
|
||||
"2": self.select_sdcard,
|
||||
"h": self.help_menu,
|
||||
}
|
||||
self.input_label_txt = "Select flash method"
|
||||
self.footer_type = FooterType.BACK_HELP
|
||||
@@ -99,9 +99,6 @@ class KlipperFlashMethodMenu(BaseMenu):
|
||||
else:
|
||||
KlipperNoFirmwareErrorMenu().run()
|
||||
|
||||
def help_menu(self, **kwargs):
|
||||
KlipperFlashMethodHelpMenu(previous_menu=self).run()
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal
|
||||
# noinspection PyMethodMayBeStatic
|
||||
@@ -110,10 +107,10 @@ class KlipperFlashCommandMenu(BaseMenu):
|
||||
super().__init__()
|
||||
|
||||
self.previous_menu: BaseMenu = previous_menu
|
||||
self.help_menu = KlipperFlashCommandHelpMenu
|
||||
self.options = {
|
||||
"1": self.select_flash,
|
||||
"2": self.select_serialflash,
|
||||
"h": self.help_menu,
|
||||
}
|
||||
self.default_option = self.select_flash
|
||||
self.input_label_txt = "Select flash command"
|
||||
@@ -145,9 +142,6 @@ class KlipperFlashCommandMenu(BaseMenu):
|
||||
def goto_next_menu(self, **kwargs):
|
||||
KlipperSelectMcuConnectionMenu(previous_menu=self).run()
|
||||
|
||||
def help_menu(self, **kwargs):
|
||||
KlipperFlashCommandHelpMenu(previous_menu=self).run()
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal
|
||||
# noinspection PyMethodMayBeStatic
|
||||
@@ -157,11 +151,11 @@ class KlipperSelectMcuConnectionMenu(BaseMenu):
|
||||
|
||||
self.__standalone = standalone
|
||||
self.previous_menu: BaseMenu = previous_menu
|
||||
self.help_menu = KlipperMcuConnectionHelpMenu
|
||||
self.options = {
|
||||
"1": self.select_usb,
|
||||
"2": self.select_dfu,
|
||||
"3": self.select_usb_dfu,
|
||||
"h": self.help_menu,
|
||||
}
|
||||
self.input_label_txt = "Select connection type"
|
||||
self.footer_type = FooterType.BACK_HELP
|
||||
@@ -229,9 +223,6 @@ class KlipperSelectMcuConnectionMenu(BaseMenu):
|
||||
def goto_next_menu(self, **kwargs):
|
||||
KlipperSelectMcuIdMenu(previous_menu=self).run()
|
||||
|
||||
def help_menu(self, **kwargs):
|
||||
KlipperMcuConnectionHelpMenu(previous_menu=self).run()
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal
|
||||
# noinspection PyMethodMayBeStatic
|
||||
|
||||
@@ -17,14 +17,6 @@ class FooterType(Enum):
|
||||
BLANK = "BLANK"
|
||||
|
||||
|
||||
NAVI_OPTIONS = {
|
||||
FooterType.QUIT: ["q"],
|
||||
FooterType.BACK: ["b"],
|
||||
FooterType.BACK_HELP: ["b", "h"],
|
||||
FooterType.BLANK: [],
|
||||
}
|
||||
|
||||
|
||||
class ExitAppException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@@ -12,10 +12,10 @@ from __future__ import annotations
|
||||
import subprocess
|
||||
import sys
|
||||
import textwrap
|
||||
from abc import abstractmethod, ABC
|
||||
from abc import abstractmethod
|
||||
from typing import Dict, Union, Callable, Type, Tuple
|
||||
|
||||
from core.menus import FooterType, NAVI_OPTIONS, ExitAppException, GoBackException
|
||||
from core.menus import FooterType, ExitAppException, GoBackException
|
||||
from utils.constants import (
|
||||
COLOR_GREEN,
|
||||
COLOR_YELLOW,
|
||||
@@ -96,22 +96,51 @@ def print_blank_footer():
|
||||
print("\=======================================================/")
|
||||
|
||||
|
||||
Options = Dict[str, Callable]
|
||||
class PostInitCaller(type):
|
||||
def __call__(cls, *args, **kwargs):
|
||||
obj = type.__call__(cls, *args, **kwargs)
|
||||
obj.__post_init__()
|
||||
return obj
|
||||
|
||||
|
||||
class BaseMenu(ABC):
|
||||
options: Options = {}
|
||||
# noinspection PyUnusedLocal
|
||||
# noinspection PyMethodMayBeStatic
|
||||
class BaseMenu(metaclass=PostInitCaller):
|
||||
options: Dict[str, Callable] = {}
|
||||
options_offset: int = 0
|
||||
default_option: Union[Callable, None] = None
|
||||
input_label_txt: str = "Perform action"
|
||||
header: bool = False
|
||||
previous_menu: Union[Type[BaseMenu], BaseMenu] = None
|
||||
help_menu: Type[BaseMenu] = None
|
||||
footer_type: FooterType = FooterType.BACK
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, **kwargs):
|
||||
if type(self) is BaseMenu:
|
||||
raise NotImplementedError("BaseMenu cannot be instantiated directly.")
|
||||
|
||||
def __post_init__(self):
|
||||
# conditionally add options based on footer type
|
||||
if self.footer_type is FooterType.QUIT:
|
||||
self.options["q"] = self.__exit
|
||||
if self.footer_type is FooterType.BACK:
|
||||
self.options["b"] = self.__go_back
|
||||
if self.footer_type is FooterType.BACK_HELP:
|
||||
self.options["b"] = self.__go_back
|
||||
self.options["h"] = self.__go_to_help
|
||||
# if defined, add the default option to the options dict
|
||||
if self.default_option is not None:
|
||||
self.options[""] = self.default_option
|
||||
|
||||
def __go_back(self, **kwargs):
|
||||
raise GoBackException()
|
||||
|
||||
def __go_to_help(self, **kwargs):
|
||||
self.help_menu(previous_menu=self).run()
|
||||
|
||||
def __exit(self, **kwargs):
|
||||
raise ExitAppException()
|
||||
|
||||
@abstractmethod
|
||||
def print_menu(self) -> None:
|
||||
raise NotImplementedError("Subclasses must implement the print_menu method")
|
||||
@@ -144,20 +173,8 @@ class BaseMenu(ABC):
|
||||
usr_input = usr_input.lower()
|
||||
option = self.options.get(usr_input, None)
|
||||
|
||||
# check if usr_input contains a character used for basic navigation, e.g. b, h or q
|
||||
# and if the current menu has the appropriate footer to allow for that action
|
||||
is_valid_navigation = self.footer_type in NAVI_OPTIONS
|
||||
user_navigated = usr_input in NAVI_OPTIONS[self.footer_type]
|
||||
if is_valid_navigation and user_navigated:
|
||||
if usr_input == "q":
|
||||
raise ExitAppException()
|
||||
elif usr_input == "b":
|
||||
raise GoBackException()
|
||||
elif usr_input == "h":
|
||||
return option, usr_input
|
||||
|
||||
# if usr_input is None or an empty string, we execute the menues default option if specified
|
||||
if usr_input == "" and self.default_option is not None:
|
||||
# if option/usr_input is None/empty string, we execute the menus default option if specified
|
||||
if (option is None or usr_input == "") and self.default_option is not None:
|
||||
return self.default_option, usr_input
|
||||
|
||||
# user selected a regular option
|
||||
@@ -168,8 +185,10 @@ class BaseMenu(ABC):
|
||||
while True:
|
||||
print(f"{COLOR_CYAN}###### {self.input_label_txt}: {RESET_FORMAT}", end="")
|
||||
usr_input = input().lower()
|
||||
validated_input = self.validate_user_input(usr_input)
|
||||
method_to_call = validated_input[0]
|
||||
|
||||
if (validated_input := self.validate_user_input(usr_input)) is not None:
|
||||
if method_to_call is not None:
|
||||
return validated_input
|
||||
else:
|
||||
Logger.print_error("Invalid input!", False)
|
||||
|
||||
Reference in New Issue
Block a user