118 lines
3.9 KiB
Python
118 lines
3.9 KiB
Python
# screensaver.py
|
|
import time
|
|
import board_config
|
|
|
|
def run_screensaver(duration_sec=120):
|
|
display = board_config.display_instance
|
|
touch = board_config.touch
|
|
|
|
if not display:
|
|
print("No display found")
|
|
return
|
|
|
|
width = display.width
|
|
height = display.height
|
|
|
|
# Calculate card dimensions based on screen size
|
|
card_w = int(width * 0.4)
|
|
card_h = int(height * 0.6)
|
|
y_offset = int((height - card_h) / 2)
|
|
x_gap = int(width * 0.08)
|
|
x1 = int((width - (card_w * 2 + x_gap)) / 2)
|
|
x2 = x1 + card_w + x_gap
|
|
|
|
# Use larger text scale on larger screens
|
|
scale = 6 if width >= 400 else 5
|
|
|
|
def draw_card(x, y, val_str, flip_state=0):
|
|
# Draw white card body
|
|
display.fill_rect(x, y, card_w, card_h, 1)
|
|
|
|
# Center coordinates for text inside card
|
|
text_w = 2 * 8 * scale
|
|
text_h = 8 * scale
|
|
tx = x + (card_w - text_w) // 2
|
|
ty = y + (card_h - text_h) // 2
|
|
|
|
# Draw text in black on the white card
|
|
display.text_large(val_str, tx, ty, scale=scale, c=0)
|
|
|
|
# Draw split line and side notches to simulate 3D split-flap cards
|
|
split_y = y + card_h // 2
|
|
if flip_state == 0:
|
|
display.line(x, split_y, x + card_w, split_y, 0)
|
|
display.fill_rect(x, split_y - 3, 3, 6, 0)
|
|
display.fill_rect(x + card_w - 3, split_y - 3, 3, 6, 0)
|
|
elif flip_state == 1:
|
|
# Widening line (flap rotating slightly down)
|
|
display.fill_rect(x, split_y - 3, card_w, 6, 0)
|
|
display.fill_rect(x, split_y - 5, 4, 10, 0)
|
|
display.fill_rect(x + card_w - 4, split_y - 5, 4, 10, 0)
|
|
elif flip_state == 2:
|
|
# Thick black bar (flap mid-rotation covering numbers)
|
|
display.fill_rect(x, split_y - 12, card_w, 24, 0)
|
|
elif flip_state == 3:
|
|
# Settling line (flap finishing rotation)
|
|
display.fill_rect(x, split_y - 4, card_w, 8, 0)
|
|
display.fill_rect(x, split_y - 5, 4, 10, 0)
|
|
display.fill_rect(x + card_w - 4, split_y - 5, 4, 10, 0)
|
|
|
|
start_time = time.time()
|
|
last_h, last_m = -1, -1
|
|
|
|
print("Screensaver running. Touch the screen to exit.")
|
|
|
|
while time.time() - start_time < duration_sec:
|
|
# Check if screen is touched to exit
|
|
if touch and touch.is_touched():
|
|
print("Touch detected. Exiting screensaver.")
|
|
break
|
|
|
|
t = time.localtime()
|
|
h, m = t[3], t[4]
|
|
h_str = f"{h:02d}"
|
|
m_str = f"{m:02d}"
|
|
|
|
# Play flip animation if minute changes
|
|
if m != last_m:
|
|
if last_m != -1:
|
|
# Play 3-frame split-flap rotation
|
|
for frame in [1, 2, 3]:
|
|
display.clear(0)
|
|
if h != last_h:
|
|
draw_card(x1, y_offset, h_str, flip_state=frame)
|
|
else:
|
|
draw_card(x1, y_offset, h_str, flip_state=0)
|
|
draw_card(x2, y_offset, m_str, flip_state=frame)
|
|
display.show()
|
|
time.sleep_ms(150)
|
|
|
|
last_h, last_m = h, m
|
|
|
|
# Draw standard static state
|
|
display.clear(0)
|
|
draw_card(x1, y_offset, h_str, flip_state=0)
|
|
draw_card(x2, y_offset, m_str, flip_state=0)
|
|
|
|
# Draw blinking seconds colon between cards
|
|
if t[5] % 2 == 0:
|
|
cx = width // 2
|
|
cy = height // 2
|
|
display.fill_rect(cx - 3, cy - 15, 6, 6, 1)
|
|
display.fill_rect(cx - 3, cy + 9, 6, 6, 1)
|
|
|
|
display.show()
|
|
|
|
# Check for touch during the 1-second pause
|
|
for _ in range(10):
|
|
if touch and touch.is_touched():
|
|
break
|
|
time.sleep_ms(100)
|
|
|
|
# Clear display on exit
|
|
display.clear(0)
|
|
display.show()
|
|
|
|
# Run the screensaver
|
|
run_screensaver()
|