From 9ed461e04c7e7ac7abdef8c9038a48eec0caa2fe Mon Sep 17 00:00:00 2001 From: TomSchimansky Date: Wed, 2 Mar 2022 00:53:58 +0100 Subject: [PATCH] dark-blue, green theme in .json, new font .otf file for circles --- customtkinter/__init__.py | 9 +-- .../assets/CustomTkinter_shapes_font-fine.otf | Bin 0 -> 3256 bytes customtkinter/assets/themes/blue.json | 36 +++++------ customtkinter/assets/themes/dark-blue.json | 57 ++++++++++++++++++ customtkinter/assets/themes/green.json | 57 ++++++++++++++++++ customtkinter/customtkinter_button.py | 2 +- customtkinter/customtkinter_canvas.py | 7 ++- customtkinter/customtkinter_dialog.py | 41 +++++-------- customtkinter/customtkinter_draw_engine.py | 28 ++++++--- customtkinter/customtkinter_entry.py | 5 +- customtkinter/customtkinter_label.py | 18 ++++-- customtkinter/customtkinter_theme_manager.py | 2 +- examples/complex_example.py | 38 ++++-------- test/test_button_antialiasing.py | 7 +-- test/test_string_dialog.py | 29 +++++++++ 15 files changed, 238 insertions(+), 98 deletions(-) create mode 100644 customtkinter/assets/CustomTkinter_shapes_font-fine.otf create mode 100644 customtkinter/assets/themes/dark-blue.json create mode 100644 customtkinter/assets/themes/green.json create mode 100644 test/test_string_dialog.py diff --git a/customtkinter/__init__.py b/customtkinter/__init__.py index 623a5ea..eaf225f 100644 --- a/customtkinter/__init__.py +++ b/customtkinter/__init__.py @@ -1,5 +1,6 @@ __version__ = "2.4" +from .customtkinter_dialog import CTkDialog from .customtkinter_button import CTkButton from .customtkinter_slider import CTkSlider from .customtkinter_frame import CTkFrame @@ -7,7 +8,6 @@ from .customtkinter_progressbar import CTkProgressBar from .customtkinter_label import CTkLabel from .customtkinter_entry import CTkEntry from .customtkinter_checkbox import CTkCheckBox -from .customtkinter_dialog import CTkDialog from .customtkinter_tk import CTk from .customtkinter_canvas import CTkCanvas from .customtkinter_toplevel import CTkToplevel @@ -59,7 +59,7 @@ def get_appearance_mode(): def set_default_color_theme(color_string): - CTkThemeManager.initialize_color_theme(color_string) + CTkThemeManager.load_theme(color_string) if not sys.platform == "darwin": @@ -70,7 +70,7 @@ if not sys.platform == "darwin": # load text fonts and custom font with circle shapes for round corner rendering script_directory = os.path.dirname(os.path.abspath(__file__)) - pyglet.font.add_file(os.path.join(script_directory, "assets", "CustomTkinter_shapes_font-Regular.otf")) + pyglet.font.add_file(os.path.join(script_directory, "assets", "CustomTkinter_shapes_font-fine.otf")) pyglet.font.add_file(os.path.join(script_directory, "assets", "Roboto", "Roboto-Regular.ttf")) pyglet.font.add_file(os.path.join(script_directory, "assets", "Roboto", "Roboto-Medium.ttf")) CTkSettings.circle_font_is_ready = pyglet.font.have_font("CustomTkinter_shapes_font") @@ -81,5 +81,6 @@ if not sys.platform == "darwin": if not CTkSettings.circle_font_is_ready: if CTkSettings.preferred_drawing_method == "font_shapes": sys.stderr.write("WARNING (customtkinter.CTkSettings): " + - "Preferred drawing method 'font_shapes' can not be used because the font file could not be loaded. Using 'circle_shapes' instead.") + "Preferred drawing method 'font_shapes' can not be used because the font file could not be loaded.\n" + + "Using 'circle_shapes' instead. The rendering quality will be very bad!") CTkSettings.preferred_drawing_method = "circle_shapes" diff --git a/customtkinter/assets/CustomTkinter_shapes_font-fine.otf b/customtkinter/assets/CustomTkinter_shapes_font-fine.otf new file mode 100644 index 0000000000000000000000000000000000000000..668452a820621fa84e548585cae164712b3fce0a GIT binary patch literal 3256 zcmbW3ZBSI_701uByS!+SU}mI3S23h@zk&qV2RvYddY@bo!E+_Dg5{z_k5P+etGu>6f%08qeY}q5r!tbkiAH z?cF)|`9J5L-+9h`UhZsBX=xFyp>L6$(sFWhGt!5Xju9oiMU;5G=)l%(zPpXLi45VY zYw&wI?Te0gi5xf3|6_~S)A+>P!Xoqq*!C7UY(KMEeapVs;tw7xwjwE|8nh32iKAa-3chr`N{mN8)r!oL(2FQ{!}6T%GH~ zb=t`|)}VG9{Qz@rX+zr(711_IrTtNDr(ENYY6rbQeNml2>Bbe+iI~IpqdF-rXL6ig z6Q|e4=||#pN}OI7r&Hr}T3ns$tvYjh0>KV{X{)b2=0UK|MlAfH$HCG+ z*bx8!2%pJc=IsvnI@&W_TU@S8Dhp3R0MlW;bOyO-3(Q5C8Cn1PT{9@_;pg=~-#2`u zu;Z}XAXCUex6rx}=AbmF40;|rEr)i~9?GRW%BL4;FHTn>?W32d2*Rw(B zCwoX@`Mu>|Jm@c6V|b7UzJ!WlP&bPJ@kZw_2)~) z_j(f^NAlZ`;%?TiXEce|AH#7psax}lO5J7U6_p38st?uF)_Lk18of=;Exym}fK`W$ z?dVklqICs2Jq_OHU&z_LCpRzu#k~cE`(7$4F4=#e)Q!3fn_)9zPMT3OW=@%LbK0CS z6XvX$G*jlBnKtLm1v6tVnoDMuHrOz|g;>(#^h>&HwwoSv&HT;w6at8*pkp5`Wi3oa5D2JJD8K1(GR!qhTHq${yU!}SuvsChkddbjkzD` zYq*~(@1@@B4Gk_8J9U9Is6DJ#lUWy}M}u;elVyP=C;^sh$t(*Rkf2`UWQ%cyc3J7I ztnbSur_Qr>Yd7mW@OcSnx4Z#-o~2v5Sl$FauU*ouZ$|LJrCg_8VeQaP*2`e7NT+tl zWiVG*I;5TD4KP>W>p+|}r2JSuhz%)?@{v<#S^e71dI|ijw5wk(fuCjZOB>4^_*rce zzs^O*EDUXm@xPWEPMu+G)i%}(z-OdQTjc`q8J1Q#%yJRAdoo)0tkhUD9^A@83JZFK4+YqK`9PJ*A3W^Iy5@RKaf z(!??aehR)Oor=8jXz1A(FC#MP)Ctx`^|GD;KOtUilr!Kb7!%UKau)mqe2s_;uTo{m z9^-#1KXK|fYrQtGo&r8D4O%a!fRD4(i-+Yj@NxA>y`Hx4A{~@dF?^{v^d+Z`ves!G z>nQk9@o1f#1V74BC$%hN;77Gq>U7NF_e#E8j`6Y>N^|NkYmL^h4uc<&8a*V#;D=di z4?Sek#ETNSNPkaP90*c(rVV%!4FBbR>|w&hghoQAPWwI48d20IPklc zdgK;(z0(vq19#p+t9|kZr=DP~)Pt5}jbFlnRzXBs!rLQmKPhqMcG9 z3oC`ZYZWrUTCU}+1Key>Q*;v zAMk#0YpL`B?_+UGDN8@_e)vkY-@-SCe)I2jD8PzpFKe-uu)YkuS4y;4UIyOFQY=L* zuK@4WA}Q8aEc_|iB*B&8DfBs~9$_uiLe?YTk4m8y$Pw^ISPG?pltu)0((U&BPRfcMGJr!Mj;9 z#l=zv-mNb9%Pjte+>$S^@P+cRQ?pppbtCI@;Im|-rpt5Svslt4oh1u=7JTW5OHRet qd=9oR@-N)_C;ndz|Gn)$g1rs<4(uxIGHeQV5;g#9h3$uB5d8~E8l{2& literal 0 HcmV?d00001 diff --git a/customtkinter/assets/themes/blue.json b/customtkinter/assets/themes/blue.json index 25bc6a2..7e0ffee 100644 --- a/customtkinter/assets/themes/blue.json +++ b/customtkinter/assets/themes/blue.json @@ -1,24 +1,24 @@ { "color": { - "window_bg_color": ["#ECECEC", "#323232"], - "button": ["#64A1D2", "#1C94CF"], + "window_bg_color": ["#ECECEC", "gray14"], + "button": ["#3599D6", "#1C94CF"], "button_hover": ["#A7C2E0", "#5FB4DD"], - "button_border": ["#A7C2E0", "#5FB4DD"], + "button_border": ["gray25", "gray86"], "checkbox_border": ["gray20", "#ededed"], - "entry": ["white", "black"], - "entry_border": ["gray65", "gray40"], + "entry": ["white", "gray10"], + "entry_border": ["gray65", "gray35"], "entry_placeholder_text": ["gray52", "gray62"], "frame_border": ["#A7C2E0", "#5FB4DD"], - "frame_low": ["#D4D5D6", "#3F3F3F"], - "frame_high": ["#BFBEC1", "#505050"], - "label": ["white", "#626061"], - "text": ["gray18", "gray90"], + "frame_low": ["#D4D5D6", "gray20"], + "frame_high": ["gray77", "gray24"], + "label": [null, null], + "text": ["gray20", "gray90"], "progressbar": ["#6B6B6B", "#222222"], - "progressbar_progress": ["#64A1D2", "#1C94CF"], + "progressbar_progress": ["#3599D6", "#1C94CF"], "progressbar_border": ["gray", "gray"], "slider": ["#6B6B6B", "#222222"], "slider_progress": ["#A5A6A5", "#555555"], - "slider_button": ["#64A1D2", "#1C94CF"], + "slider_button": ["#3599D6", "#1C94CF"], "slider_button_hover": ["#A7C2E0", "#5FB4DD"], "darken_factor": 0.8 }, @@ -26,22 +26,22 @@ "text": { "macOS": { "font": "SF Display", - "size": -14 + "size": -13 }, "Windows": { "font": "Roboto", - "size": -14 + "size": -13 }, "Linux": { "font": "Roboto", - "size": -14 + "size": -13 } }, "shape": { "button_corner_radius": 8, "button_border_width": 0, - "checkbox_corner_radius": 6, + "checkbox_corner_radius": 7, "checkbox_border_width": 3, "entry_border_width": 2, "frame_corner_radius": 10, @@ -49,9 +49,9 @@ "label_corner_radius": 8, "progressbar_border_width": 0, "progressbar_corner_radius": 100, - "slider_border_width": 5, + "slider_border_width": 6, "slider_corner_radius": 8, - "slider_button_length": 10, - "slider_button_corner_radius": 8 + "slider_button_length": 0, + "slider_button_corner_radius": 100 } } \ No newline at end of file diff --git a/customtkinter/assets/themes/dark-blue.json b/customtkinter/assets/themes/dark-blue.json new file mode 100644 index 0000000..43f25be --- /dev/null +++ b/customtkinter/assets/themes/dark-blue.json @@ -0,0 +1,57 @@ +{ + "color": { + "window_bg_color": ["gray95", "gray10"], + "button": ["#608BD5", "#395E9C"], + "button_hover": ["#A4BDE6", "#748BB3"], + "button_border": ["gray25", "gray75"], + "checkbox_border": ["gray25", "gray75"], + "entry": ["white", "gray10"], + "entry_border": ["gray65", "gray35"], + "entry_placeholder_text": ["gray52", "gray62"], + "frame_border": ["#A7C2E0", "#5FB4DD"], + "frame_low": ["gray88", "gray16"], + "frame_high": ["gray82", "gray20"], + "label": [null, null], + "text": ["gray20", "gray90"], + "progressbar": ["gray40", "gray6"], + "progressbar_progress": ["#608BD5", "#395E9C"], + "progressbar_border": ["gray", "gray"], + "slider": ["gray40", "#222222"], + "slider_progress": ["white", "#555555"], + "slider_button": ["#608BD5", "#395E9C"], + "slider_button_hover": ["#A4BDE6", "#748BB3"], + "darken_factor": 0.8 + }, + + "text": { + "macOS": { + "font": "SF Display", + "size": -13 + }, + "Windows": { + "font": "Roboto", + "size": -13 + }, + "Linux": { + "font": "Roboto", + "size": -13 + } + + }, + "shape": { + "button_corner_radius": 8, + "button_border_width": 0, + "checkbox_corner_radius": 7, + "checkbox_border_width": 3, + "entry_border_width": 2, + "frame_corner_radius": 8, + "frame_border_width": 0, + "label_corner_radius": 8, + "progressbar_border_width": 0, + "progressbar_corner_radius": 3, + "slider_border_width": 6, + "slider_corner_radius": 8, + "slider_button_length": 12, + "slider_button_corner_radius": 3 + } +} \ No newline at end of file diff --git a/customtkinter/assets/themes/green.json b/customtkinter/assets/themes/green.json new file mode 100644 index 0000000..8b9f502 --- /dev/null +++ b/customtkinter/assets/themes/green.json @@ -0,0 +1,57 @@ +{ + "color": { + "window_bg_color": ["gray95", "gray10"], + "button": ["#72CF9F", "#11B384"], + "button_hover": ["#0E9670", "#0D8A66"], + "button_border": ["gray25", "gray75"], + "checkbox_border": ["gray25", "gray75"], + "entry": ["white", "gray10"], + "entry_border": ["gray65", "gray35"], + "entry_placeholder_text": ["gray52", "gray62"], + "frame_border": ["#A7C2E0", "#5FB4DD"], + "frame_low": ["gray88", "gray16"], + "frame_high": ["gray82", "gray20"], + "label": [null, null], + "text": ["gray20", "gray90"], + "progressbar": ["gray40", "gray6"], + "progressbar_progress": ["#72CF9F", "#11B384"], + "progressbar_border": ["gray", "gray"], + "slider": ["gray40", "#222222"], + "slider_progress": ["white", "#555555"], + "slider_button": ["#72CF9F", "#11B384"], + "slider_button_hover": ["#0E9670", "#0D8A66"], + "darken_factor": 0.8 + }, + + "text": { + "macOS": { + "font": "SF Display", + "size": -13 + }, + "Windows": { + "font": "Roboto", + "size": -13 + }, + "Linux": { + "font": "Roboto", + "size": -13 + } + + }, + "shape": { + "button_corner_radius": 8, + "button_border_width": 0, + "checkbox_corner_radius": 7, + "checkbox_border_width": 3, + "entry_border_width": 2, + "frame_corner_radius": 10, + "frame_border_width": 0, + "label_corner_radius": 8, + "progressbar_border_width": 0, + "progressbar_corner_radius": 100, + "slider_border_width": 6, + "slider_corner_radius": 100, + "slider_button_length": 0, + "slider_button_corner_radius": 100 + } +} \ No newline at end of file diff --git a/customtkinter/customtkinter_button.py b/customtkinter/customtkinter_button.py index fc1564d..1e4e921 100644 --- a/customtkinter/customtkinter_button.py +++ b/customtkinter/customtkinter_button.py @@ -64,7 +64,7 @@ class CTkButton(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_hover"] if hover_color == "default_theme" else hover_color - self.border_color = CTkThemeManager.theme["color"]["button_hover"] if border_color == "default_theme" else border_color + self.border_color = CTkThemeManager.theme["color"]["button_border"] if border_color == "default_theme" else border_color # shape and size self.width = width diff --git a/customtkinter/customtkinter_canvas.py b/customtkinter/customtkinter_canvas.py index b3fabdd..eb2aee1 100644 --- a/customtkinter/customtkinter_canvas.py +++ b/customtkinter/customtkinter_canvas.py @@ -7,7 +7,10 @@ class CTkCanvas(tkinter.Canvas): # This dict maps a corner_radius of a circle to a specific font character, which is circle shape which fills the space # of one monospace character to a specific amount from 100% to 90% (A to I). 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'} + 9: 'C', 8: 'D', 7: 'C', 6: 'E', 5: 'F', 4: 'G', 3: 'H', 2: 'H', 1: 'H', 0: 'A'} + + radius_to_char_fine = {19: 'A', 18: 'A', 17: 'B', 16: 'B', 15: 'B', 14: 'B', 13: 'C', 12: 'C', 11: 'C', 10: 'C', + 9: 'D', 8: 'D', 7: 'D', 6: 'F', 5: 'D', 4: 'G', 3: 'G', 2: 'H', 1: 'H', 0: 'A'} def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -19,7 +22,7 @@ class CTkCanvas(tkinter.Canvas): if radius >= 20: return "A" else: - return self.radius_to_char[radius] + return self.radius_to_char_fine[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_dialog.py b/customtkinter/customtkinter_dialog.py index a61e1b7..51b4839 100644 --- a/customtkinter/customtkinter_dialog.py +++ b/customtkinter/customtkinter_dialog.py @@ -1,10 +1,13 @@ import tkinter import time -from customtkinter.customtkinter_label import CTkLabel -from customtkinter.customtkinter_button import CTkButton -from customtkinter.customtkinter_entry import CTkEntry -from customtkinter.customtkinter_theme_manager import CTkThemeManager +from .appearance_mode_tracker import AppearanceModeTracker +from .customtkinter_theme_manager import CTkThemeManager +from .customtkinter_label import CTkLabel +from .customtkinter_button import CTkButton +from .customtkinter_entry import CTkEntry +from .customtkinter_frame import CTkFrame +from .customtkinter_toplevel import CTkToplevel class CTkDialog: @@ -15,6 +18,8 @@ class CTkDialog: fg_color="default_theme", hover_color="default_theme", border_color="default_theme"): + + self.appearance_mode = AppearanceModeTracker.get_mode() # 0: "Light" 1: "Dark" self.master = master self.user_input = None @@ -22,11 +27,12 @@ class CTkDialog: self.height = len(text.split("\n"))*20 + 150 + self.window_bg_color = CTkThemeManager.theme["color"]["window_bg_color"] self.fg_color = CTkThemeManager.theme["color"]["button"] if fg_color == "default_theme" else fg_color self.hover_color = CTkThemeManager.theme["color"]["button_hover"] if hover_color == "default_theme" else hover_color self.border_color = CTkThemeManager.theme["color"]["button_hover"] if border_color == "default_theme" else border_color - self.top = customtkinter.CTkToplevel() + self.top = CTkToplevel() self.top.geometry(f"280x{self.height}") self.top.resizable(False, False) self.top.title(title) @@ -34,14 +40,16 @@ class CTkDialog: self.top.focus_force() self.top.grab_set() - self.label_frame = customtkinter.CTkFrame(master=self.top, + self.label_frame = CTkFrame(master=self.top, corner_radius=0, + fg_color=CTkThemeManager.single_color(self.window_bg_color, self.appearance_mode), width=300, height=self.height-100) self.label_frame.place(relx=0.5, rely=0, anchor=tkinter.N) - self.button_and_entry_frame = customtkinter.CTkFrame(master=self.top, + self.button_and_entry_frame = CTkFrame(master=self.top, corner_radius=0, + fg_color=CTkThemeManager.single_color(self.window_bg_color, self.appearance_mode), width=300, height=100) self.button_and_entry_frame.place(relx=0.5, rely=1, anchor=tkinter.S) @@ -95,22 +103,3 @@ class CTkDialog: time.sleep(0.05) self.top.destroy() return self.user_input - - -if __name__ == "__main__": - import customtkinter - customtkinter.set_appearance_mode("System") - customtkinter.set_default_color_theme("dark-blue") - - app = customtkinter.CTk() - app.geometry("400x300") - app.title("CTkDialog Test") - - def button_click_event(): - dialog = CTkDialog(master=None, text="Type in a number:", title="Test") - print("Number:", dialog.get_input()) - - button = CTkButton(master=app, text="Open Dialog", command=button_click_event) - button.place(relx=0.5, rely=0.5, anchor=tkinter.CENTER) - - app.mainloop() diff --git a/customtkinter/customtkinter_draw_engine.py b/customtkinter/customtkinter_draw_engine.py index 68380ec..6f731a7 100644 --- a/customtkinter/customtkinter_draw_engine.py +++ b/customtkinter/customtkinter_draw_engine.py @@ -67,7 +67,7 @@ class CTkDrawEngine: if self._rendering_method == "polygon_shapes": return self._draw_rounded_rect_with_border_polygon_shapes(width, height, corner_radius, border_width, inner_corner_radius) elif self._rendering_method == "font_shapes": - return self._draw_rounded_rect_with_border_font_shapes(width, height, corner_radius, border_width, inner_corner_radius, ()) + return self._draw_rounded_rect_with_border_font_shapes(width, height, corner_radius, border_width, inner_corner_radius, (), symmetric_circles=True) elif self._rendering_method == "circle_shapes": return self._draw_rounded_rect_with_border_circle_shapes(width, height, corner_radius, border_width, inner_corner_radius) @@ -125,7 +125,7 @@ class CTkDrawEngine: return requires_recoloring def _draw_rounded_rect_with_border_font_shapes(self, width: int, height: int, corner_radius: int, border_width: int, inner_corner_radius: int, - exclude_parts: tuple) -> bool: + exclude_parts: tuple, symmetric_circles: bool = True) -> bool: requires_recoloring = False # create border button parts @@ -134,16 +134,20 @@ class CTkDrawEngine: # create canvas border corner parts if not already created if not self._canvas.find_withtag("border_oval_1_a"): self._canvas.create_aa_circle(0, 0, 0, tags=("border_oval_1_a", "border_corner_part", "border_parts"), anchor=tkinter.CENTER) - self._canvas.create_aa_circle(0, 0, 0, tags=("border_oval_1_b", "border_corner_part", "border_parts"), anchor=tkinter.CENTER, angle=180) + if symmetric_circles: + 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 symmetric_circles: + self._canvas.create_aa_circle(0, 0, 0, tags=("border_oval_2_b", "border_corner_part", "border_parts"), anchor=tkinter.CENTER, angle=180) requires_recoloring = True if not self._canvas.find_withtag("border_oval_3_a") and round(corner_radius) * 2 < 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) + if symmetric_circles: + 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) + if symmetric_circles: + self._canvas.create_aa_circle(0, 0, 0, tags=("border_oval_4_b", "border_corner_part", "border_parts"), anchor=tkinter.CENTER, angle=180) requires_recoloring = True elif self._canvas.find_withtag("border_oval_3_a") and not round(corner_radius) * 2 < height: @@ -181,24 +185,28 @@ class CTkDrawEngine: # create canvas border corner parts if not already created if not self._canvas.find_withtag("inner_oval_1_a") and "inner_oval_1" not in exclude_parts: 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) + if symmetric_circles: + self._canvas.create_aa_circle(0, 0, 0, tags=("inner_oval_1_b", "inner_corner_part", "inner_parts"), anchor=tkinter.CENTER, angle=180) requires_recoloring = True if not self._canvas.find_withtag("inner_oval_2_a") and "inner_oval_2" not in exclude_parts: 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 symmetric_circles: + self._canvas.create_aa_circle(0, 0, 0, tags=("inner_oval_2_b", "inner_corner_part", "inner_parts"), anchor=tkinter.CENTER, angle=180) requires_recoloring = True if not self._canvas.find_withtag("inner_oval_3_a") and round(inner_corner_radius) * 2 < height - (2 * border_width) and "inner_oval_3" not in exclude_parts: 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) + if symmetric_circles: + self._canvas.create_aa_circle(0, 0, 0, tags=("inner_oval_3_b", "inner_corner_part", "inner_parts"), anchor=tkinter.CENTER, angle=180) requires_recoloring = True elif self._canvas.find_withtag("inner_oval_3_a") and not round(inner_corner_radius) * 2 < height - (2 * border_width): self._canvas.delete("inner_oval_3_a", "inner_oval_3_b") if not self._canvas.find_withtag("inner_oval_4_a") and round(inner_corner_radius) * 2 < height - (2 * border_width) and "inner_oval_4" not in exclude_parts: 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) + if symmetric_circles: + self._canvas.create_aa_circle(0, 0, 0, tags=("inner_oval_4_b", "inner_corner_part", "inner_parts"), anchor=tkinter.CENTER, angle=180) requires_recoloring = True elif self._canvas.find_withtag("inner_oval_4_a") and not round(inner_corner_radius) * 2 < height - (2 * border_width): self._canvas.delete("inner_oval_4_a", "inner_oval_4_b") diff --git a/customtkinter/customtkinter_entry.py b/customtkinter/customtkinter_entry.py index 8dcf612..e4d4a0e 100644 --- a/customtkinter/customtkinter_entry.py +++ b/customtkinter/customtkinter_entry.py @@ -117,8 +117,6 @@ class CTkEntry(tkinter.Frame): return self.master.cget("bg") except: pass - #print(self.master["style"]) - #return self.master.cget("background") def update_dimensions(self, event): # only redraw if dimensions changed (for performance) @@ -172,6 +170,9 @@ class CTkEntry(tkinter.Frame): fill=CTkThemeManager.single_color(self.border_color, self.appearance_mode), outline=CTkThemeManager.single_color(self.border_color, self.appearance_mode)) + if self.placeholder_text_active: + self.entry.config(fg=CTkThemeManager.single_color(self.placeholder_text_color, self.appearance_mode)) + def bind(self, *args, **kwargs): self.entry.bind(*args, **kwargs) diff --git a/customtkinter/customtkinter_label.py b/customtkinter/customtkinter_label.py index 239f611..0e50f82 100644 --- a/customtkinter/customtkinter_label.py +++ b/customtkinter/customtkinter_label.py @@ -117,12 +117,20 @@ class CTkLabel(tkinter.Frame): self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode)) - 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)) + if CTkThemeManager.single_color(self.fg_color, self.appearance_mode) is not None: + 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.text_label.configure(fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode), - bg=CTkThemeManager.single_color(self.fg_color, self.appearance_mode)) + self.text_label.configure(fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode), + bg=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.text_label.configure(fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode), + bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode)) def config(self, *args, **kwargs): self.configure(*args, **kwargs) diff --git a/customtkinter/customtkinter_theme_manager.py b/customtkinter/customtkinter_theme_manager.py index 08be887..ee4520b 100644 --- a/customtkinter/customtkinter_theme_manager.py +++ b/customtkinter/customtkinter_theme_manager.py @@ -6,7 +6,7 @@ import json class CTkThemeManager: theme = {} # contains all the theme data - built_in_themes = ["blue", "green", "dark_blue"] + built_in_themes = ["blue", "green", "dark-blue"] @classmethod def load_theme(cls, theme_name_or_path: str): diff --git a/examples/complex_example.py b/examples/complex_example.py index d6d9f9a..ea6d141 100644 --- a/examples/complex_example.py +++ b/examples/complex_example.py @@ -4,9 +4,7 @@ import customtkinter import sys customtkinter.set_appearance_mode("Light") # Modes: "System" (standard), "Dark", "Light" -customtkinter.set_default_color_theme("blue") # Themes: "blue" (standard), "green", "dark-blue" - -customtkinter.CTkSettings.preferred_drawing_method = "polygon_shapes" +customtkinter.set_default_color_theme("dark-blue") # Themes: "blue" (standard), "green", "dark-blue" class App(customtkinter.CTk): @@ -52,28 +50,29 @@ class App(customtkinter.CTk): self.label_1 = customtkinter.CTkLabel(master=self.frame_left, text="CustomTkinter", + text_font=("Roboto Medium", -16), # font name and size in px fg_color=None) self.label_1.grid(row=1, column=0, pady=10, padx=10) self.button_1 = customtkinter.CTkButton(master=self.frame_left, text="CTkButton 1", command=self.button_event, - border_width=0, - corner_radius=8) + fg_color=None, + border_width=2) self.button_1.grid(row=2, column=0, pady=10, padx=20) self.button_2 = customtkinter.CTkButton(master=self.frame_left, text="CTkButton 2", command=self.button_event, - border_width=0, - corner_radius=8) + fg_color=None, + border_width=2) self.button_2.grid(row=3, column=0, pady=10, padx=20) self.button_3 = customtkinter.CTkButton(master=self.frame_left, text="CTkButton 3", command=self.button_event, - border_width=0, - corner_radius=8) + fg_color=None, + border_width=2) self.button_3.grid(row=4, column=0, pady=10, padx=20) self.check_box_1 = customtkinter.CTkCheckBox(master=self.frame_left, @@ -103,19 +102,18 @@ class App(customtkinter.CTk): "amet consetetur sadipscing elitr,\n" + "sed diam nonumy eirmod tempor\n" + "invidunt ut labore", - width=250, + width=240, height=100, fg_color=("white", "gray38"), # <- custom tuple-color justify=tkinter.LEFT) self.label_info_1.place(relx=0.5, rely=0.15, anchor=tkinter.N) - self.progressbar = customtkinter.CTkProgressBar(master=self.frame_info) + self.progressbar = customtkinter.CTkProgressBar(master=self.frame_info, width=240) self.progressbar.place(relx=0.5, rely=0.85, anchor=tkinter.S) # ============ frame_right <- ============ self.slider_1 = customtkinter.CTkSlider(master=self.frame_right, - height=16, from_=1, to=0, number_of_steps=3, @@ -125,8 +123,6 @@ class App(customtkinter.CTk): self.slider_2 = customtkinter.CTkSlider(master=self.frame_right, width=160, - height=16, - button_length=0, command=self.progressbar.set) self.slider_2.grid(row=2, column=0, columnspan=2, pady=10, padx=20, sticky="we") self.slider_2.set(0.7) @@ -142,27 +138,19 @@ class App(customtkinter.CTk): self.button_4 = customtkinter.CTkButton(master=self.frame_right, height=25, text="CTkButton", - command=self.button_event, - border_width=0, - corner_radius=8) + command=self.button_event) self.button_4.grid(row=2, column=2, columnspan=1, pady=10, padx=20, sticky="we") self.entry = customtkinter.CTkEntry(master=self.frame_right, width=120, height=30, - corner_radius=10, - border_width=2, placeholder_text="CTkEntry") self.entry.grid(row=4, column=0, columnspan=2, pady=20, padx=20, sticky="we") self.button_5 = customtkinter.CTkButton(master=self.frame_right, - height=26, + height=30, text="CTkButton", - command=self.button_event, - fg_color="gray30", - border_width=2, - border_color=("gray30", "gray50"), - corner_radius=13) + command=self.button_event) self.button_5.grid(row=4, column=2, columnspan=1, pady=20, padx=20, sticky="we") self.progressbar.set(0.5) diff --git a/test/test_button_antialiasing.py b/test/test_button_antialiasing.py index 2eb6bd5..39e874f 100644 --- a/test/test_button_antialiasing.py +++ b/test/test_button_antialiasing.py @@ -1,7 +1,6 @@ import customtkinter import tkinter -customtkinter.CTkSettings.preferred_drawing_method = "polygon_shapes" customtkinter.set_default_color_theme("blue") customtkinter.set_appearance_mode("dark") @@ -21,7 +20,7 @@ f2 = customtkinter.CTkFrame(app, fg_color="gray10", corner_radius=0) f2.grid(row=0, column=1, rowspan=1, columnspan=1, sticky="nsew") f2.grid_columnconfigure(0, weight=1) -f3 = customtkinter.CTkFrame(app, fg_color="gray90", corner_radius=0) +f3 = customtkinter.CTkFrame(app, fg_color="gray85", corner_radius=0) f3.grid(row=0, column=2, rowspan=1, columnspan=1, sticky="nsew") f3.grid_columnconfigure(0, weight=1) @@ -38,8 +37,8 @@ for i in range(0, 18, 1): fg_color="#228da8") b.grid(row=i, column=0, pady=5, padx=15, sticky="nsew") - b = customtkinter.CTkButton(f3, corner_radius=i, height=34, border_width=3, text=f"{i} {i - 3}", - fg_color=None, border_color="gray10", text_color="black") + b = customtkinter.CTkButton(f3, corner_radius=i, height=34, border_width=2, text=f"{i} {i-2}", + fg_color=None, border_color="gray20", text_color="black") b.grid(row=i, column=0, pady=5, padx=15, sticky="nsew") b = customtkinter.CTkButton(f4, corner_radius=i, height=34, border_width=0, text=f"{i}", diff --git a/test/test_string_dialog.py b/test/test_string_dialog.py new file mode 100644 index 0000000..c0d2766 --- /dev/null +++ b/test/test_string_dialog.py @@ -0,0 +1,29 @@ +import customtkinter +import tkinter + +customtkinter.set_appearance_mode("light") +customtkinter.set_default_color_theme("dark-blue") + +app = customtkinter.CTk() +app.geometry("400x300") +app.title("CTkDialog Test") + + +def change_mode(): + if customtkinter.get_appearance_mode().lower() == "dark": + customtkinter.set_appearance_mode("light") + elif customtkinter.get_appearance_mode().lower() == "light": + customtkinter.set_appearance_mode("dark") + + +def button_click_event(): + dialog = customtkinter.CTkDialog(master=None, text="Type in a number:", title="Test") + print("Number:", dialog.get_input()) + + +button = customtkinter.CTkButton(app, text="Open Dialog", command=button_click_event) +button.place(relx=0.5, rely=0.5, anchor=tkinter.CENTER) +c1 = customtkinter.CTkCheckBox(app, text="dark mode", command=change_mode) +c1.place(relx=0.5, rely=0.8, anchor=tkinter.CENTER) + +app.mainloop() \ No newline at end of file