4
4
from events .input import BUTTON_TYPES , ButtonDownEvent
5
5
from system .eventbus import eventbus
6
6
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
8
15
9
16
10
17
def ease_out_quart (x ):
@@ -16,6 +23,7 @@ def __init__(
16
23
self ,
17
24
app : App ,
18
25
menu_items : list [str ] = [],
26
+ info_items : list [str ] = [],
19
27
position = 0 ,
20
28
select_handler : Union [Callable [[str , int ], Any ], None ] = None ,
21
29
change_handler : Union [Callable [[str ], Any ], None ] = None ,
@@ -28,6 +36,7 @@ def __init__(
28
36
):
29
37
self .app = app
30
38
self .menu_items = menu_items
39
+ self .info_items = info_items
31
40
self .position = position
32
41
self .select_handler = select_handler
33
42
self .change_handler = change_handler
@@ -38,38 +47,61 @@ def __init__(
38
47
self .focused_item_font_size = focused_item_font_size
39
48
self .focused_item_margin = focused_item_margin
40
49
self .focused_item_font_size_arr = []
50
+ self .layout = LinearLayout (items = [])
51
+ self .show_info = False
41
52
42
53
self .animation_time_ms = 0
43
54
# self.is_animating: Literal["up", "down", "none"] = "none"
44
55
self .is_animating : Literal ["up" , "down" , "none" ] = "up"
45
56
46
- eventbus .on (ButtonDownEvent , self ._handle_buttondown , app )
57
+ eventbus .on_async (ButtonDownEvent , self ._handle_buttondown , app )
47
58
48
59
def _cleanup (self ):
49
60
eventbus .remove (ButtonDownEvent , self ._handle_buttondown , self .app )
50
61
51
- def _handle_buttondown (self , event : ButtonDownEvent ):
62
+ async def _handle_buttondown (self , event : ButtonDownEvent ):
52
63
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
+ )
58
72
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
+ )
64
81
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 ()
67
87
if BUTTON_TYPES ["CONFIRM" ] in event .button :
88
+ self .show_info = False
68
89
if self .select_handler is not None :
69
90
self .select_handler (
70
91
self .menu_items [self .position % len (self .menu_items )],
71
92
self .position % len (self .menu_items ),
72
93
)
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
73
105
74
106
def up_handler (self ):
75
107
self .is_animating = "up"
@@ -100,62 +132,73 @@ def _calculate_max_focussed_font_size(self, item, ctx):
100
132
return proposed_font_size
101
133
102
134
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 ])
159
202
160
203
def update (self , delta ):
161
204
if self .is_animating != "none" :
0 commit comments