ICRA/app/app.py

82 lines
2.3 KiB
Python

"""Application composition root."""
from __future__ import annotations
import tkinter as tk
from .gui import ColorPickerMixin, ExclusionMixin, ThemeMixin, UIBuilderMixin
from .i18n import I18nMixin
from .logic import DEFAULTS, LANGUAGE, ImageProcessingMixin, ResetMixin
class ICRAApp(
I18nMixin,
ThemeMixin,
UIBuilderMixin,
ImageProcessingMixin,
ExclusionMixin,
ColorPickerMixin,
ResetMixin,
):
"""Tkinter based application for isolating configurable colour ranges."""
def __init__(self, root: tk.Tk):
self.root = root
self.init_i18n(LANGUAGE)
self.root.title(self._t("app.title"))
self._setup_window()
# Theme and styling
self.init_theme()
# Tkinter state variables
self.DEFAULTS = DEFAULTS.copy()
self.hue_min = tk.DoubleVar(value=self.DEFAULTS["hue_min"])
self.hue_max = tk.DoubleVar(value=self.DEFAULTS["hue_max"])
self.sat_min = tk.DoubleVar(value=self.DEFAULTS["sat_min"])
self.val_min = tk.DoubleVar(value=self.DEFAULTS["val_min"])
self.val_max = tk.DoubleVar(value=self.DEFAULTS["val_max"])
self.alpha = tk.IntVar(value=self.DEFAULTS["alpha"])
self.ref_hue = None
# Debounce for heavy preview updates
self.update_delay_ms = 400
self._update_job = None
# Exclusion rectangles (preview coordinates)
self.exclude_rects: list[tuple[int, int, int, int]] = []
self._rubber_start = None
self._rubber_id = None
self.pick_mode = False
# Image references
self.image_path = None
self.orig_img = None
self.preview_img = None
self.preview_tk = None
self.overlay_tk = None
self.image_paths = []
self.current_image_index = -1
# Build UI
self.setup_ui()
self._init_copy_menu()
self.bring_to_front()
def _setup_window(self) -> None:
self.root.overrideredirect(True)
screen_width = self.root.winfo_screenwidth()
screen_height = self.root.winfo_screenheight()
self.root.geometry(f"{screen_width}x{screen_height}+0+0")
self.root.configure(bg="#f2f2f7")
def start_app() -> None:
"""Entry point used by the CLI script."""
root = tk.Tk()
app = ICRAApp(root)
root.mainloop()
__all__ = ["ICRAApp", "start_app"]