Skip to content
Snippets Groups Projects
Verified Commit 3030f5f9 authored by rahix's avatar rahix
Browse files

feat(simple_menu): Add side-scrolling for long lines


Signed-off-by: default avatarRahix <rahix@rahix.de>
parent 08c02c48
No related branches found
No related tags found
No related merge requests found
...@@ -73,6 +73,10 @@ def button_events(timeout=None): ...@@ -73,6 +73,10 @@ def button_events(timeout=None):
yield buttons.TOP_RIGHT yield buttons.TOP_RIGHT
class _ExitMenuException(Exception):
pass
class Menu: class Menu:
""" """
A simple menu for card10. A simple menu for card10.
...@@ -101,6 +105,13 @@ class Menu: ...@@ -101,6 +105,13 @@ class Menu:
color_sel = color.COMMYELLOW color_sel = color.COMMYELLOW
"""Color of the selector.""" """Color of the selector."""
scroll_speed = 0.5
"""
Time to wait before scrolling to the right.
.. versionadded:: 1.9
"""
def on_scroll(self, item, index): def on_scroll(self, item, index):
""" """
Hook when the selector scrolls to a new item. Hook when the selector scrolls to a new item.
...@@ -126,12 +137,21 @@ class Menu: ...@@ -126,12 +137,21 @@ class Menu:
""" """
pass pass
def exit(self):
"""
Exit the event-loop. This should be called from inside an ``on_*`` hook.
.. versionadded:: 1.9
"""
raise _ExitMenuException()
def __init__(self, entries): def __init__(self, entries):
if len(entries) == 0: if len(entries) == 0:
raise ValueError("at least one entry is required") raise ValueError("at least one entry is required")
self.entries = entries self.entries = entries
self.idx = 0 self.idx = 0
self.select_time = utime.time_ms()
self.disp = display.open() self.disp = display.open()
def entry2name(self, value): def entry2name(self, value):
...@@ -166,8 +186,21 @@ class Menu: ...@@ -166,8 +186,21 @@ class Menu:
but **not** an index into ``entries``. but **not** an index into ``entries``.
:param int offset: Y-offset for this entry. :param int offset: Y-offset for this entry.
""" """
string = self.entry2name(value)
if offset != 20 or len(string) < 10:
string = " " + string + " " * 9
else:
# Slowly scroll entry to the side
time_offset = (utime.time_ms() - self.select_time) // int(
self.scroll_speed * 1000
)
time_offset = time_offset % (len(string) - 7) - 1
time_offset = min(len(string) - 10, max(0, time_offset))
string = " " + string[time_offset:]
self.disp.print( self.disp.print(
" " + self.entry2name(value) + " " * 9, string,
posy=offset, posy=offset,
fg=self.color_text, fg=self.color_text,
bg=self.color_1 if index % 2 == 0 else self.color_2, bg=self.color_1 if index % 2 == 0 else self.color_2,
...@@ -220,8 +253,10 @@ class Menu: ...@@ -220,8 +253,10 @@ class Menu:
def run(self): def run(self):
"""Start the event-loop.""" """Start the event-loop."""
for ev in button_events(): try:
for ev in button_events(timeout=self.scroll_speed):
if ev == buttons.BOTTOM_RIGHT: if ev == buttons.BOTTOM_RIGHT:
self.select_time = utime.time_ms()
self.draw_menu(-8) self.draw_menu(-8)
self.idx = (self.idx + 1) % len(self.entries) self.idx = (self.idx + 1) % len(self.entries)
try: try:
...@@ -230,6 +265,7 @@ class Menu: ...@@ -230,6 +265,7 @@ class Menu:
print("Exception during menu.on_scroll():") print("Exception during menu.on_scroll():")
sys.print_exception(e) sys.print_exception(e)
elif ev == buttons.BOTTOM_LEFT: elif ev == buttons.BOTTOM_LEFT:
self.select_time = utime.time_ms()
self.draw_menu(8) self.draw_menu(8)
self.idx = (self.idx + len(self.entries) - 1) % len(self.entries) self.idx = (self.idx + len(self.entries) - 1) % len(self.entries)
try: try:
...@@ -240,6 +276,7 @@ class Menu: ...@@ -240,6 +276,7 @@ class Menu:
elif ev == buttons.TOP_RIGHT: elif ev == buttons.TOP_RIGHT:
try: try:
self.on_select(self.entries[self.idx], self.idx) self.on_select(self.entries[self.idx], self.idx)
self.select_time = utime.time_ms()
except Exception as e: except Exception as e:
print("Menu crashed!") print("Menu crashed!")
sys.print_exception(e) sys.print_exception(e)
...@@ -247,3 +284,5 @@ class Menu: ...@@ -247,3 +284,5 @@ class Menu:
utime.sleep(1.0) utime.sleep(1.0)
self.draw_menu() self.draw_menu()
except _ExitMenuException:
pass
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment