"""Tooltip system for enhanced user experience.""" import tkinter as tk class ToolTip: """Create a tooltip for a given widget.""" def __init__( self, widget: tk.Widget, text: str, delay: int = 500, wrap_length: int = 250, ) -> None: self.widget = widget self.text = text self.delay = delay self.wrap_length = wrap_length self.tooltip: tk.Toplevel | None = None self.id_after: str | None = None # Bind events self.widget.bind("", self._on_enter) self.widget.bind("", self._on_leave) self.widget.bind("", self._on_leave) def _on_enter(self, event: tk.Event | None = None) -> None: """Mouse entered widget - schedule tooltip.""" self._cancel_scheduled() self.id_after = self.widget.after(self.delay, self._show_tooltip) def _on_leave(self, event: tk.Event | None = None) -> None: """Mouse left widget - hide tooltip.""" self._cancel_scheduled() self._hide_tooltip() def _cancel_scheduled(self) -> None: """Cancel any scheduled tooltip.""" if self.id_after: self.widget.after_cancel(self.id_after) self.id_after = None def _show_tooltip(self) -> None: """Display the tooltip.""" if self.tooltip: return # Get widget position x = self.widget.winfo_rootx() + 25 y = self.widget.winfo_rooty() + 25 # Create tooltip window self.tooltip = tk.Toplevel(self.widget) self.tooltip.wm_overrideredirect(True) self.tooltip.wm_geometry(f"+{x}+{y}") # Create tooltip content label = tk.Label( self.tooltip, text=self.text, justify="left", background="#ffffe0", foreground="#000000", relief="solid", borderwidth=1, font=("TkDefaultFont", "9", "normal"), wraplength=self.wrap_length, padx=8, pady=6, ) label.pack() # Make sure tooltip appears above other windows self.tooltip.lift() def _hide_tooltip(self) -> None: """Hide the tooltip.""" if self.tooltip: self.tooltip.destroy() self.tooltip = None def update_text(self, new_text: str) -> None: """Update the tooltip text.""" self.text = new_text class TooltipManager: """Manages tooltips for UI elements.""" def __init__(self, theme_manager) -> None: self.theme_manager = theme_manager self.tooltips: list[ToolTip] = [] def add_tooltip( self, widget: tk.Widget, text: str, delay: int = 500, wrap_length: int = 250, ) -> ToolTip: """Add a tooltip to a widget.""" tooltip = ToolTip(widget, text, delay, wrap_length) self.tooltips.append(tooltip) return tooltip def add_scale_tooltip(self, scale_widget: tk.Widget, pathology_name: str) -> None: """Add a specialized tooltip for pathology scales.""" text = ( f"Adjust your {pathology_name} level\\n" "• Drag the slider to set your current level\\n" "• Higher values typically indicate worse symptoms\\n" "• Use the full range for accurate tracking" ) self.add_tooltip(scale_widget, text, delay=800) def add_medicine_tooltip(self, widget: tk.Widget, medicine_name: str) -> None: """Add a specialized tooltip for medicine checkboxes.""" text = ( f"Mark if you took {medicine_name} today\\n" "• Check the box when you've taken this medication\\n" "• This helps track your medication adherence\\n" "• You can add dose details when editing entries" ) self.add_tooltip(widget, text, delay=600) def add_button_tooltip(self, widget: tk.Widget, action: str) -> None: """Add a tooltip for action buttons.""" tooltips_map = { "save": ( "Save your current entry (Ctrl+S)\\nThis will add a new daily record" ), "export": ( "Export your data to various formats\\n" "Supports CSV, PDF, and image exports" ), "refresh": ( "Reload data from file (F5)\\nUpdates the display with latest changes" ), "settings": ( "Open application settings (F2)\\nCustomize themes and preferences" ), "quit": ( "Exit the application (Ctrl+Q)\\nYour data will be automatically saved" ), } text = tooltips_map.get(action, f"Perform {action} action") self.add_tooltip(widget, text, delay=400) def add_menu_tooltip(self, widget: tk.Widget, menu_type: str) -> None: """Add tooltips for menu items.""" tooltips_map = { "theme": ( "Quick theme selection\\nClick to instantly change the app's appearance" ), "file": "File operations\\nExport data and manage files", "tools": ("Data management tools\\nConfigure medicines and pathologies"), "help": ("Get help and information\\nKeyboard shortcuts and about dialog"), } text = tooltips_map.get(menu_type, "Menu options") self.add_tooltip(widget, text, delay=600)