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.strip import Strip
|
||||||
from textual.widget import Widget
|
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.
|
"""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).
|
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
|
# Get first day of month and number of days
|
||||||
first_day = date(year, month, 1)
|
first_day = date(year, month, 1)
|
||||||
if month == 12:
|
if month == 12:
|
||||||
@@ -32,11 +38,17 @@ def get_month_calendar(year: int, month: int) -> list[list[Optional[date]]]:
|
|||||||
else:
|
else:
|
||||||
last_day = date(year, month + 1, 1) - timedelta(days=1)
|
last_day = date(year, month + 1, 1) - timedelta(days=1)
|
||||||
|
|
||||||
# Monday = 0, Sunday = 6
|
# Convert config week start to python weekday
|
||||||
first_weekday = first_day.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]]] = []
|
weeks: list[list[Optional[date]]] = []
|
||||||
current_week: list[Optional[date]] = [None] * first_weekday
|
current_week: list[Optional[date]] = [None] * days_offset
|
||||||
|
|
||||||
current = first_day
|
current = first_day
|
||||||
while current <= last_day:
|
while current <= last_day:
|
||||||
@@ -55,6 +67,22 @@ def get_month_calendar(year: int, month: int) -> list[list[Optional[date]]]:
|
|||||||
return weeks
|
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):
|
class MonthCalendar(Widget):
|
||||||
"""A compact month calendar widget for sidebars."""
|
"""A compact month calendar widget for sidebars."""
|
||||||
|
|
||||||
@@ -122,7 +150,11 @@ class MonthCalendar(Widget):
|
|||||||
@property
|
@property
|
||||||
def _weeks(self) -> list[list[Optional[date]]]:
|
def _weeks(self) -> list[list[Optional[date]]]:
|
||||||
"""Get the weeks for the current display month."""
|
"""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:
|
def get_content_height(self, container, viewport, width: int) -> int:
|
||||||
"""Calculate height: header + day names + weeks."""
|
"""Calculate height: header + day names + weeks."""
|
||||||
@@ -152,8 +184,8 @@ class MonthCalendar(Widget):
|
|||||||
return Strip([Segment(header, style)])
|
return Strip([Segment(header, style)])
|
||||||
|
|
||||||
def _render_day_names(self) -> Strip:
|
def _render_day_names(self) -> Strip:
|
||||||
"""Render the day name headers (Mo Tu We ...)."""
|
"""Render the day name headers based on week start setting."""
|
||||||
day_names = "Mo Tu We Th Fr Sa Su"
|
day_names = get_day_names(config.week_start_day())
|
||||||
# Pad to widget width
|
# Pad to widget width
|
||||||
line = day_names[: self.size.width].ljust(self.size.width)
|
line = day_names[: self.size.width].ljust(self.size.width)
|
||||||
style = Style(color="bright_black")
|
style = Style(color="bright_black")
|
||||||
|
|||||||
Reference in New Issue
Block a user