"""Виджет календаря""" import tkinter as tk from tkinter import ttk import calendar from datetime import datetime from app.config import Config class CalendarWidget(tk.Frame): """Кастомный виджет календаря""" def __init__(self, parent, db, on_date_select=None): super().__init__(parent, bg=Config.COLORS['calendar_bg']) self.db = db self.on_date_select = on_date_select self.current_date = datetime.now() self.selected_date = datetime.now() self.create_widgets() self.update_calendar() def create_widgets(self): # Заголовок с месяцем и годом self.header_frame = tk.Frame(self, bg=Config.COLORS['calendar_bg']) self.header_frame.pack(fill='x', pady=(10, 5)) self.prev_btn = tk.Button( self.header_frame, text="◀", command=self.prev_month, bg=Config.COLORS['calendar_bg'], fg=Config.COLORS['fg'], relief='flat', font=('Arial', 12), cursor='hand2' ) self.prev_btn.pack(side='left', padx=(20, 0)) self.month_label = tk.Label( self.header_frame, text="", bg=Config.COLORS['calendar_bg'], fg=Config.COLORS['calendar_header'], font=('Arial', 14, 'bold') ) self.month_label.pack(side='left', expand=True) self.next_btn = tk.Button( self.header_frame, text="▶", command=self.next_month, bg=Config.COLORS['calendar_bg'], fg=Config.COLORS['fg'], relief='flat', font=('Arial', 12), cursor='hand2' ) self.next_btn.pack(side='right', padx=(0, 20)) # Дни недели days_frame = tk.Frame(self, bg=Config.COLORS['calendar_bg']) days_frame.pack(fill='x', padx=5, pady=5) days = ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс'] for i, day in enumerate(days): days_frame.grid_columnconfigure(i, weight=1) tk.Label( days_frame, text=day, bg=Config.COLORS['calendar_bg'], fg=Config.COLORS['fg'], font=('Arial', 9, 'bold') ).grid(row=0, column=i) # Сетка календаря self.calendar_frame = tk.Frame(self, bg=Config.COLORS['calendar_bg']) self.calendar_frame.pack(fill='both', expand=True, padx=5, pady=5) self.day_buttons = [] for row in range(6): self.calendar_frame.grid_rowconfigure(row, weight=1) for col in range(7): self.calendar_frame.grid_columnconfigure(col, weight=1) btn = tk.Label( self.calendar_frame, text="", bg=Config.COLORS['calendar_bg'], fg=Config.COLORS['fg'], font=('Arial', 10), cursor='hand2' ) btn.grid(row=row, column=col, sticky='nsew', padx=1, pady=1) btn.bind('', lambda e, r=row, c=col: self.on_day_click(r, c)) self.day_buttons.append(btn) def update_calendar(self): year = self.current_date.year month = self.current_date.month # Обновляем заголовок months = ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'] self.month_label.config(text=f"{months[month - 1]} {year}") # Получаем дни с заметками days_with_notes = self.db.get_dates_with_notes(year, month) # Создаем календарь cal = calendar.monthcalendar(year, month) for idx, btn in enumerate(self.day_buttons): row = idx // 7 col = idx % 7 if row < len(cal) and col < len(cal[row]): day = cal[row][col] if day != 0: btn.config(text=str(day)) # Определяем цвет фона today = datetime.now() is_today = (day == today.day and month == today.month and year == today.year) is_selected = (day == self.selected_date.day and month == self.selected_date.month and year == self.selected_date.year) has_notes = day in days_with_notes if is_today and is_selected: btn.config( bg=Config.COLORS['today_bg'], fg=Config.COLORS['fg'] ) elif is_today: btn.config( bg=Config.COLORS['today_bg'], fg=Config.COLORS['fg'] ) elif is_selected: btn.config( bg=Config.COLORS['accent'], fg=Config.COLORS['fg'] ) elif has_notes: btn.config( bg='#5a7a3a', fg=Config.COLORS['fg'] ) else: btn.config( bg=Config.COLORS['calendar_bg'], fg=Config.COLORS['fg'] ) else: btn.config(text="", bg=Config.COLORS['calendar_bg']) else: btn.config(text="", bg=Config.COLORS['calendar_bg']) def prev_month(self): if self.current_date.month == 1: self.current_date = self.current_date.replace(year=self.current_date.year - 1, month=12) else: self.current_date = self.current_date.replace(month=self.current_date.month - 1) self.update_calendar() def next_month(self): if self.current_date.month == 12: self.current_date = self.current_date.replace(year=self.current_date.year + 1, month=1) else: self.current_date = self.current_date.replace(month=self.current_date.month + 1) self.update_calendar() def on_day_click(self, row, col): year = self.current_date.year month = self.current_date.month cal = calendar.monthcalendar(year, month) if row < len(cal) and col < len(cal[row]): day = cal[row][col] if day != 0: self.selected_date = datetime(year, month, day) self.update_calendar() if self.on_date_select: self.on_date_select(self.selected_date)