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))