"""Оформление интерфейса.""" from __future__ import annotations import tkinter as tk from tkinter import ttk DARK = { "bg": "#1b1d22", "bg2": "#22252b", "bg3": "#2a2e36", "fg": "#e6e8ec", "fg_dim": "#9aa1ad", "accent": "#4a90d9", "accent_hi": "#5fa4e8", "ok": "#2e9e5b", "warn": "#d99a2b", "danger": "#d9534f", "border": "#343943", "sel": "#2f3a4a", } LIGHT = { "bg": "#f4f5f7", "bg2": "#ffffff", "bg3": "#e9ebef", "fg": "#1d2127", "fg_dim": "#5f6773", "accent": "#2f6fb5", "accent_hi": "#3d82cf", "ok": "#1e7a45", "warn": "#a5710f", "danger": "#b8332f", "border": "#cfd4dc", "sel": "#d6e4f5", } class Theme: def __init__(self, root: tk.Misc, dark: bool = True) -> None: self.root = root self.dark = dark self.c = DARK if dark else LIGHT self.style = ttk.Style(root) self.apply() def toggle(self) -> None: self.dark = not self.dark self.c = DARK if self.dark else LIGHT self.apply() def apply(self) -> None: c = self.c s = self.style try: s.theme_use("clam") except tk.TclError: pass self.root.configure(bg=c["bg"]) base_font = ("Segoe UI", 10) s.configure(".", background=c["bg"], foreground=c["fg"], font=base_font, fieldbackground=c["bg2"], bordercolor=c["border"], lightcolor=c["bg2"], darkcolor=c["bg"]) s.configure("TFrame", background=c["bg"]) s.configure("Card.TFrame", background=c["bg2"], relief="flat") s.configure("TLabel", background=c["bg"], foreground=c["fg"]) s.configure("Card.TLabel", background=c["bg2"], foreground=c["fg"]) s.configure("Dim.TLabel", background=c["bg"], foreground=c["fg_dim"]) s.configure("CardDim.TLabel", background=c["bg2"], foreground=c["fg_dim"]) s.configure("H1.TLabel", background=c["bg"], foreground=c["fg"], font=("Segoe UI Semibold", 17)) s.configure("H2.TLabel", background=c["bg"], foreground=c["fg"], font=("Segoe UI Semibold", 12)) s.configure("CardH2.TLabel", background=c["bg2"], foreground=c["fg"], font=("Segoe UI Semibold", 12)) s.configure("Big.TLabel", background=c["bg"], foreground=c["accent_hi"], font=("Segoe UI Semibold", 26)) s.configure("CardBig.TLabel", background=c["bg2"], foreground=c["accent_hi"], font=("Segoe UI Semibold", 24)) s.configure("TButton", background=c["bg3"], foreground=c["fg"], borderwidth=0, focusthickness=0, padding=(14, 7)) s.map("TButton", background=[("active", c["border"]), ("disabled", c["bg2"])], foreground=[("disabled", c["fg_dim"])]) s.configure("Accent.TButton", background=c["accent"], foreground="#ffffff", padding=(16, 8), font=("Segoe UI Semibold", 10)) s.map("Accent.TButton", background=[("active", c["accent_hi"]), ("disabled", c["bg3"])], foreground=[("disabled", c["fg_dim"])]) s.configure("Danger.TButton", background=c["danger"], foreground="#ffffff", padding=(16, 8), font=("Segoe UI Semibold", 10)) s.map("Danger.TButton", background=[("active", "#e2645f"), ("disabled", c["bg3"])], foreground=[("disabled", c["fg_dim"])]) s.configure("TNotebook", background=c["bg"], borderwidth=0, tabmargins=(8, 6, 8, 0)) s.configure("TNotebook.Tab", background=c["bg"], foreground=c["fg_dim"], padding=(18, 9), borderwidth=0, font=("Segoe UI", 10)) s.map("TNotebook.Tab", background=[("selected", c["bg2"])], foreground=[("selected", c["fg"])]) s.configure("Treeview", background=c["bg2"], fieldbackground=c["bg2"], foreground=c["fg"], borderwidth=0, rowheight=26) s.configure("Treeview.Heading", background=c["bg3"], foreground=c["fg_dim"], borderwidth=0, padding=(8, 6), font=("Segoe UI Semibold", 9)) s.map("Treeview.Heading", background=[("active", c["border"])]) s.map("Treeview", background=[("selected", c["sel"])], foreground=[("selected", c["fg"])]) s.configure("TCheckbutton", background=c["bg"], foreground=c["fg"], focuscolor=c["bg"]) s.map("TCheckbutton", background=[("active", c["bg"])]) s.configure("Card.TCheckbutton", background=c["bg2"], foreground=c["fg"]) s.map("Card.TCheckbutton", background=[("active", c["bg2"])]) s.configure("TRadiobutton", background=c["bg"], foreground=c["fg"]) s.map("TRadiobutton", background=[("active", c["bg"])]) s.configure("TEntry", fieldbackground=c["bg2"], foreground=c["fg"], bordercolor=c["border"], insertcolor=c["fg"], padding=6) s.configure("TCombobox", fieldbackground=c["bg2"], foreground=c["fg"], background=c["bg3"], arrowcolor=c["fg"]) s.configure("TProgressbar", background=c["accent"], troughcolor=c["bg3"], borderwidth=0, thickness=6) s.configure("Thin.Horizontal.TProgressbar", background=c["accent"], troughcolor=c["bg3"], borderwidth=0, thickness=6) s.configure("TSeparator", background=c["border"]) s.configure("TPanedwindow", background=c["bg"]) s.configure("Vertical.TScrollbar", background=c["bg3"], troughcolor=c["bg"], borderwidth=0, arrowcolor=c["fg_dim"]) s.map("Vertical.TScrollbar", background=[("active", c["border"])]) s.configure("Horizontal.TScrollbar", background=c["bg3"], troughcolor=c["bg"], borderwidth=0, arrowcolor=c["fg_dim"]) def tag_colors(theme: Theme) -> dict[str, dict]: c = theme.c return { "safe": {"foreground": c["ok"]}, "low": {"foreground": c["accent_hi"]}, "medium": {"foreground": c["warn"]}, "high": {"foreground": c["danger"]}, "cat": {"foreground": c["fg"], "font": ("Segoe UI Semibold", 10)}, "dim": {"foreground": c["fg_dim"]}, }