fixed state in multiple widgets

This commit is contained in:
TomSchimansky
2022-03-10 02:12:30 +01:00
parent a5e2f2d39a
commit 15ecf18449
9 changed files with 108 additions and 174 deletions

View File

@@ -1,6 +1,6 @@
{ {
"color": { "color": {
"window_bg_color": ["gray92", "gray12"], "window_bg_color": ["gray95", "gray12"],
"button": ["#1FA6E8", "#1C94CF"], "button": ["#1FA6E8", "#1C94CF"],
"button_hover": ["#1A89BF", "#1673A1"], "button_hover": ["#1A89BF", "#1673A1"],
"button_border": ["gray40", "gray70"], "button_border": ["gray40", "gray70"],
@@ -10,10 +10,12 @@
"entry_border": ["gray70", "gray32"], "entry_border": ["gray70", "gray32"],
"entry_placeholder_text": ["gray52", "gray62"], "entry_placeholder_text": ["gray52", "gray62"],
"frame_border": ["#A7C2E0", "#5FB4DD"], "frame_border": ["#A7C2E0", "#5FB4DD"],
"frame_low": ["gray87", "gray18"], "frame_low": ["gray89", "gray18"],
"frame_high": ["gray82", "gray22"], "frame_high": ["gray84", "gray22"],
"label": [null, null], "label": [null, null],
"text": ["gray20", "gray90"], "text": ["gray20", "gray90"],
"text_disabled": ["gray60", "gray50"],
"text_button_disabled": ["gray40", "gray74"],
"progressbar": ["#6B6B6B", "gray0"], "progressbar": ["#6B6B6B", "gray0"],
"progressbar_progress": ["#3599D6", "#1C94CF"], "progressbar_progress": ["#3599D6", "#1C94CF"],
"progressbar_border": ["gray", "gray"], "progressbar_border": ["gray", "gray"],
@@ -24,8 +26,7 @@
"switch": ["gray70", "gray35"], "switch": ["gray70", "gray35"],
"switch_progress": ["#1FA6E8", "#1C94CF"], "switch_progress": ["#1FA6E8", "#1C94CF"],
"switch_button": ["gray36", "gray75"], "switch_button": ["gray36", "gray75"],
"switch_button_hover": ["gray30", "gray90"], "switch_button_hover": ["gray30", "gray90"]
"darken_factor": 0.8
}, },
"text": { "text": {

View File

@@ -14,6 +14,8 @@
"frame_high": ["gray86", "gray20"], "frame_high": ["gray86", "gray20"],
"label": [null, null], "label": [null, null],
"text": ["gray12", "gray90"], "text": ["gray12", "gray90"],
"text_disabled": ["gray60", "gray50"],
"text_button_disabled": ["gray40", "gray74"],
"progressbar": ["#6B6B6B", "gray6"], "progressbar": ["#6B6B6B", "gray6"],
"progressbar_progress": ["#608BD5", "#395E9C"], "progressbar_progress": ["#608BD5", "#395E9C"],
"progressbar_border": ["gray", "gray"], "progressbar_border": ["gray", "gray"],

View File

@@ -15,6 +15,8 @@
"frame_high": ["gray82", "gray22"], "frame_high": ["gray82", "gray22"],
"label": [null, null], "label": [null, null],
"text": ["gray20", "gray90"], "text": ["gray20", "gray90"],
"text_disabled": ["gray60", "gray50"],
"text_button_disabled": ["gray40", "gray74"],
"progressbar": ["#6B6B6B", "#222222"], "progressbar": ["#6B6B6B", "#222222"],
"progressbar_progress": ["#72CF9F", "#11B384"], "progressbar_progress": ["#72CF9F", "#11B384"],
"progressbar_border": ["gray", "gray"], "progressbar_border": ["gray", "gray"],

View File

@@ -26,6 +26,7 @@ class CTkButton(tkinter.Frame):
corner_radius="default_theme", corner_radius="default_theme",
text_font="default_theme", text_font="default_theme",
text_color="default_theme", text_color="default_theme",
text_color_disabled="default_theme",
text="CTkButton", text="CTkButton",
hover=True, hover=True,
image=None, image=None,
@@ -89,6 +90,7 @@ class CTkButton(tkinter.Frame):
self.text = text self.text = text
self.text_label = None self.text_label = None
self.text_color = CTkThemeManager.theme["color"]["text"] if text_color == "default_theme" else text_color 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 self.text_font = (CTkThemeManager.theme["text"]["font"], CTkThemeManager.theme["text"]["size"]) if text_font == "default_theme" else text_font
# callback and hover functionality # callback and hover functionality
@@ -99,11 +101,6 @@ class CTkButton(tkinter.Frame):
self.compound = compound self.compound = compound
self.click_animation_running = False 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, self.canvas = CTkCanvas(master=self,
highlightthickness=0, highlightthickness=0,
width=self.width, width=self.width,
@@ -113,16 +110,15 @@ class CTkButton(tkinter.Frame):
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method) self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
# event bindings # event bindings
if self.hover is True:
self.canvas.bind("<Enter>", self.on_enter) self.canvas.bind("<Enter>", self.on_enter)
self.canvas.bind("<Leave>", self.on_leave) self.canvas.bind("<Leave>", self.on_leave)
self.canvas.bind("<Button-1>", self.clicked) self.canvas.bind("<Button-1>", self.clicked)
self.canvas.bind("<Button-1>", self.clicked) self.canvas.bind("<Button-1>", self.clicked)
# Each time an item is resized due to pack position mode, the binding Configure is called on the widget # Each time an item is resized due to pack position mode, the binding Configure is called on the widget
self.bind('<Configure>', self.update_dimensions) self.bind('<Configure>', self.update_dimensions)
self.set_cursor()
self.draw() # initial draw self.draw() # initial draw
def destroy(self): def destroy(self):
@@ -163,18 +159,7 @@ class CTkButton(tkinter.Frame):
outline=CTkThemeManager.single_color(self.border_color, self.appearance_mode), outline=CTkThemeManager.single_color(self.border_color, self.appearance_mode),
fill=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) # set color for inner button parts
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)))
else:
if self.fg_color is None: if self.fg_color is None:
self.canvas.itemconfig("inner_parts", self.canvas.itemconfig("inner_parts",
outline=CTkThemeManager.single_color(self.bg_color, self.appearance_mode), outline=CTkThemeManager.single_color(self.bg_color, self.appearance_mode),
@@ -199,13 +184,11 @@ class CTkButton(tkinter.Frame):
# set text_label fg color (text color) # set text_label fg color (text color)
self.text_label.configure(fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode)) 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.state == tkinter.DISABLED:
if self.fg_color is None: self.text_label.configure(fg=(CTkThemeManager.single_color(self.text_color_disabled, self.appearance_mode)))
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)))
else: else:
self.text_label.configure(fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode))
if self.fg_color is None: if self.fg_color is None:
self.text_label.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode)) self.text_label.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
else: else:
@@ -233,7 +216,7 @@ class CTkButton(tkinter.Frame):
if no_color_updates is False: if no_color_updates is False:
# set image_label bg color (background color of label) # set image_label bg color (background color of label)
if self.state == tkinter.DISABLED: 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: else:
self.image_label.configure(bg=CTkThemeManager.single_color(self.fg_color, self.appearance_mode)) 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"] del kwargs["text"]
if "state" in kwargs: if "state" in kwargs:
self.set_state(kwargs["state"]) self.state = kwargs["state"]
self.set_cursor()
require_redraw = True
del kwargs["state"] del kwargs["state"]
if "image" in kwargs: if "image" in kwargs:
@@ -334,25 +319,19 @@ class CTkButton(tkinter.Frame):
if require_redraw: if require_redraw:
self.draw() self.draw()
def set_state(self, state): def set_cursor(self):
self.state = state
if self.state == tkinter.DISABLED: if self.state == tkinter.DISABLED:
self.hover = False
if sys.platform == "darwin" and self.function is not None and CTkSettings.hand_cursor_enabled: if sys.platform == "darwin" and self.function is not None and CTkSettings.hand_cursor_enabled:
self.configure(cursor="arrow") self.configure(cursor="arrow")
elif sys.platform.startswith("win") and self.function is not None and CTkSettings.hand_cursor_enabled: elif sys.platform.startswith("win") and self.function is not None and CTkSettings.hand_cursor_enabled:
self.configure(cursor="arrow") self.configure(cursor="arrow")
elif self.state == tkinter.NORMAL: elif self.state == tkinter.NORMAL:
self.hover = True
if sys.platform == "darwin" and self.function is not None and CTkSettings.hand_cursor_enabled: if sys.platform == "darwin" and self.function is not None and CTkSettings.hand_cursor_enabled:
self.configure(cursor="pointinghand") self.configure(cursor="pointinghand")
elif sys.platform.startswith("win") and self.function is not None and CTkSettings.hand_cursor_enabled: elif sys.platform.startswith("win") and self.function is not None and CTkSettings.hand_cursor_enabled:
self.configure(cursor="hand2") self.configure(cursor="hand2")
self.draw()
def set_text(self, text): def set_text(self, text):
self.text = text self.text = text
self.draw() self.draw()
@@ -362,7 +341,7 @@ class CTkButton(tkinter.Frame):
self.draw() self.draw()
def on_enter(self, event=0): 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: if self.hover_color is None:
inner_parts_color = self.fg_color inner_parts_color = self.fg_color
else: else:

