From 15ecf184496acc46ad7bfab258a216b0b7947abd Mon Sep 17 00:00:00 2001 From: TomSchimansky Date: Thu, 10 Mar 2022 02:12:30 +0100 Subject: [PATCH] fixed state in multiple widgets --- customtkinter/assets/themes/blue.json | 11 +-- customtkinter/assets/themes/dark-blue.json | 2 + customtkinter/assets/themes/green.json | 2 + customtkinter/customtkinter_button.py | 73 +++++++---------- customtkinter/customtkinter_checkbox.py | 53 ++++++++----- customtkinter/customtkinter_radiobutton.py | 44 ++++------- customtkinter/customtkinter_switch.py | 12 +-- customtkinter/customtkinter_theme_manager.py | 82 ++++---------------- examples/complex_example.py | 3 + 9 files changed, 108 insertions(+), 174 deletions(-) diff --git a/customtkinter/assets/themes/blue.json b/customtkinter/assets/themes/blue.json index 3cf2833..79de721 100644 --- a/customtkinter/assets/themes/blue.json +++ b/customtkinter/assets/themes/blue.json @@ -1,6 +1,6 @@ { "color": { - "window_bg_color": ["gray92", "gray12"], + "window_bg_color": ["gray95", "gray12"], "button": ["#1FA6E8", "#1C94CF"], "button_hover": ["#1A89BF", "#1673A1"], "button_border": ["gray40", "gray70"], @@ -10,10 +10,12 @@ "entry_border": ["gray70", "gray32"], "entry_placeholder_text": ["gray52", "gray62"], "frame_border": ["#A7C2E0", "#5FB4DD"], - "frame_low": ["gray87", "gray18"], - "frame_high": ["gray82", "gray22"], + "frame_low": ["gray89", "gray18"], + "frame_high": ["gray84", "gray22"], "label": [null, null], "text": ["gray20", "gray90"], + "text_disabled": ["gray60", "gray50"], + "text_button_disabled": ["gray40", "gray74"], "progressbar": ["#6B6B6B", "gray0"], "progressbar_progress": ["#3599D6", "#1C94CF"], "progressbar_border": ["gray", "gray"], @@ -24,8 +26,7 @@ "switch": ["gray70", "gray35"], "switch_progress": ["#1FA6E8", "#1C94CF"], "switch_button": ["gray36", "gray75"], - "switch_button_hover": ["gray30", "gray90"], - "darken_factor": 0.8 + "switch_button_hover": ["gray30", "gray90"] }, "text": { diff --git a/customtkinter/assets/themes/dark-blue.json b/customtkinter/assets/themes/dark-blue.json index e471c66..49714e2 100644 --- a/customtkinter/assets/themes/dark-blue.json +++ b/customtkinter/assets/themes/dark-blue.json @@ -14,6 +14,8 @@ "frame_high": ["gray86", "gray20"], "label": [null, null], "text": ["gray12", "gray90"], + "text_disabled": ["gray60", "gray50"], + "text_button_disabled": ["gray40", "gray74"], "progressbar": ["#6B6B6B", "gray6"], "progressbar_progress": ["#608BD5", "#395E9C"], "progressbar_border": ["gray", "gray"], diff --git a/customtkinter/assets/themes/green.json b/customtkinter/assets/themes/green.json index 0ea6487..1ea92d7 100644 --- a/customtkinter/assets/themes/green.json +++ b/customtkinter/assets/themes/green.json @@ -15,6 +15,8 @@ "frame_high": ["gray82", "gray22"], "label": [null, null], "text": ["gray20", "gray90"], + "text_disabled": ["gray60", "gray50"], + "text_button_disabled": ["gray40", "gray74"], "progressbar": ["#6B6B6B", "#222222"], "progressbar_progress": ["#72CF9F", "#11B384"], "progressbar_border": ["gray", "gray"], diff --git a/customtkinter/customtkinter_button.py b/customtkinter/customtkinter_button.py index 1e4e921..4cdc357 100644 --- a/customtkinter/customtkinter_button.py +++ b/customtkinter/customtkinter_button.py @@ -26,6 +26,7 @@ class CTkButton(tkinter.Frame): corner_radius="default_theme", text_font="default_theme", text_color="default_theme", + text_color_disabled="default_theme", text="CTkButton", hover=True, image=None, @@ -89,6 +90,7 @@ class CTkButton(tkinter.Frame): self.text = text self.text_label = None self.text_color = CTkThemeManager.theme["color"]["text"] if text_color == "default_theme" else text_color + self.text_color_disabled = CTkThemeManager.theme["color"]["text_button_disabled"] if text_color_disabled == "default_theme" else text_color_disabled self.text_font = (CTkThemeManager.theme["text"]["font"], CTkThemeManager.theme["text"]["size"]) if text_font == "default_theme" else text_font # callback and hover functionality @@ -99,11 +101,6 @@ class CTkButton(tkinter.Frame): self.compound = compound self.click_animation_running = False - if sys.platform == "darwin" and self.function is not None and CTkSettings.hand_cursor_enabled: - self.configure(cursor="pointinghand") - elif sys.platform.startswith("win") and self.function is not None and CTkSettings.hand_cursor_enabled: - self.configure(cursor="hand2") - self.canvas = CTkCanvas(master=self, highlightthickness=0, width=self.width, @@ -113,16 +110,15 @@ class CTkButton(tkinter.Frame): self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method) # event bindings - if self.hover is True: - self.canvas.bind("", self.on_enter) - self.canvas.bind("", self.on_leave) - + self.canvas.bind("", self.on_enter) + self.canvas.bind("", self.on_leave) self.canvas.bind("", self.clicked) self.canvas.bind("", self.clicked) # Each time an item is resized due to pack position mode, the binding Configure is called on the widget self.bind('', self.update_dimensions) + self.set_cursor() self.draw() # initial draw def destroy(self): @@ -163,26 +159,15 @@ class CTkButton(tkinter.Frame): outline=CTkThemeManager.single_color(self.border_color, self.appearance_mode), fill=CTkThemeManager.single_color(self.border_color, self.appearance_mode)) - # set color for inner button parts (depends on button state) - if self.state == tkinter.DISABLED: - if self.fg_color is None: - self.canvas.itemconfig("inner_parts", - outline=CTkThemeManager.darken_hex_color(CTkThemeManager.single_color(self.bg_color, self.appearance_mode)), - fill=CTkThemeManager.darken_hex_color(CTkThemeManager.single_color(self.bg_color, self.appearance_mode))) - else: - self.canvas.itemconfig("inner_parts", - outline=CTkThemeManager.darken_hex_color(CTkThemeManager.single_color(self.fg_color, self.appearance_mode)), - fill=CTkThemeManager.darken_hex_color(CTkThemeManager.single_color(self.fg_color, self.appearance_mode))) - + # set color for inner button parts + if self.fg_color is None: + self.canvas.itemconfig("inner_parts", + outline=CTkThemeManager.single_color(self.bg_color, self.appearance_mode), + fill=CTkThemeManager.single_color(self.bg_color, self.appearance_mode)) else: - if self.fg_color is None: - self.canvas.itemconfig("inner_parts", - outline=CTkThemeManager.single_color(self.bg_color, self.appearance_mode), - fill=CTkThemeManager.single_color(self.bg_color, self.appearance_mode)) - else: - self.canvas.itemconfig("inner_parts", - outline=CTkThemeManager.single_color(self.fg_color, self.appearance_mode), - fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode)) + self.canvas.itemconfig("inner_parts", + outline=CTkThemeManager.single_color(self.fg_color, self.appearance_mode), + fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode)) # create text label if text given if self.text is not None and self.text != "": @@ -199,17 +184,15 @@ class CTkButton(tkinter.Frame): # set text_label fg color (text color) self.text_label.configure(fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode)) - # set text_label bg color (label color) if self.state == tkinter.DISABLED: - if self.fg_color is None: - self.text_label.configure(bg=CTkThemeManager.darken_hex_color(CTkThemeManager.single_color(self.bg_color, self.appearance_mode))) - else: - self.text_label.configure(bg=CTkThemeManager.darken_hex_color(CTkThemeManager.single_color(self.fg_color, self.appearance_mode))) + self.text_label.configure(fg=(CTkThemeManager.single_color(self.text_color_disabled, self.appearance_mode))) else: - if self.fg_color is None: - self.text_label.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode)) - else: - self.text_label.configure(bg=CTkThemeManager.single_color(self.fg_color, self.appearance_mode)) + self.text_label.configure(fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode)) + + if self.fg_color is None: + self.text_label.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode)) + else: + self.text_label.configure(bg=CTkThemeManager.single_color(self.fg_color, self.appearance_mode)) self.text_label.configure(text=self.text) # set text @@ -233,7 +216,7 @@ class CTkButton(tkinter.Frame): if no_color_updates is False: # set image_label bg color (background color of label) if self.state == tkinter.DISABLED: - self.image_label.configure(bg=CTkThemeManager.darken_hex_color(CTkThemeManager.single_color(self.fg_color, self.appearance_mode))) + self.image_label.configure(bg=CTkThemeManager.multiply_hex_color(CTkThemeManager.single_color(self.fg_color, self.appearance_mode))) else: self.image_label.configure(bg=CTkThemeManager.single_color(self.fg_color, self.appearance_mode)) @@ -279,7 +262,9 @@ class CTkButton(tkinter.Frame): del kwargs["text"] if "state" in kwargs: - self.set_state(kwargs["state"]) + self.state = kwargs["state"] + self.set_cursor() + require_redraw = True del kwargs["state"] if "image" in kwargs: @@ -334,25 +319,19 @@ class CTkButton(tkinter.Frame): if require_redraw: self.draw() - def set_state(self, state): - self.state = state - + def set_cursor(self): if self.state == tkinter.DISABLED: - self.hover = False if sys.platform == "darwin" and self.function is not None and CTkSettings.hand_cursor_enabled: self.configure(cursor="arrow") elif sys.platform.startswith("win") and self.function is not None and CTkSettings.hand_cursor_enabled: self.configure(cursor="arrow") elif self.state == tkinter.NORMAL: - self.hover = True if sys.platform == "darwin" and self.function is not None and CTkSettings.hand_cursor_enabled: self.configure(cursor="pointinghand") elif sys.platform.startswith("win") and self.function is not None and CTkSettings.hand_cursor_enabled: self.configure(cursor="hand2") - self.draw() - def set_text(self, text): self.text = text self.draw() @@ -362,7 +341,7 @@ class CTkButton(tkinter.Frame): self.draw() def on_enter(self, event=0): - if self.hover is True: + if self.hover is True and self.state == tkinter.NORMAL: if self.hover_color is None: inner_parts_color = self.fg_color else: diff --git a/customtkinter/customtkinter_checkbox.py b/customtkinter/customtkinter_checkbox.py index 4698214..bfe2374 100644 --- a/customtkinter/customtkinter_checkbox.py +++ b/customtkinter/customtkinter_checkbox.py @@ -26,6 +26,7 @@ class CTkCheckBox(tkinter.Frame): text_font="default_theme", text_color="default_theme", text="CTkCheckBox", + text_color_disabled="default_theme", hover=True, command=None, state=tkinter.NORMAL, @@ -62,7 +63,7 @@ class CTkCheckBox(tkinter.Frame): self.bg_color = self.detect_color_of_master() if bg_color is None else bg_color self.fg_color = CTkThemeManager.theme["color"]["button"] if fg_color == "default_theme" else fg_color - self.hover_color = CTkThemeManager.theme["color"]["button"] if hover_color == "default_theme" else hover_color + self.hover_color = CTkThemeManager.theme["color"]["button_hover"] if hover_color == "default_theme" else hover_color self.border_color = CTkThemeManager.theme["color"]["checkbox_border"] if border_color == "default_theme" else border_color self.checkmark_color = CTkThemeManager.theme["color"]["checkmark"] if checkmark_color == "default_theme" else checkmark_color @@ -83,6 +84,7 @@ class CTkCheckBox(tkinter.Frame): self.text = text self.text_color = CTkThemeManager.theme["color"]["text"] if text_color == "default_theme" else text_color + self.text_color_disabled = CTkThemeManager.theme["color"]["text_disabled"] if text_color_disabled == "default_theme" else text_color_disabled self.text_font = (CTkThemeManager.theme["text"]["font"], CTkThemeManager.theme["text"]["size"]) if text_font == "default_theme" else text_font self.function = command @@ -109,11 +111,6 @@ class CTkCheckBox(tkinter.Frame): self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method) - if sys.platform == "darwin" and self.state == tkinter.NORMAL and CTkSettings.hand_cursor_enabled: - self.canvas.configure(cursor="pointinghand") - elif sys.platform.startswith("win") and self.state == tkinter.NORMAL and CTkSettings.hand_cursor_enabled: - self.canvas.configure(cursor="hand2") - if self.hover is True: self.canvas.bind("", self.on_enter) self.canvas.bind("", self.on_leave) @@ -123,6 +120,7 @@ class CTkCheckBox(tkinter.Frame): self.text_label = None + self.set_cursor() self.draw() # initial draw if self.variable is not None: @@ -186,7 +184,10 @@ class CTkCheckBox(tkinter.Frame): self.text_label.grid(row=0, column=2, padx=0, pady=0, sticky="w") self.text_label["anchor"] = "w" - self.text_label.configure(fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode)) + if self.state == tkinter.DISABLED: + self.text_label.configure(fg=(CTkThemeManager.single_color(self.text_color_disabled, self.appearance_mode))) + else: + self.text_label.configure(fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode)) self.text_label.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode)) self.set_text(self.text) @@ -202,7 +203,9 @@ class CTkCheckBox(tkinter.Frame): del kwargs["text"] if "state" in kwargs: - self.set_state(kwargs["state"]) + self.state = kwargs["state"] + self.set_cursor() + require_redraw = True del kwargs["state"] if "fg_color" in kwargs: @@ -259,25 +262,19 @@ class CTkCheckBox(tkinter.Frame): if require_redraw: self.draw() - def set_state(self, state): - self.state = state - + def set_cursor(self): if self.state == tkinter.DISABLED: - self.hover = False if sys.platform == "darwin" and CTkSettings.hand_cursor_enabled: self.canvas.configure(cursor="arrow") - elif sys.platform.startswith("sys") and CTkSettings.hand_cursor_enabled: + elif sys.platform.startswith("win") and CTkSettings.hand_cursor_enabled: self.canvas.configure(cursor="arrow") elif self.state == tkinter.NORMAL: - self.hover = True if sys.platform == "darwin" and CTkSettings.hand_cursor_enabled: self.canvas.configure(cursor="pointinghand") - elif sys.platform.startswith("sys") and CTkSettings.hand_cursor_enabled: + elif sys.platform.startswith("win") and CTkSettings.hand_cursor_enabled: self.canvas.configure(cursor="hand2") - self.draw() - def set_text(self, text): self.text = text if self.text_label is not None: @@ -286,10 +283,18 @@ class CTkCheckBox(tkinter.Frame): sys.stderr.write("ERROR (CTkButton): Cant change text because checkbox has no text.") def on_enter(self, event=0): - if self.hover is True: - self.canvas.itemconfig("inner_parts", - fill=CTkThemeManager.single_color(self.hover_color, self.appearance_mode), - outline=CTkThemeManager.single_color(self.hover_color, self.appearance_mode)) + if self.hover is True and self.state == tkinter.NORMAL: + if self.check_state is True: + self.canvas.itemconfig("inner_parts", + fill=CTkThemeManager.single_color(self.hover_color, self.appearance_mode), + outline=CTkThemeManager.single_color(self.hover_color, self.appearance_mode)) + self.canvas.itemconfig("border_parts", + fill=CTkThemeManager.single_color(self.hover_color, self.appearance_mode), + outline=CTkThemeManager.single_color(self.hover_color, self.appearance_mode)) + else: + self.canvas.itemconfig("inner_parts", + fill=CTkThemeManager.single_color(self.hover_color, self.appearance_mode), + outline=CTkThemeManager.single_color(self.hover_color, self.appearance_mode)) def on_leave(self, event=0): if self.hover is True: @@ -297,10 +302,16 @@ class CTkCheckBox(tkinter.Frame): self.canvas.itemconfig("inner_parts", fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode), outline=CTkThemeManager.single_color(self.fg_color, self.appearance_mode)) + self.canvas.itemconfig("border_parts", + fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode), + outline=CTkThemeManager.single_color(self.fg_color, self.appearance_mode)) else: self.canvas.itemconfig("inner_parts", fill=CTkThemeManager.single_color(self.bg_color, self.appearance_mode), outline=CTkThemeManager.single_color(self.bg_color, self.appearance_mode)) + self.canvas.itemconfig("border_parts", + fill=CTkThemeManager.single_color(self.border_color, self.appearance_mode), + outline=CTkThemeManager.single_color(self.border_color, self.appearance_mode)) def variable_callback(self, var_name, index, mode): if not self.variable_callback_blocked: diff --git a/customtkinter/customtkinter_radiobutton.py b/customtkinter/customtkinter_radiobutton.py index bb7efd5..84716b8 100644 --- a/customtkinter/customtkinter_radiobutton.py +++ b/customtkinter/customtkinter_radiobutton.py @@ -24,6 +24,7 @@ class CTkRadioButton(tkinter.Frame): text_font="default_theme", text_color="default_theme", text="CTkRadioButton", + text_color_disabled="default_theme", hover=True, command=None, state=tkinter.NORMAL, @@ -81,6 +82,7 @@ class CTkRadioButton(tkinter.Frame): self.text = text self.text_color = CTkThemeManager.theme["color"]["text"] if text_color == "default_theme" else text_color + self.text_color_disabled = CTkThemeManager.theme["color"]["text_disabled"] if text_color_disabled == "default_theme" else text_color_disabled self.text_font = (CTkThemeManager.theme["text"]["font"], CTkThemeManager.theme["text"]["size"]) if text_font == "default_theme" else text_font self.function = command @@ -106,20 +108,14 @@ class CTkRadioButton(tkinter.Frame): self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method) - if sys.platform == "darwin" and self.state == tkinter.NORMAL and CTkSettings.hand_cursor_enabled: - self.canvas.configure(cursor="pointinghand") - elif sys.platform.startswith("win") and self.state == tkinter.NORMAL and CTkSettings.hand_cursor_enabled: - self.canvas.configure(cursor="hand2") - - if self.hover is True: - self.canvas.bind("", self.on_enter) - self.canvas.bind("", self.on_leave) - + self.canvas.bind("", self.on_enter) + self.canvas.bind("", self.on_leave) self.canvas.bind("", self.invoke) self.canvas.bind("", self.invoke) self.text_label = None + self.set_cursor() self.draw() # initial draw if self.variable is not None: @@ -171,7 +167,11 @@ class CTkRadioButton(tkinter.Frame): self.text_label.grid(row=0, column=2, padx=0, pady=0, sticky="w") self.text_label["anchor"] = "w" - self.text_label.configure(fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode)) + if self.state == tkinter.DISABLED: + self.text_label.configure(fg=CTkThemeManager.single_color(self.text_color_disabled, self.appearance_mode)) + else: + self.text_label.configure(fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode)) + self.text_label.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode)) self.set_text(self.text) @@ -187,7 +187,9 @@ class CTkRadioButton(tkinter.Frame): del kwargs["text"] if "state" in kwargs: - self.set_state(kwargs["state"]) + self.state = kwargs["state"] + self.set_cursor() + require_redraw = True del kwargs["state"] if "fg_color" in kwargs: @@ -249,25 +251,19 @@ class CTkRadioButton(tkinter.Frame): if require_redraw: self.draw() - def set_state(self, state): - self.state = state - + def set_cursor(self): if self.state == tkinter.DISABLED: - self.hover = False if sys.platform == "darwin" and CTkSettings.hand_cursor_enabled: self.canvas.configure(cursor="arrow") - elif sys.platform.startswith("sys") and CTkSettings.hand_cursor_enabled: + elif sys.platform.startswith("win") and CTkSettings.hand_cursor_enabled: self.canvas.configure(cursor="arrow") elif self.state == tkinter.NORMAL: - self.hover = True if sys.platform == "darwin" and CTkSettings.hand_cursor_enabled: self.canvas.configure(cursor="pointinghand") - elif sys.platform.startswith("sys") and CTkSettings.hand_cursor_enabled: + elif sys.platform.startswith("win") and CTkSettings.hand_cursor_enabled: self.canvas.configure(cursor="hand2") - self.draw() - def set_text(self, text): self.text = text if self.text_label is not None: @@ -276,7 +272,7 @@ class CTkRadioButton(tkinter.Frame): sys.stderr.write("ERROR (CTkButton): Cant change text because radiobutton has no text.") def on_enter(self, event=0): - if self.hover is True: + if self.hover is True and self.state == tkinter.NORMAL: self.canvas.itemconfig("border_parts", fill=CTkThemeManager.single_color(self.hover_color, self.appearance_mode), outline=CTkThemeManager.single_color(self.hover_color, self.appearance_mode)) @@ -310,9 +306,6 @@ class CTkRadioButton(tkinter.Frame): def select(self, from_variable_callback=False): self.check_state = True - self.canvas.itemconfig("border_parts", - fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode), - outline=CTkThemeManager.single_color(self.fg_color, self.appearance_mode)) self.border_width = self.border_width_checked self.draw() @@ -323,9 +316,6 @@ class CTkRadioButton(tkinter.Frame): def deselect(self, from_variable_callback=False): self.check_state = False - self.canvas.itemconfig("border_parts", - fill=CTkThemeManager.single_color(self.border_color, self.appearance_mode), - outline=CTkThemeManager.single_color(self.border_color, self.appearance_mode)) self.border_width = self.border_width_unchecked self.draw() diff --git a/customtkinter/customtkinter_switch.py b/customtkinter/customtkinter_switch.py index b4ed140..b471fe4 100644 --- a/customtkinter/customtkinter_switch.py +++ b/customtkinter/customtkinter_switch.py @@ -24,7 +24,7 @@ class CTkSwitch(tkinter.Frame): width=36, height=18, corner_radius="default_theme", - button_corner_radius="default_theme", + # button_corner_radius="default_theme", border_width="default_theme", button_length="default_theme", command=None, @@ -72,7 +72,7 @@ class CTkSwitch(tkinter.Frame): self.width = width self.height = height self.corner_radius = CTkThemeManager.theme["shape"]["switch_corner_radius"] if corner_radius == "default_theme" else corner_radius - self.button_corner_radius = CTkThemeManager.theme["shape"]["switch_button_corner_radius"] if button_corner_radius == "default_theme" else button_corner_radius + # self.button_corner_radius = CTkThemeManager.theme["shape"]["switch_button_corner_radius"] if button_corner_radius == "default_theme" else button_corner_radius self.border_width = CTkThemeManager.theme["shape"]["switch_border_width"] if border_width == "default_theme" else border_width self.button_length = CTkThemeManager.theme["shape"]["switch_button_length"] if button_length == "default_theme" else button_length self.hover_state = False @@ -80,8 +80,8 @@ class CTkSwitch(tkinter.Frame): self.onvalue = onvalue self.offvalue = offvalue - if self.corner_radius < self.button_corner_radius: - self.corner_radius = self.button_corner_radius + #if self.corner_radius < self.button_corner_radius: + # self.corner_radius = self.button_corner_radius self.callback_function = command self.variable: tkinter.Variable = variable @@ -142,10 +142,10 @@ class CTkSwitch(tkinter.Frame): if self.check_state is True: requires_recoloring = self.draw_engine.draw_rounded_slider_with_border_and_button(self.width, self.height, self.corner_radius, self.border_width, - self.button_length, self.button_corner_radius, 1, "w") + self.button_length, self.corner_radius, 1, "w") else: requires_recoloring = self.draw_engine.draw_rounded_slider_with_border_and_button(self.width, self.height, self.corner_radius, self.border_width, - self.button_length, self.button_corner_radius, 0, "w") + self.button_length, self.corner_radius, 0, "w") if color_updates or requires_recoloring: self.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode)) diff --git a/customtkinter/customtkinter_theme_manager.py b/customtkinter/customtkinter_theme_manager.py index ee4520b..5bdb7e5 100644 --- a/customtkinter/customtkinter_theme_manager.py +++ b/customtkinter/customtkinter_theme_manager.py @@ -26,67 +26,6 @@ class CTkThemeManager: else: cls.theme["text"] = cls.theme["text"]["Linux"] - @classmethod - def initialize_color_theme(cls, theme_name): - - if sys.platform == "darwin": - cls.TEXT_FONT_NAME = "Avenir" - elif sys.platform.startswith("win"): - cls.TEXT_FONT_NAME = "Roboto" - else: - cls.TEXT_FONT_NAME = "Roboto" - - cls.TEXT_FONT_SIZE = -14 # px height - - if theme_name.lower() == "blue": - cls.WINDOW_BG_COLOR = ("#ECECEC", "#323232") # macOS standard light and dark window bg colors - cls.MAIN_COLOR = ("#64A1D2", "#1C94CF") - cls.MAIN_HOVER_COLOR = ("#A7C2E0", "#5FB4DD") - cls.ENTRY_COLOR = ("gray95", "#222222") - cls.ENTRY_BORDER_COLOR = ("gray65", "gray40") - cls.TEXT_COLOR = ("black", "white") - cls.PLACEHOLDER_TEXT_COLOR = ("gray52", "gray62") - cls.LABEL_BG_COLOR = ("white", "#626061") - cls.SLIDER_BG_COLOR = ("#6B6B6B", "#222222") - cls.SLIDER_PROGRESS_COLOR = ("#A5A6A5", "#555555") - cls.PROGRESS_BG_COLOR = ("#6B6B6B", "#222222") - cls.FRAME_COLOR = ("#D4D5D6", "#3F3F3F") - cls.FRAME_2_COLOR = ("#BFBEC1", "#505050") - cls.CHECKBOX_LINES_COLOR = ("black", "#ededed") - cls.DARKEN_COLOR_FACTOR = 0.8 # used to generate color for disabled button - - elif theme_name.lower() == "green": - cls.WINDOW_BG_COLOR = ("#ECECEC", "#323232") # macOS standard light and dark window bg colors - cls.MAIN_COLOR = ("#13C995", "#1ABE87") - cls.MAIN_HOVER_COLOR = ("#6ACBA5", "#81E4B2") - cls.ENTRY_COLOR = ("gray60", "#222223") - cls.TEXT_COLOR = ("gray25", "gray92") - cls.PLACEHOLDER_TEXT_COLOR = ("gray32", "gray55") - cls.LABEL_BG_COLOR = ("white", "#626061") - cls.SLIDER_BG_COLOR = ("#636363", "#0D1321") - cls.SLIDER_PROGRESS_COLOR = ("white", "#727578") - cls.PROGRESS_BG_COLOR = ("#636363", "#0D1321") - cls.FRAME_COLOR = ("#D4D5D6", "#3F3F3F") - cls.FRAME_2_COLOR = ("#BFBEC1", "#505050") - cls.CHECKBOX_LINES_COLOR = ("#414141", "#EDEDED") - cls.DARKEN_COLOR_FACTOR = 0.8 # used to generate color for disabled button - - elif theme_name.lower() == "dark-blue": - cls.WINDOW_BG_COLOR = ("#F1F1F1", "#192026") # macOS standard light and dark window bg colors - cls.MAIN_COLOR = ("#608BD5", "#395E9C") - cls.MAIN_HOVER_COLOR = ("#A4BDE6", "#748BB3") - cls.ENTRY_COLOR = ("#FCFCFC", "#111116") - cls.TEXT_COLOR = ("gray18", "gray75") - cls.PLACEHOLDER_TEXT_COLOR = ("gray52", "gray60") - cls.LABEL_BG_COLOR = ("white", "#444444") - cls.SLIDER_BG_COLOR = ("#444444", "#444444") - cls.SLIDER_PROGRESS_COLOR = ("white", "#AAAAAA") - cls.PROGRESS_BG_COLOR = ("#636363", "#0D1321") - cls.FRAME_COLOR = ("#DADADA", "#2B2C2E") - cls.FRAME_2_COLOR = ("#C4C4C4", "#383838") - cls.CHECKBOX_LINES_COLOR = ("#313131", "white") - cls.DARKEN_COLOR_FACTOR = 0.8 # used to generate color for disabled button - @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 @@ -124,18 +63,25 @@ class CTkThemeManager: return cls.rgb2hex(new_rgb) @classmethod - def darken_hex_color(cls, hex_color: str, darken_factor: float = None) -> str: - if darken_factor is None: - darken_factor = cls.DARKEN_COLOR_FACTOR + def disabled_color(cls, hex_color: str): + if appearance_mode == 0: # Light mode + return cls.theme["color"]["text_disabled"] + else: + return cls.multiply_hex_color(hex_color, 0.8) + + @classmethod + def multiply_hex_color(cls, hex_color: str, factor: float = None) -> str: + if factor is None: + factor = cls.theme["color"]["darken_factor"] try: rgb_color = CTkThemeManager.hex2rgb(hex_color) - dark_rgb_color = (rgb_color[0] * darken_factor, - rgb_color[1] * darken_factor, - rgb_color[2] * darken_factor) + dark_rgb_color = (min(255, rgb_color[0] * factor), + min(255, rgb_color[1] * factor), + min(255, rgb_color[2] * factor)) return CTkThemeManager.rgb2hex(dark_rgb_color) except Exception as err: - sys.stderr.write("ERROR (CTkColorManager): failed to darken the following color: " + str(hex_color) + " " + str(err)) + # sys.stderr.write("ERROR (CTkColorManager): failed to darken the following color: " + str(hex_color) + " " + str(err)) return hex_color @classmethod diff --git a/examples/complex_example.py b/examples/complex_example.py index 38129f8..e122c15 100644 --- a/examples/complex_example.py +++ b/examples/complex_example.py @@ -185,6 +185,9 @@ class App(customtkinter.CTk): self.slider_1.set(0.2) self.slider_2.set(0.7) self.progressbar.set(0.5) + self.slider_button_1.configure(state=tkinter.DISABLED, text="Disabled Button") + self.radio_button_3.configure(state=tkinter.DISABLED) + self.check_box_1.configure(state=tkinter.DISABLED, text="CheckBox disabled") self.check_box_2.select() def button_event(self):