Files
bookstorm/src/sleep_timer_menu.py

166 lines
4.7 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Sleep Timer Menu
Provides a menu for setting sleep timer or quitting immediately.
"""
import time
class SleepTimerMenu:
"""Sleep timer menu for quit/sleep options"""
def __init__(self, speechEngine):
"""
Initialize sleep timer menu
Args:
speechEngine: SpeechEngine instance for UI feedback
"""
self.speechEngine = speechEngine
self.inMenu = False
self.currentIndex = 0
# Menu options: (label, minutes)
# 0 means quit immediately
self.menuItems = [
("Quit now", 0),
("Sleep in 5 minutes", 5),
("Sleep in 10 minutes", 10),
("Sleep in 15 minutes", 15),
("Sleep in 20 minutes", 20),
("Sleep in 25 minutes", 25),
("Sleep in 30 minutes", 30),
("Sleep in 35 minutes", 35),
("Sleep in 40 minutes", 40),
("Sleep in 45 minutes", 45),
("Sleep in 50 minutes", 50),
("Sleep in 55 minutes", 55),
("Sleep in 60 minutes", 60),
]
# Timer state
self.timerActive = False
self.timerEndTime = None
self.timerMinutes = 0
def enter_menu(self):
"""Enter the sleep timer menu"""
self.inMenu = True
self.currentIndex = 0
self._speak_current_item()
def exit_menu(self):
"""Exit the sleep timer menu"""
self.inMenu = False
def is_in_menu(self):
"""Check if currently in menu"""
return self.inMenu
def navigate_menu(self, direction):
"""
Navigate menu up or down
Args:
direction: 'up' or 'down'
"""
if direction == 'up':
self.currentIndex = (self.currentIndex - 1) % len(self.menuItems)
elif direction == 'down':
self.currentIndex = (self.currentIndex + 1) % len(self.menuItems)
self._speak_current_item()
def activate_current_item(self):
"""
Activate current menu item
Returns:
Tuple: (shouldQuitNow, shouldContinue)
shouldQuitNow: True if user selected "Quit now"
shouldContinue: True if timer was set (continue reading)
"""
label, minutes = self.menuItems[self.currentIndex]
if minutes == 0:
# Quit now
self.speechEngine.speak("Quitting now")
self.inMenu = False
return (True, False)
else:
# Set sleep timer
self.timerActive = True
self.timerMinutes = minutes
self.timerEndTime = time.time() + (minutes * 60)
self.speechEngine.speak(f"Sleep timer set for {minutes} minutes")
self.inMenu = False
return (False, True)
def check_timer(self):
"""
Check if sleep timer has expired
Returns:
True if timer expired and should quit
"""
if self.timerActive and time.time() >= self.timerEndTime:
return True
return False
def should_start_fadeout(self):
"""
Check if we should start fading out (10 seconds before timer expiration)
Returns:
True if we're within 10 seconds of timer expiration
"""
if not self.timerActive:
return False
remaining = self.timerEndTime - time.time()
return 0 < remaining <= 10
def get_time_remaining(self):
"""
Get time remaining on sleep timer
Returns:
Tuple: (minutes, seconds) or None if no timer active
"""
if not self.timerActive:
return None
remaining = self.timerEndTime - time.time()
if remaining <= 0:
return (0, 0)
minutes = int(remaining // 60)
seconds = int(remaining % 60)
return (minutes, seconds)
def cancel_timer(self):
"""Cancel active sleep timer"""
if self.timerActive:
self.timerActive = False
self.timerEndTime = None
self.speechEngine.speak("Sleep timer cancelled")
def reset_fadeout_state(self):
"""
Reset fade-out state (called when timer is cancelled or new timer set)
Returns the fade state so the caller can restore volume if needed
"""
return {'isFadingOut': False, 'fadeStartVolume': None, 'fadeStartTime': None}
def is_timer_active(self):
"""Check if sleep timer is active"""
return self.timerActive
def _speak_current_item(self):
"""Speak the current menu item"""
label, _ = self.menuItems[self.currentIndex]
self.speechEngine.speak(label)