From 9996e51c1aee03e67626fdbfd754ea02ecb227ee Mon Sep 17 00:00:00 2001 From: TomSchimansky Date: Tue, 22 Feb 2022 22:38:40 +0100 Subject: [PATCH] add font rendering to button, finished --- Readme.md | 13 ++ customtkinter/__init__.py | 4 +- customtkinter/appearance_mode_tracker.py | 27 ++-- .../CustomTkinter_shapes_font-Regular.otf | Bin 0 -> 2104 bytes customtkinter/customtkinter_button.py | 124 +++++++++-------- customtkinter/customtkinter_canvas.py | 20 +-- customtkinter/customtkinter_checkbox.py | 18 +-- customtkinter/customtkinter_color_manager.py | 129 ------------------ customtkinter/customtkinter_dialog.py | 10 +- customtkinter/customtkinter_entry.py | 18 +-- customtkinter/customtkinter_frame.py | 14 +- customtkinter/customtkinter_label.py | 10 +- customtkinter/customtkinter_progressbar.py | 22 +-- customtkinter/customtkinter_settings.py | 6 + customtkinter/customtkinter_slider.py | 36 ++--- customtkinter/customtkinter_theme_manager.py | 129 ++++++++++++++++++ customtkinter/customtkinter_tk.py | 21 +-- customtkinter/customtkinter_toplevel.py | 21 +-- examples/complex_example_custom_colors.py | 14 +- examples/simple_example.py | 2 +- test/complete_test.py | 2 +- test/simple_example_standard_tkinter.py | 14 +- 22 files changed, 348 insertions(+), 306 deletions(-) create mode 100644 customtkinter/assets/CustomTkinter_shapes_font-Regular.otf delete mode 100644 customtkinter/customtkinter_color_manager.py create mode 100644 customtkinter/customtkinter_settings.py create mode 100644 customtkinter/customtkinter_theme_manager.py diff --git a/Readme.md b/Readme.md index 76e4ed0..1b57ef9 100644 --- a/Readme.md +++ b/Readme.md @@ -195,6 +195,18 @@ root_tk.configure(bg_color=(, )) ``` +### CTkToplevel + +CTkToplevel works exactly like the `Tkinter.Toplevel`, and should be used to create more than one window. + +
+Show all arguments and methods: + +argument | value +--- | --- +bg_color or bg | tuple: (light_color, dark_color) or single color +
+ ### CTkFrame Example Code: ```python @@ -376,6 +388,7 @@ text_color | text color, tuple: (light_color, dark_color) or single color text_font | button text font, tuple: (font_name, size) hover | enable/disable hover effect: True, False state | tkinter.NORMAL (standard) or tkinter.DISABLED (not clickable, darker color) +command | function will be called when the checkbox is clicked CTkCheckBox Methods: ```python diff --git a/customtkinter/__init__.py b/customtkinter/__init__.py index 2150877..f1724d2 100644 --- a/customtkinter/__init__.py +++ b/customtkinter/__init__.py @@ -13,7 +13,7 @@ from .customtkinter_canvas import CTkCanvas from .customtkinter_toplevel import CTkToplevel from .appearance_mode_tracker import AppearanceModeTracker -from .customtkinter_color_manager import CTkColorManager +from .customtkinter_theme_manager import CTkThemeManager from distutils.version import StrictVersion as Version import tkinter @@ -58,7 +58,7 @@ def get_appearance_mode(): def set_default_color_theme(color_string): - CTkColorManager.initialize_color_theme(color_string) + CTkThemeManager.initialize_color_theme(color_string) def load_font_windows(fontpath: str, private=True, enumerable=False): diff --git a/customtkinter/appearance_mode_tracker.py b/customtkinter/appearance_mode_tracker.py index 2f718dd..fc4987d 100644 --- a/customtkinter/appearance_mode_tracker.py +++ b/customtkinter/appearance_mode_tracker.py @@ -1,4 +1,3 @@ -import time import sys import tkinter from distutils.version import StrictVersion as Version @@ -28,15 +27,6 @@ class AppearanceModeTracker: cls.appearance_mode = new_appearance_mode cls.update_callbacks() - @classmethod - def get_tk_root_of_widget(cls, widget): - current_widget = widget - - while isinstance(current_widget, tkinter.Tk) is False: - current_widget = current_widget.master - - return current_widget - @classmethod def add(cls, callback, widget=None): cls.callback_list.append(callback) @@ -50,6 +40,10 @@ class AppearanceModeTracker: root_tk.after(500, cls.update) cls.update_loop_running = True + @classmethod + def remove(cls, callback): + cls.callback_list.remove(callback) + @staticmethod def detect_appearance_mode(): try: @@ -60,6 +54,15 @@ class AppearanceModeTracker: except NameError: return 0 # Light + @classmethod + def get_tk_root_of_widget(cls, widget): + current_widget = widget + + while isinstance(current_widget, tkinter.Tk) is False: + current_widget = current_widget.master + + return current_widget + @classmethod def update_callbacks(cls): if cls.appearance_mode == 0: @@ -95,10 +98,6 @@ class AppearanceModeTracker: cls.update_loop_running = False - @classmethod - def remove(cls, callback): - cls.callback_list.remove(callback) - @classmethod def get_mode(cls): return cls.appearance_mode diff --git a/customtkinter/assets/CustomTkinter_shapes_font-Regular.otf b/customtkinter/assets/CustomTkinter_shapes_font-Regular.otf new file mode 100644 index 0000000000000000000000000000000000000000..d84e543fa916405874c0b8ee40655e9598215735 GIT binary patch literal 2104 zcmbVNO-x)>6h8O885jzkg2@<-*3uD;CXGKBZ9-Z@3#DL-AZ4M62+#7Efnk^lGng(& z)VR=ks#a}E7lmXX${48;HYP%h#*I5SBrck?Y1}k%p)r~})6*8e_cQIY4QjoUd+&F? zd%kndJMYd+Pk(<8)zBMcQhi%TN8{SFkIfNNTU5 zD0B+;bkeqlcjQ}t13ruSOcI3gjqwBUI%ZQcoj>;Q-9Qwn!?G)F9m`T}uS1kDt0t_p zeR1ze3-O1D%%`%MTpo2`gzK?1x@nQRv;U>o;I=(~l4)LcPA{~)-gS92Z<%TN#cSkb)|Z`55)hkV|oCiSR~L$s5Id>jsFs}T8n zpRW$^kpQj<;4J}M8^Cn|yfuKM0bC!bv%#&?Bo(Sb?IHCLdhTFF&G7QDK~d`Su}Ph( z+s7f=PjC7-9MD#whd=v#b%2iqa7_Sj3Ee|jXp|;k*)&Om;FDxg7FG_{2z+qXXD6n{tw}t) zO$ms{;WD{t{Kks=9p}NT|8FV&e}=!skH-n0c)aD`pT+TPx%1B5`b5r`MmaYEJKic9 zO>_^{gNXn&(mvdzHfpB>)IkTSle#uGz;Al8acSebTR(1WS9IIr{{Gy?-XIjN6Dg&3 zZrYAY-{JH~={_pmZ?Sa&JtEEP2VZ6eE}#P!~CZsq=b@^nvR$(uw*2|vH;Dz&PY}-K(oL)qqD5%p_vDlm3dEd zybR43EVkGz=b%~ABQm1TL9@i#)(O_1L$f5q;K6!%_QYhC1qHFpLNkjRQhE-WS=K0s z^&B*_GLD+hR`NhoWU*w(>%pRaRV=*-&8Ms_ZFxOdlp$>iSSQc%a&t`1up}hGGJ`xb zdQ=knG&HAKC-eyGGsrW8dJ{5JsSTO}%YY296rd?+KwW^Qz 0: @@ -457,10 +460,16 @@ class CTkButton(tkinter.Frame): self.canvas.create_aa_circle(0, 0, 0, tags=("border_oval_1_b", "border_corner_part", "border_parts"), anchor=tkinter.CENTER, angle=180) self.canvas.create_aa_circle(0, 0, 0, tags=("border_oval_2_a", "border_corner_part", "border_parts"), anchor=tkinter.CENTER) self.canvas.create_aa_circle(0, 0, 0, tags=("border_oval_2_b", "border_corner_part", "border_parts"), anchor=tkinter.CENTER, angle=180) + + if not self.canvas.find_withtag("border_oval_3_a") and round(self.corner_radius) * 2 < self.height: self.canvas.create_aa_circle(0, 0, 0, tags=("border_oval_3_a", "border_corner_part", "border_parts"), anchor=tkinter.CENTER) self.canvas.create_aa_circle(0, 0, 0, tags=("border_oval_3_b", "border_corner_part", "border_parts"), anchor=tkinter.CENTER, angle=180) self.canvas.create_aa_circle(0, 0, 0, tags=("border_oval_4_a", "border_corner_part", "border_parts"), anchor=tkinter.CENTER) self.canvas.create_aa_circle(0, 0, 0, tags=("border_oval_4_b", "border_corner_part", "border_parts"), anchor=tkinter.CENTER, angle=180) + draw_color_update = True + self.canvas.tag_lower("border_parts") + elif self.canvas.find_withtag("border_oval_3_a") and not round(self.corner_radius) * 2 < self.height: + self.canvas.delete(["border_oval_3_a", "border_oval_3_b", "border_oval_4_a", "border_oval_4_b"]) # change position of border corner parts self.canvas.coords("border_oval_1_a", self.corner_radius, self.corner_radius, self.corner_radius) @@ -481,30 +490,29 @@ class CTkButton(tkinter.Frame): self.canvas.create_rectangle(0, 0, 0, 0, tags=("border_rectangle_2", "border_rectangle_part", "border_parts")) # change position of border rectangle parts - self.canvas.coords("border_rectangle_1", (0, - self.corner_radius, - self.width -1, - self.height - self.corner_radius -1)) - self.canvas.coords("border_rectangle_2", (self.corner_radius, - 0, - self.width - self.corner_radius -1, - self.height -1)) + self.canvas.coords("border_rectangle_1", (0, self.corner_radius, self.width -1, self.height - self.corner_radius -1)) + self.canvas.coords("border_rectangle_2", (self.corner_radius, 0, self.width - self.corner_radius -1, self.height -1)) # create inner button parts if self.inner_corner_radius > 0: # create canvas border corner parts if not already created - if not self.canvas.find_withtag("inner_corner_part"): + if not self.canvas.find_withtag("inner_oval_1_a"): self.canvas.create_aa_circle(0, 0, 0, tags=("inner_oval_1_a", "inner_corner_part", "inner_parts"), anchor=tkinter.CENTER) self.canvas.create_aa_circle(0, 0, 0, tags=("inner_oval_1_b", "inner_corner_part", "inner_parts"), anchor=tkinter.CENTER, angle=180) self.canvas.create_aa_circle(0, 0, 0, tags=("inner_oval_2_a", "inner_corner_part", "inner_parts"), anchor=tkinter.CENTER) self.canvas.create_aa_circle(0, 0, 0, tags=("inner_oval_2_b", "inner_corner_part", "inner_parts"), anchor=tkinter.CENTER, angle=180) + + if not self.canvas.find_withtag("inner_oval_3_a") and round(self.inner_corner_radius) * 2 < self.height - (2 * self.border_width): self.canvas.create_aa_circle(0, 0, 0, tags=("inner_oval_3_a", "inner_corner_part", "inner_parts"), anchor=tkinter.CENTER) self.canvas.create_aa_circle(0, 0, 0, tags=("inner_oval_3_b", "inner_corner_part", "inner_parts"), anchor=tkinter.CENTER, angle=180) self.canvas.create_aa_circle(0, 0, 0, tags=("inner_oval_4_a", "inner_corner_part", "inner_parts"), anchor=tkinter.CENTER) self.canvas.create_aa_circle(0, 0, 0, tags=("inner_oval_4_b", "inner_corner_part", "inner_parts"), anchor=tkinter.CENTER, angle=180) + self.canvas.tag_raise("inner_parts") + draw_color_update = True + elif self.canvas.find_withtag("inner_oval_3_a") and not round(self.inner_corner_radius) * 2 < self.height - (2 * self.border_width): + self.canvas.delete(["inner_oval_3_a", "inner_oval_3_b", "inner_oval_4_a", "inner_oval_4_b"]) - #print(self.corner_radius, self.border_width, self.inner_corner_radius) # change position of border corner parts self.canvas.coords("inner_oval_1_a", self.border_width + self.inner_corner_radius, self.border_width + self.inner_corner_radius, self.inner_corner_radius) self.canvas.coords("inner_oval_1_b", self.border_width + self.inner_corner_radius, self.border_width + self.inner_corner_radius, self.inner_corner_radius) @@ -518,9 +526,15 @@ class CTkButton(tkinter.Frame): self.canvas.delete("inner_corner_part") # delete inner corner parts if not needed # create canvas inner rectangle parts if not already created - if not self.canvas.find_withtag("inner_rectangle_part"): + if not self.canvas.find_withtag("inner_rectangle_1"): self.canvas.create_rectangle(0, 0, 0, 0, tags=("inner_rectangle_1", "inner_rectangle_part", "inner_parts")) + + if not self.canvas.find_withtag("inner_rectangle_2") and self.inner_corner_radius * 2 < self.height - (self.border_width * 2): self.canvas.create_rectangle(0, 0, 0, 0, tags=("inner_rectangle_2", "inner_rectangle_part", "inner_parts")) + self.canvas.tag_raise("inner_parts") + draw_color_update = True + elif self.canvas.find_withtag("inner_rectangle_2") and not self.inner_corner_radius * 2 < self.height - (self.border_width * 2): + self.canvas.delete("inner_rectangle_2") # change position of inner rectangle parts self.canvas.coords("inner_rectangle_1", (self.border_width + self.inner_corner_radius, @@ -532,6 +546,8 @@ class CTkButton(tkinter.Frame): self.width - self.border_width -1, self.height - self.inner_corner_radius - self.border_width -1)) + return draw_color_update + def config(self, *args, **kwargs): self.configure(*args, **kwargs) @@ -630,16 +646,16 @@ class CTkButton(tkinter.Frame): # set color of inner button parts to hover color self.canvas.itemconfig("inner_parts", - outline=CTkColorManager.single_color(inner_parts_color, self.appearance_mode), - fill=CTkColorManager.single_color(inner_parts_color, self.appearance_mode)) + outline=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode), + fill=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode)) # set text_label bg color to button hover color if self.text_label is not None: - self.text_label.configure(bg=CTkColorManager.single_color(inner_parts_color, self.appearance_mode)) + self.text_label.configure(bg=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode)) # set image_label bg color to button hover color if self.image_label is not None: - self.image_label.configure(bg=CTkColorManager.single_color(inner_parts_color, self.appearance_mode)) + self.image_label.configure(bg=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode)) def on_leave(self, event=0): self.click_animation_running = False @@ -652,16 +668,16 @@ class CTkButton(tkinter.Frame): # set color of inner button parts self.canvas.itemconfig("inner_parts", - outline=CTkColorManager.single_color(inner_parts_color, self.appearance_mode), - fill=CTkColorManager.single_color(inner_parts_color, self.appearance_mode)) + outline=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode), + fill=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode)) # set text_label bg color (label color) if self.text_label is not None: - self.text_label.configure(bg=CTkColorManager.single_color(inner_parts_color, self.appearance_mode)) + self.text_label.configure(bg=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode)) # set image_label bg color (image bg color) if self.image_label is not None: - self.image_label.configure(bg=CTkColorManager.single_color(inner_parts_color, self.appearance_mode)) + self.image_label.configure(bg=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode)) def click_animation(self): if self.click_animation_running: diff --git a/customtkinter/customtkinter_canvas.py b/customtkinter/customtkinter_canvas.py index 3213be1..ae3e260 100644 --- a/customtkinter/customtkinter_canvas.py +++ b/customtkinter/customtkinter_canvas.py @@ -1,23 +1,23 @@ import tkinter +from .customtkinter_settings import CTkSettings class CTkCanvas(tkinter.Canvas): + + radius_to_char = {19: 'B', 18: 'B', 17: 'B', 16: 'B', 15: 'B', 14: 'B', 13: 'B', 12: 'B', 11: 'B', 10: 'B', + 9: 'C', 8: 'D', 7: 'C', 6: 'E', 5: 'F', 4: 'F', 3: 'H', 2: 'H', 1: 'H', 0: 'A'} + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.aa_circle_canvas_ids = [] def get_char_from_radius(self, radius): - if radius >= 10: - char = "B" - elif radius >= 6: - char = "D" - elif radius >= 3: - char = "H" - else: - char = "H" - - return char + if CTkSettings.scaling_factor == 1: + if radius >= 20: + return "A" + else: + return self.radius_to_char[radius] def create_aa_circle(self, x_pos, y_pos, radius, angle=0, fill="white", tags="", anchor=tkinter.CENTER) -> str: # create a circle with a font element diff --git a/customtkinter/customtkinter_checkbox.py b/customtkinter/customtkinter_checkbox.py index 029b48f..9b74e9c 100644 --- a/customtkinter/customtkinter_checkbox.py +++ b/customtkinter/customtkinter_checkbox.py @@ -4,7 +4,7 @@ import sys from .customtkinter_tk import CTk from .customtkinter_frame import CTkFrame from .appearance_mode_tracker import AppearanceModeTracker -from .customtkinter_color_manager import CTkColorManager +from .customtkinter_theme_manager import CTkThemeManager class CTkCheckBox(tkinter.Frame): @@ -12,15 +12,15 @@ class CTkCheckBox(tkinter.Frame): def __init__(self, *args, bg_color=None, - fg_color="CTkColorManager", - hover_color="CTkColorManager", - border_color="CTkColorManager", + fg_color="default_theme", + hover_color="default_theme", + border_color="default_theme", border_width=3, width=25, height=25, corner_radius=4, text_font=None, - text_color="CTkColorManager", + text_color="default_theme", text="CTkCheckBox", hover=True, command=None, @@ -57,9 +57,9 @@ class CTkCheckBox(tkinter.Frame): self.appearance_mode = AppearanceModeTracker.get_mode() # 0: "Light" 1: "Dark" self.bg_color = self.detect_color_of_master() if bg_color is None else bg_color - self.fg_color = CTkColorManager.MAIN if fg_color == "CTkColorManager" else fg_color - self.hover_color = CTkColorManager.MAIN_HOVER if hover_color == "CTkColorManager" else hover_color - self.border_color = CTkColorManager.CHECKBOX_LINES if border_color == "CTkColorManager" else border_color + self.fg_color = CTkThemeManager.MAIN_COLOR if fg_color == "default_theme" else fg_color + self.hover_color = CTkThemeManager.MAIN_HOVER_COLOR if hover_color == "default_theme" else hover_color + self.border_color = CTkThemeManager.CHECKBOX_LINES_COLOR if border_color == "default_theme" else border_color self.width = width self.height = height @@ -78,7 +78,7 @@ class CTkCheckBox(tkinter.Frame): self.inner_corner_radius = 0 self.text = text - self.text_color = CTkColorManager.TEXT if text_color == "CTkColorManager" else text_color + self.text_color = CTkThemeManager.TEXT_COLOR if text_color == "default_theme" else text_color if text_font is None: if sys.platform == "darwin": # macOS self.text_font = ("Avenir", 13) diff --git a/customtkinter/customtkinter_color_manager.py b/customtkinter/customtkinter_color_manager.py deleted file mode 100644 index c83ec7c..0000000 --- a/customtkinter/customtkinter_color_manager.py +++ /dev/null @@ -1,129 +0,0 @@ -import sys - - -class CTkColorManager: - - WINDOW_BG = None - MAIN = None - MAIN_HOVER = None - ENTRY = None - TEXT = None - PLACEHOLDER_TEXT = None - LABEL_BG = None - SLIDER_BG = None - SLIDER_PROGRESS = None - PROGRESS_BG = None - FRAME = None - FRAME_2 = None - CHECKBOX_LINES = None - DARKEN_COLOR_FACTOR = None - - @classmethod - def initialize_color_theme(cls, theme_name): - - if theme_name.lower() == "blue": - cls.WINDOW_BG = ("#ECECEC", "#323232") # macOS standard light and dark window bg colors - cls.MAIN = ("#64A1D2", "#1C94CF") - cls.MAIN_HOVER = ("#A7C2E0", "#5FB4DD") - cls.ENTRY = ("white", "#222222") - cls.TEXT = ("black", "white") - cls.PLACEHOLDER_TEXT = ("gray52", "gray62") - cls.LABEL_BG = ("white", "#626061") - cls.SLIDER_BG = ("#6B6B6B", "#222222") - cls.SLIDER_PROGRESS = ("#A5A6A5", "#555555") - cls.PROGRESS_BG = ("#6B6B6B", "#222222") - cls.FRAME = ("#D4D5D6", "#3F3F3F") - cls.FRAME_2 = ("#BFBEC1", "#505050") - cls.CHECKBOX_LINES = ("black", "#ededed") - cls.DARKEN_COLOR_FACTOR = 0.8 # used to generate color for disabled button - - elif theme_name.lower() == "green": - cls.WINDOW_BG = ("#ECECEC", "#323232") # macOS standard light and dark window bg colors - cls.MAIN = ("#13C995", "#1ABE87") - cls.MAIN_HOVER = ("#6ACBA5", "#81E4B2") - cls.ENTRY = ("gray60", "#222223") - cls.TEXT = ("gray25", "gray92") - cls.PLACEHOLDER_TEXT = ("gray32", "gray55") - cls.LABEL_BG = ("white", "#626061") - cls.SLIDER_BG = ("#636363", "#0D1321") - cls.SLIDER_PROGRESS = ("white", "#727578") - cls.PROGRESS_BG = ("#636363", "#0D1321") - cls.FRAME = ("#D4D5D6", "#3F3F3F") - cls.FRAME_2 = ("#BFBEC1", "#505050") - cls.CHECKBOX_LINES = ("#414141", "#EDEDED") - cls.DARKEN_COLOR_FACTOR = 0.8 # used to generate color for disabled button - - elif theme_name.lower() == "dark-blue": - cls.WINDOW_BG = ("#F1F1F1", "#192026") # macOS standard light and dark window bg colors - cls.MAIN = ("#608BD5", "#395E9C") - cls.MAIN_HOVER = ("#A4BDE6", "#748BB3") - cls.ENTRY = ("#FCFCFC", "#111116") - cls.TEXT = ("black", "white") - cls.PLACEHOLDER_TEXT = ("gray52", "gray62") - cls.LABEL_BG = ("white", "#444444") - cls.SLIDER_BG = ("#444444", "#444444") - cls.SLIDER_PROGRESS = ("white", "#AAAAAA") - cls.PROGRESS_BG = ("#636363", "#0D1321") - cls.FRAME = ("#DADADA", "#2B2C2E") - cls.FRAME_2 = ("#C4C4C4", "#383838") - cls.CHECKBOX_LINES = ("#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 - tuple color with (light_color, dark_color). The functions then returns - always a single color string """ - - if type(color) == tuple: - 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 darken_hex_color(cls, hex_color: str, darken_factor: float = None) -> str: - if darken_factor is None: - darken_factor = cls.DARKEN_COLOR_FACTOR - - try: - rgb_color = CTkColorManager.hex2rgb(hex_color) - dark_rgb_color = (rgb_color[0] * darken_factor, - rgb_color[1] * darken_factor, - rgb_color[2] * darken_factor) - return CTkColorManager.rgb2hex(dark_rgb_color) - except Exception as err: - sys.stderr.write("ERROR (CTkColorManager): failed to darken the following color: " + str(hex_color) + " " + str(err)) - return hex_color - - @classmethod - def set_main_color(cls, main_color, main_color_hover): - cls.MAIN = main_color - cls.MAIN_HOVER = main_color_hover - - -CTkColorManager.initialize_color_theme("blue") diff --git a/customtkinter/customtkinter_dialog.py b/customtkinter/customtkinter_dialog.py index 77a005b..617b58c 100644 --- a/customtkinter/customtkinter_dialog.py +++ b/customtkinter/customtkinter_dialog.py @@ -4,7 +4,7 @@ import time from customtkinter.customtkinter_label import CTkLabel from customtkinter.customtkinter_button import CTkButton from customtkinter.customtkinter_entry import CTkEntry -from customtkinter.customtkinter_color_manager import CTkColorManager +from customtkinter.customtkinter_theme_manager import CTkThemeManager class CTkDialog: @@ -12,8 +12,8 @@ class CTkDialog: master=None, title="CTkDialog", text="CTkDialog", - fg_color="CTkColorManager", - hover_color="CTkColorManager"): + fg_color="default_theme", + hover_color="default_theme"): self.master = master self.user_input = None @@ -21,8 +21,8 @@ class CTkDialog: self.height = len(text.split("\n"))*20 + 150 - self.fg_color = CTkColorManager.MAIN if fg_color == "CTkColorManager" else fg_color - self.hover_color = CTkColorManager.MAIN_HOVER if hover_color == "CTkColorManager" else hover_color + self.fg_color = CTkThemeManager.MAIN_COLOR if fg_color == "default_theme" else fg_color + self.hover_color = CTkThemeManager.MAIN_HOVER_COLOR if hover_color == "default_theme" else hover_color self.top = customtkinter.CTkToplevel() self.top.geometry(f"280x{self.height}") diff --git a/customtkinter/customtkinter_entry.py b/customtkinter/customtkinter_entry.py index 821c711..0800f16 100644 --- a/customtkinter/customtkinter_entry.py +++ b/customtkinter/customtkinter_entry.py @@ -4,16 +4,16 @@ import sys from .customtkinter_tk import CTk from .customtkinter_frame import CTkFrame from .appearance_mode_tracker import AppearanceModeTracker -from .customtkinter_color_manager import CTkColorManager +from .customtkinter_theme_manager import CTkThemeManager class CTkEntry(tkinter.Frame): def __init__(self, *args, master=None, bg_color=None, - fg_color="CTkColorManager", - text_color="CTkColorManager", - placeholder_text_color="CTkColorManager", + fg_color="default_theme", + text_color="default_theme", + placeholder_text_color="default_theme", text_font=None, placeholder_text=None, corner_radius=8, @@ -52,9 +52,9 @@ class CTkEntry(tkinter.Frame): self.configure_basic_grid() self.bg_color = self.detect_color_of_master() if bg_color is None else bg_color - self.fg_color = CTkColorManager.ENTRY if fg_color == "CTkColorManager" else fg_color - self.text_color = CTkColorManager.TEXT if text_color == "CTkColorManager" else text_color - self.placeholder_text_color = CTkColorManager.PLACEHOLDER_TEXT if placeholder_text_color == "CTkColorManager" else placeholder_text_color + self.fg_color = CTkThemeManager.ENTRY_COLOR if fg_color == "default_theme" else fg_color + self.text_color = CTkThemeManager.TEXT_COLOR if text_color == "default_theme" else text_color + self.placeholder_text_color = CTkThemeManager.PLACEHOLDER_TEXT_COLOR if placeholder_text_color == "default_theme" else placeholder_text_color if text_font is None: if sys.platform == "darwin": # macOS @@ -152,14 +152,14 @@ class CTkEntry(tkinter.Frame): if not self.placeholder_text_active and self.entry.get() == "": self.placeholder_text_active = True self.pre_placeholder_arguments = {"show": self.entry.cget("show")} - self.entry.config(fg=CTkColorManager.single_color(self.placeholder_text_color, self.appearance_mode), show="") + self.entry.config(fg=CTkThemeManager.single_color(self.placeholder_text_color, self.appearance_mode), show="") self.entry.delete(0, tkinter.END) self.entry.insert(0, self.placeholder_text) def clear_placeholder(self, event=None): if self.placeholder_text_active: self.placeholder_text_active = False - self.entry.config(fg=CTkColorManager.single_color(self.text_color, self.appearance_mode)) + self.entry.config(fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode)) self.entry.delete(0, tkinter.END) for argument, value in self.pre_placeholder_arguments.items(): self.entry[argument] = value diff --git a/customtkinter/customtkinter_frame.py b/customtkinter/customtkinter_frame.py index 86d263a..5ed771b 100644 --- a/customtkinter/customtkinter_frame.py +++ b/customtkinter/customtkinter_frame.py @@ -3,13 +3,13 @@ import sys from .customtkinter_tk import CTk from .appearance_mode_tracker import AppearanceModeTracker -from .customtkinter_color_manager import CTkColorManager +from .customtkinter_theme_manager import CTkThemeManager class CTkFrame(tkinter.Frame): def __init__(self, *args, bg_color=None, - fg_color="CTkColorManager", + fg_color="default_theme", corner_radius=10, width=200, height=200, @@ -42,14 +42,14 @@ class CTkFrame(tkinter.Frame): self.bg_color = self.detect_color_of_master() if bg_color is None else bg_color - if fg_color == "CTkColorManager": + if fg_color == "default_theme": if isinstance(self.master, CTkFrame): - if self.master.fg_color == CTkColorManager.FRAME: - self.fg_color = CTkColorManager.FRAME_2 + if self.master.fg_color == CTkThemeManager.FRAME_COLOR: + self.fg_color = CTkThemeManager.FRAME_2_COLOR else: - self.fg_color = CTkColorManager.FRAME + self.fg_color = CTkThemeManager.FRAME_COLOR else: - self.fg_color = CTkColorManager.FRAME + self.fg_color = CTkThemeManager.FRAME_COLOR else: self.fg_color = fg_color diff --git a/customtkinter/customtkinter_label.py b/customtkinter/customtkinter_label.py index f029aab..79a197b 100644 --- a/customtkinter/customtkinter_label.py +++ b/customtkinter/customtkinter_label.py @@ -4,15 +4,15 @@ import sys from .customtkinter_tk import CTk from .customtkinter_frame import CTkFrame from .appearance_mode_tracker import AppearanceModeTracker -from .customtkinter_color_manager import CTkColorManager +from .customtkinter_theme_manager import CTkThemeManager class CTkLabel(tkinter.Frame): def __init__(self, *args, master=None, bg_color=None, - fg_color="CTkColorManager", - text_color="CTkColorManager", + fg_color="default_theme", + text_color="default_theme", corner_radius=8, width=120, height=25, @@ -49,8 +49,8 @@ class CTkLabel(tkinter.Frame): self.appearance_mode = AppearanceModeTracker.get_mode() # 0: "Light" 1: "Dark" self.bg_color = self.detect_color_of_master() if bg_color is None else bg_color - self.fg_color = CTkColorManager.LABEL_BG if fg_color == "CTkColorManager" else fg_color - self.text_color = CTkColorManager.TEXT if text_color == "CTkColorManager" else text_color + self.fg_color = CTkThemeManager.LABEL_BG_COLOR if fg_color == "default_theme" else fg_color + self.text_color = CTkThemeManager.TEXT_COLOR if text_color == "default_theme" else text_color self.width = width self.height = height diff --git a/customtkinter/customtkinter_progressbar.py b/customtkinter/customtkinter_progressbar.py index b45497b..c1ac45c 100644 --- a/customtkinter/customtkinter_progressbar.py +++ b/customtkinter/customtkinter_progressbar.py @@ -4,7 +4,7 @@ import tkinter from .customtkinter_tk import CTk from .customtkinter_frame import CTkFrame from .appearance_mode_tracker import AppearanceModeTracker -from .customtkinter_color_manager import CTkColorManager +from .customtkinter_theme_manager import CTkThemeManager class CTkProgressBar(tkinter.Frame): @@ -13,9 +13,9 @@ class CTkProgressBar(tkinter.Frame): def __init__(self, *args, variable=None, bg_color=None, - border_color="CTkColorManager", - fg_color="CTkColorManager", - progress_color="CTkColorManager", + border_color="default_theme", + fg_color="default_theme", + progress_color="default_theme", width=160, height=10, border_width=0, @@ -47,9 +47,9 @@ class CTkProgressBar(tkinter.Frame): self.appearance_mode = AppearanceModeTracker.get_mode() # 0: "Light" 1: "Dark" self.bg_color = self.detect_color_of_master() if bg_color is None else bg_color - self.border_color = CTkColorManager.PROGRESS_BG if border_color == "CTkColorManager" else border_color - self.fg_color = CTkColorManager.PROGRESS_BG if fg_color == "CTkColorManager" else fg_color - self.progress_color = CTkColorManager.MAIN if progress_color == "CTkColorManager" else progress_color + self.border_color = CTkThemeManager.PROGRESS_BG_COLOR if border_color == "default_theme" else border_color + self.fg_color = CTkThemeManager.PROGRESS_BG_COLOR if fg_color == "default_theme" else fg_color + self.progress_color = CTkThemeManager.MAIN_COLOR if progress_color == "default_theme" else progress_color self.variable = variable self.variable_callback_blocked = False @@ -125,10 +125,10 @@ class CTkProgressBar(tkinter.Frame): self.draw_with_ovals_and_rects() if no_color_updates is False: - self.canvas.configure(bg=CTkColorManager.single_color(self.bg_color, self.appearance_mode)) - self.canvas.itemconfig("border_parts", fill=CTkColorManager.single_color(self.border_color, self.appearance_mode)) - self.canvas.itemconfig("inner_parts", fill=CTkColorManager.single_color(self.fg_color, self.appearance_mode)) - self.canvas.itemconfig("progress_parts", fill=CTkColorManager.single_color(self.progress_color, self.appearance_mode)) + self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode)) + self.canvas.itemconfig("border_parts", fill=CTkThemeManager.single_color(self.border_color, self.appearance_mode)) + self.canvas.itemconfig("inner_parts", fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode)) + self.canvas.itemconfig("progress_parts", fill=CTkThemeManager.single_color(self.progress_color, self.appearance_mode)) def draw_with_polygon_shapes(self): """ draw the progress bar parts with just three polygons that have a rounded border """ diff --git a/customtkinter/customtkinter_settings.py b/customtkinter/customtkinter_settings.py new file mode 100644 index 0000000..976e0ec --- /dev/null +++ b/customtkinter/customtkinter_settings.py @@ -0,0 +1,6 @@ +import sys + + +class CTkSettings: + + scaling_factor = 1 diff --git a/customtkinter/customtkinter_slider.py b/customtkinter/customtkinter_slider.py index bf59def..d555b1b 100644 --- a/customtkinter/customtkinter_slider.py +++ b/customtkinter/customtkinter_slider.py @@ -4,7 +4,7 @@ import sys from .customtkinter_tk import CTk from .customtkinter_frame import CTkFrame from .appearance_mode_tracker import AppearanceModeTracker -from .customtkinter_color_manager import CTkColorManager +from .customtkinter_theme_manager import CTkThemeManager class CTkSlider(tkinter.Frame): @@ -13,10 +13,10 @@ class CTkSlider(tkinter.Frame): def __init__(self, *args, bg_color=None, border_color=None, - fg_color="CTkColorManager", - progress_color="CTkColorManager", - button_color="CTkColorManager", - button_hover_color="CTkColorManager", + fg_color="default_theme", + progress_color="default_theme", + button_color="default_theme", + button_hover_color="default_theme", from_=0, to=1, number_of_steps=None, @@ -54,10 +54,10 @@ class CTkSlider(tkinter.Frame): self.bg_color = self.detect_color_of_master() if bg_color is None else bg_color self.border_color = border_color - self.fg_color = CTkColorManager.SLIDER_BG if fg_color == "CTkColorManager" else fg_color - self.progress_color = CTkColorManager.SLIDER_PROGRESS if progress_color == "CTkColorManager" else progress_color - self.button_color = CTkColorManager.MAIN if button_color == "CTkColorManager" else button_color - self.button_hover_color = CTkColorManager.MAIN_HOVER if button_hover_color == "CTkColorManager" else button_hover_color + self.fg_color = CTkThemeManager.SLIDER_BG_COLOR if fg_color == "default_theme" else fg_color + self.progress_color = CTkThemeManager.SLIDER_PROGRESS_COLOR if progress_color == "default_theme" else progress_color + self.button_color = CTkThemeManager.MAIN_COLOR if button_color == "default_theme" else button_color + self.button_hover_color = CTkThemeManager.MAIN_HOVER_COLOR if button_hover_color == "default_theme" else button_hover_color self.width = width self.height = self.calc_optimal_height(height) @@ -148,21 +148,21 @@ class CTkSlider(tkinter.Frame): self.draw_with_ovals_and_rects() if no_color_updates is False: - self.canvas.configure(bg=CTkColorManager.single_color(self.bg_color, self.appearance_mode)) + self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode)) if self.border_color is None: - self.canvas.itemconfig("border_parts", fill=CTkColorManager.single_color(self.bg_color, self.appearance_mode)) + self.canvas.itemconfig("border_parts", fill=CTkThemeManager.single_color(self.bg_color, self.appearance_mode)) else: - self.canvas.itemconfig("border_parts", fill=CTkColorManager.single_color(self.border_color, self.appearance_mode)) + self.canvas.itemconfig("border_parts", fill=CTkThemeManager.single_color(self.border_color, self.appearance_mode)) - self.canvas.itemconfig("inner_parts", fill=CTkColorManager.single_color(self.fg_color, self.appearance_mode)) + self.canvas.itemconfig("inner_parts", fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode)) if self.progress_color is None: - self.canvas.itemconfig("progress_parts", fill=CTkColorManager.single_color(self.fg_color, self.appearance_mode)) + self.canvas.itemconfig("progress_parts", fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode)) else: - self.canvas.itemconfig("progress_parts", fill=CTkColorManager.single_color(self.progress_color, self.appearance_mode)) + self.canvas.itemconfig("progress_parts", fill=CTkThemeManager.single_color(self.progress_color, self.appearance_mode)) - self.canvas.itemconfig("button_parts", fill=CTkColorManager.single_color(self.button_color, self.appearance_mode)) + self.canvas.itemconfig("button_parts", fill=CTkThemeManager.single_color(self.button_color, self.appearance_mode)) def draw_with_polygon_shapes(self): """ draw the slider parts with just three polygons that have a rounded border """ @@ -327,11 +327,11 @@ class CTkSlider(tkinter.Frame): def on_enter(self, event=0): self.hover_state = True - self.canvas.itemconfig("button_parts", fill=CTkColorManager.single_color(self.button_hover_color, self.appearance_mode)) + self.canvas.itemconfig("button_parts", fill=CTkThemeManager.single_color(self.button_hover_color, self.appearance_mode)) def on_leave(self, event=0): self.hover_state = False - self.canvas.itemconfig("button_parts", fill=CTkColorManager.single_color(self.button_color, self.appearance_mode)) + self.canvas.itemconfig("button_parts", fill=CTkThemeManager.single_color(self.button_color, self.appearance_mode)) def round_to_step_size(self, value): if self.number_of_steps is not None: diff --git a/customtkinter/customtkinter_theme_manager.py b/customtkinter/customtkinter_theme_manager.py new file mode 100644 index 0000000..b203ae4 --- /dev/null +++ b/customtkinter/customtkinter_theme_manager.py @@ -0,0 +1,129 @@ +import sys + + +class CTkThemeManager: + + WINDOW_BG_COLOR = None + MAIN_COLOR = None + MAIN_HOVER_COLOR = None + ENTRY_COLOR = None + TEXT_COLOR = None + PLACEHOLDER_TEXT_COLOR = None + LABEL_BG_COLOR = None + SLIDER_BG_COLOR = None + SLIDER_PROGRESS_COLOR = None + PROGRESS_BG_COLOR = None + FRAME_COLOR = None + FRAME_2_COLOR = None + CHECKBOX_LINES_COLOR = None + DARKEN_COLOR_FACTOR = None + + @classmethod + def initialize_color_theme(cls, theme_name): + + 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 = ("white", "#222222") + 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 = ("black", "white") + cls.PLACEHOLDER_TEXT_COLOR = ("gray52", "gray62") + 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 + tuple color with (light_color, dark_color). The functions then returns + always a single color string """ + + if type(color) == tuple: + 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 darken_hex_color(cls, hex_color: str, darken_factor: float = None) -> str: + if darken_factor is None: + darken_factor = cls.DARKEN_COLOR_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) + 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)) + return hex_color + + @classmethod + def set_main_color(cls, main_color, main_color_hover): + cls.MAIN_COLOR = main_color + cls.MAIN_HOVER_COLOR = main_color_hover + + +CTkThemeManager.initialize_color_theme("blue") diff --git a/customtkinter/customtkinter_tk.py b/customtkinter/customtkinter_tk.py index d7419d2..71cc2c8 100644 --- a/customtkinter/customtkinter_tk.py +++ b/customtkinter/customtkinter_tk.py @@ -6,19 +6,19 @@ import platform import ctypes from .appearance_mode_tracker import AppearanceModeTracker -from .customtkinter_color_manager import CTkColorManager +from .customtkinter_theme_manager import CTkThemeManager class CTk(tkinter.Tk): def __init__(self, *args, - fg_color="CTkColorManager", + fg_color="default_theme", **kwargs): self.enable_macos_dark_title_bar() super().__init__(*args, **kwargs) self.appearance_mode = AppearanceModeTracker.get_mode() # 0: "Light" 1: "Dark" - self.fg_color = CTkColorManager.WINDOW_BG if fg_color == "CTkColorManager" else fg_color + self.fg_color = CTkThemeManager.WINDOW_BG_COLOR if fg_color == "default_theme" else fg_color if "bg" in kwargs: self.fg_color = kwargs["bg"] @@ -28,7 +28,8 @@ class CTk(tkinter.Tk): del kwargs["background"] AppearanceModeTracker.add(self.set_appearance_mode, self) - super().configure(bg=CTkColorManager.single_color(self.fg_color, self.appearance_mode)) + super().configure(bg=CTkThemeManager.single_color(self.fg_color, self.appearance_mode)) + super().title("CTk") self.window_exists = False # indicates if the window is already shown through .update or .mainloop @@ -73,14 +74,14 @@ class CTk(tkinter.Tk): if "bg" in kwargs: self.fg_color = kwargs["bg"] bg_changed = True - kwargs["bg"] = CTkColorManager.single_color(self.fg_color, self.appearance_mode) + kwargs["bg"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode) elif "background" in kwargs: self.fg_color = kwargs["background"] bg_changed = True - kwargs["background"] = CTkColorManager.single_color(self.fg_color, self.appearance_mode) + kwargs["background"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode) elif "fg_color" in kwargs: self.fg_color = kwargs["fg_color"] - kwargs["bg"] = CTkColorManager.single_color(self.fg_color, self.appearance_mode) + kwargs["bg"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode) del kwargs["fg_color"] bg_changed = True @@ -88,11 +89,11 @@ class CTk(tkinter.Tk): if "bg" in args[0]: self.fg_color=args[0]["bg"] bg_changed = True - args[0]["bg"] = CTkColorManager.single_color(self.fg_color, self.appearance_mode) + args[0]["bg"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode) elif "background" in args[0]: self.fg_color=args[0]["background"] bg_changed = True - args[0]["background"] = CTkColorManager.single_color(self.fg_color, self.appearance_mode) + args[0]["background"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode) if bg_changed: from .customtkinter_slider import CTkSlider @@ -181,4 +182,4 @@ class CTk(tkinter.Tk): else: self.windows_set_titlebar_color("light") - super().configure(bg=CTkColorManager.single_color(self.fg_color, self.appearance_mode)) + super().configure(bg=CTkThemeManager.single_color(self.fg_color, self.appearance_mode)) diff --git a/customtkinter/customtkinter_toplevel.py b/customtkinter/customtkinter_toplevel.py index b1c1f7e..b3de789 100644 --- a/customtkinter/customtkinter_toplevel.py +++ b/customtkinter/customtkinter_toplevel.py @@ -6,19 +6,19 @@ import platform import ctypes from .appearance_mode_tracker import AppearanceModeTracker -from .customtkinter_color_manager import CTkColorManager +from .customtkinter_theme_manager import CTkThemeManager class CTkToplevel(tkinter.Toplevel): def __init__(self, *args, - fg_color="CTkColorManager", + fg_color="default_theme", **kwargs): self.enable_macos_dark_title_bar() super().__init__(*args, **kwargs) self.appearance_mode = AppearanceModeTracker.get_mode() # 0: "Light" 1: "Dark" - self.fg_color = CTkColorManager.WINDOW_BG if fg_color == "CTkColorManager" else fg_color + self.fg_color = CTkThemeManager.WINDOW_BG_COLOR if fg_color == "default_theme" else fg_color if "bg" in kwargs: self.fg_color = kwargs["bg"] @@ -28,7 +28,8 @@ class CTkToplevel(tkinter.Toplevel): del kwargs["background"] AppearanceModeTracker.add(self.set_appearance_mode, self) - super().configure(bg=CTkColorManager.single_color(self.fg_color, self.appearance_mode)) + super().configure(bg=CTkThemeManager.single_color(self.fg_color, self.appearance_mode)) + super().title("CTkToplevel") if sys.platform.startswith("win"): if self.appearance_mode == 1: @@ -59,14 +60,14 @@ class CTkToplevel(tkinter.Toplevel): if "bg" in kwargs: self.fg_color = kwargs["bg"] bg_changed = True - kwargs["bg"] = CTkColorManager.single_color(self.fg_color, self.appearance_mode) + kwargs["bg"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode) elif "background" in kwargs: self.fg_color = kwargs["background"] bg_changed = True - kwargs["background"] = CTkColorManager.single_color(self.fg_color, self.appearance_mode) + kwargs["background"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode) elif "fg_color" in kwargs: self.fg_color = kwargs["fg_color"] - kwargs["bg"] = CTkColorManager.single_color(self.fg_color, self.appearance_mode) + kwargs["bg"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode) del kwargs["fg_color"] bg_changed = True @@ -74,11 +75,11 @@ class CTkToplevel(tkinter.Toplevel): if "bg" in args[0]: self.fg_color=args[0]["bg"] bg_changed = True - args[0]["bg"] = CTkColorManager.single_color(self.fg_color, self.appearance_mode) + args[0]["bg"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode) elif "background" in args[0]: self.fg_color=args[0]["background"] bg_changed = True - args[0]["background"] = CTkColorManager.single_color(self.fg_color, self.appearance_mode) + args[0]["background"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode) if bg_changed: from .customtkinter_slider import CTkSlider @@ -164,4 +165,4 @@ class CTkToplevel(tkinter.Toplevel): else: self.windows_set_titlebar_color("light") - super().configure(bg=CTkColorManager.single_color(self.fg_color, self.appearance_mode)) + super().configure(bg=CTkThemeManager.single_color(self.fg_color, self.appearance_mode)) diff --git a/examples/complex_example_custom_colors.py b/examples/complex_example_custom_colors.py index f2a9a09..8a0d45b 100644 --- a/examples/complex_example_custom_colors.py +++ b/examples/complex_example_custom_colors.py @@ -53,7 +53,7 @@ class App(customtkinter.CTk): text="CTkButton", command=self.button_event, border_width=3, - corner_radius=5) + corner_radius=6) self.button_1.place(relx=0.5, y=50, anchor=tkinter.CENTER) self.button_2 = customtkinter.CTkButton(master=self.frame_left, @@ -63,7 +63,7 @@ class App(customtkinter.CTk): text="CTkButton", command=self.button_event, border_width=3, - corner_radius=5) + corner_radius=6) self.button_2.place(relx=0.5, y=100, anchor=tkinter.CENTER) self.button_3 = customtkinter.CTkButton(master=self.frame_left, @@ -73,7 +73,7 @@ class App(customtkinter.CTk): text="CTkButton", command=self.button_event, border_width=3, - corner_radius=5) + corner_radius=6) self.button_3.place(relx=0.5, y=150, anchor=tkinter.CENTER) # ============ frame_right ============ @@ -93,7 +93,7 @@ class App(customtkinter.CTk): "invidunt ut labore", width=250, height=100, - corner_radius=5, + corner_radius=6, fg_color=("white", "gray20"), text_color=App.MAIN_COLOR, justify=tkinter.LEFT) @@ -145,13 +145,13 @@ class App(customtkinter.CTk): text="CTkButton", command=self.button_event, border_width=3, - corner_radius=5) + corner_radius=6) self.button_4.place(x=310, rely=0.7, anchor=tkinter.CENTER) self.entry = customtkinter.CTkEntry(master=self.frame_right, width=120, height=28, - corner_radius=5) + corner_radius=6) self.entry.place(relx=0.33, rely=0.92, anchor=tkinter.CENTER) self.entry.insert(0, "CTkEntry") @@ -163,7 +163,7 @@ class App(customtkinter.CTk): text="CTkButton", command=self.button_event, border_width=3, - corner_radius=5) + corner_radius=6) self.button_5.place(relx=0.66, rely=0.92, anchor=tkinter.CENTER) def button_event(self): diff --git a/examples/simple_example.py b/examples/simple_example.py index e6b895c..acfd1b3 100644 --- a/examples/simple_example.py +++ b/examples/simple_example.py @@ -32,7 +32,7 @@ label_1.pack(pady=y_padding, padx=10) progressbar_1 = customtkinter.CTkProgressBar(master=frame_1) progressbar_1.pack(pady=y_padding, padx=10) -button_1 = customtkinter.CTkButton(master=frame_1, corner_radius=10, command=button_function) +button_1 = customtkinter.CTkButton(master=frame_1, corner_radius=8, command=button_function) button_1.pack(pady=y_padding, padx=10) # button_1.configure(state="disabled") diff --git a/test/complete_test.py b/test/complete_test.py index eb7027b..4ab1a9d 100644 --- a/test/complete_test.py +++ b/test/complete_test.py @@ -65,7 +65,7 @@ class TestApp(customtkinter.CTk): self.frame_2 = customtkinter.CTkFrame(master=self.ctk_frame, width=200, height=60) self.frame_2.place(relx=0.5, y=y + 80, anchor=tkinter.CENTER) - self.button_2 = customtkinter.CTkButton(master=self.ctk_frame, border_width=3, border_color=customtkinter.CTkColorManager.MAIN_HOVER, + self.button_2 = customtkinter.CTkButton(master=self.ctk_frame, border_width=3, border_color=customtkinter.CTkThemeManager.MAIN_HOVER_COLOR, ) self.button_2.place(relx=0.5, y=y + 160, anchor=tkinter.CENTER) diff --git a/test/simple_example_standard_tkinter.py b/test/simple_example_standard_tkinter.py index 6b740c2..4a808e2 100644 --- a/test/simple_example_standard_tkinter.py +++ b/test/simple_example_standard_tkinter.py @@ -1,7 +1,13 @@ +#import tkinter.ttk as ttk +import ctypes +print(ctypes.windll.shcore.SetProcessDpiAwareness(ctypes.c_int(1))) + import tkinter -import tkinter.ttk as ttk app = tkinter.Tk() +print(app.winfo_fpixels('1i')) +#app.tk.call('tk', 'scaling', 1.0) +print(app.winfo_fpixels('1i')) app.geometry("400x300") app.title("Standard Tkinter Test") @@ -22,9 +28,9 @@ frame_1.pack(padx=60, pady=20, fill="both", expand=True) label_1 = tkinter.Label(master=frame_1, text="Label", bg="lightgray") label_1.pack(pady=y_padding, padx=10) -progressbar_1 = ttk.Progressbar(master=frame_1,style='black.Horizontal.TProgressbar', length=150) -progressbar_1.pack(pady=y_padding, padx=10) -progressbar_1["value"] = 50 +#progressbar_1 = ttk.Progressbar(master=frame_1,style='black.Horizontal.TProgressbar', length=150) +#progressbar_1.pack(pady=y_padding, padx=10) +#progressbar_1["value"] = 50 button_1 = tkinter.Button(master=frame_1, command=button_function, text="Button", highlightbackground="lightgray") button_1.pack(pady=y_padding, padx=10)