renamed ThemeManage.single_color to _apply_appearance_mode and moved it to baseclass and windows

This commit is contained in:
Tom Schimansky 2022-10-29 01:20:32 +02:00
parent 08a0835fd0
commit e5484cb6cd
20 changed files with 315 additions and 330 deletions

View File

@ -25,63 +25,3 @@ class ThemeManager:
cls.theme["text"] = cls.theme["text"]["Windows"] cls.theme["text"] = cls.theme["text"]["Windows"]
else: else:
cls.theme["text"] = cls.theme["text"]["Linux"] cls.theme["text"] = cls.theme["text"]["Linux"]
@staticmethod
def single_color(color, appearance_mode: int) -> str:
""" color can be either a single hex color string or a color name or it can be a
tuple color with (light_color, dark_color). The functions then returns
always a single color string """
if type(color) == tuple or type(color) == list:
return color[appearance_mode]
else:
return color
@staticmethod
def rgb2hex(rgb_color: tuple) -> str:
return "#{:02x}{:02x}{:02x}".format(round(rgb_color[0]), round(rgb_color[1]), round(rgb_color[2]))
@staticmethod
def hex2rgb(hex_color: str) -> tuple:
return tuple(int(hex_color.strip("#")[i:i+2], 16) for i in (0, 2, 4))
@classmethod
def linear_blend(cls, color_1: str, color_2: str, blend_factor: float) -> str:
""" Blends two hex colors linear, where blend_factor of 0
results in color_1 and blend_factor of 1 results in color_2. """
if color_1 is None or color_2 is None:
return None
rgb_1 = cls.hex2rgb(color_1)
rgb_2 = cls.hex2rgb(color_2)
new_rgb = (rgb_1[0] + (rgb_2[0] - rgb_1[0]) * blend_factor,
rgb_1[1] + (rgb_2[1] - rgb_1[1]) * blend_factor,
rgb_1[2] + (rgb_2[2] - rgb_1[2]) * blend_factor)
return cls.rgb2hex(new_rgb)
@classmethod
def get_minimal_darker(cls, color: str) -> str:
if color.startswith("#"):
color_rgb = cls.hex2rgb(color)
if color_rgb[0] > 0:
return cls.rgb2hex((color_rgb[0] - 1, color_rgb[1], color_rgb[2]))
elif color_rgb[1] > 0:
return cls.rgb2hex((color_rgb[0], color_rgb[1] - 1, color_rgb[2]))
elif color_rgb[2] > 0:
return cls.rgb2hex((color_rgb[0], color_rgb[1], color_rgb[2] - 1))
else:
return cls.rgb2hex((color_rgb[0] + 1, color_rgb[1], color_rgb[2] - 1)) # otherwise slightly lighter
@classmethod
def multiply_hex_color(cls, hex_color: str, factor: float = 1.0) -> str:
try:
rgb_color = ThemeManager.hex2rgb(hex_color)
dark_rgb_color = (min(255, rgb_color[0] * factor),
min(255, rgb_color[1] * factor),
min(255, rgb_color[2] * factor))
return ThemeManager.rgb2hex(dark_rgb_color)
except Exception as err:
return hex_color

View File

@ -0,0 +1,15 @@
from typing import Union, Tuple, List
class CTkAppearanceModeBaseClass:
def __init__(self):
def _apply_appearance_mode(self, color: Union[str, Tuple[str, str], List[str]]) -> str:
""" color can be either a single hex color string or a color name or it can be a
tuple color with (light_color, dark_color). The functions returns
always a single color string """
if type(color) == tuple or type(color) == list:
return color[self._appearance_mode]
else:
return color

View File

@ -65,24 +65,24 @@ class DropdownMenu(tkinter.Menu):
elif sys.platform.startswith("win"): elif sys.platform.startswith("win"):
super().configure(tearoff=False, super().configure(tearoff=False,
relief="flat", relief="flat",
activebackground=ThemeManager.single_color(self._hover_color, self._appearance_mode), activebackground=ThemeManager._apply_appearance_mode(self._hover_color, self._appearance_mode),
borderwidth=self._apply_widget_scaling(4), borderwidth=self._apply_widget_scaling(4),
activeborderwidth=self._apply_widget_scaling(4), activeborderwidth=self._apply_widget_scaling(4),
bg=ThemeManager.single_color(self._fg_color, self._appearance_mode), bg=ThemeManager._apply_appearance_mode(self._fg_color, self._appearance_mode),
fg=ThemeManager.single_color(self._text_color, self._appearance_mode), fg=ThemeManager._apply_appearance_mode(self._text_color, self._appearance_mode),
activeforeground=ThemeManager.single_color(self._text_color, self._appearance_mode), activeforeground=ThemeManager._apply_appearance_mode(self._text_color, self._appearance_mode),
font=self._apply_font_scaling(self._font), font=self._apply_font_scaling(self._font),
cursor="hand2") cursor="hand2")
else: else:
super().configure(tearoff=False, super().configure(tearoff=False,
relief="flat", relief="flat",
activebackground=ThemeManager.single_color(self._hover_color, self._appearance_mode), activebackground=ThemeManager._apply_appearance_mode(self._hover_color, self._appearance_mode),
borderwidth=0, borderwidth=0,
activeborderwidth=0, activeborderwidth=0,
bg=ThemeManager.single_color(self._fg_color, self._appearance_mode), bg=ThemeManager._apply_appearance_mode(self._fg_color, self._appearance_mode),
fg=ThemeManager.single_color(self._text_color, self._appearance_mode), fg=ThemeManager._apply_appearance_mode(self._text_color, self._appearance_mode),
activeforeground=ThemeManager.single_color(self._text_color, self._appearance_mode), activeforeground=ThemeManager._apply_appearance_mode(self._text_color, self._appearance_mode),
font=self._apply_font_scaling(self._font)) font=self._apply_font_scaling(self._font))
def _add_menu_commands(self): def _add_menu_commands(self):
@ -120,15 +120,15 @@ class DropdownMenu(tkinter.Menu):
def configure(self, **kwargs): def configure(self, **kwargs):
if "fg_color" in kwargs: if "fg_color" in kwargs:
self._fg_color = kwargs.pop("fg_color") self._fg_color = kwargs.pop("fg_color")
super().configure(bg=ThemeManager.single_color(self._fg_color, self._appearance_mode)) super().configure(bg=ThemeManager._apply_appearance_mode(self._fg_color, self._appearance_mode))
if "hover_color" in kwargs: if "hover_color" in kwargs:
self._hover_color = kwargs.pop("hover_color") self._hover_color = kwargs.pop("hover_color")
super().configure(activebackground=ThemeManager.single_color(self._hover_color, self._appearance_mode)) super().configure(activebackground=ThemeManager._apply_appearance_mode(self._hover_color, self._appearance_mode))
if "text_color" in kwargs: if "text_color" in kwargs:
self._text_color = kwargs.pop("text_color") self._text_color = kwargs.pop("text_color")
super().configure(fg=ThemeManager.single_color(self._text_color, self._appearance_mode)) super().configure(fg=ThemeManager._apply_appearance_mode(self._text_color, self._appearance_mode))
if "font" in kwargs: if "font" in kwargs:
if isinstance(self._font, CTkFont): if isinstance(self._font, CTkFont):

View File

@ -2,7 +2,8 @@ import sys
import tkinter import tkinter
import tkinter.ttk as ttk import tkinter.ttk as ttk
import copy import copy
from typing import Union, Callable, Tuple from typing import Union, Callable, Tuple, List
from abc import ABC, abstractmethod
try: try:
from typing import TypedDict from typing import TypedDict
@ -15,12 +16,11 @@ from ...appearance_mode_tracker import AppearanceModeTracker
from ...scaling_tracker import ScalingTracker from ...scaling_tracker import ScalingTracker
from ...theme_manager import ThemeManager from ...theme_manager import ThemeManager
from ..font.ctk_font import CTkFont from ..font.ctk_font import CTkFont
from ..image.ctk_image import CTkImage
from ...utility.utility_functions import pop_from_dict_by_set, check_kwargs_empty from ...utility.utility_functions import pop_from_dict_by_set, check_kwargs_empty
class CTkBaseClass(tkinter.Frame): class CTkBaseClass(tkinter.Frame, ABC):
""" Base class of every CTk widget, handles the dimensions, _bg_color, """ Base class of every CTk widget, handles the dimensions, _bg_color,
appearance_mode changes, scaling, bg changes of master if master is not a CTk widget """ appearance_mode changes, scaling, bg changes of master if master is not a CTk widget """
@ -69,7 +69,7 @@ class CTkBaseClass(tkinter.Frame):
# background color # background color
self._bg_color: Union[str, Tuple[str, str]] = self._detect_color_of_master() if bg_color is None else bg_color self._bg_color: Union[str, Tuple[str, str]] = self._detect_color_of_master() if bg_color is None else bg_color
super().configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) super().configure(bg=self._apply_appearance_mode(self._bg_color))
super().bind('<Configure>', self._update_dimensions_event) super().bind('<Configure>', self._update_dimensions_event)
# overwrite configure methods of master when master is tkinter widget, so that bg changes get applied on child CTk widget as well # overwrite configure methods of master when master is tkinter widget, so that bg changes get applied on child CTk widget as well
@ -93,9 +93,9 @@ class CTkBaseClass(tkinter.Frame):
self.master.config = new_configure self.master.config = new_configure
self.master.configure = new_configure self.master.configure = new_configure
@abstractmethod
def _draw(self, no_color_updates: bool = False): def _draw(self, no_color_updates: bool = False):
""" abstract of draw method to be overridden """ return
pass
def config(self, *args, **kwargs): def config(self, *args, **kwargs):
raise AttributeError("'config' is not implemented for CTk widgets. For consistency, always use 'configure' instead.") raise AttributeError("'config' is not implemented for CTk widgets. For consistency, always use 'configure' instead.")
@ -200,7 +200,7 @@ class CTkBaseClass(tkinter.Frame):
elif mode_string.lower() == "light": elif mode_string.lower() == "light":
self._appearance_mode = 0 self._appearance_mode = 0
super().configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) super().configure(bg=self._apply_appearance_mode(self._bg_color))
self._draw() self._draw()
def _set_scaling(self, new_widget_scaling, new_window_scaling): def _set_scaling(self, new_widget_scaling, new_window_scaling):
@ -265,6 +265,16 @@ class CTkBaseClass(tkinter.Frame):
return scaled_kwargs return scaled_kwargs
def _apply_appearance_mode(self, color: Union[str, Tuple[str, str], List[str]]) -> str:
""" color can be either a single hex color string or a color name or it can be a
tuple color with (light_color, dark_color). The functions returns
always a single color string """
if type(color) == tuple or type(color) == list:
return color[self._appearance_mode]
else:
return color
def destroy(self): def destroy(self):
""" Destroy this and all descendants widgets. """ """ Destroy this and all descendants widgets. """
AppearanceModeTracker.remove(self._set_appearance_mode) AppearanceModeTracker.remove(self._set_appearance_mode)

View File

@ -144,10 +144,10 @@ class CTkButton(CTkBaseClass):
if self._background_corner_colors is not None: if self._background_corner_colors is not None:
self._draw_engine.draw_background_corners(self._apply_widget_scaling(self._current_width), self._draw_engine.draw_background_corners(self._apply_widget_scaling(self._current_width),
self._apply_widget_scaling(self._current_height)) self._apply_widget_scaling(self._current_height))
self._canvas.itemconfig("background_corner_top_left", fill=ThemeManager.single_color(self._background_corner_colors[0], self._appearance_mode)) self._canvas.itemconfig("background_corner_top_left", fill=self._apply_appearance_mode(self._background_corner_colors[0]))
self._canvas.itemconfig("background_corner_top_right", fill=ThemeManager.single_color(self._background_corner_colors[1], self._appearance_mode)) self._canvas.itemconfig("background_corner_top_right", fill=self._apply_appearance_mode(self._background_corner_colors[1]))
self._canvas.itemconfig("background_corner_bottom_right", fill=ThemeManager.single_color(self._background_corner_colors[2], self._appearance_mode)) self._canvas.itemconfig("background_corner_bottom_right", fill=self._apply_appearance_mode(self._background_corner_colors[2]))
self._canvas.itemconfig("background_corner_bottom_left", fill=ThemeManager.single_color(self._background_corner_colors[3], self._appearance_mode)) self._canvas.itemconfig("background_corner_bottom_left", fill=self._apply_appearance_mode(self._background_corner_colors[3]))
else: else:
self._canvas.delete("background_parts") self._canvas.delete("background_parts")
@ -158,22 +158,22 @@ class CTkButton(CTkBaseClass):
if no_color_updates is False or requires_recoloring: if no_color_updates is False or requires_recoloring:
self._canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._canvas.configure(bg=self._apply_appearance_mode(self._bg_color))
# set color for the button border parts (outline) # set color for the button border parts (outline)
self._canvas.itemconfig("border_parts", self._canvas.itemconfig("border_parts",
outline=ThemeManager.single_color(self._border_color, self._appearance_mode), outline=self._apply_appearance_mode(self._border_color),
fill=ThemeManager.single_color(self._border_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._border_color))
# set color for inner button parts # set color for inner button parts
if self._fg_color is None: if self._fg_color is None:
self._canvas.itemconfig("inner_parts", self._canvas.itemconfig("inner_parts",
outline=ThemeManager.single_color(self._bg_color, self._appearance_mode), outline=self._apply_appearance_mode(self._bg_color),
fill=ThemeManager.single_color(self._bg_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._bg_color))
else: else:
self._canvas.itemconfig("inner_parts", self._canvas.itemconfig("inner_parts",
outline=ThemeManager.single_color(self._fg_color, self._appearance_mode), outline=self._apply_appearance_mode(self._fg_color),
fill=ThemeManager.single_color(self._fg_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._fg_color))
# create text label if text given # create text label if text given
if self._text is not None and self._text != "": if self._text is not None and self._text != "":
@ -195,17 +195,17 @@ class CTkButton(CTkBaseClass):
if no_color_updates is False: if no_color_updates is False:
# set text_label fg color (text color) # set text_label fg color (text color)
self._text_label.configure(fg=ThemeManager.single_color(self._text_color, self._appearance_mode)) self._text_label.configure(fg=self._apply_appearance_mode(self._text_color))
if self._state == tkinter.DISABLED: if self._state == tkinter.DISABLED:
self._text_label.configure(fg=(ThemeManager.single_color(self._text_color_disabled, self._appearance_mode))) self._text_label.configure(fg=(self._apply_appearance_mode(self._text_color_disabled)))
else: else:
self._text_label.configure(fg=ThemeManager.single_color(self._text_color, self._appearance_mode)) self._text_label.configure(fg=self._apply_appearance_mode(self._text_color))
if self._fg_color is None: if self._fg_color is None:
self._text_label.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._text_label.configure(bg=self._apply_appearance_mode(self._bg_color))
else: else:
self._text_label.configure(bg=ThemeManager.single_color(self._fg_color, self._appearance_mode)) self._text_label.configure(bg=self._apply_appearance_mode(self._fg_color))
else: else:
# delete text_label if no text given # delete text_label if no text given
@ -229,9 +229,9 @@ class CTkButton(CTkBaseClass):
if no_color_updates is False: if no_color_updates is False:
# set image_label bg color (background color of label) # set image_label bg color (background color of label)
if self._fg_color is None: if self._fg_color is None:
self._image_label.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._image_label.configure(bg=self._apply_appearance_mode(self._bg_color))
else: else:
self._image_label.configure(bg=ThemeManager.single_color(self._fg_color, self._appearance_mode)) self._image_label.configure(bg=self._apply_appearance_mode(self._fg_color))
self._image_label.configure(image=self._image) # set image self._image_label.configure(image=self._image) # set image
@ -461,16 +461,16 @@ class CTkButton(CTkBaseClass):
# set color of inner button parts to hover color # set color of inner button parts to hover color
self._canvas.itemconfig("inner_parts", self._canvas.itemconfig("inner_parts",
outline=ThemeManager.single_color(inner_parts_color, self._appearance_mode), outline=self._apply_appearance_mode(inner_parts_color),
fill=ThemeManager.single_color(inner_parts_color, self._appearance_mode)) fill=self._apply_appearance_mode(inner_parts_color))
# set text_label bg color to button hover color # set text_label bg color to button hover color
if self._text_label is not None: if self._text_label is not None:
self._text_label.configure(bg=ThemeManager.single_color(inner_parts_color, self._appearance_mode)) self._text_label.configure(bg=self._apply_appearance_mode(inner_parts_color))
# set image_label bg color to button hover color # set image_label bg color to button hover color
if self._image_label is not None: if self._image_label is not None:
self._image_label.configure(bg=ThemeManager.single_color(inner_parts_color, self._appearance_mode)) self._image_label.configure(bg=self._apply_appearance_mode(inner_parts_color))
def _on_leave(self, event=None): def _on_leave(self, event=None):
self._click_animation_running = False self._click_animation_running = False
@ -482,16 +482,16 @@ class CTkButton(CTkBaseClass):
# set color of inner button parts # set color of inner button parts
self._canvas.itemconfig("inner_parts", self._canvas.itemconfig("inner_parts",
outline=ThemeManager.single_color(inner_parts_color, self._appearance_mode), outline=self._apply_appearance_mode(inner_parts_color),
fill=ThemeManager.single_color(inner_parts_color, self._appearance_mode)) fill=self._apply_appearance_mode(inner_parts_color))
# set text_label bg color (label color) # set text_label bg color (label color)
if self._text_label is not None: if self._text_label is not None:
self._text_label.configure(bg=ThemeManager.single_color(inner_parts_color, self._appearance_mode)) self._text_label.configure(bg=self._apply_appearance_mode(inner_parts_color))
# set image_label bg color (image bg color) # set image_label bg color (image bg color)
if self._image_label is not None: if self._image_label is not None:
self._image_label.configure(bg=ThemeManager.single_color(inner_parts_color, self._appearance_mode)) self._image_label.configure(bg=self._apply_appearance_mode(inner_parts_color))
def _click_animation(self): def _click_animation(self):
if self._click_animation_running: if self._click_animation_running:

View File

@ -183,35 +183,35 @@ class CTkCheckBox(CTkBaseClass):
self._canvas.delete("checkmark") self._canvas.delete("checkmark")
if no_color_updates is False or requires_recoloring_1 or requires_recoloring_2: if no_color_updates is False or requires_recoloring_1 or requires_recoloring_2:
self._bg_canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._bg_canvas.configure(bg=self._apply_appearance_mode(self._bg_color))
self._canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._canvas.configure(bg=self._apply_appearance_mode(self._bg_color))
if self._check_state is True: if self._check_state is True:
self._canvas.itemconfig("inner_parts", self._canvas.itemconfig("inner_parts",
outline=ThemeManager.single_color(self._fg_color, self._appearance_mode), outline=self._apply_appearance_mode(self._fg_color),
fill=ThemeManager.single_color(self._fg_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._fg_color))
self._canvas.itemconfig("border_parts", self._canvas.itemconfig("border_parts",
outline=ThemeManager.single_color(self._fg_color, self._appearance_mode), outline=self._apply_appearance_mode(self._fg_color),
fill=ThemeManager.single_color(self._fg_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._fg_color))
if "create_line" in self._canvas.gettags("checkmark"): if "create_line" in self._canvas.gettags("checkmark"):
self._canvas.itemconfig("checkmark", fill=ThemeManager.single_color(self._checkmark_color, self._appearance_mode)) self._canvas.itemconfig("checkmark", fill=self._apply_appearance_mode(self._checkmark_color))
else: else:
self._canvas.itemconfig("checkmark", fill=ThemeManager.single_color(self._checkmark_color, self._appearance_mode)) self._canvas.itemconfig("checkmark", fill=self._apply_appearance_mode(self._checkmark_color))
else: else:
self._canvas.itemconfig("inner_parts", self._canvas.itemconfig("inner_parts",
outline=ThemeManager.single_color(self._bg_color, self._appearance_mode), outline=self._apply_appearance_mode(self._bg_color),
fill=ThemeManager.single_color(self._bg_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._bg_color))
self._canvas.itemconfig("border_parts", self._canvas.itemconfig("border_parts",
outline=ThemeManager.single_color(self._border_color, self._appearance_mode), outline=self._apply_appearance_mode(self._border_color),
fill=ThemeManager.single_color(self._border_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._border_color))
if self._state == tkinter.DISABLED: if self._state == tkinter.DISABLED:
self._text_label.configure(fg=(ThemeManager.single_color(self._text_color_disabled, self._appearance_mode))) self._text_label.configure(fg=(self._apply_appearance_mode(self._text_color_disabled)))
else: else:
self._text_label.configure(fg=ThemeManager.single_color(self._text_color, self._appearance_mode)) self._text_label.configure(fg=self._apply_appearance_mode(self._text_color))
self._text_label.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._text_label.configure(bg=self._apply_appearance_mode(self._bg_color))
def configure(self, require_redraw=False, **kwargs): def configure(self, require_redraw=False, **kwargs):
if "checkbox_width" in kwargs: if "checkbox_width" in kwargs:
@ -349,31 +349,31 @@ class CTkCheckBox(CTkBaseClass):
if self._hover is True and self._state == tkinter.NORMAL: if self._hover is True and self._state == tkinter.NORMAL:
if self._check_state is True: if self._check_state is True:
self._canvas.itemconfig("inner_parts", self._canvas.itemconfig("inner_parts",
fill=ThemeManager.single_color(self._hover_color, self._appearance_mode), fill=self._apply_appearance_mode(self._hover_color),
outline=ThemeManager.single_color(self._hover_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._hover_color))
self._canvas.itemconfig("border_parts", self._canvas.itemconfig("border_parts",
fill=ThemeManager.single_color(self._hover_color, self._appearance_mode), fill=self._apply_appearance_mode(self._hover_color),
outline=ThemeManager.single_color(self._hover_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._hover_color))
else: else:
self._canvas.itemconfig("inner_parts", self._canvas.itemconfig("inner_parts",
fill=ThemeManager.single_color(self._hover_color, self._appearance_mode), fill=self._apply_appearance_mode(self._hover_color),
outline=ThemeManager.single_color(self._hover_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._hover_color))
def _on_leave(self, event=0): def _on_leave(self, event=0):
if self._check_state is True: if self._check_state is True:
self._canvas.itemconfig("inner_parts", self._canvas.itemconfig("inner_parts",
fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), fill=self._apply_appearance_mode(self._fg_color),
outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._fg_color))
self._canvas.itemconfig("border_parts", self._canvas.itemconfig("border_parts",
fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), fill=self._apply_appearance_mode(self._fg_color),
outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._fg_color))
else: else:
self._canvas.itemconfig("inner_parts", self._canvas.itemconfig("inner_parts",
fill=ThemeManager.single_color(self._bg_color, self._appearance_mode), fill=self._apply_appearance_mode(self._bg_color),
outline=ThemeManager.single_color(self._bg_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._bg_color))
self._canvas.itemconfig("border_parts", self._canvas.itemconfig("border_parts",
fill=ThemeManager.single_color(self._border_color, self._appearance_mode), fill=self._apply_appearance_mode(self._border_color),
outline=ThemeManager.single_color(self._border_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._border_color))
def _variable_callback(self, var_name, index, mode): def _variable_callback(self, var_name, index, mode):
if not self._variable_callback_blocked: if not self._variable_callback_blocked:

View File

@ -35,7 +35,7 @@ class CTkComboBox(CTkBaseClass):
text_color_disabled: Union[str, Tuple[str, str]] = "default_theme", text_color_disabled: Union[str, Tuple[str, str]] = "default_theme",
font: Union[tuple, CTkFont] = "default_theme", font: Union[tuple, CTkFont] = "default_theme",
dropdown_font: any = "default_theme", dropdown_font: Union[tuple, CTkFont] = "default_theme",
values: List[str] = None, values: List[str] = None,
state: str = tkinter.NORMAL, state: str = tkinter.NORMAL,
hover: bool = True, hover: bool = True,
@ -180,34 +180,34 @@ class CTkComboBox(CTkBaseClass):
if no_color_updates is False or requires_recoloring or requires_recoloring_2: if no_color_updates is False or requires_recoloring or requires_recoloring_2:
self._canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._canvas.configure(bg=self._apply_appearance_mode(self._bg_color))
self._canvas.itemconfig("inner_parts_left", self._canvas.itemconfig("inner_parts_left",
outline=ThemeManager.single_color(self._fg_color, self._appearance_mode), outline=self._apply_appearance_mode(self._fg_color),
fill=ThemeManager.single_color(self._fg_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._fg_color))
self._canvas.itemconfig("border_parts_left", self._canvas.itemconfig("border_parts_left",
outline=ThemeManager.single_color(self._border_color, self._appearance_mode), outline=self._apply_appearance_mode(self._border_color),
fill=ThemeManager.single_color(self._border_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._border_color))
self._canvas.itemconfig("inner_parts_right", self._canvas.itemconfig("inner_parts_right",
outline=ThemeManager.single_color(self._border_color, self._appearance_mode), outline=self._apply_appearance_mode(self._border_color),
fill=ThemeManager.single_color(self._border_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._border_color))
self._canvas.itemconfig("border_parts_right", self._canvas.itemconfig("border_parts_right",
outline=ThemeManager.single_color(self._border_color, self._appearance_mode), outline=self._apply_appearance_mode(self._border_color),
fill=ThemeManager.single_color(self._border_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._border_color))
self._entry.configure(bg=ThemeManager.single_color(self._fg_color, self._appearance_mode), self._entry.configure(bg=self._apply_appearance_mode(self._fg_color),
fg=ThemeManager.single_color(self._text_color, self._appearance_mode), fg=self._apply_appearance_mode(self._text_color),
disabledbackground=ThemeManager.single_color(self._fg_color, self._appearance_mode), disabledbackground=self._apply_appearance_mode(self._fg_color),
disabledforeground=ThemeManager.single_color(self._text_color_disabled, self._appearance_mode), disabledforeground=self._apply_appearance_mode(self._text_color_disabled),
highlightcolor=ThemeManager.single_color(self._fg_color, self._appearance_mode), highlightcolor=self._apply_appearance_mode(self._fg_color),
insertbackground=ThemeManager.single_color(self._text_color, self._appearance_mode)) insertbackground=self._apply_appearance_mode(self._text_color))
if self._state == tkinter.DISABLED: if self._state == tkinter.DISABLED:
self._canvas.itemconfig("dropdown_arrow", self._canvas.itemconfig("dropdown_arrow",
fill=ThemeManager.single_color(self._text_color_disabled, self._appearance_mode)) fill=self._apply_appearance_mode(self._text_color_disabled))
else: else:
self._canvas.itemconfig("dropdown_arrow", self._canvas.itemconfig("dropdown_arrow",
fill=ThemeManager.single_color(self._text_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._text_color))
def _open_dropdown_menu(self): def _open_dropdown_menu(self):
self._dropdown_menu.open(self.winfo_rootx(), self._dropdown_menu.open(self.winfo_rootx(),
@ -345,11 +345,11 @@ class CTkComboBox(CTkBaseClass):
# set color of inner button parts to hover color # set color of inner button parts to hover color
self._canvas.itemconfig("inner_parts_right", self._canvas.itemconfig("inner_parts_right",
outline=ThemeManager.single_color(self._button_hover_color, self._appearance_mode), outline=self._apply_appearance_mode(self._button_hover_color),
fill=ThemeManager.single_color(self._button_hover_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._button_hover_color))
self._canvas.itemconfig("border_parts_right", self._canvas.itemconfig("border_parts_right",
outline=ThemeManager.single_color(self._button_hover_color, self._appearance_mode), outline=self._apply_appearance_mode(self._button_hover_color),
fill=ThemeManager.single_color(self._button_hover_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._button_hover_color))
def _on_leave(self, event=0): def _on_leave(self, event=0):
if sys.platform == "darwin" and len(self._values) > 0 and self._cursor_manipulation_enabled: if sys.platform == "darwin" and len(self._values) > 0 and self._cursor_manipulation_enabled:
@ -359,11 +359,11 @@ class CTkComboBox(CTkBaseClass):
# set color of inner button parts # set color of inner button parts
self._canvas.itemconfig("inner_parts_right", self._canvas.itemconfig("inner_parts_right",
outline=ThemeManager.single_color(self._button_color, self._appearance_mode), outline=self._apply_appearance_mode(self._button_color),
fill=ThemeManager.single_color(self._button_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._button_color))
self._canvas.itemconfig("border_parts_right", self._canvas.itemconfig("border_parts_right",
outline=ThemeManager.single_color(self._button_color, self._appearance_mode), outline=self._apply_appearance_mode(self._button_color),
fill=ThemeManager.single_color(self._button_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._button_color))
def _dropdown_callback(self, value: str): def _dropdown_callback(self, value: str):
if self._state == "readonly": if self._state == "readonly":

View File

@ -148,7 +148,7 @@ class CTkEntry(CTkBaseClass):
super().destroy() super().destroy()
def _draw(self, no_color_updates=False): def _draw(self, no_color_updates=False):
self._canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._canvas.configure(bg=self._apply_appearance_mode(self._bg_color))
requires_recoloring = self._draw_engine.draw_rounded_rect_with_border(self._apply_widget_scaling(self._current_width), requires_recoloring = self._draw_engine.draw_rounded_rect_with_border(self._apply_widget_scaling(self._current_width),
self._apply_widget_scaling(self._current_height), self._apply_widget_scaling(self._current_height),
@ -156,33 +156,33 @@ class CTkEntry(CTkBaseClass):
self._apply_widget_scaling(self._border_width)) self._apply_widget_scaling(self._border_width))
if requires_recoloring or no_color_updates is False: if requires_recoloring or no_color_updates is False:
if ThemeManager.single_color(self._fg_color, self._appearance_mode) is not None: if self._apply_appearance_mode(self._fg_color) is not None:
self._canvas.itemconfig("inner_parts", self._canvas.itemconfig("inner_parts",
fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), fill=self._apply_appearance_mode(self._fg_color),
outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._fg_color))
self._entry.configure(bg=ThemeManager.single_color(self._fg_color, self._appearance_mode), self._entry.configure(bg=self._apply_appearance_mode(self._fg_color),
fg=ThemeManager.single_color(self._text_color, self._appearance_mode), fg=self._apply_appearance_mode(self._text_color),
disabledbackground=ThemeManager.single_color(self._fg_color, self._appearance_mode), disabledbackground=self._apply_appearance_mode(self._fg_color),
disabledforeground=ThemeManager.single_color(self._text_color, self._appearance_mode), disabledforeground=self._apply_appearance_mode(self._text_color),
highlightcolor=ThemeManager.single_color(self._fg_color, self._appearance_mode), highlightcolor=self._apply_appearance_mode(self._fg_color),
insertbackground=ThemeManager.single_color(self._text_color, self._appearance_mode)) insertbackground=self._apply_appearance_mode(self._text_color))
else: else:
self._canvas.itemconfig("inner_parts", self._canvas.itemconfig("inner_parts",
fill=ThemeManager.single_color(self._bg_color, self._appearance_mode), fill=self._apply_appearance_mode(self._bg_color),
outline=ThemeManager.single_color(self._bg_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._bg_color))
self._entry.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode), self._entry.configure(bg=self._apply_appearance_mode(self._bg_color),
fg=ThemeManager.single_color(self._text_color, self._appearance_mode), fg=self._apply_appearance_mode(self._text_color),
disabledbackground=ThemeManager.single_color(self._bg_color, self._appearance_mode), disabledbackground=self._apply_appearance_mode(self._bg_color),
disabledforeground=ThemeManager.single_color(self._text_color, self._appearance_mode), disabledforeground=self._apply_appearance_mode(self._text_color),
highlightcolor=ThemeManager.single_color(self._bg_color, self._appearance_mode), highlightcolor=self._apply_appearance_mode(self._bg_color),
insertbackground=ThemeManager.single_color(self._text_color, self._appearance_mode)) insertbackground=self._apply_appearance_mode(self._text_color))
self._canvas.itemconfig("border_parts", self._canvas.itemconfig("border_parts",
fill=ThemeManager.single_color(self._border_color, self._appearance_mode), fill=self._apply_appearance_mode(self._border_color),
outline=ThemeManager.single_color(self._border_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._border_color))
if self._placeholder_text_active: if self._placeholder_text_active:
self._entry.config(fg=ThemeManager.single_color(self._placeholder_text_color, self._appearance_mode)) self._entry.config(fg=self._apply_appearance_mode(self._placeholder_text_color))
def configure(self, require_redraw=False, **kwargs): def configure(self, require_redraw=False, **kwargs):
if "state" in kwargs: if "state" in kwargs:
@ -287,7 +287,7 @@ class CTkEntry(CTkBaseClass):
self._placeholder_text_active = True self._placeholder_text_active = True
self._pre_placeholder_arguments = {"show": self._entry.cget("show")} self._pre_placeholder_arguments = {"show": self._entry.cget("show")}
self._entry.config(fg=ThemeManager.single_color(self._placeholder_text_color, self._appearance_mode), show="") self._entry.config(fg=self._apply_appearance_mode(self._placeholder_text_color), show="")
self._entry.delete(0, tkinter.END) self._entry.delete(0, tkinter.END)
self._entry.insert(0, self._placeholder_text) self._entry.insert(0, self._placeholder_text)
@ -295,7 +295,7 @@ class CTkEntry(CTkBaseClass):
if self._placeholder_text_active: if self._placeholder_text_active:
self._placeholder_text_active = False self._placeholder_text_active = False
self._entry.config(fg=ThemeManager.single_color(self._text_color, self._appearance_mode)) self._entry.config(fg=self._apply_appearance_mode(self._text_color))
self._entry.delete(0, tkinter.END) self._entry.delete(0, tkinter.END)
for argument, value in self._pre_placeholder_arguments.items(): for argument, value in self._pre_placeholder_arguments.items():
self._entry[argument] = value self._entry[argument] = value

View File

@ -58,7 +58,7 @@ class CTkFrame(CTkBaseClass):
width=self._apply_widget_scaling(self._current_width), width=self._apply_widget_scaling(self._current_width),
height=self._apply_widget_scaling(self._current_height)) height=self._apply_widget_scaling(self._current_height))
self._canvas.place(x=0, y=0, relwidth=1, relheight=1) self._canvas.place(x=0, y=0, relwidth=1, relheight=1)
self._canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._canvas.configure(bg=self._apply_appearance_mode(self._bg_color))
self._draw_engine = DrawEngine(self._canvas) self._draw_engine = DrawEngine(self._canvas)
self._overwrite_preferred_drawing_method = overwrite_preferred_drawing_method self._overwrite_preferred_drawing_method = overwrite_preferred_drawing_method
@ -97,10 +97,10 @@ class CTkFrame(CTkBaseClass):
if self._background_corner_colors is not None: if self._background_corner_colors is not None:
self._draw_engine.draw_background_corners(self._apply_widget_scaling(self._current_width), self._draw_engine.draw_background_corners(self._apply_widget_scaling(self._current_width),
self._apply_widget_scaling(self._current_height)) self._apply_widget_scaling(self._current_height))
self._canvas.itemconfig("background_corner_top_left", fill=ThemeManager.single_color(self._background_corner_colors[0], self._appearance_mode)) self._canvas.itemconfig("background_corner_top_left", fill=self._apply_appearance_mode(self._background_corner_colors[0]))
self._canvas.itemconfig("background_corner_top_right", fill=ThemeManager.single_color(self._background_corner_colors[1], self._appearance_mode)) self._canvas.itemconfig("background_corner_top_right", fill=self._apply_appearance_mode(self._background_corner_colors[1]))
self._canvas.itemconfig("background_corner_bottom_right", fill=ThemeManager.single_color(self._background_corner_colors[2], self._appearance_mode)) self._canvas.itemconfig("background_corner_bottom_right", fill=self._apply_appearance_mode(self._background_corner_colors[2]))
self._canvas.itemconfig("background_corner_bottom_left", fill=ThemeManager.single_color(self._background_corner_colors[3], self._appearance_mode)) self._canvas.itemconfig("background_corner_bottom_left", fill=self._apply_appearance_mode(self._background_corner_colors[3]))
else: else:
self._canvas.delete("background_parts") self._canvas.delete("background_parts")
@ -113,17 +113,17 @@ class CTkFrame(CTkBaseClass):
if no_color_updates is False or requires_recoloring: if no_color_updates is False or requires_recoloring:
if self._fg_color is None: if self._fg_color is None:
self._canvas.itemconfig("inner_parts", self._canvas.itemconfig("inner_parts",
fill=ThemeManager.single_color(self._bg_color, self._appearance_mode), fill=self._apply_appearance_mode(self._bg_color),
outline=ThemeManager.single_color(self._bg_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._bg_color))
else: else:
self._canvas.itemconfig("inner_parts", self._canvas.itemconfig("inner_parts",
fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), fill=self._apply_appearance_mode(self._fg_color),
outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._fg_color))
self._canvas.itemconfig("border_parts", self._canvas.itemconfig("border_parts",
fill=ThemeManager.single_color(self._border_color, self._appearance_mode), fill=self._apply_appearance_mode(self._border_color),
outline=ThemeManager.single_color(self._border_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._border_color))
self._canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._canvas.configure(bg=self._apply_appearance_mode(self._bg_color))
# self._canvas.tag_lower("inner_parts") # maybe unnecessary, I don't know ??? # self._canvas.tag_lower("inner_parts") # maybe unnecessary, I don't know ???
# self._canvas.tag_lower("border_parts") # self._canvas.tag_lower("border_parts")

View File

@ -123,22 +123,22 @@ class CTkLabel(CTkBaseClass):
0) 0)
if no_color_updates is False or requires_recoloring: if no_color_updates is False or requires_recoloring:
if ThemeManager.single_color(self._fg_color, self._appearance_mode) is not None: if self._apply_appearance_mode(self._fg_color) is not None:
self._canvas.itemconfig("inner_parts", self._canvas.itemconfig("inner_parts",
fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), fill=self._apply_appearance_mode(self._fg_color),
outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._fg_color))
self._text_label.configure(fg=ThemeManager.single_color(self._text_color, self._appearance_mode), self._text_label.configure(fg=self._apply_appearance_mode(self._text_color),
bg=ThemeManager.single_color(self._fg_color, self._appearance_mode)) bg=self._apply_appearance_mode(self._fg_color))
else: else:
self._canvas.itemconfig("inner_parts", self._canvas.itemconfig("inner_parts",
fill=ThemeManager.single_color(self._bg_color, self._appearance_mode), fill=self._apply_appearance_mode(self._bg_color),
outline=ThemeManager.single_color(self._bg_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._bg_color))
self._text_label.configure(fg=ThemeManager.single_color(self._text_color, self._appearance_mode), self._text_label.configure(fg=self._apply_appearance_mode(self._text_color),
bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) bg=self._apply_appearance_mode(self._bg_color))
self._canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._canvas.configure(bg=self._apply_appearance_mode(self._bg_color))
def configure(self, require_redraw=False, **kwargs): def configure(self, require_redraw=False, **kwargs):
if "anchor" in kwargs: if "anchor" in kwargs:

View File

@ -193,27 +193,27 @@ class CTkOptionMenu(CTkBaseClass):
if no_color_updates is False or requires_recoloring or requires_recoloring_2: if no_color_updates is False or requires_recoloring or requires_recoloring_2:
self._canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._canvas.configure(bg=self._apply_appearance_mode(self._bg_color))
self._canvas.itemconfig("inner_parts_left", self._canvas.itemconfig("inner_parts_left",
outline=ThemeManager.single_color(self._fg_color, self._appearance_mode), outline=self._apply_appearance_mode(self._fg_color),
fill=ThemeManager.single_color(self._fg_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._fg_color))
self._canvas.itemconfig("inner_parts_right", self._canvas.itemconfig("inner_parts_right",
outline=ThemeManager.single_color(self._button_color, self._appearance_mode), outline=self._apply_appearance_mode(self._button_color),
fill=ThemeManager.single_color(self._button_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._button_color))
self._text_label.configure(fg=ThemeManager.single_color(self._text_color, self._appearance_mode)) self._text_label.configure(fg=self._apply_appearance_mode(self._text_color))
if self._state == tkinter.DISABLED: if self._state == tkinter.DISABLED:
self._text_label.configure(fg=(ThemeManager.single_color(self._text_color_disabled, self._appearance_mode))) self._text_label.configure(fg=(self._apply_appearance_mode(self._text_color_disabled)))
self._canvas.itemconfig("dropdown_arrow", self._canvas.itemconfig("dropdown_arrow",
fill=ThemeManager.single_color(self._text_color_disabled, self._appearance_mode)) fill=self._apply_appearance_mode(self._text_color_disabled))
else: else:
self._text_label.configure(fg=ThemeManager.single_color(self._text_color, self._appearance_mode)) self._text_label.configure(fg=self._apply_appearance_mode(self._text_color))
self._canvas.itemconfig("dropdown_arrow", self._canvas.itemconfig("dropdown_arrow",
fill=ThemeManager.single_color(self._text_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._text_color))
self._text_label.configure(bg=ThemeManager.single_color(self._fg_color, self._appearance_mode)) self._text_label.configure(bg=self._apply_appearance_mode(self._fg_color))
self._canvas.update_idletasks() self._canvas.update_idletasks()
@ -350,14 +350,14 @@ class CTkOptionMenu(CTkBaseClass):
if self._hover is True and self._state == tkinter.NORMAL and len(self._values) > 0: if self._hover is True and self._state == tkinter.NORMAL and len(self._values) > 0:
# set color of inner button parts to hover color # set color of inner button parts to hover color
self._canvas.itemconfig("inner_parts_right", self._canvas.itemconfig("inner_parts_right",
outline=ThemeManager.single_color(self._button_hover_color, self._appearance_mode), outline=self._apply_appearance_mode(self._button_hover_color),
fill=ThemeManager.single_color(self._button_hover_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._button_hover_color))
def _on_leave(self, event=0): def _on_leave(self, event=0):
# set color of inner button parts # set color of inner button parts
self._canvas.itemconfig("inner_parts_right", self._canvas.itemconfig("inner_parts_right",
outline=ThemeManager.single_color(self._button_color, self._appearance_mode), outline=self._apply_appearance_mode(self._button_color),
fill=ThemeManager.single_color(self._button_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._button_color))
def _variable_callback(self, var_name, index, mode): def _variable_callback(self, var_name, index, mode):
if not self._variable_callback_blocked: if not self._variable_callback_blocked:

View File

@ -139,16 +139,16 @@ class CTkProgressBar(CTkBaseClass):
orientation) orientation)
if no_color_updates is False or requires_recoloring: if no_color_updates is False or requires_recoloring:
self._canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._canvas.configure(bg=self._apply_appearance_mode(self._bg_color))
self._canvas.itemconfig("border_parts", self._canvas.itemconfig("border_parts",
fill=ThemeManager.single_color(self._border_color, self._appearance_mode), fill=self._apply_appearance_mode(self._border_color),
outline=ThemeManager.single_color(self._border_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._border_color))
self._canvas.itemconfig("inner_parts", self._canvas.itemconfig("inner_parts",
fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), fill=self._apply_appearance_mode(self._fg_color),
outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._fg_color))
self._canvas.itemconfig("progress_parts", self._canvas.itemconfig("progress_parts",
fill=ThemeManager.single_color(self._progress_color, self._appearance_mode), fill=self._apply_appearance_mode(self._progress_color),
outline=ThemeManager.single_color(self._progress_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._progress_color))
def configure(self, require_redraw=False, **kwargs): def configure(self, require_redraw=False, **kwargs):
if "fg_color" in kwargs: if "fg_color" in kwargs:

View File

@ -169,28 +169,28 @@ class CTkRadioButton(CTkBaseClass):
self._apply_widget_scaling(self._border_width)) self._apply_widget_scaling(self._border_width))
if no_color_updates is False or requires_recoloring: if no_color_updates is False or requires_recoloring:
self._bg_canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._bg_canvas.configure(bg=self._apply_appearance_mode(self._bg_color))
self._canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._canvas.configure(bg=self._apply_appearance_mode(self._bg_color))
if self._check_state is False: if self._check_state is False:
self._canvas.itemconfig("border_parts", self._canvas.itemconfig("border_parts",
outline=ThemeManager.single_color(self._border_color, self._appearance_mode), outline=self._apply_appearance_mode(self._border_color),
fill=ThemeManager.single_color(self._border_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._border_color))
else: else:
self._canvas.itemconfig("border_parts", self._canvas.itemconfig("border_parts",
outline=ThemeManager.single_color(self._fg_color, self._appearance_mode), outline=self._apply_appearance_mode(self._fg_color),
fill=ThemeManager.single_color(self._fg_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._fg_color))
self._canvas.itemconfig("inner_parts", self._canvas.itemconfig("inner_parts",
outline=ThemeManager.single_color(self._bg_color, self._appearance_mode), outline=self._apply_appearance_mode(self._bg_color),
fill=ThemeManager.single_color(self._bg_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._bg_color))
if self._state == tkinter.DISABLED: if self._state == tkinter.DISABLED:
self._text_label.configure(fg=ThemeManager.single_color(self._text_color_disabled, self._appearance_mode)) self._text_label.configure(fg=self._apply_appearance_mode(self._text_color_disabled))
else: else:
self._text_label.configure(fg=ThemeManager.single_color(self._text_color, self._appearance_mode)) self._text_label.configure(fg=self._apply_appearance_mode(self._text_color))
self._text_label.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._text_label.configure(bg=self._apply_appearance_mode(self._bg_color))
def configure(self, require_redraw=False, **kwargs): def configure(self, require_redraw=False, **kwargs):
if "radiobutton_width" in kwargs: if "radiobutton_width" in kwargs:
@ -332,18 +332,18 @@ class CTkRadioButton(CTkBaseClass):
def _on_enter(self, event=0): def _on_enter(self, event=0):
if self._hover is True and self._state == tkinter.NORMAL: if self._hover is True and self._state == tkinter.NORMAL:
self._canvas.itemconfig("border_parts", self._canvas.itemconfig("border_parts",
fill=ThemeManager.single_color(self._hover_color, self._appearance_mode), fill=self._apply_appearance_mode(self._hover_color),
outline=ThemeManager.single_color(self._hover_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._hover_color))
def _on_leave(self, event=0): def _on_leave(self, event=0):
if self._check_state is True: if self._check_state is True:
self._canvas.itemconfig("border_parts", self._canvas.itemconfig("border_parts",
fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), fill=self._apply_appearance_mode(self._fg_color),
outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._fg_color))
else: else:
self._canvas.itemconfig("border_parts", self._canvas.itemconfig("border_parts",
fill=ThemeManager.single_color(self._border_color, self._appearance_mode), fill=self._apply_appearance_mode(self._border_color),
outline=ThemeManager.single_color(self._border_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._border_color))
def _variable_callback(self, var_name, index, mode): def _variable_callback(self, var_name, index, mode):
if not self._variable_callback_blocked: if not self._variable_callback_blocked:

View File

@ -130,23 +130,23 @@ class CTkScrollbar(CTkBaseClass):
if no_color_updates is False or requires_recoloring: if no_color_updates is False or requires_recoloring:
if self._hover_state is True: if self._hover_state is True:
self._canvas.itemconfig("scrollbar_parts", self._canvas.itemconfig("scrollbar_parts",
fill=ThemeManager.single_color(self._scrollbar_hover_color, self._appearance_mode), fill=self._apply_appearance_mode(self._scrollbar_hover_color),
outline=ThemeManager.single_color(self._scrollbar_hover_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._scrollbar_hover_color))
else: else:
self._canvas.itemconfig("scrollbar_parts", self._canvas.itemconfig("scrollbar_parts",
fill=ThemeManager.single_color(self._scrollbar_color, self._appearance_mode), fill=self._apply_appearance_mode(self._scrollbar_color),
outline=ThemeManager.single_color(self._scrollbar_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._scrollbar_color))
if self._fg_color is None: if self._fg_color is None:
self._canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._canvas.configure(bg=self._apply_appearance_mode(self._bg_color))
self._canvas.itemconfig("border_parts", self._canvas.itemconfig("border_parts",
fill=ThemeManager.single_color(self._bg_color, self._appearance_mode), fill=self._apply_appearance_mode(self._bg_color),
outline=ThemeManager.single_color(self._bg_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._bg_color))
else: else:
self._canvas.configure(bg=ThemeManager.single_color(self._fg_color, self._appearance_mode)) self._canvas.configure(bg=self._apply_appearance_mode(self._fg_color))
self._canvas.itemconfig("border_parts", self._canvas.itemconfig("border_parts",
fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), fill=self._apply_appearance_mode(self._fg_color),
outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._fg_color))
self._canvas.update_idletasks() self._canvas.update_idletasks()
@ -208,14 +208,14 @@ class CTkScrollbar(CTkBaseClass):
if self._hover is True: if self._hover is True:
self._hover_state = True self._hover_state = True
self._canvas.itemconfig("scrollbar_parts", self._canvas.itemconfig("scrollbar_parts",
outline=ThemeManager.single_color(self._scrollbar_hover_color, self._appearance_mode), outline=self._apply_appearance_mode(self._scrollbar_hover_color),
fill=ThemeManager.single_color(self._scrollbar_hover_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._scrollbar_hover_color))
def _on_leave(self, event=0): def _on_leave(self, event=0):
self._hover_state = False self._hover_state = False
self._canvas.itemconfig("scrollbar_parts", self._canvas.itemconfig("scrollbar_parts",
outline=ThemeManager.single_color(self._scrollbar_color, self._appearance_mode), outline=self._apply_appearance_mode(self._scrollbar_color),
fill=ThemeManager.single_color(self._scrollbar_color, self._appearance_mode)) fill=self._apply_appearance_mode(self._scrollbar_color))
def _clicked(self, event): def _clicked(self, event):
if self._orientation == "vertical": if self._orientation == "vertical":

View File

@ -161,33 +161,33 @@ class CTkSlider(CTkBaseClass):
self._value, orientation) self._value, orientation)
if no_color_updates is False or requires_recoloring: if no_color_updates is False or requires_recoloring:
self._canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._canvas.configure(bg=self._apply_appearance_mode(self._bg_color))
if self._border_color is None: if self._border_color is None:
self._canvas.itemconfig("border_parts", fill=ThemeManager.single_color(self._bg_color, self._appearance_mode), self._canvas.itemconfig("border_parts", fill=self._apply_appearance_mode(self._bg_color),
outline=ThemeManager.single_color(self._bg_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._bg_color))
else: else:
self._canvas.itemconfig("border_parts", fill=ThemeManager.single_color(self._border_color, self._appearance_mode), self._canvas.itemconfig("border_parts", fill=self._apply_appearance_mode(self._border_color),
outline=ThemeManager.single_color(self._border_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._border_color))
self._canvas.itemconfig("inner_parts", fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), self._canvas.itemconfig("inner_parts", fill=self._apply_appearance_mode(self._fg_color),
outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._fg_color))
if self._progress_color is None: if self._progress_color is None:
self._canvas.itemconfig("progress_parts", fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), self._canvas.itemconfig("progress_parts", fill=self._apply_appearance_mode(self._fg_color),
outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._fg_color))
else: else:
self._canvas.itemconfig("progress_parts", fill=ThemeManager.single_color(self._progress_color, self._appearance_mode), self._canvas.itemconfig("progress_parts", fill=self._apply_appearance_mode(self._progress_color),
outline=ThemeManager.single_color(self._progress_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._progress_color))
if self._hover_state is True: if self._hover_state is True:
self._canvas.itemconfig("slider_parts", self._canvas.itemconfig("slider_parts",
fill=ThemeManager.single_color(self._button_hover_color, self._appearance_mode), fill=self._apply_appearance_mode(self._button_hover_color),
outline=ThemeManager.single_color(self._button_hover_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._button_hover_color))
else: else:
self._canvas.itemconfig("slider_parts", self._canvas.itemconfig("slider_parts",
fill=ThemeManager.single_color(self._button_color, self._appearance_mode), fill=self._apply_appearance_mode(self._button_color),
outline=ThemeManager.single_color(self._button_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._button_color))
def configure(self, require_redraw=False, **kwargs): def configure(self, require_redraw=False, **kwargs):
if "state" in kwargs: if "state" in kwargs:
@ -318,14 +318,14 @@ class CTkSlider(CTkBaseClass):
if self._hover is True and self._state == "normal": if self._hover is True and self._state == "normal":
self._hover_state = True self._hover_state = True
self._canvas.itemconfig("slider_parts", self._canvas.itemconfig("slider_parts",
fill=ThemeManager.single_color(self._button_hover_color, self._appearance_mode), fill=self._apply_appearance_mode(self._button_hover_color),
outline=ThemeManager.single_color(self._button_hover_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._button_hover_color))
def _on_leave(self, event=0): def _on_leave(self, event=0):
self._hover_state = False self._hover_state = False
self._canvas.itemconfig("slider_parts", self._canvas.itemconfig("slider_parts",
fill=ThemeManager.single_color(self._button_color, self._appearance_mode), fill=self._apply_appearance_mode(self._button_color),
outline=ThemeManager.single_color(self._button_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._button_color))
def _round_to_step_size(self, value) -> float: def _round_to_step_size(self, value) -> float:
if self._number_of_steps is not None: if self._number_of_steps is not None:

View File

@ -212,35 +212,35 @@ class CTkSwitch(CTkBaseClass):
0, "w") 0, "w")
if no_color_updates is False or requires_recoloring: if no_color_updates is False or requires_recoloring:
self._bg_canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._bg_canvas.configure(bg=self._apply_appearance_mode(self._bg_color))
self._canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._canvas.configure(bg=self._apply_appearance_mode(self._bg_color))
if self._border_color is None: if self._border_color is None:
self._canvas.itemconfig("border_parts", fill=ThemeManager.single_color(self._bg_color, self._appearance_mode), self._canvas.itemconfig("border_parts", fill=self._apply_appearance_mode(self._bg_color),
outline=ThemeManager.single_color(self._bg_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._bg_color))
else: else:
self._canvas.itemconfig("border_parts", fill=ThemeManager.single_color(self._border_color, self._appearance_mode), self._canvas.itemconfig("border_parts", fill=self._apply_appearance_mode(self._border_color),
outline=ThemeManager.single_color(self._border_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._border_color))
self._canvas.itemconfig("inner_parts", fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), self._canvas.itemconfig("inner_parts", fill=self._apply_appearance_mode(self._fg_color),
outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._fg_color))
if self._progress_color is None: if self._progress_color is None:
self._canvas.itemconfig("progress_parts", fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), self._canvas.itemconfig("progress_parts", fill=self._apply_appearance_mode(self._fg_color),
outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._fg_color))
else: else:
self._canvas.itemconfig("progress_parts", fill=ThemeManager.single_color(self._progress_color, self._appearance_mode), self._canvas.itemconfig("progress_parts", fill=self._apply_appearance_mode(self._progress_color),
outline=ThemeManager.single_color(self._progress_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._progress_color))
self._canvas.itemconfig("slider_parts", fill=ThemeManager.single_color(self._button_color, self._appearance_mode), self._canvas.itemconfig("slider_parts", fill=self._apply_appearance_mode(self._button_color),
outline=ThemeManager.single_color(self._button_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._button_color))
if self._state == tkinter.DISABLED: if self._state == tkinter.DISABLED:
self._text_label.configure(fg=(ThemeManager.single_color(self._text_color_disabled, self._appearance_mode))) self._text_label.configure(fg=(self._apply_appearance_mode(self._text_color_disabled)))
else: else:
self._text_label.configure(fg=ThemeManager.single_color(self._text_color, self._appearance_mode)) self._text_label.configure(fg=self._apply_appearance_mode(self._text_color))
self._text_label.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._text_label.configure(bg=self._apply_appearance_mode(self._bg_color))
def configure(self, require_redraw=False, **kwargs): def configure(self, require_redraw=False, **kwargs):
if "switch_width" in kwargs: if "switch_width" in kwargs:
@ -417,14 +417,14 @@ class CTkSwitch(CTkBaseClass):
if self._hover is True and self._state == "normal": if self._hover is True and self._state == "normal":
self._hover_state = True self._hover_state = True
self._canvas.itemconfig("slider_parts", self._canvas.itemconfig("slider_parts",
fill=ThemeManager.single_color(self._button_hover_color, self._appearance_mode), fill=self._apply_appearance_mode(self._button_hover_color),
outline=ThemeManager.single_color(self._button_hover_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._button_hover_color))
def _on_leave(self, event=0): def _on_leave(self, event=0):
self._hover_state = False self._hover_state = False
self._canvas.itemconfig("slider_parts", self._canvas.itemconfig("slider_parts",
fill=ThemeManager.single_color(self._button_color, self._appearance_mode), fill=self._apply_appearance_mode(self._button_color),
outline=ThemeManager.single_color(self._button_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._button_color))
def _variable_callback(self, var_name, index, mode): def _variable_callback(self, var_name, index, mode):
if not self._variable_callback_blocked: if not self._variable_callback_blocked:

View File

@ -65,7 +65,7 @@ class CTkTabview(CTkBaseClass):
self._border_width = ThemeManager.theme["shape"]["frame_border_width"] if border_width == "default_theme" else border_width self._border_width = ThemeManager.theme["shape"]["frame_border_width"] if border_width == "default_theme" else border_width
self._canvas = CTkCanvas(master=self, self._canvas = CTkCanvas(master=self,
bg=ThemeManager.single_color(self._bg_color, self._appearance_mode), bg=self._apply_appearance_mode(self._bg_color),
highlightthickness=0, highlightthickness=0,
width=self._apply_widget_scaling(self._current_width - self._top_spacing - self._top_button_overhang), width=self._apply_widget_scaling(self._current_width - self._top_spacing - self._top_button_overhang),
height=self._apply_widget_scaling(self._current_height)) height=self._apply_widget_scaling(self._current_height))
@ -199,17 +199,17 @@ class CTkTabview(CTkBaseClass):
if no_color_updates is False or requires_recoloring: if no_color_updates is False or requires_recoloring:
if self._fg_color is None: if self._fg_color is None:
self._canvas.itemconfig("inner_parts", self._canvas.itemconfig("inner_parts",
fill=ThemeManager.single_color(self._bg_color, self._appearance_mode), fill=self._apply_appearance_mode(self._bg_color),
outline=ThemeManager.single_color(self._bg_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._bg_color))
else: else:
self._canvas.itemconfig("inner_parts", self._canvas.itemconfig("inner_parts",
fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), fill=self._apply_appearance_mode(self._fg_color),
outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._fg_color))
self._canvas.itemconfig("border_parts", self._canvas.itemconfig("border_parts",
fill=ThemeManager.single_color(self._border_color, self._appearance_mode), fill=self._apply_appearance_mode(self._border_color),
outline=ThemeManager.single_color(self._border_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._border_color))
self._canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._canvas.configure(bg=self._apply_appearance_mode(self._bg_color))
def configure(self, require_redraw=False, **kwargs): def configure(self, require_redraw=False, **kwargs):
if "corner_radius" in kwargs: if "corner_radius" in kwargs:

View File

@ -76,18 +76,18 @@ class CTkTextbox(CTkBaseClass):
width=self._apply_widget_scaling(self._current_width), width=self._apply_widget_scaling(self._current_width),
height=self._apply_widget_scaling(self._current_height)) height=self._apply_widget_scaling(self._current_height))
self._canvas.grid(row=0, column=0, rowspan=2, columnspan=2, sticky="nsew") self._canvas.grid(row=0, column=0, rowspan=2, columnspan=2, sticky="nsew")
self._canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._canvas.configure(bg=self._apply_appearance_mode(self._bg_color))
self._draw_engine = DrawEngine(self._canvas) self._draw_engine = DrawEngine(self._canvas)
self._textbox = tkinter.Text(self, self._textbox = tkinter.Text(self,
fg=ThemeManager.single_color(self._text_color, self._appearance_mode), fg=self._apply_appearance_mode(self._text_color),
width=0, width=0,
height=0, height=0,
font=self._apply_font_scaling(self._font), font=self._apply_font_scaling(self._font),
highlightthickness=0, highlightthickness=0,
relief="flat", relief="flat",
insertbackground=ThemeManager.single_color(self._text_color, self._appearance_mode), insertbackground=self._apply_appearance_mode(self._text_color),
bg=ThemeManager.single_color(self._fg_color, self._appearance_mode), bg=self._apply_appearance_mode(self._fg_color),
**pop_from_dict_by_set(kwargs, self._valid_tk_text_attributes)) **pop_from_dict_by_set(kwargs, self._valid_tk_text_attributes))
check_kwargs_empty(kwargs, raise_error=True) check_kwargs_empty(kwargs, raise_error=True)
@ -222,31 +222,31 @@ class CTkTextbox(CTkBaseClass):
if no_color_updates is False or requires_recoloring: if no_color_updates is False or requires_recoloring:
if self._fg_color is None: if self._fg_color is None:
self._canvas.itemconfig("inner_parts", self._canvas.itemconfig("inner_parts",
fill=ThemeManager.single_color(self._bg_color, self._appearance_mode), fill=self._apply_appearance_mode(self._bg_color),
outline=ThemeManager.single_color(self._bg_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._bg_color))
self._textbox.configure(fg=ThemeManager.single_color(self._text_color, self._appearance_mode), self._textbox.configure(fg=self._apply_appearance_mode(self._text_color),
bg=ThemeManager.single_color(self._bg_color, self._appearance_mode), bg=self._apply_appearance_mode(self._bg_color),
insertbackground=ThemeManager.single_color(self._text_color, self._appearance_mode)) insertbackground=self._apply_appearance_mode(self._text_color))
self._x_scrollbar.configure(fg_color=self._bg_color, scrollbar_color=self._scrollbar_color, self._x_scrollbar.configure(fg_color=self._bg_color, scrollbar_color=self._scrollbar_color,
scrollbar_hover_color=self._scrollbar_hover_color) scrollbar_hover_color=self._scrollbar_hover_color)
self._y_scrollbar.configure(fg_color=self._bg_color, scrollbar_color=self._scrollbar_color, self._y_scrollbar.configure(fg_color=self._bg_color, scrollbar_color=self._scrollbar_color,
scrollbar_hover_color=self._scrollbar_hover_color) scrollbar_hover_color=self._scrollbar_hover_color)
else: else:
self._canvas.itemconfig("inner_parts", self._canvas.itemconfig("inner_parts",
fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), fill=self._apply_appearance_mode(self._fg_color),
outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._fg_color))
self._textbox.configure(fg=ThemeManager.single_color(self._text_color, self._appearance_mode), self._textbox.configure(fg=self._apply_appearance_mode(self._text_color),
bg=ThemeManager.single_color(self._fg_color, self._appearance_mode), bg=self._apply_appearance_mode(self._fg_color),
insertbackground=ThemeManager.single_color(self._text_color, self._appearance_mode)) insertbackground=self._apply_appearance_mode(self._text_color))
self._x_scrollbar.configure(fg_color=self._fg_color, scrollbar_color=self._scrollbar_color, self._x_scrollbar.configure(fg_color=self._fg_color, scrollbar_color=self._scrollbar_color,
scrollbar_hover_color=self._scrollbar_hover_color) scrollbar_hover_color=self._scrollbar_hover_color)
self._y_scrollbar.configure(fg_color=self._fg_color, scrollbar_color=self._scrollbar_color, self._y_scrollbar.configure(fg_color=self._fg_color, scrollbar_color=self._scrollbar_color,
scrollbar_hover_color=self._scrollbar_hover_color) scrollbar_hover_color=self._scrollbar_hover_color)
self._canvas.itemconfig("border_parts", self._canvas.itemconfig("border_parts",
fill=ThemeManager.single_color(self._border_color, self._appearance_mode), fill=self._apply_appearance_mode(self._border_color),
outline=ThemeManager.single_color(self._border_color, self._appearance_mode)) outline=self._apply_appearance_mode(self._border_color))
self._canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) self._canvas.configure(bg=self._apply_appearance_mode(self._bg_color))
self._canvas.tag_lower("inner_parts") self._canvas.tag_lower("inner_parts")
self._canvas.tag_lower("border_parts") self._canvas.tag_lower("border_parts")

View File

@ -5,7 +5,7 @@ import os
import platform import platform
import ctypes import ctypes
import re import re
from typing import Union, Tuple from typing import Union, Tuple, List
from ..appearance_mode_tracker import AppearanceModeTracker from ..appearance_mode_tracker import AppearanceModeTracker
from ..theme_manager import ThemeManager from ..theme_manager import ThemeManager
@ -57,7 +57,7 @@ class CTk(tkinter.Tk):
self._fg_color = ThemeManager.theme["color"]["window_bg_color"] if fg_color == "default_theme" else fg_color self._fg_color = ThemeManager.theme["color"]["window_bg_color"] if fg_color == "default_theme" else fg_color
super().configure(bg=ThemeManager.single_color(self._fg_color, self._appearance_mode)) super().configure(bg=self._apply_appearance_mode(self._fg_color))
super().title("CTk") super().title("CTk")
self.geometry(f"{self._current_width}x{self._current_height}") self.geometry(f"{self._current_width}x{self._current_height}")
@ -244,10 +244,20 @@ class CTk(tkinter.Tk):
else: else:
return value return value
def _apply_appearance_mode(self, color: Union[str, Tuple[str, str], List[str]]) -> str:
""" color can be either a single hex color string or a color name or it can be a
tuple color with (light_color, dark_color). The functions returns
always a single color string """
if type(color) == tuple or type(color) == list:
return color[self._appearance_mode]
else:
return color
def configure(self, **kwargs): def configure(self, **kwargs):
if "fg_color" in kwargs: if "fg_color" in kwargs:
self._fg_color = kwargs.pop("fg_color") self._fg_color = kwargs.pop("fg_color")
super().configure(bg=ThemeManager.single_color(self._fg_color, self._appearance_mode)) super().configure(bg=self._apply_appearance_mode(self._fg_color))
for child in self.winfo_children(): for child in self.winfo_children():
try: try:
@ -354,4 +364,4 @@ class CTk(tkinter.Tk):
else: else:
self._windows_set_titlebar_color("light") self._windows_set_titlebar_color("light")
super().configure(bg=ThemeManager.single_color(self._fg_color, self._appearance_mode)) super().configure(bg=self._apply_appearance_mode(self._fg_color))

View File

@ -5,7 +5,7 @@ import os
import platform import platform
import ctypes import ctypes
import re import re
from typing import Union, Tuple from typing import Union, Tuple, List
from ..appearance_mode_tracker import AppearanceModeTracker from ..appearance_mode_tracker import AppearanceModeTracker
from ..theme_manager import ThemeManager from ..theme_manager import ThemeManager
@ -54,7 +54,7 @@ class CTkToplevel(tkinter.Toplevel):
self._fg_color = ThemeManager.theme["color"]["window_bg_color"] if fg_color == "default_theme" else fg_color self._fg_color = ThemeManager.theme["color"]["window_bg_color"] if fg_color == "default_theme" else fg_color
super().configure(bg=ThemeManager.single_color(self._fg_color, self._appearance_mode)) super().configure(bg=self._apply_appearance_mode(self._fg_color))
super().title("CTkToplevel") super().title("CTkToplevel")
self._state_before_windows_set_titlebar_color = None self._state_before_windows_set_titlebar_color = None
@ -157,6 +157,16 @@ class CTkToplevel(tkinter.Toplevel):
else: else:
return value return value
def _apply_appearance_mode(self, color: Union[str, Tuple[str, str], List[str]]) -> str:
""" color can be either a single hex color string or a color name or it can be a
tuple color with (light_color, dark_color). The functions returns
always a single color string """
if type(color) == tuple or type(color) == list:
return color[self._appearance_mode]
else:
return color
def destroy(self): def destroy(self):
AppearanceModeTracker.remove(self._set_appearance_mode) AppearanceModeTracker.remove(self._set_appearance_mode)
ScalingTracker.remove_window(self._set_scaling, self) ScalingTracker.remove_window(self._set_scaling, self)
@ -204,7 +214,7 @@ class CTkToplevel(tkinter.Toplevel):
def configure(self, **kwargs): def configure(self, **kwargs):
if "fg_color" in kwargs: if "fg_color" in kwargs:
self._fg_color = kwargs.pop("fg_color") self._fg_color = kwargs.pop("fg_color")
super().configure(bg=ThemeManager.single_color(self._fg_color, self._appearance_mode)) super().configure(bg=self._apply_appearance_mode(self._fg_color))
for child in self.winfo_children(): for child in self.winfo_children():
try: try:
@ -314,4 +324,4 @@ class CTkToplevel(tkinter.Toplevel):
else: else:
self._windows_set_titlebar_color("light") self._windows_set_titlebar_color("light")
super().configure(bg=ThemeManager.single_color(self._fg_color, self._appearance_mode)) super().configure(bg=self._apply_appearance_mode(self._fg_color))