diff --git a/app/tools/cs2_patterns.py b/app/tools/cs2_patterns.py index d02593f..3900825 100644 --- a/app/tools/cs2_patterns.py +++ b/app/tools/cs2_patterns.py @@ -183,12 +183,12 @@ class CS2PatternTool(tk.Toplevel): self.theme = getattr(self.app, "theme", "light") self.title(self._t("cs2.title")) self.geometry("560x380") - self.minsize(520, 320) + self.minsize(540, 340) self.resizable(True, True) self._drag_offset: tuple[int, int] | None = None self._setup_window() - self.body = ttk.Frame(self) - self.body.pack(fill=tk.BOTH, expand=True, padx=16, pady=(12, 16)) + self.body = ttk.Frame(self.container, style="CS2.TFrame") + self.body.pack(fill=tk.BOTH, expand=True, padx=18, pady=(14, 18)) self._toolbar_buttons: list[dict[str, Any]] = [] self.weapons_var = tk.StringVar() @@ -196,6 +196,7 @@ class CS2PatternTool(tk.Toplevel): self.directory_var = tk.StringVar(value=str(IMAGES_DIR.resolve())) self.status_var = tk.StringVar(value=self._t("cs2.status_loading")) + self._init_styles() self._init_widgets() self._data_loaded = False self._load_thread: Optional[threading.Thread] = None @@ -203,60 +204,63 @@ class CS2PatternTool(tk.Toplevel): self.protocol("WM_DELETE_WINDOW", self._on_close) self._bring_to_front() + self._center_window() # UI construction -------------------------------------------------- def _init_widgets(self) -> None: frame = self.body - toolbar = ttk.Frame(frame) + toolbar = tk.Frame(frame, bg=self._background_colour(), bd=0, highlightthickness=0) toolbar.pack(fill=tk.X, pady=(0, 16)) + self._toolbar_frame = toolbar for icon, label, command in self._toolbar_button_defs(): self._add_toolbar_button(toolbar, icon, label, command) - top = ttk.Frame(frame) + top = ttk.Frame(frame, style="CS2.TFrame") top.pack(fill=tk.X, pady=(0, 12)) - ttk.Label(top, text=self._t("cs2.weapon_label")).grid(row=0, column=0, sticky="w") + ttk.Label(top, text=self._t("cs2.weapon_label"), style="CS2.TLabel").grid(row=0, column=0, sticky="w") self.weapon_combo = ttk.Combobox( - top, textvariable=self.weapons_var, state="disabled" + top, textvariable=self.weapons_var, state="disabled", style="CS2.TCombobox" ) self.weapon_combo.grid(row=1, column=0, sticky="we", padx=(0, 12)) self.weapon_combo.bind("<>", self._on_weapon_selected) - ttk.Label(top, text=self._t("cs2.pattern_label")).grid( + ttk.Label(top, text=self._t("cs2.pattern_label"), style="CS2.TLabel").grid( row=0, column=1, sticky="w" ) self.pattern_combo = ttk.Combobox( - top, textvariable=self.patterns_var, state="disabled" + top, textvariable=self.patterns_var, state="disabled", style="CS2.TCombobox" ) self.pattern_combo.grid(row=1, column=1, sticky="we") self.pattern_combo.bind("<>", self._on_pattern_selected) top.columnconfigure(0, weight=1) top.columnconfigure(1, weight=1) - dir_frame = ttk.Frame(frame) + dir_frame = ttk.Frame(frame, style="CS2.TFrame") dir_frame.pack(fill=tk.X, pady=(0, 12)) - ttk.Label(dir_frame, text=self._t("cs2.output_label")).grid( + ttk.Label(dir_frame, text=self._t("cs2.output_label"), style="CS2.TLabel").grid( row=0, column=0, sticky="w" ) - entry = ttk.Entry(dir_frame, textvariable=self.directory_var) + entry = ttk.Entry(dir_frame, textvariable=self.directory_var, style="CS2.TEntry") entry.grid(row=1, column=0, sticky="we", padx=(0, 8)) dir_frame.columnconfigure(0, weight=1) - status_label = ttk.Label( - frame, textvariable=self.status_var, anchor="w", justify="left" - ) + status_label = ttk.Label(frame, textvariable=self.status_var, anchor="w", justify="left", style="CS2.TLabel") status_label.pack(fill=tk.X) self._refresh_toolbar_buttons_theme() def _setup_window(self) -> None: self.overrideredirect(True) - self.configure(bg=self._background_colour()) + border_colour = "#27272b" if self.theme == "dark" else "#d0d0d8" + self.configure(bg=border_colour) + self.container = tk.Frame(self, bg=self._background_colour(), bd=0, highlightthickness=0) + self.container.pack(fill=tk.BOTH, expand=True, padx=2, pady=2) self._create_titlebar() def _create_titlebar(self) -> None: - bar_bg = "#1f1f1f" - title_bar = tk.Frame(self, bg=bar_bg, relief="flat", height=34) + bar_bg = "#1f1f1f" if self.theme == "dark" else "#2f2f35" + title_bar = tk.Frame(self.container, bg=bar_bg, relief="flat", height=34) title_bar.pack(fill=tk.X, side=tk.TOP) title_bar.pack_propagate(False) @@ -321,6 +325,70 @@ class CS2PatternTool(tk.Toplevel): except Exception: # noqa: BLE001 pass + def _center_window(self) -> None: + try: + self.update_idletasks() + root = self.app.root + root.update_idletasks() + width = self.winfo_width() + height = self.winfo_height() + root_width = root.winfo_width() + root_height = root.winfo_height() + root_x = root.winfo_rootx() + root_y = root.winfo_rooty() + x = root_x + (root_width - width) // 2 + y = root_y + (root_height - height) // 2 + self.geometry(f"{width}x{height}+{x}+{y}") + except Exception: # noqa: BLE001 + pass + + def _init_styles(self) -> None: + style = ttk.Style(self) + try: + style.theme_use("clam") + except Exception: # noqa: BLE001 + pass + base_bg = self._background_colour() + fg = "#f5f5f5" if self.theme == "dark" else "#202020" + field_bg = "#1f1f25" if self.theme == "dark" else "#f5f5f8" + border = "#4d4d50" if self.theme == "dark" else "#b8b8c0" + + style.configure("CS2.TFrame", background=base_bg) + style.configure("CS2.TLabel", background=base_bg, foreground=fg, font=("Segoe UI", 10)) + + style.configure( + "CS2.TEntry", + fieldbackground=field_bg, + foreground=fg, + insertcolor=fg, + bordercolor=border, + lightcolor=border, + darkcolor=border, + relief="flat", + padding=6, + ) + style.map("CS2.TEntry", fieldbackground=[("disabled", field_bg)], foreground=[("disabled", fg)]) + + style.configure( + "CS2.TCombobox", + fieldbackground=field_bg, + foreground=fg, + background=field_bg, + bordercolor=border, + arrowcolor=fg, + relief="flat", + padding=4, + ) + style.map( + "CS2.TCombobox", + fieldbackground=[("readonly", field_bg)], + foreground=[("readonly", fg)], + background=[("readonly", field_bg)], + ) + + self.container.configure(bg=base_bg) + self.body.configure(style="CS2.TFrame") + # Data loading ----------------------------------------------------- def _start_loading(self) -> None: @@ -596,6 +664,11 @@ class CS2PatternTool(tk.Toplevel): return palette = self._toolbar_palette() bg = self._background_colour() + if hasattr(self, "_toolbar_frame") and self._toolbar_frame is not None: + try: + self._toolbar_frame.configure(bg=bg) + except Exception: # noqa: BLE001 + pass for data in self._toolbar_buttons: canvas = data["canvas"] rect = data["rect"]