From 0f44b347019e620e09b2423a4b82f7895db0b96b Mon Sep 17 00:00:00 2001 From: Falko Habel Date: Thu, 28 Mar 2024 15:22:48 +0100 Subject: [PATCH] implemented new ColorPicker Widget --- Widgets/color_widget/ctk_color_picker.py | 112 ++++++++++++----------- main.py | 2 +- scripts/settings.py | 4 +- 3 files changed, 63 insertions(+), 55 deletions(-) diff --git a/Widgets/color_widget/ctk_color_picker.py b/Widgets/color_widget/ctk_color_picker.py index eae627b..d9c6b6d 100644 --- a/Widgets/color_widget/ctk_color_picker.py +++ b/Widgets/color_widget/ctk_color_picker.py @@ -1,7 +1,4 @@ -# CTk Color Picker for Ctk -# Original Author: Akash Bora (Akascape) -# Contributers: Victor Vimbert-Guerlais (helloHackYnow) - +# this is a modified version of the CTkColorPicker from GitHub import customtkinter as Ctk from PIL import Image, ImageTk @@ -14,23 +11,20 @@ class AskColor(Ctk.CTkToplevel): def __init__(self, master, - width: int = 300, + font = None, + width: int = 250, title: str = "Choose Color", initial_color: str = None, - bg_color: str = None, - fg_color: str = None, - button_color: str = None, - button_hover_color: str = None, text: str = "apply", - corner_radius: int = 24, + corner_radius: int = 16, slider_border: int = 1, **button_kwargs): - super().__init__(master, **button_kwargs) - + self.selected_color = None self.title(title) - WIDTH = width if width>=200 else 200 - HEIGHT = WIDTH + 150 + WIDTH = width if width >= 250 else 250 + HEIGHT = WIDTH + 110 + self.font = font if font is not None else Ctk.CTkFont(family="kDefaultFont", size=16) self.image_dimension = self._apply_window_scaling(WIDTH - 100) self.target_dimension = self._apply_window_scaling(20) self.initial_color = initial_color @@ -39,30 +33,23 @@ class AskColor(Ctk.CTkToplevel): self.resizable(width=False, height=False) self.transient(self.master) self.lift() - self.grid_columnconfigure(0, weight=1) - self.grid_rowconfigure(0, weight=1) self.after(10) self.protocol("WM_DELETE_WINDOW", self._on_closing) self.default_hex_color = "#ffffff" self.default_rgb = [255, 255, 255] self.rgb_color = self.default_rgb[:] - - self.bg_color = self._apply_appearance_mode(Ctk.ThemeManager.theme["CTkFrame"]["fg_color"]) if bg_color is None else bg_color - self.fg_color = self.fg_color = self._apply_appearance_mode(Ctk.ThemeManager.theme["CTkFrame"]["top_fg_color"]) if fg_color is None else fg_color - self.button_color = self._apply_appearance_mode(Ctk.ThemeManager.theme["CTkButton"]["fg_color"]) if button_color is None else button_color - self.button_hover_color = self._apply_appearance_mode(Ctk.ThemeManager.theme["CTkButton"]["hover_color"]) if button_hover_color is None else button_hover_color self.button_text = text self.corner_radius = corner_radius - self.slider_border = 10 if slider_border>=10 else slider_border + self.slider_border = 10 if slider_border >= 10 else slider_border - self.config(bg=self.bg_color) - - self.frame = Ctk.CTkFrame(master=self, fg_color=self.fg_color, bg_color=self.bg_color) - self.frame.grid(padx=20, pady=20, sticky="nswe") - + self.frame = Ctk.CTkFrame(master=self) + self.frame.grid(sticky="nswe", padx=5, pady=5) + self.fg_color = self.fg_color = self._apply_appearance_mode(Ctk.ThemeManager.theme["CTkFrame"]["fg_color"]) self.canvas = Ctk.CTkCanvas(self.frame, height=self.image_dimension, width=self.image_dimension, highlightthickness=0, bg=self.fg_color) - self.canvas.pack(pady=20) + self.canvas.grid(row=0, column=0, columnspan=2, pady=20) + + self.canvas.bind("", self.on_mouse_drag) self.img1 = Image.open(os.path.join(PATH, 'color_wheel.png')).resize((self.image_dimension, self.image_dimension), Image.Resampling.LANCZOS) @@ -81,35 +68,58 @@ class AskColor(Ctk.CTkToplevel): button_length=15, progress_color=self.default_hex_color, from_=0, to=255, variable=self.brightness_slider_value, number_of_steps=256, button_corner_radius=self.corner_radius, corner_radius=self.corner_radius, - button_color=self.button_color, button_hover_color=self.button_hover_color, command=lambda x:self.update_colors()) - self.slider.pack(fill="both", pady=(0,15), padx=20-self.slider_border) - - self.label = Ctk.CTkLabel(master=self.frame, text_color="#000000", height=50, fg_color=self.default_hex_color, - corner_radius=self.corner_radius, text=self.default_hex_color) - self.label.pack(fill="both", padx=10) - self.button = Ctk.CTkButton(master=self.frame, text=self.button_text, height=50, corner_radius=self.corner_radius, fg_color=self.button_color, - hover_color=self.button_hover_color, command=self._ok_event, **button_kwargs) - self.button.pack(fill="both", padx=10, pady=20) + self.slider.grid(row=1, column=0, columnspan=2, pady=(0, 15), padx=20-self.slider_border) + + self.label = Ctk.CTkLabel(master=self.frame, text_color="#000000", height=50, width=75, fg_color=self.default_hex_color, + corner_radius=self.corner_radius, text="") + + self.color_entry = Ctk.CTkEntry(master=self.frame, height=50, corner_radius=self.corner_radius, font=self.font, width=100) + self.color_entry.configure(placeholder_text=self.default_hex_color) # Insert the new text + + + + self.button = Ctk.CTkButton(master=self.frame, text=self.button_text, height=50, corner_radius=self.corner_radius,width = 200, + command=self._ok_event, **button_kwargs) + + self.label.grid(row=2, column=0, padx=(5, 20), pady=10, sticky="e") + self.color_entry.grid(row=2, column=1, padx=(5, 5), pady=10, sticky="w") + self.button.grid(row=3, column=0, columnspan=3, padx=5, pady=10) self.after(150, lambda: self.label.focus()) - + self.grab_set() + def get(self): - self._color = self.label._fg_color - self.wait_window(self) - return self._color + # Use the stored selected_color instead of accessing the widget + return self.selected_color def _ok_event(self, event=None): - self._color = self.label._fg_color + input_string = self.color_entry.get() + self.selected_color = self.check_rgb_hex_color(input_string) # Store the selected color self.grab_release() self.destroy() del self.img1 del self.img2 del self.wheel del self.target + + def check_rgb_hex_color(self, input_string): + if not input_string: + return self.default_hex_color + if not input_string.startswith("#"): + input_string = "#" + input_string + hex_color = input_string.lstrip("#") + if len(hex_color) != 6: + return None + try: + int(hex_color, 16) + return input_string + except ValueError: + return None + def _on_closing(self): self._color = None @@ -166,15 +176,9 @@ class AskColor(Ctk.CTkToplevel): self.slider.configure(progress_color=self.default_hex_color) self.label.configure(fg_color=self.default_hex_color) - self.label.configure(text=str(self.default_hex_color)) - - if self.brightness_slider_value.get() < 70: - self.label.configure(text_color="white") - else: - self.label.configure(text_color="black") - - if str(self.label._fg_color)=="black": - self.label.configure(text_color="white") + self.color_entry.delete(0, Ctk.END) # Delete any existing text in the color_entry widget + self.color_entry.configure(placeholder_text=self.default_hex_color) # Insert the new text + def projection_on_circle(self, point_x, point_y, circle_x, circle_y, radius): angle = math.atan2(point_y - circle_y, point_x - circle_x) @@ -261,5 +265,7 @@ class AskColor(Ctk.CTkToplevel): self.canvas.create_image(center, center, image=self.target) if __name__ == "__main__": - app = AskColor() - app.mainloop() + app = AskColor(master=None, font=None) + app.wait_window(app) # This waits until the window is closed + color = app.get() # Access the color stored before the window was destroyed + print("Selected color:", color) \ No newline at end of file diff --git a/main.py b/main.py index d7de1a4..a9d2047 100644 --- a/main.py +++ b/main.py @@ -4,7 +4,7 @@ from PIL import Image import scripts.get_sys_info as system_code from scripts.ClosePopup import ClosePopup -from scripts.Settings import Settings +from scripts.settings import Settings from scripts.Converter import Converter from scripts.Labeling import Labeling diff --git a/scripts/settings.py b/scripts/settings.py index 887d522..3aa9ab4 100644 --- a/scripts/settings.py +++ b/scripts/settings.py @@ -69,8 +69,10 @@ class Settings(Ctk.CTkFrame): self.thickness_slider_value.configure(text=value) def ask_color(self): - self.pick_color = AskColor(master=self.master, initial_color=system_code.color) + self.pick_color = AskColor(master=self.master, font=self.my_font) + self.wait_window(self.pick_color) self.color = self.pick_color.get() # get the color string + if self.color is not None: self.color_btn.configure(fg_color=self.color) # set the wanted image format