Skip to content

Commit 817d579

Browse files
TinyuZhaolbuque
authored andcommitted
libs/m5ui: Add LVGL Menu widget.
Signed-off-by: tinyu <[email protected]>
1 parent 4599017 commit 817d579

File tree

3 files changed

+159
-0
lines changed

3 files changed

+159
-0
lines changed

m5stack/libs/m5ui/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"M5LED": "led",
2121
"M5Line": "line",
2222
"M5List": "list",
23+
"M5Menu": "menu",
2324
"M5Msgbox": "msgbox",
2425
"M5Page": "page",
2526
"M5Roller": "roller",

m5stack/libs/m5ui/manifest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"led.py",
2222
"line.py",
2323
"list.py",
24+
"menu.py",
2425
"msgbox.py",
2526
"page.py",
2627
"port.py",

m5stack/libs/m5ui/menu.py

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
# SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
from m5ui.base import M5Base
6+
import lvgl as lv
7+
import m5ui
8+
9+
10+
class M5Menu(lv.menu):
11+
"""Create a list object.
12+
13+
:param int x: The x position of the menu.
14+
:param int y: The y position of the menu.
15+
:param int w: The width of the menu.
16+
:param int h: The height of the menu.
17+
:param lv.obj parent: The parent object to attach the menu to. If not specified, the menu will be attached to the default screen.
18+
19+
UiFlow2 Code Block:
20+
21+
None
22+
23+
MicroPython Code Block:
24+
25+
.. code-block:: python
26+
27+
from m5ui import M5Menu
28+
import lvgl as lv
29+
30+
m5ui.init()
31+
menu0 = M5Menu(x=120, y=80, w=60, h=30, parent=page0)
32+
"""
33+
34+
def __init__(
35+
self,
36+
x=0,
37+
y=0,
38+
w=0,
39+
h=0,
40+
parent=None,
41+
):
42+
if parent is None:
43+
parent = lv.screen_active()
44+
super().__init__(parent)
45+
self.set_pos(x, y)
46+
self.set_size(w, h)
47+
self.main_page = lv.menu_page(self, None) # Create a main page
48+
49+
def add_label(
50+
self,
51+
text,
52+
text_c=0x212121,
53+
text_opa=255,
54+
bg_c=0xFFFFFF,
55+
bg_opa=255,
56+
font=lv.font_montserrat_14,
57+
parent=None,
58+
):
59+
"""Add a label to the menu.
60+
61+
:param str text: The text to display on the label.
62+
:param int text_c: The text color of the label.
63+
:param int bg_c: The background color of the label.
64+
:param int bg_opa: The background opacity of the label.
65+
:param lv.font_t font: The font of the label.
66+
:param lv.obj parent: The parent object to attach the label to. If not specified, the label will be attached to the main page of the menu.
67+
:return: The created label object.
68+
:rtype: :ref:`m5ui.M5Label <m5ui.M5Label>`
69+
70+
UiFlow2 Code Block:
71+
72+
|add_label.png|
73+
74+
|add_label2.png|
75+
76+
MicroPython Code Block:
77+
78+
.. code-block:: python
79+
80+
label0 = menu0.add_label("Hello, World!", text_c=0x212121, bg_c=0xFFFFFF, bg_opa=255, font=lv.font_montserrat_14, parent=menu0.main_page)
81+
"""
82+
if parent is None:
83+
parent = self.main_page
84+
_cont = lv.menu_cont(parent)
85+
_label = m5ui.M5Label(
86+
text=text, text_c=text_c, bg_c=bg_c, bg_opa=bg_opa, font=font, parent=_cont
87+
)
88+
_label.cont = _cont
89+
_label.set_style_text_opa(text_opa, lv.PART.MAIN | lv.STATE.DEFAULT)
90+
return _label
91+
92+
def add_switch(
93+
self,
94+
text,
95+
w=50,
96+
h=20,
97+
bg_c=0xE7E3E7,
98+
bg_opa=255,
99+
bg_c_checked=0x0288FB,
100+
bg_c_checked_opa=255,
101+
circle_c=0xFFFFFF,
102+
circle_opa=255,
103+
parent=None,
104+
):
105+
"""Add a switch to the menu.
106+
107+
:param str text: The text to display next to the switch.
108+
:param int w: The width of the switch.
109+
110+
:param int h: The height of the switch.
111+
:param int bg_c: The background color of the switch when unchecked.
112+
:param int bg_c_checked: The background color of the switch when checked.
113+
:param int circle_c: The color of the switch circle.
114+
:param lv.obj parent: The parent object to attach the switch to. If not specified, the switch will be attached to the main page of the menu.
115+
:return: The created switch object.
116+
:rtype: :ref:`m5ui.M5Switch <m5ui.M5Switch>`
117+
118+
UiFlow2 Code Block:
119+
120+
|add_switch.png|
121+
122+
|add_switch2.png|
123+
124+
MicroPython Code Block:
125+
126+
.. code-block:: python
127+
128+
switch_0 = menu0.add_switch("Switch 1", w=50, h=20, bg_c=0xE7E3E7, bg_c_checked=0x0288FB, circle_c=0xFFFFFF, parent=menu0.main_page)
129+
"""
130+
131+
if parent is None:
132+
parent = self.main_page
133+
_cont = lv.menu_cont(parent)
134+
_label = lv.label(_cont)
135+
_label.set_text(text)
136+
_label.set_long_mode(lv.label.LONG_MODE.SCROLL_CIRCULAR)
137+
_switch = m5ui.M5Switch(
138+
w=w,
139+
h=h,
140+
bg_c=bg_c,
141+
bg_c_checked=bg_c_checked,
142+
circle_c=circle_c,
143+
parent=_cont,
144+
)
145+
_switch.set_style_bg_opa(bg_opa, lv.PART.MAIN | lv.STATE.DEFAULT)
146+
_switch.set_style_bg_opa(bg_c_checked_opa, lv.PART.INDICATOR | lv.STATE.CHECKED)
147+
_switch.set_style_bg_opa(circle_opa, lv.PART.KNOB | lv.STATE.DEFAULT)
148+
149+
return _switch
150+
151+
def __getattr__(self, name):
152+
if hasattr(M5Base, name):
153+
method = getattr(M5Base, name)
154+
bound_method = lambda *args, **kwargs: method(self, *args, **kwargs)
155+
setattr(self, name, bound_method)
156+
return bound_method
157+
raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'")

0 commit comments

Comments
 (0)