1
0
Files
Programm-Shortcut/gui/modern_widgets.py
2025-09-08 17:19:22 +02:00

288 lines
10 KiB
Python

import tkinter as tk
from tkinter import ttk
from typing import Optional, Callable, Any
from config import Config
class ModernStyle:
"""Manages modern styling for tkinter widgets"""
def __init__(self):
self.theme = Config.get_theme()
self.fonts = Config.FONTS
self.spacing = Config.SPACING
def configure_styles(self, style: ttk.Style):
"""Configure modern ttk styles"""
theme = self.theme
# Configure main frame
style.configure("Modern.TFrame",
background=theme["bg_primary"],
relief="flat")
# Configure card frames
style.configure("Card.TFrame",
background=theme["bg_secondary"],
relief="flat",
borderwidth=1)
# Configure modern buttons
style.configure("Modern.TButton",
background=theme["accent"],
foreground=theme["text_primary"] if "dark" in Config.CURRENT_THEME else "white",
font=self.fonts["button"],
borderwidth=0,
focuscolor="none",
relief="flat",
padding=(12, 8))
style.map("Modern.TButton",
background=[("active", theme["accent_hover"]),
("pressed", theme["accent"])],
foreground=[("active", "white"),
("pressed", "white")])
# Configure success buttons
style.configure("Success.TButton",
background=theme["success"],
foreground="white",
font=self.fonts["button"],
borderwidth=0,
focuscolor="none",
relief="flat",
padding=(12, 8))
style.map("Success.TButton",
background=[("active", theme["success_hover"]),
("pressed", theme["success"])],
foreground=[("active", "white"),
("pressed", "white")])
# Configure secondary buttons
style.configure("Secondary.TButton",
background=theme["bg_tertiary"],
foreground=theme["text_primary"],
font=self.fonts["body"],
borderwidth=1,
focuscolor="none",
relief="flat",
padding=(8, 6))
style.map("Secondary.TButton",
background=[("active", theme["border"]),
("pressed", theme["bg_tertiary"])],
relief=[("pressed", "flat")])
# Configure icon buttons
style.configure("Icon.TButton",
background=theme["bg_tertiary"],
foreground=theme["text_primary"],
font=self.fonts["subheading"],
borderwidth=1,
focuscolor="none",
relief="flat",
padding=(8, 8))
style.map("Icon.TButton",
background=[("active", theme["border"]),
("pressed", theme["bg_tertiary"])],
relief=[("pressed", "flat")])
# Configure labels
style.configure("Heading.TLabel",
background=theme["bg_primary"],
foreground=theme["text_primary"],
font=self.fonts["heading"])
style.configure("Subheading.TLabel",
background=theme["bg_primary"],
foreground=theme["text_secondary"],
font=self.fonts["subheading"])
style.configure("Body.TLabel",
background=theme["bg_primary"],
foreground=theme["text_secondary"],
font=self.fonts["body"])
style.configure("Caption.TLabel",
background=theme["bg_primary"],
foreground=theme["text_muted"],
font=self.fonts["caption"])
# Configure modern treeview
style.configure("Modern.Treeview",
background=theme["bg_secondary"],
foreground=theme["text_primary"],
fieldbackground=theme["bg_secondary"],
borderwidth=0,
relief="flat",
font=self.fonts["body"])
style.configure("Modern.Treeview.Heading",
background=theme["bg_tertiary"],
foreground=theme["text_primary"],
font=self.fonts["subheading"],
relief="flat",
borderwidth=0)
style.map("Modern.Treeview",
background=[("selected", theme["selection"])],
foreground=[("selected", "white")])
style.map("Modern.Treeview.Heading",
background=[("active", theme["border"])])
# Configure modern listbox (via tk styling)
# Note: Listbox doesn't support ttk styling, will be handled in widget creation
# Configure modern entry
style.configure("Modern.TEntry",
fieldbackground=theme["bg_secondary"],
foreground=theme["text_primary"],
borderwidth=1,
relief="flat",
insertcolor=theme["text_primary"],
font=self.fonts["body"])
style.map("Modern.TEntry",
focuscolor=[("focus", theme["accent"])],
bordercolor=[("focus", theme["accent"])])
# Configure modern combobox
style.configure("Modern.TCombobox",
fieldbackground=theme["bg_secondary"],
foreground=theme["text_primary"],
background=theme["bg_secondary"],
borderwidth=1,
relief="flat",
font=self.fonts["body"])
# Configure modern checkbutton
style.configure("Modern.TCheckbutton",
background=theme["bg_secondary"],
foreground=theme["text_primary"],
font=self.fonts["body"],
focuscolor="none")
style.map("Modern.TCheckbutton",
background=[("active", theme["bg_secondary"]),
("pressed", theme["bg_secondary"])])
class ModernCard(ttk.Frame):
"""A modern card-like container with shadow effect simulation"""
def __init__(self, parent, padding=None, **kwargs):
super().__init__(parent, style="Card.TFrame",
padding=padding or Config.CARD_PADDING, **kwargs)
class ModernButton(ttk.Button):
"""Enhanced button with modern styling and hover effects"""
def __init__(self, parent, text="", style_type="primary", icon=None,
command=None, **kwargs):
# Determine style based on type
if style_type == "primary":
style = "Modern.TButton"
elif style_type == "success":
style = "Success.TButton"
elif style_type == "secondary":
style = "Secondary.TButton"
else:
style = "Modern.TButton"
super().__init__(parent, text=text, style=style, command=command, **kwargs)
# Add hover effects
self.bind("<Enter>", self._on_enter)
self.bind("<Leave>", self._on_leave)
def _on_enter(self, event):
"""Handle mouse enter"""
self.configure(cursor="hand2")
def _on_leave(self, event):
"""Handle mouse leave"""
self.configure(cursor="")
class ModernListbox(tk.Listbox):
"""Modern styled listbox with custom colors"""
def __init__(self, parent, **kwargs):
theme = Config.get_theme()
# Configure modern listbox appearance
defaults = {
"background": theme["bg_secondary"],
"foreground": theme["text_primary"],
"selectbackground": theme["selection"],
"selectforeground": "white",
"activestyle": "none",
"relief": "flat",
"borderwidth": 0,
"highlightthickness": 1,
"highlightcolor": theme["accent"],
"highlightbackground": theme["border"],
"font": Config.FONTS["body"]
}
# Merge with user provided kwargs
defaults.update(kwargs)
super().__init__(parent, **defaults)
class ModernTreeview(ttk.Treeview):
"""Enhanced treeview with modern styling"""
def __init__(self, parent, **kwargs):
super().__init__(parent, style="Modern.Treeview", **kwargs)
# Configure modern row height
style = ttk.Style()
style.configure("Modern.Treeview", rowheight=32)
class ModernScrollbar(ttk.Scrollbar):
"""Modern styled scrollbar"""
def __init__(self, parent, **kwargs):
super().__init__(parent, **kwargs)
# Configure modern scrollbar
style = ttk.Style()
theme = Config.get_theme()
style.configure("Modern.Vertical.TScrollbar",
background=theme["bg_tertiary"],
troughcolor=theme["bg_primary"],
borderwidth=0,
arrowcolor=theme["text_muted"],
darkcolor=theme["bg_tertiary"],
lightcolor=theme["bg_tertiary"])
class IconButton(ttk.Button):
"""Button designed specifically for icons"""
def __init__(self, parent, icon_text="", command=None, **kwargs):
super().__init__(parent, text=icon_text, style="Icon.TButton",
command=command, **kwargs)
self.configure(width=3)
# Add hover effects
self.bind("<Enter>", self._on_enter)
self.bind("<Leave>", self._on_leave)
def _on_enter(self, event):
"""Handle mouse enter"""
self.configure(cursor="hand2")
def _on_leave(self, event):
"""Handle mouse leave"""
self.configure(cursor="")