Compare commits
3 Commits
923b773ee4
...
a1c105dba1
| Author | SHA1 | Date |
|---|---|---|
|
|
a1c105dba1 | |
|
|
43c26ce9a6 | |
|
|
7156bbb6c4 |
|
|
@ -145,6 +145,11 @@ cython_debug/
|
||||||
*.ipr
|
*.ipr
|
||||||
*.iws
|
*.iws
|
||||||
|
|
||||||
|
# uv / build artifacts
|
||||||
|
uv.lock
|
||||||
|
uv/
|
||||||
|
.uv/
|
||||||
|
|
||||||
# Git worktree cruft
|
# Git worktree cruft
|
||||||
*.orig
|
*.orig
|
||||||
*.rej
|
*.rej
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,6 @@ uv pip install . # install ICRS and dependencies
|
||||||
uv run icrs # launches the GUI
|
uv run icrs # launches the GUI
|
||||||
```
|
```
|
||||||
The launcher copies Tcl/Tk resources into the virtualenv on first run, so no manual environment tweaks are needed.
|
The launcher copies Tcl/Tk resources into the virtualenv on first run, so no manual environment tweaks are needed.
|
||||||
To include the optional ttkbootstrap theme pack:
|
|
||||||
```bash
|
|
||||||
uv pip install '.[ui]'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Workflow
|
## Workflow
|
||||||
1. Load an image (`๐`) or a folder (`๐`).
|
1. Load an image (`๐`) or a folder (`๐`).
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,12 @@
|
||||||
|
|
||||||
from .color_picker import ColorPickerMixin
|
from .color_picker import ColorPickerMixin
|
||||||
from .exclusions import ExclusionMixin
|
from .exclusions import ExclusionMixin
|
||||||
from .theme import ThemeMixin, HAS_TTKBOOTSTRAP
|
from .theme import ThemeMixin
|
||||||
from .ui import UIBuilderMixin
|
from .ui import UIBuilderMixin
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"ColorPickerMixin",
|
"ColorPickerMixin",
|
||||||
"ExclusionMixin",
|
"ExclusionMixin",
|
||||||
"ThemeMixin",
|
"ThemeMixin",
|
||||||
"HAS_TTKBOOTSTRAP",
|
|
||||||
"UIBuilderMixin",
|
"UIBuilderMixin",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,6 @@ from __future__ import annotations
|
||||||
import platform
|
import platform
|
||||||
from tkinter import ttk
|
from tkinter import ttk
|
||||||
|
|
||||||
try:
|
|
||||||
import ttkbootstrap as tb # type: ignore
|
|
||||||
|
|
||||||
HAS_TTKBOOTSTRAP = True
|
|
||||||
except Exception: # pragma: no cover - optional dependency
|
|
||||||
tb = None
|
|
||||||
HAS_TTKBOOTSTRAP = False
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import winreg
|
import winreg
|
||||||
except Exception: # pragma: no cover - platform-specific
|
except Exception: # pragma: no cover - platform-specific
|
||||||
|
|
@ -24,27 +16,12 @@ class ThemeMixin:
|
||||||
|
|
||||||
theme: str
|
theme: str
|
||||||
style: ttk.Style
|
style: ttk.Style
|
||||||
using_tb: bool
|
|
||||||
scale_style: str
|
scale_style: str
|
||||||
|
|
||||||
def init_theme(self) -> None:
|
def init_theme(self) -> None:
|
||||||
"""Initialise ttk style handling and apply the detected theme."""
|
"""Initialise ttk style handling and apply the detected theme."""
|
||||||
if HAS_TTKBOOTSTRAP:
|
self.style = ttk.Style()
|
||||||
try:
|
self.style.theme_use("clam")
|
||||||
try:
|
|
||||||
self.root.tk.call("package", "require", "msgcat") # type: ignore[attr-defined]
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
self.style = tb.Style()
|
|
||||||
self.using_tb = True
|
|
||||||
except Exception:
|
|
||||||
self.style = ttk.Style()
|
|
||||||
self.style.theme_use("clam")
|
|
||||||
self.using_tb = False
|
|
||||||
else:
|
|
||||||
self.style = ttk.Style()
|
|
||||||
self.style.theme_use("clam")
|
|
||||||
self.using_tb = False
|
|
||||||
|
|
||||||
self.theme = "light"
|
self.theme = "light"
|
||||||
self.apply_theme(self.detect_system_theme())
|
self.apply_theme(self.detect_system_theme())
|
||||||
|
|
@ -54,17 +31,7 @@ class ThemeMixin:
|
||||||
mode = (mode or "light").lower()
|
mode = (mode or "light").lower()
|
||||||
self.theme = "dark" if mode == "dark" else "light"
|
self.theme = "dark" if mode == "dark" else "light"
|
||||||
|
|
||||||
if HAS_TTKBOOTSTRAP:
|
self.scale_style = "Horizontal.TScale"
|
||||||
try:
|
|
||||||
theme_name = "darkly" if self.theme == "dark" else "flatly"
|
|
||||||
self.style.theme_use(theme_name)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
self.scale_style = (
|
|
||||||
"info.Horizontal.TScale" if self.theme == "dark" else "primary.Horizontal.TScale"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
self.scale_style = "Horizontal.TScale"
|
|
||||||
|
|
||||||
if self.theme == "dark":
|
if self.theme == "dark":
|
||||||
bg, fg = "#0f0f10", "#f1f1f1"
|
bg, fg = "#0f0f10", "#f1f1f1"
|
||||||
|
|
@ -77,11 +44,10 @@ class ThemeMixin:
|
||||||
s = self.style
|
s = self.style
|
||||||
s.configure("TFrame", background=bg)
|
s.configure("TFrame", background=bg)
|
||||||
s.configure("TLabel", background=bg, foreground=fg, font=("Segoe UI", 10))
|
s.configure("TLabel", background=bg, foreground=fg, font=("Segoe UI", 10))
|
||||||
if not HAS_TTKBOOTSTRAP:
|
s.configure(
|
||||||
s.configure(
|
"TButton", padding=8, relief="flat", background="#e0e0e0", foreground=fg, font=("Segoe UI", 10)
|
||||||
"TButton", padding=8, relief="flat", background="#e0e0e0", foreground=fg, font=("Segoe UI", 10)
|
)
|
||||||
)
|
s.map("TButton", background=[("active", "#d0d0d0")])
|
||||||
s.map("TButton", background=[("active", "#d0d0d0")])
|
|
||||||
|
|
||||||
button_refresher = getattr(self, "_refresh_toolbar_buttons_theme", None)
|
button_refresher = getattr(self, "_refresh_toolbar_buttons_theme", None)
|
||||||
if callable(button_refresher):
|
if callable(button_refresher):
|
||||||
|
|
@ -123,4 +89,4 @@ class ThemeMixin:
|
||||||
self.update_preview() # type: ignore[attr-defined]
|
self.update_preview() # type: ignore[attr-defined]
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["ThemeMixin", "HAS_TTKBOOTSTRAP"]
|
__all__ = ["ThemeMixin"]
|
||||||
|
|
|
||||||
|
|
@ -192,11 +192,11 @@ class UIBuilderMixin:
|
||||||
swatch.bind("<Leave>", lambda _e: swatch.configure(highlightbackground="#b1b1b6"))
|
swatch.bind("<Leave>", lambda _e: swatch.configure(highlightbackground="#b1b1b6"))
|
||||||
|
|
||||||
def _add_toolbar_button(self, parent, text: str, command) -> None:
|
def _add_toolbar_button(self, parent, text: str, command) -> None:
|
||||||
font = tkfont.Font(root=self.root, family="Segoe UI", size=10, weight="bold")
|
font = tkfont.Font(root=self.root, family="Segoe UI", size=9)
|
||||||
padding_x = 18
|
padding_x = 12
|
||||||
width = font.measure(text) + padding_x * 2
|
width = font.measure(text) + padding_x * 2
|
||||||
height = 32
|
height = 28
|
||||||
radius = 12
|
radius = 9
|
||||||
bg = self.root.cget("bg") if hasattr(self.root, "cget") else "#f2f2f7"
|
bg = self.root.cget("bg") if hasattr(self.root, "cget") else "#f2f2f7"
|
||||||
canvas = tk.Canvas(
|
canvas = tk.Canvas(
|
||||||
parent,
|
parent,
|
||||||
|
|
@ -209,7 +209,7 @@ class UIBuilderMixin:
|
||||||
cursor="hand2",
|
cursor="hand2",
|
||||||
takefocus=1,
|
takefocus=1,
|
||||||
)
|
)
|
||||||
canvas.pack(side=tk.LEFT, padx=6)
|
canvas.pack(side=tk.LEFT, padx=4, pady=1)
|
||||||
|
|
||||||
palette = self._toolbar_palette()
|
palette = self._toolbar_palette()
|
||||||
rect_id = self._create_round_rect(
|
rect_id = self._create_round_rect(
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,6 @@ dependencies = [
|
||||||
"pillow>=10.0.0",
|
"pillow>=10.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.optional-dependencies]
|
|
||||||
ui = ["ttkbootstrap>=1.10.0"]
|
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
icrs = "app.launcher:main"
|
icrs = "app.launcher:main"
|
||||||
|
|
||||||
|
|
|
||||||
Loadingโฆ
Reference in New Issue