Added MenuEntry class
This commit is contained in:
parent
49983fa4e1
commit
0623b070c3
1 changed files with 47 additions and 20 deletions
|
|
@ -15,11 +15,43 @@ COLORS = {
|
||||||
'PURPLE': '\033[35m',
|
'PURPLE': '\033[35m',
|
||||||
'CYAN': '\033[36m',
|
'CYAN': '\033[36m',
|
||||||
}
|
}
|
||||||
|
VALID_ENTRY_TYPES = (
|
||||||
|
'Action',
|
||||||
|
'Option',
|
||||||
|
'Set',
|
||||||
|
'Toggle',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Classes
|
# Classes
|
||||||
|
class MenuEntry():
|
||||||
|
"""Class for advanced menu entries"""
|
||||||
|
# pylint: disable=too-few-public-methods
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
kwargs = {str(k).lower(): v for k, v in kwargs.items()}
|
||||||
|
self.name = kwargs.pop('name', None)
|
||||||
|
self.type = kwargs.pop('type', None)
|
||||||
|
self.disabled = kwargs.pop('disabled', False)
|
||||||
|
self.hidden = kwargs.pop('hidden', False)
|
||||||
|
self.selected = kwargs.pop('selected', False)
|
||||||
|
self.separator = kwargs.pop('separator', False)
|
||||||
|
|
||||||
|
# Other attributes
|
||||||
|
for _key, _value in kwargs.items():
|
||||||
|
setattr(self, _key, kwargs.get(_key))
|
||||||
|
del kwargs
|
||||||
|
|
||||||
|
# Check attributes
|
||||||
|
self.check()
|
||||||
|
|
||||||
|
def check(self):
|
||||||
|
"""Check for invalid or missing attributes."""
|
||||||
|
assert self.name, 'Invalid menu entry name.'
|
||||||
|
assert self.type in VALID_ENTRY_TYPES, 'Invalid menu entry type.'
|
||||||
|
|
||||||
|
|
||||||
class MenuState():
|
class MenuState():
|
||||||
"""Class to track various parts of a menu."""
|
"""Class to track various parts of the advanced menu."""
|
||||||
def __init__(self, title):
|
def __init__(self, title):
|
||||||
self.checkmark = '✓' if 'DISPLAY' in os.environ else '*'
|
self.checkmark = '✓' if 'DISPLAY' in os.environ else '*'
|
||||||
self.entries = OrderedDict({})
|
self.entries = OrderedDict({})
|
||||||
|
|
@ -28,21 +60,16 @@ class MenuState():
|
||||||
self.sep_len = 0
|
self.sep_len = 0
|
||||||
self.title = title
|
self.title = title
|
||||||
|
|
||||||
def add_entry(self, name, kind, **kwargs):
|
def add_entry(self, **kwargs):
|
||||||
"""Add entry and update state."""
|
"""Add entry and update state."""
|
||||||
if name in self.entries:
|
_e = MenuEntry(**kwargs)
|
||||||
raise Exception('Entry {} already exists.'.format(name))
|
assert _e.name not in self.entries, 'Duplicate menu entry.'
|
||||||
|
|
||||||
# Add to entries
|
# Add to entries
|
||||||
self.entries[name] = {
|
self.entries[_e.name] = _e
|
||||||
'Kind': kind,
|
|
||||||
'Selected': False,
|
|
||||||
'Disabled': kwargs.get('Disabled', False),
|
|
||||||
}
|
|
||||||
self.entries[name].update(**kwargs)
|
|
||||||
|
|
||||||
# Update sep length
|
# Update sep length
|
||||||
self.sep_len = max(len(name), self.sep_len)
|
self.sep_len = max(len(_e.name), self.sep_len)
|
||||||
|
|
||||||
def make_single_selection(self):
|
def make_single_selection(self):
|
||||||
"""Select single entry."""
|
"""Select single entry."""
|
||||||
|
|
@ -51,31 +78,31 @@ class MenuState():
|
||||||
valid_answers = {}
|
valid_answers = {}
|
||||||
|
|
||||||
# Safety Check
|
# Safety Check
|
||||||
assert self.entries, "No menu entries defined."
|
assert self.entries, 'No menu entries defined.'
|
||||||
|
|
||||||
# Build Menu
|
# Build Menu
|
||||||
i = 1
|
i = 1
|
||||||
for name, details in self.entries.items():
|
for name, entry in self.entries.items():
|
||||||
# Skip sets
|
# Skip sets
|
||||||
if details['Kind'] in ('Set', 'Toggle'):
|
if entry.type in ('Set', 'Toggle'):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Separators
|
# Separators
|
||||||
if details.get('Separator', False):
|
if entry.separator:
|
||||||
display_list.append(self.sep * _sep_len)
|
display_list.append(self.sep * _sep_len)
|
||||||
|
|
||||||
# Entries
|
# Entries
|
||||||
_prefix = None
|
_prefix = None
|
||||||
if details['Kind'] == 'Option':
|
if entry.type == 'Option':
|
||||||
_prefix = str(i)
|
_prefix = str(i)
|
||||||
i += 1
|
i += 1
|
||||||
elif details['Kind'] == 'Action':
|
elif entry.type == 'Action':
|
||||||
_prefix = name[0:1].upper()
|
_prefix = name[0:1].upper()
|
||||||
display_list.append('{}: {}'.format(_prefix, name))
|
display_list.append('{}: {}'.format(_prefix, name))
|
||||||
valid_answers[_prefix] = name
|
valid_answers[_prefix] = name
|
||||||
|
|
||||||
# Disable entry if necessary
|
# Disable entry if necessary
|
||||||
if details['Disabled']:
|
if entry.disabled:
|
||||||
display_list[-1] = '{ORANGE}{text}{CLEAR}'.format(
|
display_list[-1] = '{ORANGE}{text}{CLEAR}'.format(
|
||||||
text=display_list[-1],
|
text=display_list[-1],
|
||||||
**COLORS,
|
**COLORS,
|
||||||
|
|
@ -83,7 +110,7 @@ class MenuState():
|
||||||
valid_answers.pop(_prefix)
|
valid_answers.pop(_prefix)
|
||||||
|
|
||||||
# Hide action entry if necessary
|
# Hide action entry if necessary
|
||||||
if details['Kind'] == 'Action' and details.get('Hidden', False):
|
if entry.type == 'Action' and entry.hidden:
|
||||||
display_list.pop()
|
display_list.pop()
|
||||||
|
|
||||||
# Show Menu and make selection
|
# Show Menu and make selection
|
||||||
|
|
@ -110,4 +137,4 @@ def clear():
|
||||||
os.system('clear')
|
os.system('clear')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
print("This file is not meant to be called directly.")
|
print('This file is not meant to be called directly.')
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue