diff --git a/customtkinter/theme_manager.py b/customtkinter/theme_manager.py index ff3a52a..5a882aa 100644 --- a/customtkinter/theme_manager.py +++ b/customtkinter/theme_manager.py @@ -25,63 +25,3 @@ class ThemeManager: cls.theme["text"] = cls.theme["text"]["Windows"] else: 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 diff --git a/customtkinter/widgets/core_widget_classes/appearance_mode_base_class.py b/customtkinter/widgets/core_widget_classes/appearance_mode_base_class.py new file mode 100644 index 0000000..d3c6857 --- /dev/null +++ b/customtkinter/widgets/core_widget_classes/appearance_mode_base_class.py @@ -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 diff --git a/customtkinter/widgets/core_widget_classes/dropdown_menu.py b/customtkinter/widgets/core_widget_classes/dropdown_menu.py index b5cfba9..4254ea8 100644 --- a/customtkinter/widgets/core_widget_classes/dropdown_menu.py +++ b/customtkinter/widgets/core_widget_classes/dropdown_menu.py @@ -65,24 +65,24 @@ class DropdownMenu(tkinter.Menu): elif sys.platform.startswith("win"): super().configure(tearoff=False, 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), activeborderwidth=self._apply_widget_scaling(4), - bg=ThemeManager.single_color(self._fg_color, self._appearance_mode), - fg=ThemeManager.single_color(self._text_color, self._appearance_mode), - activeforeground=ThemeManager.single_color(self._text_color, self._appearance_mode), + bg=ThemeManager._apply_appearance_mode(self._fg_color, self._appearance_mode), + fg=ThemeManager._apply_appearance_mode(self._text_color, self._appearance_mode), + activeforeground=ThemeManager._apply_appearance_mode(self._text_color, self._appearance_mode), font=self._apply_font_scaling(self._font), cursor="hand2") else: super().configure(tearoff=False, 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, activeborderwidth=0, - bg=ThemeManager.single_color(self._fg_color, self._appearance_mode), - fg=ThemeManager.single_color(self._text_color, self._appearance_mode), - activeforeground=ThemeManager.single_color(self._text_color, self._appearance_mode), + bg=ThemeManager._apply_appearance_mode(self._fg_color, self._appearance_mode), + fg=ThemeManager._apply_appearance_mode(self._text_color, self._appearance_mode), + activeforeground=ThemeManager._apply_appearance_mode(self._text_color, self._appearance_mode), font=self._apply_font_scaling(self._font)) def _add_menu_commands(self): @@ -120,15 +120,15 @@ class DropdownMenu(tkinter.Menu): def configure(self, **kwargs): if "fg_color" in kwargs: 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: 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: 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 isinstance(self._font, CTkFont): diff --git a/customtkinter/widgets/core_widget_classes/widget_base_class.py b/customtkinter/widgets/core_widget_classes/widget_base_class.py index 6b96d0c..411d6df 100644 --- a/customtkinter/widgets/core_widget_classes/widget_base_class.py +++ b/customtkinter/widgets/core_widget_classes/widget_base_class.py @@ -2,7 +2,8 @@ import sys import tkinter import tkinter.ttk as ttk import copy -from typing import Union, Callable, Tuple +from typing import Union, Callable, Tuple, List +from abc import ABC, abstractmethod try: from typing import TypedDict @@ -15,12 +16,11 @@ from ...appearance_mode_tracker import AppearanceModeTracker from ...scaling_tracker import ScalingTracker from ...theme_manager import ThemeManager 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 -class CTkBaseClass(tkinter.Frame): +class CTkBaseClass(tkinter.Frame, ABC): """ 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 """ @@ -69,7 +69,7 @@ class CTkBaseClass(tkinter.Frame): # background 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('', 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 @@ -93,9 +93,9 @@ class CTkBaseClass(tkinter.Frame): self.master.config = new_configure self.master.configure = new_configure + @abstractmethod def _draw(self, no_color_updates: bool = False): - """ abstract of draw method to be overridden """ - pass + return def config(self, *args, **kwargs): 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": 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() def _set_scaling(self, new_widget_scaling, new_window_scaling): @@ -265,6 +265,16 @@ class CTkBaseClass(tkinter.Frame): 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): """ Destroy this and all descendants widgets. """ AppearanceModeTracker.remove(self._set_appearance_mode) diff --git a/customtkinter/widgets/ctk_button.py b/customtkinter/widgets/ctk_button.py index 3a10c54..172c8cc 100644 --- a/customtkinter/widgets/ctk_button.py +++ b/customtkinter/widgets/ctk_button.py @@ -144,10 +144,10 @@ class CTkButton(CTkBaseClass): if self._background_corner_colors is not None: self._draw_engine.draw_background_corners(self._apply_widget_scaling(self._current_width), 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_right", fill=ThemeManager.single_color(self._background_corner_colors[1], self._appearance_mode)) - 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_left", fill=ThemeManager.single_color(self._background_corner_colors[3], 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=self._apply_appearance_mode(self._background_corner_colors[1])) + 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=self._apply_appearance_mode(self._background_corner_colors[3])) else: self._canvas.delete("background_parts") @@ -158,22 +158,22 @@ class CTkButton(CTkBaseClass): 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) self._canvas.itemconfig("border_parts", - outline=ThemeManager.single_color(self._border_color, self._appearance_mode), - fill=ThemeManager.single_color(self._border_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._border_color), + fill=self._apply_appearance_mode(self._border_color)) # set color for inner button parts if self._fg_color is None: self._canvas.itemconfig("inner_parts", - outline=ThemeManager.single_color(self._bg_color, self._appearance_mode), - fill=ThemeManager.single_color(self._bg_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._bg_color), + fill=self._apply_appearance_mode(self._bg_color)) else: self._canvas.itemconfig("inner_parts", - outline=ThemeManager.single_color(self._fg_color, self._appearance_mode), - fill=ThemeManager.single_color(self._fg_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._fg_color), + fill=self._apply_appearance_mode(self._fg_color)) # create text label if text given if self._text is not None and self._text != "": @@ -195,17 +195,17 @@ class CTkButton(CTkBaseClass): if no_color_updates is False: # 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: - 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: - 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: - 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: - 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: # delete text_label if no text given @@ -229,9 +229,9 @@ class CTkButton(CTkBaseClass): if no_color_updates is False: # set image_label bg color (background color of label) 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: - 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 @@ -461,16 +461,16 @@ class CTkButton(CTkBaseClass): # set color of inner button parts to hover color self._canvas.itemconfig("inner_parts", - outline=ThemeManager.single_color(inner_parts_color, self._appearance_mode), - fill=ThemeManager.single_color(inner_parts_color, self._appearance_mode)) + outline=self._apply_appearance_mode(inner_parts_color), + fill=self._apply_appearance_mode(inner_parts_color)) # set text_label bg color to button hover color 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 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): self._click_animation_running = False @@ -482,16 +482,16 @@ class CTkButton(CTkBaseClass): # set color of inner button parts self._canvas.itemconfig("inner_parts", - outline=ThemeManager.single_color(inner_parts_color, self._appearance_mode), - fill=ThemeManager.single_color(inner_parts_color, self._appearance_mode)) + outline=self._apply_appearance_mode(inner_parts_color), + fill=self._apply_appearance_mode(inner_parts_color)) # set text_label bg color (label color) 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) 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): if self._click_animation_running: diff --git a/customtkinter/widgets/ctk_checkbox.py b/customtkinter/widgets/ctk_checkbox.py index 9d5ab93..b4891a2 100644 --- a/customtkinter/widgets/ctk_checkbox.py +++ b/customtkinter/widgets/ctk_checkbox.py @@ -183,35 +183,35 @@ class CTkCheckBox(CTkBaseClass): self._canvas.delete("checkmark") 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._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=self._apply_appearance_mode(self._bg_color)) if self._check_state is True: self._canvas.itemconfig("inner_parts", - outline=ThemeManager.single_color(self._fg_color, self._appearance_mode), - fill=ThemeManager.single_color(self._fg_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._fg_color), + fill=self._apply_appearance_mode(self._fg_color)) self._canvas.itemconfig("border_parts", - outline=ThemeManager.single_color(self._fg_color, self._appearance_mode), - fill=ThemeManager.single_color(self._fg_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._fg_color), + fill=self._apply_appearance_mode(self._fg_color)) 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: - 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: self._canvas.itemconfig("inner_parts", - outline=ThemeManager.single_color(self._bg_color, self._appearance_mode), - fill=ThemeManager.single_color(self._bg_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._bg_color), + fill=self._apply_appearance_mode(self._bg_color)) self._canvas.itemconfig("border_parts", - outline=ThemeManager.single_color(self._border_color, self._appearance_mode), - fill=ThemeManager.single_color(self._border_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._border_color), + fill=self._apply_appearance_mode(self._border_color)) 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: - 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): if "checkbox_width" in kwargs: @@ -349,31 +349,31 @@ class CTkCheckBox(CTkBaseClass): if self._hover is True and self._state == tkinter.NORMAL: if self._check_state is True: self._canvas.itemconfig("inner_parts", - fill=ThemeManager.single_color(self._hover_color, self._appearance_mode), - outline=ThemeManager.single_color(self._hover_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._hover_color), + outline=self._apply_appearance_mode(self._hover_color)) self._canvas.itemconfig("border_parts", - fill=ThemeManager.single_color(self._hover_color, self._appearance_mode), - outline=ThemeManager.single_color(self._hover_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._hover_color), + outline=self._apply_appearance_mode(self._hover_color)) else: self._canvas.itemconfig("inner_parts", - fill=ThemeManager.single_color(self._hover_color, self._appearance_mode), - outline=ThemeManager.single_color(self._hover_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._hover_color), + outline=self._apply_appearance_mode(self._hover_color)) def _on_leave(self, event=0): if self._check_state is True: self._canvas.itemconfig("inner_parts", - fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), - outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._fg_color), + outline=self._apply_appearance_mode(self._fg_color)) self._canvas.itemconfig("border_parts", - fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), - outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._fg_color), + outline=self._apply_appearance_mode(self._fg_color)) else: self._canvas.itemconfig("inner_parts", - fill=ThemeManager.single_color(self._bg_color, self._appearance_mode), - outline=ThemeManager.single_color(self._bg_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._bg_color), + outline=self._apply_appearance_mode(self._bg_color)) self._canvas.itemconfig("border_parts", - fill=ThemeManager.single_color(self._border_color, self._appearance_mode), - outline=ThemeManager.single_color(self._border_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._border_color), + outline=self._apply_appearance_mode(self._border_color)) def _variable_callback(self, var_name, index, mode): if not self._variable_callback_blocked: diff --git a/customtkinter/widgets/ctk_combobox.py b/customtkinter/widgets/ctk_combobox.py index 76dcb7b..63bca4e 100644 --- a/customtkinter/widgets/ctk_combobox.py +++ b/customtkinter/widgets/ctk_combobox.py @@ -35,7 +35,7 @@ class CTkComboBox(CTkBaseClass): text_color_disabled: Union[str, Tuple[str, str]] = "default_theme", font: Union[tuple, CTkFont] = "default_theme", - dropdown_font: any = "default_theme", + dropdown_font: Union[tuple, CTkFont] = "default_theme", values: List[str] = None, state: str = tkinter.NORMAL, hover: bool = True, @@ -180,34 +180,34 @@ class CTkComboBox(CTkBaseClass): 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", - outline=ThemeManager.single_color(self._fg_color, self._appearance_mode), - fill=ThemeManager.single_color(self._fg_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._fg_color), + fill=self._apply_appearance_mode(self._fg_color)) self._canvas.itemconfig("border_parts_left", - outline=ThemeManager.single_color(self._border_color, self._appearance_mode), - fill=ThemeManager.single_color(self._border_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._border_color), + fill=self._apply_appearance_mode(self._border_color)) self._canvas.itemconfig("inner_parts_right", - outline=ThemeManager.single_color(self._border_color, self._appearance_mode), - fill=ThemeManager.single_color(self._border_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._border_color), + fill=self._apply_appearance_mode(self._border_color)) self._canvas.itemconfig("border_parts_right", - outline=ThemeManager.single_color(self._border_color, self._appearance_mode), - fill=ThemeManager.single_color(self._border_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._border_color), + fill=self._apply_appearance_mode(self._border_color)) - self._entry.configure(bg=ThemeManager.single_color(self._fg_color, self._appearance_mode), - fg=ThemeManager.single_color(self._text_color, self._appearance_mode), - disabledbackground=ThemeManager.single_color(self._fg_color, self._appearance_mode), - disabledforeground=ThemeManager.single_color(self._text_color_disabled, self._appearance_mode), - highlightcolor=ThemeManager.single_color(self._fg_color, self._appearance_mode), - insertbackground=ThemeManager.single_color(self._text_color, self._appearance_mode)) + self._entry.configure(bg=self._apply_appearance_mode(self._fg_color), + fg=self._apply_appearance_mode(self._text_color), + disabledbackground=self._apply_appearance_mode(self._fg_color), + disabledforeground=self._apply_appearance_mode(self._text_color_disabled), + highlightcolor=self._apply_appearance_mode(self._fg_color), + insertbackground=self._apply_appearance_mode(self._text_color)) if self._state == tkinter.DISABLED: 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: 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): self._dropdown_menu.open(self.winfo_rootx(), @@ -345,11 +345,11 @@ class CTkComboBox(CTkBaseClass): # set color of inner button parts to hover color self._canvas.itemconfig("inner_parts_right", - outline=ThemeManager.single_color(self._button_hover_color, self._appearance_mode), - fill=ThemeManager.single_color(self._button_hover_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._button_hover_color), + fill=self._apply_appearance_mode(self._button_hover_color)) self._canvas.itemconfig("border_parts_right", - outline=ThemeManager.single_color(self._button_hover_color, self._appearance_mode), - fill=ThemeManager.single_color(self._button_hover_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._button_hover_color), + fill=self._apply_appearance_mode(self._button_hover_color)) def _on_leave(self, event=0): 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 self._canvas.itemconfig("inner_parts_right", - outline=ThemeManager.single_color(self._button_color, self._appearance_mode), - fill=ThemeManager.single_color(self._button_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._button_color), + fill=self._apply_appearance_mode(self._button_color)) self._canvas.itemconfig("border_parts_right", - outline=ThemeManager.single_color(self._button_color, self._appearance_mode), - fill=ThemeManager.single_color(self._button_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._button_color), + fill=self._apply_appearance_mode(self._button_color)) def _dropdown_callback(self, value: str): if self._state == "readonly": diff --git a/customtkinter/widgets/ctk_entry.py b/customtkinter/widgets/ctk_entry.py index 1709346..290196f 100644 --- a/customtkinter/widgets/ctk_entry.py +++ b/customtkinter/widgets/ctk_entry.py @@ -148,7 +148,7 @@ class CTkEntry(CTkBaseClass): super().destroy() 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), self._apply_widget_scaling(self._current_height), @@ -156,33 +156,33 @@ class CTkEntry(CTkBaseClass): self._apply_widget_scaling(self._border_width)) 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", - fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), - outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) - self._entry.configure(bg=ThemeManager.single_color(self._fg_color, self._appearance_mode), - fg=ThemeManager.single_color(self._text_color, self._appearance_mode), - disabledbackground=ThemeManager.single_color(self._fg_color, self._appearance_mode), - disabledforeground=ThemeManager.single_color(self._text_color, self._appearance_mode), - highlightcolor=ThemeManager.single_color(self._fg_color, self._appearance_mode), - insertbackground=ThemeManager.single_color(self._text_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._fg_color), + outline=self._apply_appearance_mode(self._fg_color)) + self._entry.configure(bg=self._apply_appearance_mode(self._fg_color), + fg=self._apply_appearance_mode(self._text_color), + disabledbackground=self._apply_appearance_mode(self._fg_color), + disabledforeground=self._apply_appearance_mode(self._text_color), + highlightcolor=self._apply_appearance_mode(self._fg_color), + insertbackground=self._apply_appearance_mode(self._text_color)) else: self._canvas.itemconfig("inner_parts", - fill=ThemeManager.single_color(self._bg_color, self._appearance_mode), - outline=ThemeManager.single_color(self._bg_color, self._appearance_mode)) - self._entry.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode), - fg=ThemeManager.single_color(self._text_color, self._appearance_mode), - disabledbackground=ThemeManager.single_color(self._bg_color, self._appearance_mode), - disabledforeground=ThemeManager.single_color(self._text_color, self._appearance_mode), - highlightcolor=ThemeManager.single_color(self._bg_color, self._appearance_mode), - insertbackground=ThemeManager.single_color(self._text_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._bg_color), + outline=self._apply_appearance_mode(self._bg_color)) + self._entry.configure(bg=self._apply_appearance_mode(self._bg_color), + fg=self._apply_appearance_mode(self._text_color), + disabledbackground=self._apply_appearance_mode(self._bg_color), + disabledforeground=self._apply_appearance_mode(self._text_color), + highlightcolor=self._apply_appearance_mode(self._bg_color), + insertbackground=self._apply_appearance_mode(self._text_color)) self._canvas.itemconfig("border_parts", - fill=ThemeManager.single_color(self._border_color, self._appearance_mode), - outline=ThemeManager.single_color(self._border_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._border_color), + outline=self._apply_appearance_mode(self._border_color)) 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): if "state" in kwargs: @@ -287,7 +287,7 @@ class CTkEntry(CTkBaseClass): self._placeholder_text_active = True 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.insert(0, self._placeholder_text) @@ -295,7 +295,7 @@ class CTkEntry(CTkBaseClass): if self._placeholder_text_active: 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) for argument, value in self._pre_placeholder_arguments.items(): self._entry[argument] = value diff --git a/customtkinter/widgets/ctk_frame.py b/customtkinter/widgets/ctk_frame.py index 537855d..1dcf946 100644 --- a/customtkinter/widgets/ctk_frame.py +++ b/customtkinter/widgets/ctk_frame.py @@ -58,7 +58,7 @@ class CTkFrame(CTkBaseClass): width=self._apply_widget_scaling(self._current_width), height=self._apply_widget_scaling(self._current_height)) 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._overwrite_preferred_drawing_method = overwrite_preferred_drawing_method @@ -97,10 +97,10 @@ class CTkFrame(CTkBaseClass): if self._background_corner_colors is not None: self._draw_engine.draw_background_corners(self._apply_widget_scaling(self._current_width), 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_right", fill=ThemeManager.single_color(self._background_corner_colors[1], self._appearance_mode)) - 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_left", fill=ThemeManager.single_color(self._background_corner_colors[3], 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=self._apply_appearance_mode(self._background_corner_colors[1])) + 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=self._apply_appearance_mode(self._background_corner_colors[3])) else: self._canvas.delete("background_parts") @@ -113,17 +113,17 @@ class CTkFrame(CTkBaseClass): if no_color_updates is False or requires_recoloring: if self._fg_color is None: self._canvas.itemconfig("inner_parts", - fill=ThemeManager.single_color(self._bg_color, self._appearance_mode), - outline=ThemeManager.single_color(self._bg_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._bg_color), + outline=self._apply_appearance_mode(self._bg_color)) else: self._canvas.itemconfig("inner_parts", - fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), - outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._fg_color), + outline=self._apply_appearance_mode(self._fg_color)) self._canvas.itemconfig("border_parts", - fill=ThemeManager.single_color(self._border_color, self._appearance_mode), - outline=ThemeManager.single_color(self._border_color, self._appearance_mode)) - self._canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._border_color), + outline=self._apply_appearance_mode(self._border_color)) + 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("border_parts") diff --git a/customtkinter/widgets/ctk_label.py b/customtkinter/widgets/ctk_label.py index 02b23ed..ddb150c 100644 --- a/customtkinter/widgets/ctk_label.py +++ b/customtkinter/widgets/ctk_label.py @@ -123,22 +123,22 @@ class CTkLabel(CTkBaseClass): 0) 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", - fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), - outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._fg_color), + outline=self._apply_appearance_mode(self._fg_color)) - self._text_label.configure(fg=ThemeManager.single_color(self._text_color, self._appearance_mode), - bg=ThemeManager.single_color(self._fg_color, self._appearance_mode)) + self._text_label.configure(fg=self._apply_appearance_mode(self._text_color), + bg=self._apply_appearance_mode(self._fg_color)) else: self._canvas.itemconfig("inner_parts", - fill=ThemeManager.single_color(self._bg_color, self._appearance_mode), - outline=ThemeManager.single_color(self._bg_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._bg_color), + outline=self._apply_appearance_mode(self._bg_color)) - self._text_label.configure(fg=ThemeManager.single_color(self._text_color, self._appearance_mode), - bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) + self._text_label.configure(fg=self._apply_appearance_mode(self._text_color), + 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): if "anchor" in kwargs: diff --git a/customtkinter/widgets/ctk_optionmenu.py b/customtkinter/widgets/ctk_optionmenu.py index d9ff3f4..89cc8eb 100644 --- a/customtkinter/widgets/ctk_optionmenu.py +++ b/customtkinter/widgets/ctk_optionmenu.py @@ -193,27 +193,27 @@ class CTkOptionMenu(CTkBaseClass): 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", - outline=ThemeManager.single_color(self._fg_color, self._appearance_mode), - fill=ThemeManager.single_color(self._fg_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._fg_color), + fill=self._apply_appearance_mode(self._fg_color)) self._canvas.itemconfig("inner_parts_right", - outline=ThemeManager.single_color(self._button_color, self._appearance_mode), - fill=ThemeManager.single_color(self._button_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._button_color), + 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: - 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", - fill=ThemeManager.single_color(self._text_color_disabled, self._appearance_mode)) + fill=self._apply_appearance_mode(self._text_color_disabled)) 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", - 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() @@ -350,14 +350,14 @@ class CTkOptionMenu(CTkBaseClass): if self._hover is True and self._state == tkinter.NORMAL and len(self._values) > 0: # set color of inner button parts to hover color self._canvas.itemconfig("inner_parts_right", - outline=ThemeManager.single_color(self._button_hover_color, self._appearance_mode), - fill=ThemeManager.single_color(self._button_hover_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._button_hover_color), + fill=self._apply_appearance_mode(self._button_hover_color)) def _on_leave(self, event=0): # set color of inner button parts self._canvas.itemconfig("inner_parts_right", - outline=ThemeManager.single_color(self._button_color, self._appearance_mode), - fill=ThemeManager.single_color(self._button_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._button_color), + fill=self._apply_appearance_mode(self._button_color)) def _variable_callback(self, var_name, index, mode): if not self._variable_callback_blocked: diff --git a/customtkinter/widgets/ctk_progressbar.py b/customtkinter/widgets/ctk_progressbar.py index 5ffe585..68e7c72 100644 --- a/customtkinter/widgets/ctk_progressbar.py +++ b/customtkinter/widgets/ctk_progressbar.py @@ -139,16 +139,16 @@ class CTkProgressBar(CTkBaseClass): orientation) 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", - fill=ThemeManager.single_color(self._border_color, self._appearance_mode), - outline=ThemeManager.single_color(self._border_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._border_color), + outline=self._apply_appearance_mode(self._border_color)) self._canvas.itemconfig("inner_parts", - fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), - outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._fg_color), + outline=self._apply_appearance_mode(self._fg_color)) self._canvas.itemconfig("progress_parts", - fill=ThemeManager.single_color(self._progress_color, self._appearance_mode), - outline=ThemeManager.single_color(self._progress_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._progress_color), + outline=self._apply_appearance_mode(self._progress_color)) def configure(self, require_redraw=False, **kwargs): if "fg_color" in kwargs: diff --git a/customtkinter/widgets/ctk_radiobutton.py b/customtkinter/widgets/ctk_radiobutton.py index fe23d08..100b3d4 100644 --- a/customtkinter/widgets/ctk_radiobutton.py +++ b/customtkinter/widgets/ctk_radiobutton.py @@ -169,28 +169,28 @@ class CTkRadioButton(CTkBaseClass): self._apply_widget_scaling(self._border_width)) if no_color_updates is False or requires_recoloring: - self._bg_canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) - self._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=self._apply_appearance_mode(self._bg_color)) if self._check_state is False: self._canvas.itemconfig("border_parts", - outline=ThemeManager.single_color(self._border_color, self._appearance_mode), - fill=ThemeManager.single_color(self._border_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._border_color), + fill=self._apply_appearance_mode(self._border_color)) else: self._canvas.itemconfig("border_parts", - outline=ThemeManager.single_color(self._fg_color, self._appearance_mode), - fill=ThemeManager.single_color(self._fg_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._fg_color), + fill=self._apply_appearance_mode(self._fg_color)) self._canvas.itemconfig("inner_parts", - outline=ThemeManager.single_color(self._bg_color, self._appearance_mode), - fill=ThemeManager.single_color(self._bg_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._bg_color), + fill=self._apply_appearance_mode(self._bg_color)) 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: - 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): if "radiobutton_width" in kwargs: @@ -332,18 +332,18 @@ class CTkRadioButton(CTkBaseClass): def _on_enter(self, event=0): if self._hover is True and self._state == tkinter.NORMAL: self._canvas.itemconfig("border_parts", - fill=ThemeManager.single_color(self._hover_color, self._appearance_mode), - outline=ThemeManager.single_color(self._hover_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._hover_color), + outline=self._apply_appearance_mode(self._hover_color)) def _on_leave(self, event=0): if self._check_state is True: self._canvas.itemconfig("border_parts", - fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), - outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._fg_color), + outline=self._apply_appearance_mode(self._fg_color)) else: self._canvas.itemconfig("border_parts", - fill=ThemeManager.single_color(self._border_color, self._appearance_mode), - outline=ThemeManager.single_color(self._border_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._border_color), + outline=self._apply_appearance_mode(self._border_color)) def _variable_callback(self, var_name, index, mode): if not self._variable_callback_blocked: diff --git a/customtkinter/widgets/ctk_scrollbar.py b/customtkinter/widgets/ctk_scrollbar.py index 83429e8..bb2ff46 100644 --- a/customtkinter/widgets/ctk_scrollbar.py +++ b/customtkinter/widgets/ctk_scrollbar.py @@ -130,23 +130,23 @@ class CTkScrollbar(CTkBaseClass): if no_color_updates is False or requires_recoloring: if self._hover_state is True: self._canvas.itemconfig("scrollbar_parts", - fill=ThemeManager.single_color(self._scrollbar_hover_color, self._appearance_mode), - outline=ThemeManager.single_color(self._scrollbar_hover_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._scrollbar_hover_color), + outline=self._apply_appearance_mode(self._scrollbar_hover_color)) else: self._canvas.itemconfig("scrollbar_parts", - fill=ThemeManager.single_color(self._scrollbar_color, self._appearance_mode), - outline=ThemeManager.single_color(self._scrollbar_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._scrollbar_color), + outline=self._apply_appearance_mode(self._scrollbar_color)) 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", - fill=ThemeManager.single_color(self._bg_color, self._appearance_mode), - outline=ThemeManager.single_color(self._bg_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._bg_color), + outline=self._apply_appearance_mode(self._bg_color)) 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", - fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), - outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._fg_color), + outline=self._apply_appearance_mode(self._fg_color)) self._canvas.update_idletasks() @@ -208,14 +208,14 @@ class CTkScrollbar(CTkBaseClass): if self._hover is True: self._hover_state = True self._canvas.itemconfig("scrollbar_parts", - outline=ThemeManager.single_color(self._scrollbar_hover_color, self._appearance_mode), - fill=ThemeManager.single_color(self._scrollbar_hover_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._scrollbar_hover_color), + fill=self._apply_appearance_mode(self._scrollbar_hover_color)) def _on_leave(self, event=0): self._hover_state = False self._canvas.itemconfig("scrollbar_parts", - outline=ThemeManager.single_color(self._scrollbar_color, self._appearance_mode), - fill=ThemeManager.single_color(self._scrollbar_color, self._appearance_mode)) + outline=self._apply_appearance_mode(self._scrollbar_color), + fill=self._apply_appearance_mode(self._scrollbar_color)) def _clicked(self, event): if self._orientation == "vertical": diff --git a/customtkinter/widgets/ctk_slider.py b/customtkinter/widgets/ctk_slider.py index 8f7a657..d97c739 100644 --- a/customtkinter/widgets/ctk_slider.py +++ b/customtkinter/widgets/ctk_slider.py @@ -161,33 +161,33 @@ class CTkSlider(CTkBaseClass): self._value, orientation) 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: - self._canvas.itemconfig("border_parts", fill=ThemeManager.single_color(self._bg_color, self._appearance_mode), - outline=ThemeManager.single_color(self._bg_color, self._appearance_mode)) + self._canvas.itemconfig("border_parts", fill=self._apply_appearance_mode(self._bg_color), + outline=self._apply_appearance_mode(self._bg_color)) else: - self._canvas.itemconfig("border_parts", fill=ThemeManager.single_color(self._border_color, self._appearance_mode), - outline=ThemeManager.single_color(self._border_color, self._appearance_mode)) + self._canvas.itemconfig("border_parts", fill=self._apply_appearance_mode(self._border_color), + outline=self._apply_appearance_mode(self._border_color)) - self._canvas.itemconfig("inner_parts", fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), - outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) + self._canvas.itemconfig("inner_parts", fill=self._apply_appearance_mode(self._fg_color), + outline=self._apply_appearance_mode(self._fg_color)) if self._progress_color is None: - self._canvas.itemconfig("progress_parts", fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), - outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) + self._canvas.itemconfig("progress_parts", fill=self._apply_appearance_mode(self._fg_color), + outline=self._apply_appearance_mode(self._fg_color)) else: - self._canvas.itemconfig("progress_parts", fill=ThemeManager.single_color(self._progress_color, self._appearance_mode), - outline=ThemeManager.single_color(self._progress_color, self._appearance_mode)) + self._canvas.itemconfig("progress_parts", fill=self._apply_appearance_mode(self._progress_color), + outline=self._apply_appearance_mode(self._progress_color)) if self._hover_state is True: self._canvas.itemconfig("slider_parts", - fill=ThemeManager.single_color(self._button_hover_color, self._appearance_mode), - outline=ThemeManager.single_color(self._button_hover_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._button_hover_color), + outline=self._apply_appearance_mode(self._button_hover_color)) else: self._canvas.itemconfig("slider_parts", - fill=ThemeManager.single_color(self._button_color, self._appearance_mode), - outline=ThemeManager.single_color(self._button_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._button_color), + outline=self._apply_appearance_mode(self._button_color)) def configure(self, require_redraw=False, **kwargs): if "state" in kwargs: @@ -318,14 +318,14 @@ class CTkSlider(CTkBaseClass): if self._hover is True and self._state == "normal": self._hover_state = True self._canvas.itemconfig("slider_parts", - fill=ThemeManager.single_color(self._button_hover_color, self._appearance_mode), - outline=ThemeManager.single_color(self._button_hover_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._button_hover_color), + outline=self._apply_appearance_mode(self._button_hover_color)) def _on_leave(self, event=0): self._hover_state = False self._canvas.itemconfig("slider_parts", - fill=ThemeManager.single_color(self._button_color, self._appearance_mode), - outline=ThemeManager.single_color(self._button_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._button_color), + outline=self._apply_appearance_mode(self._button_color)) def _round_to_step_size(self, value) -> float: if self._number_of_steps is not None: diff --git a/customtkinter/widgets/ctk_switch.py b/customtkinter/widgets/ctk_switch.py index d9a3303..22d1e52 100644 --- a/customtkinter/widgets/ctk_switch.py +++ b/customtkinter/widgets/ctk_switch.py @@ -212,35 +212,35 @@ class CTkSwitch(CTkBaseClass): 0, "w") if no_color_updates is False or requires_recoloring: - self._bg_canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) - self._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=self._apply_appearance_mode(self._bg_color)) if self._border_color is None: - self._canvas.itemconfig("border_parts", fill=ThemeManager.single_color(self._bg_color, self._appearance_mode), - outline=ThemeManager.single_color(self._bg_color, self._appearance_mode)) + self._canvas.itemconfig("border_parts", fill=self._apply_appearance_mode(self._bg_color), + outline=self._apply_appearance_mode(self._bg_color)) else: - self._canvas.itemconfig("border_parts", fill=ThemeManager.single_color(self._border_color, self._appearance_mode), - outline=ThemeManager.single_color(self._border_color, self._appearance_mode)) + self._canvas.itemconfig("border_parts", fill=self._apply_appearance_mode(self._border_color), + outline=self._apply_appearance_mode(self._border_color)) - self._canvas.itemconfig("inner_parts", fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), - outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) + self._canvas.itemconfig("inner_parts", fill=self._apply_appearance_mode(self._fg_color), + outline=self._apply_appearance_mode(self._fg_color)) if self._progress_color is None: - self._canvas.itemconfig("progress_parts", fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), - outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) + self._canvas.itemconfig("progress_parts", fill=self._apply_appearance_mode(self._fg_color), + outline=self._apply_appearance_mode(self._fg_color)) else: - self._canvas.itemconfig("progress_parts", fill=ThemeManager.single_color(self._progress_color, self._appearance_mode), - outline=ThemeManager.single_color(self._progress_color, self._appearance_mode)) + self._canvas.itemconfig("progress_parts", fill=self._apply_appearance_mode(self._progress_color), + outline=self._apply_appearance_mode(self._progress_color)) - self._canvas.itemconfig("slider_parts", fill=ThemeManager.single_color(self._button_color, self._appearance_mode), - outline=ThemeManager.single_color(self._button_color, self._appearance_mode)) + self._canvas.itemconfig("slider_parts", fill=self._apply_appearance_mode(self._button_color), + outline=self._apply_appearance_mode(self._button_color)) 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: - 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): if "switch_width" in kwargs: @@ -417,14 +417,14 @@ class CTkSwitch(CTkBaseClass): if self._hover is True and self._state == "normal": self._hover_state = True self._canvas.itemconfig("slider_parts", - fill=ThemeManager.single_color(self._button_hover_color, self._appearance_mode), - outline=ThemeManager.single_color(self._button_hover_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._button_hover_color), + outline=self._apply_appearance_mode(self._button_hover_color)) def _on_leave(self, event=0): self._hover_state = False self._canvas.itemconfig("slider_parts", - fill=ThemeManager.single_color(self._button_color, self._appearance_mode), - outline=ThemeManager.single_color(self._button_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._button_color), + outline=self._apply_appearance_mode(self._button_color)) def _variable_callback(self, var_name, index, mode): if not self._variable_callback_blocked: diff --git a/customtkinter/widgets/ctk_tabview.py b/customtkinter/widgets/ctk_tabview.py index 91f49dd..b9d89cf 100644 --- a/customtkinter/widgets/ctk_tabview.py +++ b/customtkinter/widgets/ctk_tabview.py @@ -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._canvas = CTkCanvas(master=self, - bg=ThemeManager.single_color(self._bg_color, self._appearance_mode), + bg=self._apply_appearance_mode(self._bg_color), highlightthickness=0, width=self._apply_widget_scaling(self._current_width - self._top_spacing - self._top_button_overhang), 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 self._fg_color is None: self._canvas.itemconfig("inner_parts", - fill=ThemeManager.single_color(self._bg_color, self._appearance_mode), - outline=ThemeManager.single_color(self._bg_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._bg_color), + outline=self._apply_appearance_mode(self._bg_color)) else: self._canvas.itemconfig("inner_parts", - fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), - outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._fg_color), + outline=self._apply_appearance_mode(self._fg_color)) self._canvas.itemconfig("border_parts", - fill=ThemeManager.single_color(self._border_color, self._appearance_mode), - outline=ThemeManager.single_color(self._border_color, self._appearance_mode)) - self._canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._border_color), + outline=self._apply_appearance_mode(self._border_color)) + self._canvas.configure(bg=self._apply_appearance_mode(self._bg_color)) def configure(self, require_redraw=False, **kwargs): if "corner_radius" in kwargs: diff --git a/customtkinter/widgets/ctk_textbox.py b/customtkinter/widgets/ctk_textbox.py index da2b6f4..bfca4fd 100644 --- a/customtkinter/widgets/ctk_textbox.py +++ b/customtkinter/widgets/ctk_textbox.py @@ -76,18 +76,18 @@ class CTkTextbox(CTkBaseClass): width=self._apply_widget_scaling(self._current_width), height=self._apply_widget_scaling(self._current_height)) 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._textbox = tkinter.Text(self, - fg=ThemeManager.single_color(self._text_color, self._appearance_mode), + fg=self._apply_appearance_mode(self._text_color), width=0, height=0, font=self._apply_font_scaling(self._font), highlightthickness=0, relief="flat", - insertbackground=ThemeManager.single_color(self._text_color, self._appearance_mode), - bg=ThemeManager.single_color(self._fg_color, self._appearance_mode), + insertbackground=self._apply_appearance_mode(self._text_color), + bg=self._apply_appearance_mode(self._fg_color), **pop_from_dict_by_set(kwargs, self._valid_tk_text_attributes)) check_kwargs_empty(kwargs, raise_error=True) @@ -222,31 +222,31 @@ class CTkTextbox(CTkBaseClass): if no_color_updates is False or requires_recoloring: if self._fg_color is None: self._canvas.itemconfig("inner_parts", - fill=ThemeManager.single_color(self._bg_color, self._appearance_mode), - outline=ThemeManager.single_color(self._bg_color, self._appearance_mode)) - self._textbox.configure(fg=ThemeManager.single_color(self._text_color, self._appearance_mode), - bg=ThemeManager.single_color(self._bg_color, self._appearance_mode), - insertbackground=ThemeManager.single_color(self._text_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._bg_color), + outline=self._apply_appearance_mode(self._bg_color)) + self._textbox.configure(fg=self._apply_appearance_mode(self._text_color), + bg=self._apply_appearance_mode(self._bg_color), + insertbackground=self._apply_appearance_mode(self._text_color)) self._x_scrollbar.configure(fg_color=self._bg_color, scrollbar_color=self._scrollbar_color, scrollbar_hover_color=self._scrollbar_hover_color) self._y_scrollbar.configure(fg_color=self._bg_color, scrollbar_color=self._scrollbar_color, scrollbar_hover_color=self._scrollbar_hover_color) else: self._canvas.itemconfig("inner_parts", - fill=ThemeManager.single_color(self._fg_color, self._appearance_mode), - outline=ThemeManager.single_color(self._fg_color, self._appearance_mode)) - self._textbox.configure(fg=ThemeManager.single_color(self._text_color, self._appearance_mode), - bg=ThemeManager.single_color(self._fg_color, self._appearance_mode), - insertbackground=ThemeManager.single_color(self._text_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._fg_color), + outline=self._apply_appearance_mode(self._fg_color)) + self._textbox.configure(fg=self._apply_appearance_mode(self._text_color), + bg=self._apply_appearance_mode(self._fg_color), + insertbackground=self._apply_appearance_mode(self._text_color)) self._x_scrollbar.configure(fg_color=self._fg_color, scrollbar_color=self._scrollbar_color, scrollbar_hover_color=self._scrollbar_hover_color) self._y_scrollbar.configure(fg_color=self._fg_color, scrollbar_color=self._scrollbar_color, scrollbar_hover_color=self._scrollbar_hover_color) self._canvas.itemconfig("border_parts", - fill=ThemeManager.single_color(self._border_color, self._appearance_mode), - outline=ThemeManager.single_color(self._border_color, self._appearance_mode)) - self._canvas.configure(bg=ThemeManager.single_color(self._bg_color, self._appearance_mode)) + fill=self._apply_appearance_mode(self._border_color), + outline=self._apply_appearance_mode(self._border_color)) + self._canvas.configure(bg=self._apply_appearance_mode(self._bg_color)) self._canvas.tag_lower("inner_parts") self._canvas.tag_lower("border_parts") diff --git a/customtkinter/windows/ctk_tk.py b/customtkinter/windows/ctk_tk.py index 8c11b1c..d7f14b8 100644 --- a/customtkinter/windows/ctk_tk.py +++ b/customtkinter/windows/ctk_tk.py @@ -5,7 +5,7 @@ import os import platform import ctypes import re -from typing import Union, Tuple +from typing import Union, Tuple, List from ..appearance_mode_tracker import AppearanceModeTracker 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 - 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") self.geometry(f"{self._current_width}x{self._current_height}") @@ -244,10 +244,20 @@ class CTk(tkinter.Tk): else: 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): if "fg_color" in kwargs: 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(): try: @@ -354,4 +364,4 @@ class CTk(tkinter.Tk): else: 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)) diff --git a/customtkinter/windows/ctk_toplevel.py b/customtkinter/windows/ctk_toplevel.py index 7035088..6a9ba84 100644 --- a/customtkinter/windows/ctk_toplevel.py +++ b/customtkinter/windows/ctk_toplevel.py @@ -5,7 +5,7 @@ import os import platform import ctypes import re -from typing import Union, Tuple +from typing import Union, Tuple, List from ..appearance_mode_tracker import AppearanceModeTracker 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 - 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") self._state_before_windows_set_titlebar_color = None @@ -157,6 +157,16 @@ class CTkToplevel(tkinter.Toplevel): else: 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): AppearanceModeTracker.remove(self._set_appearance_mode) ScalingTracker.remove_window(self._set_scaling, self) @@ -204,7 +214,7 @@ class CTkToplevel(tkinter.Toplevel): def configure(self, **kwargs): if "fg_color" in kwargs: 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(): try: @@ -314,4 +324,4 @@ class CTkToplevel(tkinter.Toplevel): else: 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))