Captain_s-Log/app/ui/calendar_widget.py
Vic Sergeev a385308f38 working
2026-07-04 16:04:48 +03:00

189 lines
No EOL
6.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Виджет календаря"""
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('<Button-1>', 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)