Refactor app layout and load defaults from config

This commit is contained in:
lm 2025-10-15 18:16:18 +02:00
parent fc821f64aa
commit 02255f5dee
14 changed files with 109 additions and 29 deletions

View File

@ -1,4 +1,4 @@
"""ColorCalc application package."""
"""Application package."""
from .app import PurpleTunerApp, start_app

View File

@ -4,13 +4,8 @@ from __future__ import annotations
import tkinter as tk
from .color_picker import ColorPickerMixin
from .constants import DEFAULTS
from .exclusions import ExclusionMixin
from .image_processing import ImageProcessingMixin
from .reset import ResetMixin
from .theme import ThemeMixin
from .ui import UIBuilderMixin
from .gui import ColorPickerMixin, ExclusionMixin, ThemeMixin, UIBuilderMixin
from .logic import DEFAULTS, ImageProcessingMixin, ResetMixin
class PurpleTunerApp(

14
app/gui/__init__.py Normal file
View File

@ -0,0 +1,14 @@
"""GUI-related mixins and helpers for the application."""
from .color_picker import ColorPickerMixin
from .exclusions import ExclusionMixin
from .theme import ThemeMixin, HAS_TTKBOOTSTRAP
from .ui import UIBuilderMixin
__all__ = [
"ColorPickerMixin",
"ExclusionMixin",
"ThemeMixin",
"HAS_TTKBOOTSTRAP",
"UIBuilderMixin",
]

14
app/logic/__init__.py Normal file
View File

@ -0,0 +1,14 @@
"""Logic utilities and mixins for processing and configuration."""
from .constants import BASE_DIR, DEFAULTS, IMAGES_DIR, PREVIEW_MAX_SIZE
from .image_processing import ImageProcessingMixin
from .reset import ResetMixin
__all__ = [
"BASE_DIR",
"DEFAULTS",
"IMAGES_DIR",
"PREVIEW_MAX_SIZE",
"ImageProcessingMixin",
"ResetMixin",
]

66
app/logic/constants.py Normal file
View File

@ -0,0 +1,66 @@
"""Shared configuration constants for the application."""
from __future__ import annotations
import contextlib
from pathlib import Path
from typing import Any, Callable
try: # Python 3.11 and above
import tomllib # type: ignore[attr-defined]
except ModuleNotFoundError: # pragma: no cover - fallback for <3.11
with contextlib.suppress(ModuleNotFoundError):
import tomli as tomllib # type: ignore[assignment]
if "tomllib" not in globals():
tomllib = None # type: ignore[assignment]
PREVIEW_MAX_SIZE = (1200, 800)
BASE_DIR = Path(__file__).resolve().parents[2]
IMAGES_DIR = BASE_DIR / "images"
CONFIG_FILE = BASE_DIR / "config.toml"
_DEFAULTS_BASE = {
"hue_min": 250.0,
"hue_max": 310.0,
"sat_min": 15.0,
"val_min": 15.0,
"val_max": 100.0,
"alpha": 120,
}
_DEFAULT_TYPES: dict[str, Callable[[Any], Any]] = {
"hue_min": float,
"hue_max": float,
"sat_min": float,
"val_min": float,
"val_max": float,
"alpha": int,
}
def _load_default_overrides() -> dict[str, Any]:
"""Load default slider overrides from config.toml if available."""
if tomllib is None or not CONFIG_FILE.exists():
return {}
decode_error = getattr(tomllib, "TOMLDecodeError", ValueError) # type: ignore[attr-defined]
try:
with CONFIG_FILE.open("rb") as handle:
data = tomllib.load(handle)
except (OSError, AttributeError, decode_error, TypeError): # type: ignore[arg-type]
return {}
settings = data.get("defaults")
if not isinstance(settings, dict):
return {}
overrides: dict[str, Any] = {}
for key, caster in _DEFAULT_TYPES.items():
if key not in settings:
continue
try:
overrides[key] = caster(settings[key])
except (TypeError, ValueError):
continue
return overrides
DEFAULTS = {**_DEFAULTS_BASE, **_load_default_overrides()}

View File

@ -1,19 +0,0 @@
"""Shared configuration constants for ColorCalc."""
from __future__ import annotations
from pathlib import Path
PREVIEW_MAX_SIZE = (1200, 800)
DEFAULTS = {
"hue_min": 250.0,
"hue_max": 310.0,
"sat_min": 15.0,
"val_min": 15.0,
"val_max": 100.0,
"alpha": 120,
}
BASE_DIR = Path(__file__).resolve().parent.parent
IMAGES_DIR = BASE_DIR / "images"

10
config.toml Normal file
View File

@ -0,0 +1,10 @@
[defaults]
# Override any of the following keys to tweak the initial slider values:
# hue_min, hue_max, sat_min, val_min, val_max accept floating point numbers.
# alpha accepts an integer between 0 and 255.
hue_min = 250.0
hue_max = 310.0
sat_min = 15.0
val_min = 15.0
val_max = 100.0
alpha = 120

View File

@ -1,6 +1,6 @@
"""CLI entry point for the ColorCalc application."""
"""CLI entry point for the application."""
from colorcalc import start_app
from app import start_app
if __name__ == "__main__":