Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5c60704

Browse files
Add mpos.ui.topmenu
1 parent8c4aa0d commit5c60704

File tree

1 file changed

+391
-0
lines changed

1 file changed

+391
-0
lines changed
Lines changed: 391 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,391 @@
1+
importlvglaslv
2+
3+
importmpos.ui
4+
frommpos.ui.animimportWidgetAnimator
5+
6+
NOTIFICATION_BAR_HEIGHT=24
7+
8+
CLOCK_UPDATE_INTERVAL=1000# 10 or even 1 ms doesn't seem to change the framerate but 100ms is enough
9+
WIFI_ICON_UPDATE_INTERVAL=1500
10+
BATTERY_ICON_UPDATE_INTERVAL=5000
11+
TEMPERATURE_UPDATE_INTERVAL=2000
12+
MEMFREE_UPDATE_INTERVAL=5000# not too frequent because there's a forced gc.collect() to give it a reliable value
13+
14+
DRAWER_ANIM_DURATION=300
15+
16+
17+
hide_bar_animation=None
18+
show_bar_animation=None
19+
show_bar_animation_start_value=-NOTIFICATION_BAR_HEIGHT
20+
show_bar_animation_end_value=0
21+
hide_bar_animation_start_value=show_bar_animation_end_value
22+
hide_bar_animation_end_value=show_bar_animation_start_value
23+
24+
drawer=None
25+
drawer_open=False
26+
bar_open=False
27+
28+
scroll_start_y=None
29+
30+
31+
# Widgets:
32+
notification_bar=None
33+
34+
defopen_drawer():
35+
globaldrawer_open,drawer
36+
ifnotdrawer_open:
37+
open_bar()
38+
drawer_open=True
39+
WidgetAnimator.show_widget(drawer,anim_type="slide_down",duration=1000,delay=0)
40+
drawer.scroll_to(0,0,lv.ANIM.OFF)# make sure it's at the top, not scrolled down
41+
42+
defclose_drawer(to_launcher=False):
43+
globaldrawer_open,drawer,foreground_app_name
44+
ifdrawer_open:
45+
drawer_open=False
46+
ifnotto_launcherandnotmpos.apps.is_launcher(mpos.ui.foreground_app_name):
47+
print(f"close_drawer: also closing bar because to_launcher is{to_launcher} and foreground_app_name is{foreground_app_name}")
48+
close_bar()
49+
WidgetAnimator.hide_widget(drawer,anim_type="slide_up",duration=1000,delay=0)
50+
51+
defopen_bar():
52+
print("opening bar...")
53+
globalbar_open,show_bar_animation,hide_bar_animation,notification_bar
54+
ifnotbar_open:
55+
#print("not open so opening...")
56+
bar_open=True
57+
hide_bar_animation.current_value=hide_bar_animation_end_value
58+
show_bar_animation.start()
59+
else:
60+
print("bar already open")
61+
62+
defclose_bar():
63+
globalbar_open,show_bar_animation,hide_bar_animation
64+
ifbar_open:
65+
bar_open=False
66+
show_bar_animation.current_value=show_bar_animation_end_value
67+
hide_bar_animation.start()
68+
69+
70+
71+
72+
defcreate_notification_bar():
73+
globalnotification_bar
74+
# Create notification bar
75+
notification_bar=lv.obj(lv.layer_top())
76+
notification_bar.set_size(lv.pct(100),NOTIFICATION_BAR_HEIGHT)
77+
notification_bar.set_pos(0,show_bar_animation_start_value)
78+
notification_bar.set_scrollbar_mode(lv.SCROLLBAR_MODE.OFF)
79+
notification_bar.set_scroll_dir(lv.DIR.NONE)
80+
notification_bar.set_style_border_width(0,0)
81+
notification_bar.set_style_radius(0,0)
82+
# Time label
83+
time_label=lv.label(notification_bar)
84+
time_label.set_text("00:00:00")
85+
time_label.align(lv.ALIGN.LEFT_MID,0,0)
86+
temp_label=lv.label(notification_bar)
87+
temp_label.set_text("00°C")
88+
temp_label.align_to(time_label,lv.ALIGN.OUT_RIGHT_MID,mpos.ui.pct_of_display_width(7),0)
89+
memfree_label=lv.label(notification_bar)
90+
memfree_label.set_text("")
91+
memfree_label.align_to(temp_label,lv.ALIGN.OUT_RIGHT_MID,mpos.ui.pct_of_display_width(7),0)
92+
#style = lv.style_t()
93+
#style.init()
94+
#style.set_text_font(lv.font_montserrat_8) # tiny font
95+
#memfree_label.add_style(style, 0)
96+
# Notification icon (bell)
97+
#notif_icon = lv.label(notification_bar)
98+
#notif_icon.set_text(lv.SYMBOL.BELL)
99+
#notif_icon.align_to(time_label, lv.ALIGN.OUT_RIGHT_MID, PADDING_TINY, 0)
100+
# Battery percentage
101+
#battery_label = lv.label(notification_bar)
102+
#battery_label.set_text("100%")
103+
#battery_label.align(lv.ALIGN.RIGHT_MID, 0, 0)
104+
#battery_label.add_flag(lv.obj.FLAG.HIDDEN)
105+
# Battery icon
106+
battery_icon=lv.label(notification_bar)
107+
battery_icon.set_text(lv.SYMBOL.BATTERY_FULL)
108+
#battery_icon.align_to(battery_label, lv.ALIGN.OUT_LEFT_MID, 0, 0)
109+
battery_icon.align(lv.ALIGN.RIGHT_MID,0,0)
110+
battery_icon.add_flag(lv.obj.FLAG.HIDDEN)# keep it hidden until it has a correct value
111+
# WiFi icon
112+
wifi_icon=lv.label(notification_bar)
113+
wifi_icon.set_text(lv.SYMBOL.WIFI)
114+
wifi_icon.align_to(battery_icon,lv.ALIGN.OUT_LEFT_MID,-mpos.ui.pct_of_display_width(1),0)
115+
wifi_icon.add_flag(lv.obj.FLAG.HIDDEN)
116+
# Update time
117+
defupdate_time(timer):
118+
hours=mpos.time.localtime()[3]
119+
minutes=mpos.time.localtime()[4]
120+
seconds=mpos.time.localtime()[5]
121+
time_label.set_text(f"{hours:02d}:{minutes:02d}:{seconds:02d}")
122+
123+
can_check_network=False
124+
try:
125+
importnetwork
126+
can_check_network=True
127+
exceptExceptionase:
128+
print("Warning: could not check WLAN status:",str(e))
129+
130+
defupdate_battery_icon(timer=None):
131+
percent=mpos.battery_voltage.get_battery_percentage()
132+
ifpercent>80:# 4.1V
133+
battery_icon.set_text(lv.SYMBOL.BATTERY_FULL)
134+
elifpercent>60:# 4.0V
135+
battery_icon.set_text(lv.SYMBOL.BATTERY_3)
136+
elifpercent>40:# 3.9V
137+
battery_icon.set_text(lv.SYMBOL.BATTERY_2)
138+
elifpercent>20:# 3.8V
139+
battery_icon.set_text(lv.SYMBOL.BATTERY_1)
140+
else:# > 3.7V
141+
battery_icon.set_text(lv.SYMBOL.BATTERY_EMPTY)
142+
battery_icon.remove_flag(lv.obj.FLAG.HIDDEN)
143+
# Percentage is not shown for now:
144+
#battery_label.set_text(f"{round(percent)}%")
145+
#battery_label.remove_flag(lv.obj.FLAG.HIDDEN)
146+
update_battery_icon()# run it immediately instead of waiting for the timer
147+
148+
defupdate_wifi_icon(timer):
149+
ifmpos.wifi.WifiService.is_connected():
150+
wifi_icon.remove_flag(lv.obj.FLAG.HIDDEN)
151+
else:
152+
wifi_icon.add_flag(lv.obj.FLAG.HIDDEN)
153+
154+
can_check_temperature=False
155+
try:
156+
importesp32
157+
can_check_temperature=True
158+
exceptExceptionase:
159+
print("Warning: can't check temperature sensor:",str(e))
160+
161+
defupdate_temperature(timer):
162+
ifcan_check_temperature:
163+
temp_label.set_text(f"{esp32.mcu_temperature()}°C")
164+
else:
165+
temp_label.set_text("42°C")
166+
167+
defupdate_memfree(timer):
168+
importgc
169+
gc.collect()# otherwise it goes down to 10% before shooting back up to 70%
170+
free=gc.mem_free()
171+
used=gc.mem_alloc()
172+
total_memory=gc.mem_free()+gc.mem_alloc()
173+
percentage=round(free*100/ (free+used))
174+
memfree_label.set_text(f"{percentage}%")
175+
176+
lv.timer_create(update_time,CLOCK_UPDATE_INTERVAL,None)
177+
lv.timer_create(update_temperature,TEMPERATURE_UPDATE_INTERVAL,None)
178+
lv.timer_create(update_memfree,MEMFREE_UPDATE_INTERVAL,None)
179+
lv.timer_create(update_wifi_icon,WIFI_ICON_UPDATE_INTERVAL,None)
180+
lv.timer_create(update_battery_icon,BATTERY_ICON_UPDATE_INTERVAL,None)
181+
182+
# hide bar animation
183+
globalhide_bar_animation
184+
hide_bar_animation=lv.anim_t()
185+
hide_bar_animation.init()
186+
hide_bar_animation.set_var(notification_bar)
187+
hide_bar_animation.set_values(0,-NOTIFICATION_BAR_HEIGHT)
188+
hide_bar_animation.set_time(2000)
189+
hide_bar_animation.set_custom_exec_cb(lambdanot_used,value :notification_bar.set_y(value))
190+
191+
# show bar animation
192+
globalshow_bar_animation
193+
show_bar_animation=lv.anim_t()
194+
show_bar_animation.init()
195+
show_bar_animation.set_var(notification_bar)
196+
show_bar_animation.set_values(show_bar_animation_start_value,show_bar_animation_end_value)
197+
show_bar_animation.set_time(1000)
198+
show_bar_animation.set_custom_exec_cb(lambdanot_used,value :notification_bar.set_y(value))
199+
200+
201+
202+
defcreate_drawer(display=None):
203+
globaldrawer
204+
drawer=lv.obj(lv.layer_top())
205+
drawer.set_size(lv.pct(100),lv.pct(90))
206+
drawer.set_pos(0,NOTIFICATION_BAR_HEIGHT)
207+
drawer.set_scroll_dir(lv.DIR.VER)
208+
drawer.set_style_pad_all(15,0)
209+
drawer.set_style_border_width(0,0)
210+
drawer.set_style_radius(0,0)
211+
drawer.add_flag(lv.obj.FLAG.HIDDEN)
212+
drawer.add_event_cb(drawer_scroll_callback,lv.EVENT.SCROLL_BEGIN,None)
213+
drawer.add_event_cb(drawer_scroll_callback,lv.EVENT.SCROLL,None)
214+
drawer.add_event_cb(drawer_scroll_callback,lv.EVENT.SCROLL_END,None)
215+
slider_label=lv.label(drawer)
216+
prefs=mpos.config.SharedPreferences("com.micropythonos.settings")
217+
brightness_int=prefs.get_int("display_brightness",100)
218+
ifdisplay:
219+
display.set_backlight(brightness_int)
220+
slider_label.set_text(f"Brightness:{brightness_int}%")
221+
slider_label.align(lv.ALIGN.TOP_MID,0,lv.pct(4))
222+
slider=lv.slider(drawer)
223+
slider.set_range(1,100)
224+
slider.set_value(int(brightness_int),False)
225+
slider.set_width(lv.pct(80))
226+
slider.align_to(slider_label,lv.ALIGN.OUT_BOTTOM_MID,0,10)
227+
defbrightness_slider_changed(e):
228+
brightness_int=slider.get_value()
229+
slider_label.set_text(f"Brightness:{brightness_int}%")
230+
ifdisplay:
231+
display.set_backlight(brightness_int)
232+
defbrightness_slider_released(e):
233+
brightness_int=slider.get_value()
234+
prefs=mpos.config.SharedPreferences("com.micropythonos.settings")
235+
old_brightness_int=prefs.get_int("display_brightness")
236+
ifold_brightness_int!=brightness_int:
237+
editor=prefs.edit()
238+
editor.put_int("display_brightness",brightness_int)
239+
editor.commit()
240+
slider.add_event_cb(brightness_slider_changed,lv.EVENT.VALUE_CHANGED,None)
241+
slider.add_event_cb(brightness_slider_released,lv.EVENT.RELEASED,None)
242+
drawer_button_pct=31
243+
wifi_btn=lv.button(drawer)
244+
wifi_btn.set_size(lv.pct(drawer_button_pct),lv.pct(20))
245+
wifi_btn.align(lv.ALIGN.LEFT_MID,0,0)
246+
wifi_label=lv.label(wifi_btn)
247+
wifi_label.set_text(lv.SYMBOL.WIFI+" WiFi")
248+
wifi_label.center()
249+
defwifi_event(e):
250+
close_drawer()
251+
mpos.apps.start_app_by_name("com.micropythonos.wifi")
252+
wifi_btn.add_event_cb(wifi_event,lv.EVENT.CLICKED,None)
253+
settings_btn=lv.button(drawer)
254+
settings_btn.set_size(lv.pct(drawer_button_pct),lv.pct(20))
255+
settings_btn.align(lv.ALIGN.RIGHT_MID,0,0)
256+
settings_label=lv.label(settings_btn)
257+
settings_label.set_text(lv.SYMBOL.SETTINGS+" Settings")
258+
settings_label.center()
259+
defsettings_event(e):
260+
close_drawer()
261+
mpos.apps.start_app_by_name("com.micropythonos.settings")
262+
settings_btn.add_event_cb(settings_event,lv.EVENT.CLICKED,None)
263+
launcher_btn=lv.button(drawer)
264+
launcher_btn.set_size(lv.pct(drawer_button_pct),lv.pct(20))
265+
launcher_btn.align(lv.ALIGN.CENTER,0,0)
266+
launcher_label=lv.label(launcher_btn)
267+
launcher_label.set_text(lv.SYMBOL.HOME+" Home")
268+
launcher_label.center()
269+
deflauncher_event(e):
270+
print("Home button pressed!")
271+
close_drawer(True)
272+
mpos.ui.show_launcher()
273+
launcher_btn.add_event_cb(launcher_event,lv.EVENT.CLICKED,None)
274+
'''
275+
sleep_btn=lv.button(drawer)
276+
sleep_btn.set_size(lv.pct(drawer_button_pct),lv.pct(20))
277+
sleep_btn.align(lv.ALIGN.BOTTOM_LEFT,0,0)
278+
sleep_label=lv.label(sleep_btn)
279+
sleep_label.set_text("Zz Sleep")
280+
sleep_label.center()
281+
def sleep_event(e):
282+
print("Sleep button pressed!")
283+
import sys
284+
if sys.platform == "esp32":
285+
#On ESP32, there's no power off but there's a hundred-year deepsleep.
286+
import machine
287+
machine.deepsleep(10000) # TODO: make it wakeup when it receives an interrupt from the accelerometer or a button press
288+
else: # assume unix:
289+
# maybe do a system suspend here? or at least show a popup toast "not supported"
290+
close_drawer(True)
291+
show_launcher()
292+
sleep_btn.add_event_cb(sleep_event,lv.EVENT.CLICKED,None)
293+
'''
294+
restart_btn=lv.button(drawer)
295+
restart_btn.set_size(lv.pct(45),lv.pct(20))
296+
restart_btn.align(lv.ALIGN.BOTTOM_LEFT,0,0)
297+
restart_label=lv.label(restart_btn)
298+
restart_label.set_text(lv.SYMBOL.REFRESH+" Reset")
299+
restart_label.center()
300+
defreset_cb(e):
301+
importmachine
302+
ifhasattr(machine,'reset'):
303+
machine.reset()
304+
elifhasattr(machine,'soft_reset'):
305+
machine.soft_reset()
306+
else:
307+
print("Warning: machine has no reset or soft_reset method available")
308+
restart_btn.add_event_cb(reset_cb,lv.EVENT.CLICKED,None)
309+
poweroff_btn=lv.button(drawer)
310+
poweroff_btn.set_size(lv.pct(45),lv.pct(20))
311+
poweroff_btn.align(lv.ALIGN.BOTTOM_RIGHT,0,0)
312+
poweroff_label=lv.label(poweroff_btn)
313+
poweroff_label.set_text(lv.SYMBOL.POWER+" Off")
314+
poweroff_label.center()
315+
defpoweroff_cb(e):
316+
print("Power off action...")
317+
remove_and_stop_current_activity()# make sure current app, like camera, does cleanup, saves progress, stops hardware etc.
318+
importsys
319+
ifsys.platform=="esp32":
320+
#On ESP32, there's no power off but there is a forever sleep
321+
importmachine
322+
# DON'T configure BOOT button (Pin 0) as wake-up source because it wakes up immediately.
323+
# Luckily, the RESET button can be used to wake it up.
324+
#wake_pin = machine.Pin(0, machine.Pin.IN, machine.Pin.PULL_UP) # Pull-up enabled, active low
325+
#import esp32
326+
#esp32.wake_on_ext0(pin=wake_pin, level=esp32.WAKEUP_ALL_LOW)
327+
print("Entering deep sleep. Press BOOT button to wake up.")
328+
machine.deepsleep()# sleep forever
329+
else:# assume unix:
330+
lv.deinit()# Deinitialize LVGL (if supported)
331+
sys.exit(0)
332+
poweroff_btn.add_event_cb(poweroff_cb,lv.EVENT.CLICKED,None)
333+
# Add invisible padding at the bottom to make the drawer scrollable
334+
l2=lv.label(drawer)
335+
l2.set_text("\n")
336+
l2.set_pos(0,mpos.ui.vertical_resolution)
337+
338+
339+
340+
341+
defdrawer_any_event(event):
342+
event_code=event.get_code()
343+
# Ignore:
344+
# =======
345+
# 19: HIT_TEST
346+
# COVER_CHECK
347+
# DRAW_MAIN
348+
# DRAW_MAIN_BEGIN
349+
# DRAW_MAIN_END
350+
# DRAW_POST
351+
# DRAW_POST_BEGIN
352+
# DRAW_POST_END
353+
# GET_SELF_SIZE
354+
# 47 STYLE CHANGED
355+
ifevent_codenotin [19,23,25,26,27,28,29,30,47,49]:
356+
name=mpos.ui.get_event_name(event_code)
357+
x,y=mpos.ui.get_pointer_xy()
358+
print(f"drawer_any_event: code={event_code}, name={name},{x},{y}")
359+
360+
drawer_swipe_start_y=0
361+
defdrawer_swipe_cb(event):
362+
globaldrawer_swipe_start_y
363+
event_code=event.get_code()
364+
name=mpos.ui.get_event_name(event_code)
365+
print(f"drawer_swipe_cb{event_code} and{name}")
366+
ifevent_code==lv.EVENT.PRESSED:
367+
x,drawer_swipe_start_y=mpos.ui.get_pointer_xy()
368+
elifevent_code==lv.EVENT.RELEASED:
369+
x,end_y=mpos.ui.get_pointer_xy()
370+
ifend_y<drawer_swipe_start_y-NOTIFICATION_BAR_HEIGHT:
371+
close_drawer()
372+
drawer_swipe_start_y=0
373+
374+
defdrawer_scroll_callback(event):
375+
globalscroll_start_y
376+
event_code=event.get_code()
377+
x,y=mpos.ui.get_pointer_xy()
378+
#name = mpos.ui.get_event_name(event_code)
379+
#print(f"drawer_scroll: code={event_code}, name={name}, ({x},{y})")
380+
ifevent_code==lv.EVENT.SCROLL_BEGINandscroll_start_y==None:
381+
scroll_start_y=y
382+
#print(f"scroll_starts at: {x},{y}")
383+
elifevent_code==lv.EVENT.SCROLLandscroll_start_y!=None:
384+
diff=y-scroll_start_y
385+
print(f"scroll distance:{diff}")
386+
ifdiff<-NOTIFICATION_BAR_HEIGHT:
387+
close_drawer()
388+
scroll_start_y=None
389+
elifevent_code==lv.EVENT.SCROLL_ENDandscroll_start_y!=None:
390+
scroll_start_y=None
391+

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp