svg-processor/gui/theme_manager.py
2025-05-16 18:15:31 +04:00

100 lines
5.7 KiB
Python

import tkinter as tk
from tkinter import ttk
class ThemeManager:
"""Manager for application theme configuration (defaulting to light theme)."""
def __init__(self, root):
"""
Initialize the theme manager and apply the light theme.
Args:
root: The Tkinter root window (needed for background config).
"""
self.root = root
self.style = ttk.Style()
self.apply_theme() # Directly apply light theme
def apply_theme(self):
"""Applies the light theme."""
self._apply_light_theme()
# Ensure the root window background matches the theme
try:
bg_color = self.style.lookup('.', 'background')
self.root.configure(background=bg_color)
except tk.TclError:
# Fallback if style lookup fails
self.root.configure(background='SystemButtonFace')
def _apply_light_theme(self):
"""Configure a standard light theme using system defaults where possible."""
try:
# Use a standard theme, preferring OS native look
available_themes = self.style.theme_names()
# Windows preference order
preferred_themes = ['vista', 'xpnative', 'clam', 'alt', 'default']
chosen_theme = 'default'
for theme in preferred_themes:
if theme in available_themes:
try:
self.style.theme_use(theme)
chosen_theme = theme
# print(f"Using theme: {chosen_theme}") # Debug
break
except tk.TclError:
continue
# Reset most styles to theme defaults by configuring with empty strings
# or removing specific configure calls if they were only for dark theme.
# Explicitly set base theme colors for light mode
self.style.configure('.', background='SystemButtonFace', foreground='SystemWindowText')
self.style.configure('TFrame', background='SystemButtonFace')
# Explicitly set foreground AND background for visibility
self.style.configure('TLabel', foreground='SystemWindowText', background='SystemButtonFace')
# Explicitly set foreground AND background for visibility
self.style.configure('TButton', foreground='SystemWindowText', background='SystemButtonFace', padding=5)
# Reset button border color explicitly if needed, or remove if SystemButtonFace is desired
self.style.configure('TButton', bordercolor='SystemGrayText') # Example: Use a visible border
self.style.map('TButton',
background=[('active', 'SystemButtonHighlight'), ('pressed', '!focus', 'SystemButtonFace'), ('focus', 'SystemButtonHighlight')]) # Example map
# Keep Danger button distinct
self.style.configure('Danger.TButton', foreground='black', background='#cc3333', bordercolor='#aa2222', padding=5) # Enhanced danger button
self.style.map('Danger.TButton',
background=[('active', '#dd4444'), ('pressed', '#bb2222')],
foreground=[('active', 'black'), ('pressed', 'black')])
# TEntry: Use defaults. Let's ensure its colors are sensible too.
self.style.configure('TEntry', foreground='SystemWindowText', fieldbackground='SystemWindow', insertcolor='SystemWindowText', bordercolor='SystemGrayText')
# self.style.map('TEntry') # Reset map - might not be needed if configure is explicit
self.style.configure('TLabelframe', background='SystemButtonFace', bordercolor='SystemGrayText')
# Ensure label frame labels are also visible
self.style.configure('TLabelframe.Label', background='SystemButtonFace', foreground='SystemWindowText')
# TNotebook adjustments (if needed, often inherit well)
self.style.configure('TNotebook', background='SystemButtonFace', bordercolor='SystemGrayText', tabmargins=[2, 5, 2, 0])
self.style.configure('TNotebook.Tab', foreground='SystemWindowText', background='SystemButtonFace', padding=[10, 5])
self.style.map('TNotebook.Tab', background=[('selected', 'SystemButtonHighlight')]) # Example map
# Progressbar and Scrollbar adjustments
self.style.configure('Horizontal.TProgressbar', background='SystemHighlight', troughcolor='SystemButtonFace', bordercolor='SystemGrayText')
self.style.configure('TScrollbar', troughcolor='SystemButtonFace', background='SystemScrollbar', bordercolor='SystemGrayText', arrowcolor='SystemWindowText')
# self.style.map('TScrollbar') # Reset map
except Exception as e:
print(f"Error applying light theme: {e}")
def get_scrolledtext_colors(self):
"""Returns appropriate background/foreground colors for ScrolledText (light theme defaults)."""
# Always return light theme defaults now
try:
default_bg = self.root.option_get('background', 'Text')
default_fg = self.root.option_get('foreground', 'Text')
insert_bg = self.root.option_get('insertBackground', 'Text')
if not default_bg: default_bg = 'SystemWindow' # Tk default color name
if not default_fg: default_fg = 'SystemWindowText'
if not insert_bg: insert_bg = default_fg # Cursor color often matches text
return {'bg': default_bg, 'fg': default_fg, 'insertbackground': insert_bg}
except tk.TclError:
# Fallback if options can't be retrieved
return {'bg': 'white', 'fg': 'black', 'insertbackground': 'black'}