From 005cbe157ac74e79043a55cf31bd04e67f7e1707 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janar=20S=C3=B6=C3=B6t?= Date: Thu, 20 Dec 2018 21:02:24 +0200 Subject: [PATCH] menu: allow names in card content and simplify define single card decks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Janar Sööt --- config/example-menu.cfg | 9 +++++++ klippy/extras/display/menu.py | 44 ++++++++++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/config/example-menu.cfg b/config/example-menu.cfg index 81359081..453e1552 100644 --- a/config/example-menu.cfg +++ b/config/example-menu.cfg @@ -171,6 +171,11 @@ #items: # It accepts only 'card' elements. You are able to switch between different card screens # by using encoder or up/down buttons. +#content: +# It allows quickly define single card decks by adding content directly to deck. +# You have to remove deck item attribute and use named items in content. +# The menu functionality will then internally create one card item for this deck. +# This is optional. #[menu card1] #type: card @@ -179,6 +184,10 @@ # Card screen content. Each line represents display line. # Quotes can be used in the beginning and end of line. # Rendered elements are available for output formatting as {0}..{x}. It's always string type. +# It's possible directly use menu item names in content by leaving items attribute out or empty +# and use menu items names directly in content as {msg,xpos|ypos}. The menu functionality will then +# internally build a item list and replace names with indexes in content. +# This is optional. #items: # List of elements in card. Each line represents a single index for content formatting. # It's possible to show multiple elements in one place by separating them with comma on single line. diff --git a/klippy/extras/display/menu.py b/klippy/extras/display/menu.py index 2830df99..07f3f3b8 100644 --- a/klippy/extras/display/menu.py +++ b/klippy/extras/display/menu.py @@ -5,7 +5,7 @@ # Copyright (C) 2018 Janar Sööt # # This file may be distributed under the terms of the GNU GPLv3 license. -import os, logging, sys, ast, re +import os, logging, sys, ast, re, string class error(Exception): @@ -573,7 +573,7 @@ class MenuGroup(MenuContainer): self._sep = sep self._show_back = False self.selected = None - self.items = config.get('items') + self.items = config.get('items', '') def is_accepted(self, item): return (super(MenuGroup, self).is_accepted(item) @@ -739,7 +739,7 @@ class MenuList(MenuContainer): super(MenuList, self).__init__(manager, config, namespace) self._enter_gcode = config.get('enter_gcode', None) self._leave_gcode = config.get('leave_gcode', None) - self.items = config.get('items') + self.items = config.get('items', '') def is_accepted(self, item): return (super(MenuList, self).is_accepted(item) @@ -799,6 +799,32 @@ class MenuCard(MenuGroup): def __init__(self, manager, config, namespace=''): super(MenuCard, self).__init__(manager, config, namespace) self.content = config.get('content') + if not self.items: + self.content = self._parse_content_items(self.content) + + def _parse_content_items(self, content): + formatter = string.Formatter() + out = "" + items = [] + + try: + parsed_content = list(formatter.parse(content)) + except Exception: + logging.exception("Card content parsing error") + + for part in parsed_content: + # (literal_text, field_name, format_spec, conversion) + out += part[0] + if part[1]: + out += "{%s%s%s}" % ( + len(items), + ("!" + part[3]) if part[3] else '', + (":" + part[2]) if part[2] else '', + ) + items.append(str(part[1])) + + self.items = "\n".join(items) + return out def _names_aslist(self): return self._lines_aslist(self.items) @@ -853,6 +879,18 @@ class MenuDeck(MenuList): self.menu = None self._show_back = False self._show_title = False + if not self.items: + card = MenuCard(self._manager, { + 'name': ' '.join([self._name, 'Card']), + 'use_cursor': config.get('use_cursor', 'false'), + 'allow_without_selection': config.get( + 'allow_without_selection', 'true'), + 'content': config.get('content') + }, self.namespace) + name = " ".join( + config.get_name().split()[1:]) + "__singlecarddeck__" + self._manager.add_menuitem(name, card) + self.items = name def _populate_menu(self): self.menu = None