61 lines
2.0 KiB
Python
61 lines
2.0 KiB
Python
"""Color selection utilities."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import colorsys
|
|
|
|
from tkinter import colorchooser, messagebox
|
|
|
|
|
|
class ColorPickerMixin:
|
|
"""Handles colour selection from dialogs and mouse clicks."""
|
|
|
|
ref_hue: float | None
|
|
|
|
def choose_color(self):
|
|
rgb, hex_colour = colorchooser.askcolor(title="Farbe wählen")
|
|
if rgb is None:
|
|
return
|
|
r, g, b = [int(channel) for channel in rgb]
|
|
h, s, v = colorsys.rgb_to_hsv(r / 255.0, g / 255.0, b / 255.0)
|
|
self.ref_hue = h * 360.0
|
|
span = 30
|
|
self.hue_min.set((self.ref_hue - span) % 360)
|
|
self.hue_max.set((self.ref_hue + span) % 360)
|
|
self.update_preview()
|
|
self.status.config(text=f"Farbe gewählt: {hex_colour} (Hue {self.ref_hue:.1f}°)")
|
|
|
|
def enable_pick_mode(self):
|
|
if self.preview_img is None:
|
|
messagebox.showinfo("Info", "Bitte zuerst ein Bild laden.")
|
|
return
|
|
self.pick_mode = True
|
|
self.status.config(text="Pick-Modus: Klicke links ins Bild, um Farbe zu wählen (Esc beendet)")
|
|
|
|
def disable_pick_mode(self, event=None):
|
|
if self.pick_mode:
|
|
self.pick_mode = False
|
|
self.status.config(text="Pick-Modus beendet.")
|
|
|
|
def on_canvas_click(self, event):
|
|
if not self.pick_mode or self.preview_img is None:
|
|
return
|
|
x = int(event.x)
|
|
y = int(event.y)
|
|
if x < 0 or y < 0 or x >= self.preview_img.width or y >= self.preview_img.height:
|
|
return
|
|
r, g, b, a = self.preview_img.getpixel((x, y))
|
|
if a == 0:
|
|
return
|
|
h, s, v = colorsys.rgb_to_hsv(r / 255.0, g / 255.0, b / 255.0)
|
|
self.ref_hue = h * 360.0
|
|
span = 30
|
|
self.hue_min.set((self.ref_hue - span) % 360)
|
|
self.hue_max.set((self.ref_hue + span) % 360)
|
|
self.disable_pick_mode()
|
|
self.update_preview()
|
|
self.status.config(text=f"Farbe vom Bild gewählt: Hue {self.ref_hue:.1f}°")
|
|
|
|
|
|
__all__ = ["ColorPickerMixin"]
|