Source code for complex_problems.complex_problems_dialog

"""Dialog for selecting which complex problem to solve."""

from __future__ import annotations

import tkinter as tk
from tkinter import ttk

from complex_problems.problem_registry import PROBLEM_REGISTRY
from config import get_env_from_schema
from frontend.ui_dialogs import ToolTip, setup_arrow_enter_navigation
from frontend.window_utils import bind_wraplength, fit_and_center, make_modal
from utils import get_logger

logger = get_logger(__name__)


[docs] class ComplexProblemsDialog: """Window for selecting a complex problem to solve. Args: parent: Parent window. """ def __init__(self, parent: tk.Tk | tk.Toplevel) -> None: self.parent = parent self.win = tk.Toplevel(parent) self.win.title("Complex Problems") bg: str = get_env_from_schema("UI_BACKGROUND") self.win.configure(bg=bg) self._build_ui() fit_and_center(self.win, min_width=640, min_height=680, resizable=True) make_modal(self.win, parent) logger.info("Complex problems dialog opened") def _build_ui(self) -> None: """Construct the dialog layout.""" pad: int = get_env_from_schema("UI_PADDING") main_frame = ttk.Frame(self.win, padding=pad * 2) main_frame.pack(fill=tk.BOTH, expand=True) ttk.Label( main_frame, text="Complex Problems", style="Title.TLabel", ).pack(pady=(0, pad)) desc = ttk.Label( main_frame, text=( "Select a special problem to solve. Each problem has\n" "custom parameters, statistics, and visualizations." ), style="Small.TLabel", justify=tk.CENTER, ) desc.pack(pady=(0, pad * 2)) bind_wraplength(main_frame, desc, pad=4 * pad, min_wrap=200) # Buttons for each problem btn_frame = ttk.Frame(main_frame) btn_frame.pack(fill=tk.BOTH, expand=True) for i, (prob_id, descriptor) in enumerate(PROBLEM_REGISTRY.items()): btn = ttk.Button( btn_frame, text=descriptor.name, command=self._make_open_callback(descriptor), ) btn.pack(fill=tk.X, padx=pad, pady=pad // 2) ToolTip(btn, descriptor.description) btn_close = ttk.Button( main_frame, text="Close", style="Cancel.TButton", command=self.win.destroy, ) btn_close.pack(pady=(pad * 2, 0)) setup_arrow_enter_navigation([[btn_close]]) btn_close.focus_set() def _make_open_callback(self, descriptor): """Create a callback that opens the problem dialog and closes this one.""" def _on_click() -> None: self.win.destroy() descriptor.open_dialog(self.parent) return _on_click