Fix mini-calendar to respect week_start_day config setting
This commit is contained in:
@@ -16,15 +16,21 @@ from textual.reactive import reactive
|
||||
from textual.strip import Strip
|
||||
from textual.widget import Widget
|
||||
|
||||
from src.calendar import config
|
||||
|
||||
def get_month_calendar(year: int, month: int) -> list[list[Optional[date]]]:
|
||||
|
||||
def get_month_calendar(
|
||||
year: int, month: int, week_start_day: int = 0
|
||||
) -> list[list[Optional[date]]]:
|
||||
"""Generate a calendar grid for a month.
|
||||
|
||||
Returns a list of weeks, where each week is a list of 7 dates (or None for empty cells).
|
||||
Week starts on Monday.
|
||||
"""
|
||||
import calendar
|
||||
|
||||
Args:
|
||||
year: The year
|
||||
month: The month (1-12)
|
||||
week_start_day: Config format (0=Sunday, 1=Monday, ..., 6=Saturday)
|
||||
"""
|
||||
# Get first day of month and number of days
|
||||
first_day = date(year, month, 1)
|
||||
if month == 12:
|
||||
@@ -32,11 +38,17 @@ def get_month_calendar(year: int, month: int) -> list[list[Optional[date]]]:
|
||||
else:
|
||||
last_day = date(year, month + 1, 1) - timedelta(days=1)
|
||||
|
||||
# Monday = 0, Sunday = 6
|
||||
first_weekday = first_day.weekday()
|
||||
# Convert config week start to python weekday
|
||||
# Config: 0=Sunday, 1=Monday, ..., 6=Saturday
|
||||
# Python: 0=Monday, 1=Tuesday, ..., 6=Sunday
|
||||
python_week_start = (week_start_day - 1) % 7
|
||||
|
||||
# Calculate which day of the week the first day falls on (relative to week start)
|
||||
first_python_weekday = first_day.weekday() # 0=Monday, 6=Sunday
|
||||
days_offset = (first_python_weekday - python_week_start) % 7
|
||||
|
||||
weeks: list[list[Optional[date]]] = []
|
||||
current_week: list[Optional[date]] = [None] * first_weekday
|
||||
current_week: list[Optional[date]] = [None] * days_offset
|
||||
|
||||
current = first_day
|
||||
while current <= last_day:
|
||||
@@ -55,6 +67,22 @@ def get_month_calendar(year: int, month: int) -> list[list[Optional[date]]]:
|
||||
return weeks
|
||||
|
||||
|
||||
def get_day_names(week_start_day: int = 0) -> str:
|
||||
"""Get day name headers based on week start day.
|
||||
|
||||
Args:
|
||||
week_start_day: Config format (0=Sunday, 1=Monday, ..., 6=Saturday)
|
||||
|
||||
Returns:
|
||||
String like "Su Mo Tu We Th Fr Sa" or "Mo Tu We Th Fr Sa Su"
|
||||
"""
|
||||
# Full list starting from Sunday (config day 0)
|
||||
all_days = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
|
||||
# Rotate to start from week_start_day
|
||||
rotated = all_days[week_start_day:] + all_days[:week_start_day]
|
||||
return " ".join(rotated)
|
||||
|
||||
|
||||
class MonthCalendar(Widget):
|
||||
"""A compact month calendar widget for sidebars."""
|
||||
|
||||
@@ -122,7 +150,11 @@ class MonthCalendar(Widget):
|
||||
@property
|
||||
def _weeks(self) -> list[list[Optional[date]]]:
|
||||
"""Get the weeks for the current display month."""
|
||||
return get_month_calendar(self.display_month.year, self.display_month.month)
|
||||
return get_month_calendar(
|
||||
self.display_month.year,
|
||||
self.display_month.month,
|
||||
config.week_start_day(),
|
||||
)
|
||||
|
||||
def get_content_height(self, container, viewport, width: int) -> int:
|
||||
"""Calculate height: header + day names + weeks."""
|
||||
@@ -152,8 +184,8 @@ class MonthCalendar(Widget):
|
||||
return Strip([Segment(header, style)])
|
||||
|
||||
def _render_day_names(self) -> Strip:
|
||||
"""Render the day name headers (Mo Tu We ...)."""
|
||||
day_names = "Mo Tu We Th Fr Sa Su"
|
||||
"""Render the day name headers based on week start setting."""
|
||||
day_names = get_day_names(config.week_start_day())
|
||||
# Pad to widget width
|
||||
line = day_names[: self.size.width].ljust(self.size.width)
|
||||
style = Style(color="bright_black")
|
||||
|
||||
Reference in New Issue
Block a user