diff --git a/src/gui/widgets.py b/src/gui/widgets.py index c84cf1b..8262d64 100644 --- a/src/gui/widgets.py +++ b/src/gui/widgets.py @@ -6,7 +6,6 @@ consistent styling from gui/styles.py. from __future__ import annotations -import os import threading import customtkinter as ctk @@ -439,9 +438,7 @@ class ProgressIndicator(ctk.CTkFrame): class StatusDisplay(ctk.CTkFrame): """Status display widget for operation results. - Shows status messages in a multi-line, expandable text area that - uses the full available space. Messages are color-coded and - automatically wrapped. + Shows a status message with color-coded feedback. """ def __init__(self, master, **kwargs): @@ -455,19 +452,15 @@ class StatusDisplay(ctk.CTkFrame): self._create_widgets() def _create_widgets(self) -> None: - """Create the status display UI — multi-line expandable area.""" - self.grid_rowconfigure(0, weight=1) - self.grid_columnconfigure(0, weight=1) - - self._status_text = ctk.CTkTextbox( + """Create the status display UI.""" + self._status_label = ctk.CTkLabel( self, + text="Ready", font=FONT_BODY, - corner_radius=CORNER_RADIUS, - state="disabled", - wrap="word", + anchor="w", ) - self._status_text.grid( - row=0, column=0, sticky="nsew", padx=PADDING, pady=PADDING_SMALL + self._status_label.pack( + fill="x", padx=PADDING, pady=PADDING_SMALL ) def set_status(self, message: str, status: str = "info") -> None: @@ -477,32 +470,20 @@ class StatusDisplay(ctk.CTkFrame): message: Status message text. status: Status type for coloring ('info', 'success', 'error', 'warning'). """ - self._status_text.configure(state="normal") - self._status_text.delete("1.0", "end") - + self._status_label.configure(text=message) colors = { "info": INFO_COLOR, "success": SUCCESS_COLOR, "error": DANGER_COLOR, "warning": WARNING_COLOR, } - color = colors.get(status, INFO_COLOR) - - self._status_text.insert("1.0", message) - # Tag the entire text with the color - self._status_text.tag_configure("status", foreground=color) - self._status_text.tag_add("status", "1.0", "end") - - self._status_text.configure(state="disabled") + self._status_label.configure(text_color=colors.get(status, INFO_COLOR)) class FileSelector(ctk.CTkFrame): """File selector widget with browse button and path display. - Stores the full absolute path internally but displays only the - filename in the entry field. Supports relative paths: the - ``set_relative_path()`` / ``get_relative_path()`` methods work - with paths relative to a given base directory. + Allows users to browse for files and displays the selected path. """ def __init__( @@ -525,9 +506,7 @@ class FileSelector(ctk.CTkFrame): self._callback = callback self._file_types = file_types or [("All files", "*")] - self._full_path: str = "" # absolute path (internal) - self._relative_path: str = "" # relative path (synced to Config) - self._display_text = ctk.StringVar(value="") + self._selected_path = ctk.StringVar(value="") self._create_widgets(label_text) @@ -545,10 +524,10 @@ class FileSelector(ctk.CTkFrame): ) label.grid(row=0, column=0, sticky="w", padx=(PADDING, PADDING_SMALL)) - # Path entry — shows only the filename + # Path entry self._entry = ctk.CTkEntry( self, - textvariable=self._display_text, + textvariable=self._selected_path, font=FONT_MONO, state="readonly", ) @@ -570,60 +549,33 @@ class FileSelector(ctk.CTkFrame): def _browse(self) -> None: """Open file dialog and set selected path.""" + import customtkinter from tkinter import filedialog file_path = filedialog.askopenfilename( - title="Select file", + title=f"Select {self._selected_path.get() or 'file'}", filetypes=self._file_types, ) if file_path: self.set_path(file_path) def set_path(self, path: str) -> None: - """Set the selected file path (absolute or relative). - - Internally stores the absolute path and displays only the - filename. + """Set the selected file path. Args: - path: Absolute or relative path to the selected file. + path: Absolute path to the selected file. """ - self._full_path = path - self._display_text.set(os.path.basename(path) if path else "") - if self._callback: - self._callback(path) - - def set_relative_path(self, path: str) -> None: - """Set a relative path (from config). - - Resolves to absolute for internal storage, shows only filename. - - Args: - path: Relative path string. - """ - self._relative_path = path - # Resolve to absolute for internal use - if path: - self._full_path = path # caller should resolve before calling - self._display_text.set(os.path.basename(path) if path else "") + self._selected_path.set(path) if self._callback: self._callback(path) def get_path(self) -> str: - """Get the currently selected file path (absolute). + """Get the currently selected file path. Returns: Selected file path string. """ - return self._full_path - - def get_relative_path(self) -> str: - """Get the currently selected relative path. - - Returns: - Relative path string, or empty string. - """ - return self._relative_path + return self._selected_path.get() class LogDisplay(ctk.CTkFrame):