Files
controller-wisetopdataserver/python/biopro/devlib/menu.py
T
2021-12-20 14:52:55 +08:00

165 lines
3.6 KiB
Python

import abc
from typing import Any, Optional, Union, List, Dict
from biopro.util.json import JsonSerialize
class MenuEntry(JsonSerialize, metaclass=abc.ABCMeta):
"""menu entry
**json format**
::
MenuEntry = {
"name" :str
"text" :str
"description" :str?
}
"""
__slots__ = ('name', 'text', 'desp')
def __init__(self,
name: str,
text: str,
desp: Optional[str] = None):
self.name = name
self.text = text
self.desp = desp
def as_json(self) -> Dict[str, Any]:
return {
'name': self.name,
'text': self.text,
'description': self.desp
}
class MenuItem(MenuEntry):
"""menu item
**json format**
::
MenuItem (MenuEntry) = {
"command" :str?
"active" :bool
}
"""
__slots__ = ('command', 'active')
def __init__(self,
name: str,
text: str,
desp: Optional[str] = None,
command: Union[None, str, List[str]] = None,
active: bool = False):
super().__init__(name, text, desp)
if isinstance(command, list):
self.command: Optional[str] = ';'.join(command)
else:
self.command: Optional[str] = command
self.active = active
def as_json(self):
ret = super().as_json()
ret.update({
'command': self.command,
'active': self.active
})
return ret
class Menu(MenuEntry):
"""menu
**json format**
::
Menu (MenuEntry) = {
"menu" :[MenuEntry]
}
"""
__slots__ = ('_menu',)
# XXX condition menu?
def __init__(self,
name: str,
text: str,
menu: List[MenuEntry] = None,
desp: Optional[str] = None):
super().__init__(name, text, desp)
self._menu: List[MenuEntry] = menu if menu is not None else []
def __len__(self):
return len(self._menu)
def __getitem__(self, index: int) -> MenuEntry:
return self._menu[index]
def __setitem__(self, index: int, value: MenuEntry):
self._menu[index] = value
def __delitem__(self, index: Union[int, slice]):
del self._menu[index]
def __iter__(self):
return iter(self._menu)
def append(self, menu: MenuEntry):
self._menu.append(menu)
def append_item(self,
name: str,
text: str,
desp: Optional[str] = None,
command: Union[None, str, List[str]] = None,
active: bool = False) -> MenuItem:
e = MenuItem(name, text, desp=desp, command=command, active=active)
self._menu.append(e)
return e
def append_menu(self,
name: str,
text: str,
menu: List[MenuEntry] = None,
desp: Optional[str] = None) -> 'Menu':
e = Menu(name, text, desp=desp, menu=menu)
self._menu.append(e)
return e
def extend(self, menu: Union[List[MenuEntry], 'Menu']):
if isinstance(menu, Menu):
self._menu.extend(menu._menu)
elif isinstance(menu, list):
self._menu.extend(menu)
else:
raise TypeError(menu.__class__.__name__)
def as_json(self):
ret = super().as_json()
ret.update({
'menu': [v.as_json() for v in self._menu]
})
return ret