Kompletter Rewrite
This commit is contained in:
288
gui/modern_widgets.py
Normal file
288
gui/modern_widgets.py
Normal file
@@ -0,0 +1,288 @@
|
||||
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="")
|
||||
Reference in New Issue
Block a user