Skip to content

Commit 893f10f

Browse files
committed
Add information option to Menu widget
1 parent 73c0310 commit 893f10f

File tree

2 files changed

+118
-71
lines changed

2 files changed

+118
-71
lines changed

modules/app_components/menu.py

Lines changed: 114 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,14 @@
44
from events.input import BUTTON_TYPES, ButtonDownEvent
55
from system.eventbus import eventbus
66

7-
from .tokens import heading_font_size, label_font_size, line_height, set_color
7+
from .tokens import (
8+
heading_font_size,
9+
label_font_size,
10+
line_height,
11+
set_color,
12+
clear_background,
13+
)
14+
from .layout import TextDisplay, LinearLayout
815

916

1017
def ease_out_quart(x):
@@ -16,6 +23,7 @@ def __init__(
1623
self,
1724
app: App,
1825
menu_items: list[str] = [],
26+
info_items: list[str] = [],
1927
position=0,
2028
select_handler: Union[Callable[[str, int], Any], None] = None,
2129
change_handler: Union[Callable[[str], Any], None] = None,
@@ -28,6 +36,7 @@ def __init__(
2836
):
2937
self.app = app
3038
self.menu_items = menu_items
39+
self.info_items = info_items
3140
self.position = position
3241
self.select_handler = select_handler
3342
self.change_handler = change_handler
@@ -38,38 +47,61 @@ def __init__(
3847
self.focused_item_font_size = focused_item_font_size
3948
self.focused_item_margin = focused_item_margin
4049
self.focused_item_font_size_arr = []
50+
self.layout = LinearLayout(items=[])
51+
self.show_info = False
4152

4253
self.animation_time_ms = 0
4354
# self.is_animating: Literal["up", "down", "none"] = "none"
4455
self.is_animating: Literal["up", "down", "none"] = "up"
4556

46-
eventbus.on(ButtonDownEvent, self._handle_buttondown, app)
57+
eventbus.on_async(ButtonDownEvent, self._handle_buttondown, app)
4758

4859
def _cleanup(self):
4960
eventbus.remove(ButtonDownEvent, self._handle_buttondown, self.app)
5061

51-
def _handle_buttondown(self, event: ButtonDownEvent):
62+
async def _handle_buttondown(self, event: ButtonDownEvent):
5263
if BUTTON_TYPES["UP"] in event.button:
53-
self.up_handler()
54-
if self.change_handler is not None:
55-
self.change_handler(
56-
self.menu_items[self.position % len(self.menu_items)]
57-
)
64+
if self.show_info and self.info_items:
65+
await self.layout.button_event(event)
66+
else:
67+
self.up_handler()
68+
if self.change_handler is not None:
69+
self.change_handler(
70+
self.menu_items[self.position % len(self.menu_items)]
71+
)
5872
if BUTTON_TYPES["DOWN"] in event.button:
59-
self.down_handler()
60-
if self.change_handler is not None:
61-
self.change_handler(
62-
self.menu_items[self.position % len(self.menu_items)]
63-
)
73+
if self.show_info and self.info_items:
74+
await self.layout.button_event(event)
75+
else:
76+
self.down_handler()
77+
if self.change_handler is not None:
78+
self.change_handler(
79+
self.menu_items[self.position % len(self.menu_items)]
80+
)
6481
if BUTTON_TYPES["CANCEL"] in event.button:
65-
if self.back_handler is not None:
66-
self.back_handler()
82+
if self.show_info:
83+
self.show_info = False
84+
else:
85+
if self.back_handler is not None:
86+
self.back_handler()
6787
if BUTTON_TYPES["CONFIRM"] in event.button:
88+
self.show_info = False
6889
if self.select_handler is not None:
6990
self.select_handler(
7091
self.menu_items[self.position % len(self.menu_items)],
7192
self.position % len(self.menu_items),
7293
)
94+
if BUTTON_TYPES["RIGHT"] in event.button:
95+
self.layout.items = []
96+
if self.info_items:
97+
entry = TextDisplay(
98+
self.info_items[self.position % len(self.info_items)]
99+
)
100+
self.layout.items.append(entry)
101+
self.show_info = True
102+
if BUTTON_TYPES["LEFT"] in event.button:
103+
self.layout.items = []
104+
self.show_info = False
73105

74106
def up_handler(self):
75107
self.is_animating = "up"
@@ -100,62 +132,73 @@ def _calculate_max_focussed_font_size(self, item, ctx):
100132
return proposed_font_size
101133

102134
def draw(self, ctx):
103-
# calculate biggest font size a menu item should grow to
104-
if not self.focused_item_font_size_arr:
105-
for item in self.menu_items:
106-
fs = self._calculate_max_focussed_font_size(item, ctx)
107-
self.focused_item_font_size_arr = self.focused_item_font_size_arr + [fs]
108-
109-
animation_progress = ease_out_quart(self.animation_time_ms / self.speed_ms)
110-
animation_direction = 1 if self.is_animating == "up" else -1
111-
112-
ctx.text_align = ctx.CENTER
113-
ctx.text_baseline = ctx.MIDDLE
114-
115-
set_color(ctx, "label")
116-
num_menu_items = len(self.menu_items)
117-
118-
# Current menu item
119-
ctx.font_size = self.item_font_size + animation_progress * (
120-
self.focused_item_font_size_arr[
121-
self.position % num_menu_items if num_menu_items > 0 else 1
122-
]
123-
- self.item_font_size
124-
)
125-
126-
label = ""
127-
try:
128-
label = self.menu_items[
129-
self.position % num_menu_items if num_menu_items > 0 else 1
130-
]
131-
except IndexError:
132-
label = "Empty Menu"
133-
ctx.move_to(
134-
0, animation_direction * -30 + animation_progress * animation_direction * 30
135-
).text(label)
136-
137-
# Previous menu items
138-
ctx.font_size = self.item_font_size
139-
for i in range(1, 4):
140-
if (self.position - i) >= 0 and len(self.menu_items):
141-
ctx.move_to(
142-
0,
143-
-self.focused_item_margin
144-
+ -i * self.item_line_height
145-
- animation_direction * 30
146-
+ animation_progress * animation_direction * 30,
147-
).text(self.menu_items[self.position - i])
148-
149-
# Next menu items
150-
for i in range(1, 4):
151-
if (self.position + i) < len(self.menu_items):
152-
ctx.move_to(
153-
0,
154-
self.focused_item_margin
155-
+ i * self.item_line_height
156-
- animation_direction * 30
157-
+ animation_progress * animation_direction * 30,
158-
).text(self.menu_items[self.position + i])
135+
if self.show_info and self.info_items:
136+
# show info for item
137+
ctx.save()
138+
clear_background(ctx)
139+
self.layout.draw(ctx)
140+
ctx.restore()
141+
else:
142+
# calculate biggest font size a menu item should grow to
143+
if not self.focused_item_font_size_arr:
144+
for item in self.menu_items:
145+
fs = self._calculate_max_focussed_font_size(item, ctx)
146+
self.focused_item_font_size_arr = (
147+
self.focused_item_font_size_arr + [fs]
148+
)
149+
150+
animation_progress = ease_out_quart(self.animation_time_ms / self.speed_ms)
151+
animation_direction = 1 if self.is_animating == "up" else -1
152+
153+
ctx.text_align = ctx.CENTER
154+
ctx.text_baseline = ctx.MIDDLE
155+
156+
set_color(ctx, "label")
157+
num_menu_items = len(self.menu_items)
158+
159+
# Current menu item
160+
ctx.font_size = self.item_font_size + animation_progress * (
161+
self.focused_item_font_size_arr[
162+
self.position % num_menu_items if num_menu_items > 0 else 1
163+
]
164+
- self.item_font_size
165+
)
166+
167+
label = ""
168+
try:
169+
label = self.menu_items[
170+
self.position % num_menu_items if num_menu_items > 0 else 1
171+
]
172+
except IndexError:
173+
label = "Empty Menu"
174+
ctx.move_to(
175+
0,
176+
animation_direction * -30
177+
+ animation_progress * animation_direction * 30,
178+
).text(label)
179+
180+
# Previous menu items
181+
ctx.font_size = self.item_font_size
182+
for i in range(1, 4):
183+
if (self.position - i) >= 0 and len(self.menu_items):
184+
ctx.move_to(
185+
0,
186+
-self.focused_item_margin
187+
+ -i * self.item_line_height
188+
- animation_direction * 30
189+
+ animation_progress * animation_direction * 30,
190+
).text(self.menu_items[self.position - i])
191+
192+
# Next menu items
193+
for i in range(1, 4):
194+
if (self.position + i) < len(self.menu_items):
195+
ctx.move_to(
196+
0,
197+
self.focused_item_margin
198+
+ i * self.item_line_height
199+
- animation_direction * 30
200+
+ animation_progress * animation_direction * 30,
201+
).text(self.menu_items[self.position + i])
159202

160203
def update(self, delta):
161204
if self.is_animating != "none":

modules/firmware_apps/app_store.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ def exit_available_menu():
144144
self.available_menu = Menu(
145145
self,
146146
menu_items=[app["manifest"]["app"]["name"] for app in self.app_store_index],
147+
info_items=[
148+
app["manifest"]["metadata"]["description"]
149+
for app in self.app_store_index
150+
],
147151
select_handler=on_select,
148152
back_handler=exit_available_menu,
149153
focused_item_font_size=fourteen_pt,

0 commit comments

Comments
 (0)