138 lines
4.5 KiB
Python
138 lines
4.5 KiB
Python
"""
|
|
Main menu screen for the AUTOPARTES console application.
|
|
|
|
Displays a numbered Pick-style menu with navigation options for all
|
|
application sections. Number keys jump directly; arrow keys move the
|
|
selection; ENTER activates.
|
|
"""
|
|
|
|
from console.core.screens import Screen
|
|
from console.core.keybindings import Key
|
|
from console.config import APP_NAME, APP_SUBTITLE, VERSION
|
|
|
|
|
|
# Menu items: list of (display_number, label, screen_name).
|
|
# Separators use display_number None and screen_name None.
|
|
_MENU_ITEMS = [
|
|
("1", "Consulta por Vehiculo", "vehiculo_nav"),
|
|
("2", "Busqueda por Numero de Parte", "buscar_parte"),
|
|
("3", "Busqueda por Descripcion", "buscar_texto"),
|
|
("4", "Decodificador VIN", "vin_decoder"),
|
|
("5", "Catalogo de Categorias", "catalogo"),
|
|
(None, None, None), # separator
|
|
("6", "Administracion de Partes", "admin_partes"),
|
|
("7", "Administracion de Fabricantes", "admin_fabricantes"),
|
|
("8", "Cross-References", "admin_crossref"),
|
|
("9", "Importar / Exportar Datos", "admin_import"),
|
|
(None, None, None), # separator
|
|
("0", "Estadisticas del Sistema", "estadisticas"),
|
|
]
|
|
|
|
# Quick lookup: digit character -> screen name
|
|
_KEY_MAP = {item[0]: item[2] for item in _MENU_ITEMS if item[0] is not None}
|
|
|
|
# Footer key labels
|
|
_FOOTER = [
|
|
("F1", "Ayuda"),
|
|
("F3", "Buscar"),
|
|
("F10", "Menu"),
|
|
("ESC", "Salir"),
|
|
]
|
|
|
|
|
|
class MenuPrincipalScreen(Screen):
|
|
"""Main menu screen with numbered items and arrow-key navigation."""
|
|
|
|
def __init__(self):
|
|
super().__init__(name="menu", title="Menu Principal")
|
|
self._selected = 0 # index into _MENU_ITEMS (skipping separators)
|
|
|
|
# ------------------------------------------------------------------
|
|
# Helpers
|
|
# ------------------------------------------------------------------
|
|
|
|
def _selectable_indices(self):
|
|
"""Return list of indices in _MENU_ITEMS that are not separators."""
|
|
return [i for i, item in enumerate(_MENU_ITEMS) if item[0] is not None]
|
|
|
|
def _move_selection(self, direction):
|
|
"""Move selection up (-1) or down (+1), skipping separators."""
|
|
indices = self._selectable_indices()
|
|
if not indices:
|
|
return
|
|
try:
|
|
pos = indices.index(self._selected)
|
|
except ValueError:
|
|
pos = 0
|
|
pos = max(0, min(len(indices) - 1, pos + direction))
|
|
self._selected = indices[pos]
|
|
|
|
# ------------------------------------------------------------------
|
|
# Screen interface
|
|
# ------------------------------------------------------------------
|
|
|
|
def render(self, context, db, renderer):
|
|
# Header
|
|
renderer.draw_header(
|
|
f" {APP_NAME} v{VERSION}",
|
|
f"{APP_SUBTITLE} ",
|
|
)
|
|
|
|
# Build items list for draw_menu.
|
|
# Separators use the special "---" marker understood by the renderer.
|
|
menu_items = []
|
|
for num, label, _screen in _MENU_ITEMS:
|
|
if num is None:
|
|
menu_items.append(("---", ""))
|
|
else:
|
|
menu_items.append((num, label))
|
|
|
|
renderer.draw_menu(
|
|
menu_items,
|
|
selected_index=self._selected,
|
|
title="MENU PRINCIPAL",
|
|
)
|
|
|
|
# Footer
|
|
renderer.draw_footer(_FOOTER)
|
|
|
|
def on_key(self, key, context, db, renderer, nav):
|
|
# --- Number keys: direct navigation ---
|
|
if 48 <= key <= 57: # ord('0') .. ord('9')
|
|
digit = chr(key)
|
|
screen_name = _KEY_MAP.get(digit)
|
|
if screen_name:
|
|
label = next(
|
|
(lbl for num, lbl, _ in _MENU_ITEMS if num == digit),
|
|
screen_name,
|
|
)
|
|
return (screen_name, {}, label)
|
|
|
|
# --- Arrow keys ---
|
|
if key == Key.UP:
|
|
self._move_selection(-1)
|
|
return None
|
|
|
|
if key == Key.DOWN:
|
|
self._move_selection(1)
|
|
return None
|
|
|
|
# --- ENTER: activate selected ---
|
|
if key == Key.ENTER:
|
|
item = _MENU_ITEMS[self._selected]
|
|
num, label, screen_name = item
|
|
if screen_name is not None:
|
|
return (screen_name, {}, label)
|
|
return None
|
|
|
|
# --- ESC: quit confirmation ---
|
|
if key == Key.ESCAPE:
|
|
confirmed = renderer.show_message(
|
|
"Desea salir de la aplicacion?", "confirm"
|
|
)
|
|
if confirmed:
|
|
return "quit"
|
|
return None
|
|
|
|
return None
|