feat: menu demo
This commit is contained in:
@@ -5,6 +5,7 @@ from time import sleep, time_ns
|
||||
|
||||
from machine import SPI, Pin
|
||||
|
||||
from encoder import Encoder
|
||||
from ili9341 import Display, color565
|
||||
|
||||
colors = {
|
||||
@@ -18,6 +19,12 @@ colors = {
|
||||
"NAVY": (0, 0, 128),
|
||||
}
|
||||
|
||||
menu = [
|
||||
"Option 1",
|
||||
"Option 2",
|
||||
"Option 3",
|
||||
]
|
||||
|
||||
|
||||
def display():
|
||||
bg = Pin(33, Pin.OUT)
|
||||
@@ -26,70 +33,80 @@ def display():
|
||||
|
||||
bg.on()
|
||||
|
||||
while True:
|
||||
encoder_a = Pin(2, Pin.IN, Pin.PULL_UP)
|
||||
encoder_b = Pin(4, Pin.IN, Pin.PULL_UP)
|
||||
|
||||
def draw_debug_text(text: str, y: int):
|
||||
display.draw_text8x8(
|
||||
10,
|
||||
10,
|
||||
"ILI9341 Display Test",
|
||||
y,
|
||||
text,
|
||||
color565(255, 255, 255),
|
||||
color565(0, 0, 0),
|
||||
270,
|
||||
)
|
||||
display.draw_text8x8(
|
||||
10,
|
||||
280,
|
||||
"PPAP",
|
||||
color565(255, 255, 255),
|
||||
color565(0, 0, 0),
|
||||
270,
|
||||
)
|
||||
sleep(1)
|
||||
# Calculate valid hlines parameters for display clear method
|
||||
valid_hlines = []
|
||||
for i in range(1, display.height):
|
||||
if display.height % i == 0:
|
||||
valid_hlines.append(i)
|
||||
# Ensure only 13 entries, truncate or repeat the last one
|
||||
valid_hlines = valid_hlines[:8]
|
||||
if len(valid_hlines) < 8:
|
||||
valid_hlines += [valid_hlines[-1]] * (8 - len(valid_hlines))
|
||||
# Ensure only 13 entries, truncate or repeat the last one
|
||||
valid_hlines = valid_hlines[:8]
|
||||
if len(valid_hlines) < 8:
|
||||
valid_hlines += [valid_hlines[-1]] * (8 - len(valid_hlines))
|
||||
|
||||
print("Clearing to black...")
|
||||
start = time_ns()
|
||||
display.clear()
|
||||
end = time_ns()
|
||||
print(f"Display cleared in {end - start} ms.")
|
||||
sleep(2)
|
||||
last_registered: int = time_ns()
|
||||
|
||||
print("Clearing to white...")
|
||||
start = time_ns()
|
||||
display.clear(color565(255, 255, 255))
|
||||
end = time_ns()
|
||||
print(f"Display cleared in {end - start} ms.")
|
||||
sleep(2)
|
||||
menu_index = 0
|
||||
|
||||
for hlines, (color, rgb) in zip(valid_hlines, colors.items()):
|
||||
def handle_button_pres(dir: str):
|
||||
nonlocal last_registered
|
||||
nonlocal menu_index
|
||||
|
||||
if (time_ns() - last_registered) < 100000000:
|
||||
return
|
||||
|
||||
last_registered = time_ns()
|
||||
|
||||
if dir == "Left":
|
||||
menu_index = (menu_index - 1) % 3
|
||||
elif dir == "Right":
|
||||
menu_index = (menu_index + 1) % 3
|
||||
else:
|
||||
return
|
||||
|
||||
refresh_display()
|
||||
|
||||
encoder = Encoder(
|
||||
encoder_a,
|
||||
encoder_b,
|
||||
on_left=lambda x: handle_button_pres("Left"),
|
||||
on_right=lambda x: handle_button_pres("Right"),
|
||||
)
|
||||
|
||||
display.clear(color=color565(*colors["BLUE"]))
|
||||
|
||||
display.draw_text8x8(
|
||||
10,
|
||||
10,
|
||||
"Menu:",
|
||||
color565(255, 255, 255),
|
||||
color565(0, 0, 0),
|
||||
)
|
||||
|
||||
display.draw_text8x8(
|
||||
230 - (8 * 4),
|
||||
10,
|
||||
"PPAP",
|
||||
color565(255, 255, 255),
|
||||
color565(0, 0, 0),
|
||||
)
|
||||
|
||||
def get_cursor(line: int):
|
||||
nonlocal menu_index
|
||||
if line == menu_index:
|
||||
return "> "
|
||||
else:
|
||||
return " "
|
||||
|
||||
def refresh_display():
|
||||
for i, line in enumerate(menu):
|
||||
display.draw_text8x8(
|
||||
10,
|
||||
10,
|
||||
f"Next color: {color}",
|
||||
18 + (i + 1) * 8,
|
||||
get_cursor(i) + line,
|
||||
color565(255, 255, 255),
|
||||
color565(0, 0, 0),
|
||||
270,
|
||||
)
|
||||
sleep(1)
|
||||
print(f"Clearing display to {color}, hlines={hlines}...")
|
||||
try:
|
||||
start = time_ns()
|
||||
display.clear(hlines=hlines, color=color565(*rgb))
|
||||
end = time_ns()
|
||||
print(f"Display cleared in {end - start} ms.")
|
||||
except Exception as e:
|
||||
print(e)
|
||||
sleep(1)
|
||||
|
||||
sleep(5)
|
||||
refresh_display()
|
||||
|
||||
10
encoder.py
Normal file
10
encoder.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from machine import Pin
|
||||
|
||||
|
||||
class Encoder:
|
||||
def __init__(self, pin_a: Pin, pin_b: Pin, on_left, on_right) -> None:
|
||||
self.pin_a = pin_a
|
||||
self.pin_b = pin_b
|
||||
pin_a.irq(trigger=Pin.IRQ_RISING, handler=on_left)
|
||||
pin_b.irq(trigger=Pin.IRQ_RISING, handler=on_right)
|
||||
pass
|
||||
4
main.py
4
main.py
@@ -13,5 +13,5 @@ import led_program
|
||||
import motor
|
||||
|
||||
# _thread.start_new_thread(led_program.boostrap, ())
|
||||
# _thread.start_new_thread(display_program.display, ())
|
||||
_thread.start_new_thread(motor.motor_run, ())
|
||||
_thread.start_new_thread(display_program.display, ())
|
||||
# _thread.start_new_thread(motor.motor_run, ())
|
||||
|
||||
76
menu.py
Normal file
76
menu.py
Normal file
@@ -0,0 +1,76 @@
|
||||
from this import d
|
||||
|
||||
from ili9341 import Display, color565
|
||||
|
||||
|
||||
class MenuItem:
|
||||
def __init__(self, name: str, navigate: str):
|
||||
self.name = name
|
||||
self.navigate = navigate
|
||||
|
||||
|
||||
class MenuPage:
|
||||
UP = 0
|
||||
DOWN = 1
|
||||
|
||||
def __init__(self, title: str, item: list[MenuItem]):
|
||||
self.title = title
|
||||
self.items = item
|
||||
self.items.append(MenuItem("Back", "Root"))
|
||||
self.cursor = 0
|
||||
|
||||
def size(self) -> int:
|
||||
return len(self.items)
|
||||
|
||||
def move(self, direction: int):
|
||||
match direction:
|
||||
case self.UP:
|
||||
self.cursor = (self.cursor + 1) % self.size()
|
||||
case self.DOWN:
|
||||
self.cursor = (self.cursor - 1) % self.size()
|
||||
|
||||
def draw(self) -> str:
|
||||
|
||||
lines: list[str] = []
|
||||
|
||||
for i, item in enumerate(self.items):
|
||||
if i == self.cursor:
|
||||
lines.append("> {item.name}\n")
|
||||
else:
|
||||
lines.append(" {item.name}\n")
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
def current_at_cursor(self, cursor: int) -> MenuItem:
|
||||
return self.items[cursor]
|
||||
|
||||
|
||||
class DisplayMenu:
|
||||
def __init__(self, display: Display, pages: list[MenuPage]):
|
||||
self.display = display
|
||||
self.pages = pages
|
||||
self.cursor = 0
|
||||
self.current_page = self.pages[0]
|
||||
self.update()
|
||||
|
||||
def __draw_display_line(self, line: str, offset: int):
|
||||
self.display.draw_text8x8(
|
||||
10,
|
||||
10 + (offset * 8),
|
||||
line,
|
||||
color565(255, 255, 255),
|
||||
color565(0, 0, 0),
|
||||
)
|
||||
|
||||
def move_up(self):
|
||||
self.current_page.move(MenuPage.UP)
|
||||
|
||||
def move_down(self):
|
||||
self.current_page.move(MenuPage.DOWN)
|
||||
|
||||
def select(self):
|
||||
pass
|
||||
|
||||
def update(self):
|
||||
self.__draw_display_line(self.current_page.title, 0)
|
||||
self.__draw_display_line(self.current_page.draw(), 2)
|
||||
Reference in New Issue
Block a user