View File

@@ -26,6 +26,7 @@ class CTkCheckBox(tkinter.Frame):
text_font="default_theme", text_font="default_theme",
text_color="default_theme", text_color="default_theme",
text="CTkCheckBox", text="CTkCheckBox",
text_color_disabled="default_theme",
hover=True, hover=True,
command=None, command=None,
state=tkinter.NORMAL, 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.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.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.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 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 = text
self.text_color = CTkThemeManager.theme["color"]["text"] if text_color == "default_theme" else text_color 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.text_font = (CTkThemeManager.theme["text"]["font"], CTkThemeManager.theme["text"]["size"]) if text_font == "default_theme" else text_font
self.function = command self.function = command
@@ -109,11 +111,6 @@ class CTkCheckBox(tkinter.Frame):
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method) 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: if self.hover is True:
self.canvas.bind("<Enter>", self.on_enter) self.canvas.bind("<Enter>", self.on_enter)
self.canvas.bind("<Leave>", self.on_leave) self.canvas.bind("<Leave>", self.on_leave)
@@ -123,6 +120,7 @@ class CTkCheckBox(tkinter.Frame):
self.text_label = None self.text_label = None
self.set_cursor()
self.draw() # initial draw self.draw() # initial draw
if self.variable is not None: if self.variable is not None:
@@ -186,6 +184,9 @@ class CTkCheckBox(tkinter.Frame):
self.text_label.grid(row=0, column=2, padx=0, pady=0, sticky="w") self.text_label.grid(row=0, column=2, padx=0, pady=0, sticky="w")
self.text_label["anchor"] = "w" self.text_label["anchor"] = "w"
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(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.text_label.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
@@ -202,7 +203,9 @@ class CTkCheckBox(tkinter.Frame):
del kwargs["text"] del kwargs["text"]
if "state" in kwargs: if "state" in kwargs:
self.set_state(kwargs["state"]) self.state = kwargs["state"]
self.set_cursor()
require_redraw = True
del kwargs["state"] del kwargs["state"]
if "fg_color" in kwargs: if "fg_color" in kwargs:
@@ -259,25 +262,19 @@ class CTkCheckBox(tkinter.Frame):
if require_redraw: if require_redraw:
self.draw() self.draw()
def set_state(self, state): def set_cursor(self):
self.state = state
if self.state == tkinter.DISABLED: if self.state == tkinter.DISABLED:
self.hover = False
if sys.platform == "darwin" and CTkSettings.hand_cursor_enabled: if sys.platform == "darwin" and CTkSettings.hand_cursor_enabled:
self.canvas.configure(cursor="arrow") 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") self.canvas.configure(cursor="arrow")
elif self.state == tkinter.NORMAL: elif self.state == tkinter.NORMAL:
self.hover = True
if sys.platform == "darwin" and CTkSettings.hand_cursor_enabled: if sys.platform == "darwin" and CTkSettings.hand_cursor_enabled:
self.canvas.configure(cursor="pointinghand") 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.canvas.configure(cursor="hand2")
self.draw()
def set_text(self, text): def set_text(self, text):
self.text = text self.text = text
if self.text_label is not None: if self.text_label is not None:
@@ -286,7 +283,15 @@ class CTkCheckBox(tkinter.Frame):
sys.stderr.write("ERROR (CTkButton): Cant change text because checkbox has no text.") sys.stderr.write("ERROR (CTkButton): Cant change text because checkbox has no text.")
def on_enter(self, event=0): def on_enter(self, event=0):
if self.hover is True: 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", self.canvas.itemconfig("inner_parts",
fill=CTkThemeManager.single_color(self.hover_color, self.appearance_mode), fill=CTkThemeManager.single_color(self.hover_color, self.appearance_mode),
outline=CTkThemeManager.single_color(self.hover_color, self.appearance_mode)) outline=CTkThemeManager.single_color(self.hover_color, self.appearance_mode))
@@ -297,10 +302,16 @@ class CTkCheckBox(tkinter.Frame):
self.canvas.itemconfig("inner_parts", self.canvas.itemconfig("inner_parts",
fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode), fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode),
outline=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: else:
self.canvas.itemconfig("inner_parts", self.canvas.itemconfig("inner_parts",
fill=CTkThemeManager.single_color(self.bg_color, self.appearance_mode), fill=CTkThemeManager.single_color(self.bg_color, self.appearance_mode),
outline=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): def variable_callback(self, var_name, index, mode):
if not self.variable_callback_blocked: if not self.variable_callback_blocked:

View File

@@ -24,6 +24,7 @@ class CTkRadioButton(tkinter.Frame):
text_font="default_theme", text_font="default_theme",
text_color="default_theme", text_color="default_theme",
text="CTkRadioButton", text="CTkRadioButton",
text_color_disabled="default_theme",
hover=True, hover=True,
command=None, command=None,
state=tkinter.NORMAL, state=tkinter.NORMAL,
@@ -81,6 +82,7 @@ class CTkRadioButton(tkinter.Frame):
self.text = text self.text = text
self.text_color = CTkThemeManager.theme["color"]["text"] if text_color == "default_theme" else text_color 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.text_font = (CTkThemeManager.theme["text"]["font"], CTkThemeManager.theme["text"]["size"]) if text_font == "default_theme" else text_font
self.function = command self.function = command
@@ -106,20 +108,14 @@ class CTkRadioButton(tkinter.Frame):
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method) 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("<Enter>", self.on_enter) self.canvas.bind("<Enter>", self.on_enter)
self.canvas.bind("<Leave>", self.on_leave) self.canvas.bind("<Leave>", self.on_leave)
self.canvas.bind("<Button-1>", self.invoke) self.canvas.bind("<Button-1>", self.invoke)
self.canvas.bind("<Button-1>", self.invoke) self.canvas.bind("<Button-1>", self.invoke)
self.text_label = None self.text_label = None
self.set_cursor()
self.draw() # initial draw self.draw() # initial draw
if self.variable is not None: 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.grid(row=0, column=2, padx=0, pady=0, sticky="w")
self.text_label["anchor"] = "w" self.text_label["anchor"] = "w"
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(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.text_label.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
self.set_text(self.text) self.set_text(self.text)
@@ -187,7 +187,9 @@ class CTkRadioButton(tkinter.Frame):
del kwargs["text"] del kwargs["text"]
if "state" in kwargs: if "state" in kwargs:
self.set_state(kwargs["state"]) self.state = kwargs["state"]
self.set_cursor()
require_redraw = True
del kwargs["state"] del kwargs["state"]
if "fg_color" in kwargs: if "fg_color" in kwargs:
@@ -249,25 +251,19 @@ class CTkRadioButton(tkinter.Frame):
if require_redraw: if require_redraw:
self.draw() self.draw()
def set_state(self, state): def set_cursor(self):
self.state = state
if self.state == tkinter.DISABLED: if self.state == tkinter.DISABLED:
self.hover = False
if sys.platform == "darwin" and CTkSettings.hand_cursor_enabled: if sys.platform == "darwin" and CTkSettings.hand_cursor_enabled:
self.canvas.configure(cursor="arrow") 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") self.canvas.configure(cursor="arrow")
elif self.state == tkinter.NORMAL: elif self.state == tkinter.NORMAL:
self.hover = True
if sys.platform == "darwin" and CTkSettings.hand_cursor_enabled: if sys.platform == "darwin" and CTkSettings.hand_cursor_enabled:
self.canvas.configure(cursor="pointinghand") 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.canvas.configure(cursor="hand2")
self.draw()
def set_text(self, text): def set_text(self, text):
self.text = text self.text = text
if self.text_label is not None: 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.") sys.stderr.write("ERROR (CTkButton): Cant change text because radiobutton has no text.")
def on_enter(self, event=0): 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", self.canvas.itemconfig("border_parts",
fill=CTkThemeManager.single_color(self.hover_color, self.appearance_mode), fill=CTkThemeManager.single_color(self.hover_color, self.appearance_mode),
outline=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): def select(self, from_variable_callback=False):
self.check_state = True 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.border_width = self.border_width_checked
self.draw() self.draw()
@@ -323,9 +316,6 @@ class CTkRadioButton(tkinter.Frame):
def deselect(self, from_variable_callback=False): def deselect(self, from_variable_callback=False):
self.check_state = 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.border_width = self.border_width_unchecked
self.draw() self.draw()

