eee_alarm_clock/clock/ui/active_alarm.py

116 lines
3.9 KiB
Python
Raw Normal View History

import curses
from datetime import datetime
from .utils import init_colors, draw_big_digit
class ActiveAlarmView:
def __init__(self, storage, control_queue):
self.storage = storage
self.control_queue = control_queue
self.active_alarms = {}
def reset_state(self):
"""Reset the view state"""
self.active_alarms.clear()
def draw(self, stdscr):
"""Draw the active alarm screen"""
init_colors()
height, width = stdscr.getmaxyx()
current_time = datetime.now()
self._draw_main_clock(stdscr, height, width, current_time)
self._draw_active_alarm_info(stdscr, height, width)
self._draw_instructions(stdscr, height, width)
def handle_input(self, key):
"""Handle user input and return the next view name or None to stay"""
if not self.active_alarms:
return 'CLOCK'
alarm_id = list(self.active_alarms.keys())[0]
if key == ord('s'):
self._handle_snooze(alarm_id)
return None
elif key == ord('d'):
self._handle_dismiss(alarm_id)
return 'CLOCK'
return None
def update_active_alarms(self, active_alarms):
"""Update the active alarms state"""
self.active_alarms = active_alarms
def _draw_main_clock(self, stdscr, height, width, current_time):
"""Draw the main clock display"""
time_str = current_time.strftime("%H:%M:%S")
digit_width = 14
total_width = digit_width * len(time_str)
start_x = (width - total_width) // 2
start_y = (height - 7) // 2 - 4
# Draw blinking dot
if int(current_time.timestamp()) % 2 == 0:
stdscr.attron(curses.color_pair(1))
stdscr.addstr(start_y - 1, start_x + total_width - 2, "")
stdscr.attroff(curses.color_pair(1))
# Draw big time digits
stdscr.attron(curses.color_pair(1))
for i, digit in enumerate(time_str):
draw_big_digit(stdscr, start_y, start_x + i * digit_width, digit)
stdscr.attroff(curses.color_pair(1))
# Draw date
date_str = current_time.strftime("%Y-%m-%d")
date_x = width // 2 - len(date_str) // 2
date_y = height // 2 + 4
stdscr.attron(curses.color_pair(2))
stdscr.addstr(date_y, date_x, date_str)
stdscr.attroff(curses.color_pair(2))
def _draw_active_alarm_info(self, stdscr, height, width):
"""Draw information about the active alarm"""
if not self.active_alarms:
return
alarm_id = list(self.active_alarms.keys())[0]
alarm_info = self.active_alarms[alarm_id]
alarm_config = alarm_info['config']
alarm_name = alarm_config.get('name', 'Unnamed Alarm')
alarm_time = alarm_config.get('time', 'Unknown Time')
alarm_str = f"[ {alarm_name} - {alarm_time} ]"
# Position alarm info above the date
date_y = height // 2 + 4 # Same as in _draw_main_clock
alarm_y = date_y - 2
alarm_x = max(0, width // 2 - len(alarm_str) // 2)
stdscr.attron(curses.color_pair(1))
stdscr.addstr(alarm_y, alarm_x, alarm_str)
stdscr.attroff(curses.color_pair(1))
def _draw_instructions(self, stdscr, height, width):
"""Draw the user instructions"""
if self.active_alarms:
instructions = "S: Snooze D: Dismiss"
stdscr.addstr(height - 2, width // 2 - len(instructions) // 2, instructions)
def _handle_snooze(self, alarm_id):
"""Handle snoozing the alarm"""
self.control_queue.put({
'type': 'snooze',
'alarm_id': alarm_id
})
del self.active_alarms[alarm_id]
def _handle_dismiss(self, alarm_id):
"""Handle dismissing the alarm"""
self.control_queue.put({
'type': 'dismiss',
'alarm_id': alarm_id
})
del self.active_alarms[alarm_id]