ICRA/app/gui/color_picker.py

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"]