View File

@@ -24,7 +24,7 @@ class CTkSwitch(tkinter.Frame):
width=36, width=36,
height=18, height=18,
corner_radius="default_theme", corner_radius="default_theme",
button_corner_radius="default_theme", # button_corner_radius="default_theme",
border_width="default_theme", border_width="default_theme",
button_length="default_theme", button_length="default_theme",
command=None, command=None,
@@ -72,7 +72,7 @@ class CTkSwitch(tkinter.Frame):
self.width = width self.width = width
self.height = height self.height = height
self.corner_radius = CTkThemeManager.theme["shape"]["switch_corner_radius"] if corner_radius == "default_theme" else corner_radius 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.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.button_length = CTkThemeManager.theme["shape"]["switch_button_length"] if button_length == "default_theme" else button_length
self.hover_state = False self.hover_state = False
@@ -80,8 +80,8 @@ class CTkSwitch(tkinter.Frame):
self.onvalue = onvalue self.onvalue = onvalue
self.offvalue = offvalue self.offvalue = offvalue
if self.corner_radius < self.button_corner_radius: #if self.corner_radius < self.button_corner_radius:
self.corner_radius = self.button_corner_radius # self.corner_radius = self.button_corner_radius
self.callback_function = command self.callback_function = command
self.variable: tkinter.Variable = variable self.variable: tkinter.Variable = variable
@@ -142,10 +142,10 @@ class CTkSwitch(tkinter.Frame):
if self.check_state is True: 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, 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: else:
requires_recoloring = self.draw_engine.draw_rounded_slider_with_border_and_button(self.width, self.height, self.corner_radius, self.border_width, 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: if color_updates or requires_recoloring:
self.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode)) self.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))

