87 lines
3.3 KiB
Python
87 lines
3.3 KiB
Python
![]() |
import curses
|
||
|
from datetime import datetime
|
||
|
from .utils import init_colors, draw_big_digit
|
||
|
|
||
|
def draw_list_alarms(stdscr, context):
|
||
|
"""Draw the list of alarms screen"""
|
||
|
init_colors()
|
||
|
height, width = stdscr.getmaxyx()
|
||
|
|
||
|
# Get required data from context
|
||
|
alarms = context.get('alarms', [])
|
||
|
selected_index = context.get('selected_index', 0)
|
||
|
weekday_names = context.get('weekday_names', ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'])
|
||
|
|
||
|
# Calculate visible range for scrolling
|
||
|
max_visible_items = height - 8 # Leave space for header and footer
|
||
|
total_items = len(alarms) + 1 # +1 for "Add new alarm" option
|
||
|
|
||
|
# Calculate scroll position
|
||
|
start_idx = max(0, min(selected_index - max_visible_items // 2,
|
||
|
total_items - max_visible_items))
|
||
|
if start_idx < 0:
|
||
|
start_idx = 0
|
||
|
end_idx = min(start_idx + max_visible_items, total_items)
|
||
|
|
||
|
# Header
|
||
|
header_text = "Alarms"
|
||
|
stdscr.attron(curses.color_pair(1) | curses.A_BOLD)
|
||
|
stdscr.addstr(2, width // 2 - len(header_text) // 2, header_text)
|
||
|
stdscr.attroff(curses.color_pair(1) | curses.A_BOLD)
|
||
|
|
||
|
# Draw alarms
|
||
|
for i in range(start_idx, end_idx):
|
||
|
y_pos = 4 + (i - start_idx)
|
||
|
|
||
|
if i == len(alarms): # "Add new alarm" option
|
||
|
display_str = "Add new alarm..."
|
||
|
else:
|
||
|
alarm = alarms[i]
|
||
|
# Format time
|
||
|
time_str = alarm.get('time', 'Unknown')
|
||
|
|
||
|
# Format repeat info
|
||
|
repeat_info = ""
|
||
|
repeat_rule = alarm.get('repeat_rule', {})
|
||
|
if repeat_rule:
|
||
|
if repeat_rule.get('type') == 'weekly':
|
||
|
days = repeat_rule.get('days', [])
|
||
|
repeat_info = f" (Every {', '.join(weekday_names[d] for d in days)})"
|
||
|
elif repeat_rule.get('type') == 'once' and repeat_rule.get('date'):
|
||
|
repeat_info = f" (On {repeat_rule['date']})"
|
||
|
|
||
|
# Status indicator (in green)
|
||
|
status = "✓" if alarm.get('enabled', True) else "✗"
|
||
|
display_str = f"{status} {time_str} {alarm.get('name', 'Unnamed')}{repeat_info}"
|
||
|
|
||
|
# Truncate if too long (leaving space for selection brackets)
|
||
|
max_length = width - 6
|
||
|
if len(display_str) > max_length:
|
||
|
display_str = display_str[:max_length-3] + "..."
|
||
|
|
||
|
# Center the item
|
||
|
x_pos = width // 2 - len(display_str) // 2
|
||
|
|
||
|
# Highlight selected item
|
||
|
if i == selected_index:
|
||
|
# Draw selection brackets in green
|
||
|
stdscr.attron(curses.color_pair(1))
|
||
|
stdscr.addstr(y_pos, x_pos - 2, "[ ")
|
||
|
stdscr.addstr(y_pos, x_pos + len(display_str), " ]")
|
||
|
stdscr.attroff(curses.color_pair(1))
|
||
|
# Draw text in yellow (highlighted)
|
||
|
stdscr.attron(curses.color_pair(2))
|
||
|
stdscr.addstr(y_pos, x_pos, display_str)
|
||
|
stdscr.attroff(curses.color_pair(2))
|
||
|
else:
|
||
|
# Draw normal items in green
|
||
|
stdscr.attron(curses.color_pair(1))
|
||
|
stdscr.addstr(y_pos, x_pos, display_str)
|
||
|
stdscr.attroff(curses.color_pair(1))
|
||
|
|
||
|
# Instructions
|
||
|
instructions = "j/k: Move d: Delete a: Add/Edit Esc: Back"
|
||
|
stdscr.attron(curses.color_pair(1))
|
||
|
stdscr.addstr(height - 2, width // 2 - len(instructions) // 2, instructions)
|
||
|
stdscr.attroff(curses.color_pair(1))
|