220 lines
8.2 KiB
Python
220 lines
8.2 KiB
Python
import curses
|
|
from datetime import datetime
|
|
from .utils import init_colors, draw_big_digit
|
|
|
|
def draw_add_alarm(stdscr, context):
|
|
"""Draw the add alarm screen"""
|
|
# Ensure context is a dictionary with default values
|
|
if context is None:
|
|
context = {}
|
|
|
|
# Provide default values with more explicit checks
|
|
context = {
|
|
'new_alarm_selected': context.get('new_alarm_selected', 0),
|
|
'new_alarm_name': context.get('new_alarm_name', 'New Alarm'),
|
|
'new_alarm_hour': context.get('new_alarm_hour', datetime.now().hour),
|
|
'new_alarm_minute': context.get('new_alarm_minute', datetime.now().minute),
|
|
'new_alarm_enabled': context.get('new_alarm_enabled', True),
|
|
'new_alarm_date': context.get('new_alarm_date') or None,
|
|
'new_alarm_weekdays': context.get('new_alarm_weekdays', []) or [],
|
|
'weekday_names': context.get('weekday_names', ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']),
|
|
'date_edit_pos': context.get('date_edit_pos', 2) # 0 = year, 1 = month, 2 = day
|
|
}
|
|
|
|
init_colors()
|
|
height, width = stdscr.getmaxyx()
|
|
|
|
# Center the form vertically with good spacing
|
|
form_y = height // 2 - 8
|
|
|
|
# Title with green color and bold
|
|
title = "Add New Alarm"
|
|
stdscr.attron(curses.color_pair(1) | curses.A_BOLD)
|
|
stdscr.addstr(form_y, width // 2 - len(title) // 2, title)
|
|
stdscr.attroff(curses.color_pair(1) | curses.A_BOLD)
|
|
|
|
# Helper function to draw a labeled field
|
|
def draw_field(y, label, value, is_selected, center_offset=0):
|
|
label_str = f"{label}: "
|
|
total_width = len(label_str) + len(str(value))
|
|
x = width // 2 - total_width // 2 + center_offset
|
|
|
|
# Draw label in green
|
|
stdscr.attron(curses.color_pair(1))
|
|
stdscr.addstr(y, x, label_str)
|
|
stdscr.attroff(curses.color_pair(1))
|
|
|
|
# Draw value (highlighted if selected)
|
|
if is_selected:
|
|
stdscr.attron(curses.color_pair(2)) # Yellow for selected
|
|
stdscr.addstr(y, x + len(label_str), str(value))
|
|
stdscr.attroff(curses.color_pair(2))
|
|
else:
|
|
stdscr.attron(curses.color_pair(1)) # Green for normal
|
|
stdscr.addstr(y, x + len(label_str), str(value))
|
|
stdscr.attroff(curses.color_pair(1))
|
|
|
|
# Name field with proper spacing
|
|
name_str = str(context['new_alarm_name'])
|
|
draw_field(form_y + 2, "Name", name_str, context['new_alarm_selected'] == 4)
|
|
|
|
# Time selection with centered layout
|
|
time_y = form_y + 4
|
|
time_label = "Time: "
|
|
hour_str = f"{int(context['new_alarm_hour']):02d}"
|
|
minute_str = f"{int(context['new_alarm_minute']):02d}"
|
|
|
|
# Calculate center position for time
|
|
time_total_width = len(time_label) + 5 # 5 = HH:MM
|
|
time_x = width // 2 - time_total_width // 2
|
|
|
|
# Draw time label
|
|
stdscr.attron(curses.color_pair(1))
|
|
stdscr.addstr(time_y, time_x, time_label)
|
|
stdscr.attroff(curses.color_pair(1))
|
|
|
|
# Draw hour
|
|
if context['new_alarm_selected'] == 0:
|
|
stdscr.attron(curses.color_pair(2))
|
|
else:
|
|
stdscr.attron(curses.color_pair(1))
|
|
stdscr.addstr(time_y, time_x + len(time_label), hour_str)
|
|
if context['new_alarm_selected'] == 0:
|
|
stdscr.attroff(curses.color_pair(2))
|
|
else:
|
|
stdscr.attroff(curses.color_pair(1))
|
|
|
|
# Draw colon
|
|
stdscr.attron(curses.color_pair(1))
|
|
stdscr.addstr(time_y, time_x + len(time_label) + 2, ":")
|
|
stdscr.attroff(curses.color_pair(1))
|
|
|
|
# Draw minute
|
|
if context['new_alarm_selected'] == 1:
|
|
stdscr.attron(curses.color_pair(2))
|
|
else:
|
|
stdscr.attron(curses.color_pair(1))
|
|
stdscr.addstr(time_y, time_x + len(time_label) + 3, minute_str)
|
|
if context['new_alarm_selected'] == 1:
|
|
stdscr.attroff(curses.color_pair(2))
|
|
else:
|
|
stdscr.attroff(curses.color_pair(1))
|
|
|
|
# Draw weekdays
|
|
weekday_y = form_y + 6
|
|
weekdays_label = "Repeat: "
|
|
weekday_x = width // 2 - (len(weekdays_label) + len(context['weekday_names']) * 4) // 2
|
|
|
|
# Draw label
|
|
stdscr.attron(curses.color_pair(1))
|
|
stdscr.addstr(weekday_y, weekday_x, weekdays_label)
|
|
stdscr.attroff(curses.color_pair(1))
|
|
|
|
# Draw each weekday
|
|
for i, day in enumerate(context['weekday_names']):
|
|
x_pos = weekday_x + len(weekdays_label) + i * 4
|
|
is_selected = context['new_alarm_selected'] == 3 and i == context.get('weekday_edit_pos', 0)
|
|
is_active = i in context['new_alarm_weekdays']
|
|
|
|
if is_selected:
|
|
stdscr.attron(curses.color_pair(2))
|
|
elif is_active:
|
|
stdscr.attron(curses.color_pair(1) | curses.A_BOLD)
|
|
else:
|
|
stdscr.attron(curses.color_pair(1))
|
|
|
|
stdscr.addstr(weekday_y, x_pos, day)
|
|
|
|
if is_selected:
|
|
stdscr.attroff(curses.color_pair(2))
|
|
elif is_active:
|
|
stdscr.attroff(curses.color_pair(1) | curses.A_BOLD)
|
|
else:
|
|
stdscr.attroff(curses.color_pair(1))
|
|
|
|
# Date selection
|
|
date_y = form_y + 8
|
|
|
|
if context['new_alarm_weekdays']:
|
|
draw_field(date_y, "Date", "Repeating weekly", context['new_alarm_selected'] == 2)
|
|
else:
|
|
date_label = "Date: "
|
|
if context.get('new_alarm_date'):
|
|
date = context['new_alarm_date']
|
|
date_edit_pos = context.get('date_edit_pos', 0)
|
|
|
|
# Calculate center position
|
|
total_width = len(date_label) + len("YYYY-MM-DD")
|
|
date_x = width // 2 - total_width // 2
|
|
|
|
# Draw label
|
|
stdscr.attron(curses.color_pair(1))
|
|
stdscr.addstr(date_y, date_x, date_label)
|
|
stdscr.attroff(curses.color_pair(1))
|
|
|
|
# Draw date components
|
|
year_str = f"{date.year}"
|
|
month_str = f"{date.month:02d}"
|
|
day_str = f"{date.day:02d}"
|
|
current_x = date_x + len(date_label)
|
|
|
|
# Draw year
|
|
if context['new_alarm_selected'] == 2 and date_edit_pos == 0:
|
|
stdscr.attron(curses.color_pair(2))
|
|
else:
|
|
stdscr.attron(curses.color_pair(1))
|
|
stdscr.addstr(date_y, current_x, year_str)
|
|
if context['new_alarm_selected'] == 2 and date_edit_pos == 0:
|
|
stdscr.attroff(curses.color_pair(2))
|
|
else:
|
|
stdscr.attroff(curses.color_pair(1))
|
|
current_x += len(year_str)
|
|
|
|
# Draw first dash
|
|
stdscr.attron(curses.color_pair(1))
|
|
stdscr.addstr(date_y, current_x, "-")
|
|
stdscr.attroff(curses.color_pair(1))
|
|
current_x += 1
|
|
|
|
# Draw month
|
|
if context['new_alarm_selected'] == 2 and date_edit_pos == 1:
|
|
stdscr.attron(curses.color_pair(2))
|
|
else:
|
|
stdscr.attron(curses.color_pair(1))
|
|
stdscr.addstr(date_y, current_x, month_str)
|
|
if context['new_alarm_selected'] == 2 and date_edit_pos == 1:
|
|
stdscr.attroff(curses.color_pair(2))
|
|
else:
|
|
stdscr.attroff(curses.color_pair(1))
|
|
current_x += len(month_str)
|
|
|
|
# Draw second dash
|
|
stdscr.attron(curses.color_pair(1))
|
|
stdscr.addstr(date_y, current_x, "-")
|
|
stdscr.attroff(curses.color_pair(1))
|
|
current_x += 1
|
|
|
|
# Draw day
|
|
if context['new_alarm_selected'] == 2 and date_edit_pos == 2:
|
|
stdscr.attron(curses.color_pair(2))
|
|
else:
|
|
stdscr.attron(curses.color_pair(1))
|
|
stdscr.addstr(date_y, current_x, day_str)
|
|
if context['new_alarm_selected'] == 2 and date_edit_pos == 2:
|
|
stdscr.attroff(curses.color_pair(2))
|
|
else:
|
|
stdscr.attroff(curses.color_pair(1))
|
|
else:
|
|
draw_field(date_y, "Date", "No specific date", context['new_alarm_selected'] == 2)
|
|
|
|
# Enabled/Disabled toggle with visual indicator
|
|
status_y = form_y + 10
|
|
enabled_str = "● Enabled" if context['new_alarm_enabled'] else "○ Disabled"
|
|
draw_field(status_y, "Status", enabled_str, context['new_alarm_selected'] == 5, -2)
|
|
|
|
# Instructions in green at the bottom
|
|
instructions = "j/k: Change h/l: Switch Space: Toggle Enter: Save Esc: Cancel"
|
|
stdscr.attron(curses.color_pair(1))
|
|
stdscr.addstr(height - 2, width // 2 - len(instructions) // 2, instructions)
|
|
stdscr.attroff(curses.color_pair(1))
|