View File

@@ -26,67 +26,6 @@ class CTkThemeManager:
else: else:
cls.theme["text"] = cls.theme["text"]["Linux"] 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 @staticmethod
def single_color(color, appearance_mode: int) -> str: 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 """ 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) return cls.rgb2hex(new_rgb)
@classmethod @classmethod
def darken_hex_color(cls, hex_color: str, darken_factor: float = None) -> str: def disabled_color(cls, hex_color: str):
if darken_factor is None: if appearance_mode == 0: # Light mode
darken_factor = cls.DARKEN_COLOR_FACTOR 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: try:
rgb_color = CTkThemeManager.hex2rgb(hex_color) rgb_color = CTkThemeManager.hex2rgb(hex_color)
dark_rgb_color = (rgb_color[0] * darken_factor, dark_rgb_color = (min(255, rgb_color[0] * factor),
rgb_color[1] * darken_factor, min(255, rgb_color[1] * factor),
rgb_color[2] * darken_factor) min(255, rgb_color[2] * factor))
return CTkThemeManager.rgb2hex(dark_rgb_color) return CTkThemeManager.rgb2hex(dark_rgb_color)
except Exception as err: 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 return hex_color
@classmethod @classmethod

View File

@@ -185,6 +185,9 @@ class App(customtkinter.CTk):
self.slider_1.set(0.2) self.slider_1.set(0.2)
self.slider_2.set(0.7) self.slider_2.set(0.7)
self.progressbar.set(0.5) 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() self.check_box_2.select()
def button_event(self): def button_event(self):