Select Git revision
port_diag.py
-
Paul Sokolovsky authored
A shortcut for users to provide background diagnostic info for bug reports.
Paul Sokolovsky authoredA shortcut for users to provide background diagnostic info for bug reports.
menu.py 5.91 KiB
import ui
import time
import hardware
import math
import event
menu_stack = []
active_menu = None
class Menu():
def __init__(self,name="menu",has_back=True):
self.name=name
self.items=[]
self.__index = 0
self.ui = ui.GroupRing(r=80)
self.ui.element_center = ui.Text(self.name)
self.icon = ui.Icon(label=name)
self.angle = 0
self.angle_step= 0.2
if has_back:
self.add(MenuItemBack())
def __repr__(self):
return "{} ({}): {}".format(self.name, self.__index, self.items)
def add(self, item):
self.items.append(item)
self.ui.add(item.ui)
def pop(self):
self.items.pop()
self.ui.children.pop()
def start(self):
print(self)
active_menu = self
render()
def scroll(self, n=0):
self.__index= (self.__index+n)%len(self.items)
return self.items[self.__index]
def rotate_by(self,angle):
self.rotate_to(self.angle+angle)
def rotate_to(self, angle):
self.angle = angle%(math.pi*2)
self.ui.angle_offset = self.angle
def rotate_steps(self, steps=1):
self.rotate_by(self.angle_step*steps)
def _get_hovered_index(self):
index = round(-self.angle/(math.pi*2)*len(self.items))
i = index%len(self.items)
return i
def get_hovered_item(self):
return self.items[self._get_hovered_index()]
def _get_angle_for_index(self,index):
return (math.pi*2/len(self.items)*(index)+self.angle)%(math.pi*2)
def _get_topness_for_index(self,index):
angle = self._get_angle_for_index(index)
dist = min(angle,math.pi*2-angle)
topness = 1-(dist/math.pi)
return topness
def draw(self):
hovered_index = self._get_hovered_index()
for i in range(len(self.items)):
item = self.items[i]
my_extra = abs(self._get_topness_for_index(i))*40
if i == hovered_index:
item.ui.has_highlight=True
my_extra+=20
else:
item.ui.has_highlight=False
item.ui.size=30+my_extra
self.ui.draw()
class MenuItem():
def __init__(self,name="item",action=None):
self.name= name
self.action= action
self.ui = ui.Icon(label=name)
def __repr__(self):
return "item: {} (action: {})".format(self.name,"?")
def enter(self,data={}):
print("Enter MenuItem {}".format(self.name))
if self.action:
self.action(data)
class MenuItemApp(MenuItem):
def __init__(self,app):
super().__init__(name=app.title)
self.target = app
def enter(self,data={}):
if self.target:
self.target.run()
class MenuItemSubmenu(MenuItem):
def __init__(self,submenu):
super().__init__(name=submenu.name)
self.ui = submenu.icon
self.target = submenu
def enter(self,data={}):
print("Enter Submenu {}".format(self.target.name))
menu_stack.append(active_menu)
set_active_menu(self.target)
class MenuItemBack(MenuItem):
def __init__(self):
super().__init__(name="<-")
def enter(self,data={}):
menu_back()
class MenuItemControl(MenuItem):
def __init__(self,name,control):
super().__init__(name=name)
self.control=control
self.ui=control.ui
def enter(self):
print("menu enter")
self.control.enter()
def scroll(self,delta):
self.control.scroll(delta)
def on_scroll(d):
if active_menu is None:
return
if d["index"]==0:#right button
hovered=active_menu.get_hovered_item()
if hasattr(hovered, "scroll"):
hovered.scroll(d["value"])
else: #index=1, #left button
if active_menu.angle_step<0.5:
active_menu.angle_step+=0.025
if d["value"] == -1:
active_menu.rotate_steps(-1)
elif d["value"] == 1:
active_menu.rotate_steps(1)
render()
def on_scroll_captouch(d):
if active_menu is None:
return
if abs(d["radius"]) < 10000:
return
print(d["angle"])
active_menu.rotate_to(d["angle"]+math.pi)
render()
def on_release(d):
if active_menu is None:
return
active_menu.angle_step = 0.2
render()
def on_enter(d):
if active_menu is None:
#TODO this should not bee needed...
event.the_engine.userloop=None
menu_back()
return
if active_menu:
active_menu.get_hovered_item().enter()
render()
else:
return
event.Event(name="menu rotation button",group_id="menu",
condition=lambda e: e["type"] =="button" and not e["change"] and abs(e["value"])==1,
action=on_scroll, enabled=True
)
event.Event(name="menu rotation captouch",group_id="menu",
condition=lambda e: e["type"] =="captouch" and not e["change"] and abs(e["value"])==1 and e["index"]==2,
action=on_scroll_captouch, enabled=False
)
event.Event(name="menu rotation button release",group_id="menu",
condition=lambda e: e["type"] =="button" and e["change"] and e["value"] ==0,
action=on_release, enabled=True
)
event.Event(name="menu button enter",group_id="menu",
condition=lambda e: e["type"] =="button" and e["change"] and e["from"] == 2,
action=on_enter, enabled=True
)
def render():
print (active_menu)
if active_menu is None:
return
ui.the_ctx.rectangle(-120,-120,240,240).rgb(0,0,0).fill()
active_menu.draw()
#hardware.display_update()
def set_active_menu(menu):
global active_menu
active_menu = menu
def menu_disable():
global active_menu
if active_menu:
menu_stack.append(active_menu)
active_menu=None
def menu_back():
if not menu_stack:
return
previous = menu_stack.pop()
set_active_menu(previous)
render()