mirror of
https://github.com/hacksider/Deep-Live-Cam.git
synced 2026-04-22 17:16:26 +02:00
e340b0da8a
Add ToolTip class (modules/ui_tooltip.py) and wire descriptive hover tooltips onto every button, switch, slider, and dropdown in the main window. Tooltips appear after a 500ms hover delay and are clamped to screen bounds. This requires no new dependencies — ToolTip uses only customtkinter. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
75 lines
2.0 KiB
Python
75 lines
2.0 KiB
Python
"""Lightweight hover tooltip for CustomTkinter widgets."""
|
|
|
|
import customtkinter as ctk
|
|
|
|
|
|
class ToolTip:
|
|
"""Show a floating tooltip popup when the user hovers over a widget.
|
|
|
|
Usage:
|
|
ToolTip(my_button, "Helpful description text")
|
|
"""
|
|
|
|
def __init__(self, widget: ctk.CTkBaseClass, text: str, delay: int = 500):
|
|
self._widget = widget
|
|
self._text = text
|
|
self._delay = delay
|
|
self._tooltip_window = None
|
|
self._after_id = None
|
|
|
|
widget.bind("<Enter>", self._schedule_show, add="+")
|
|
widget.bind("<Leave>", self._hide, add="+")
|
|
|
|
def _schedule_show(self, event=None):
|
|
self._cancel()
|
|
self._after_id = self._widget.after(self._delay, self._show)
|
|
|
|
def _show(self):
|
|
if self._tooltip_window is not None:
|
|
return
|
|
|
|
x = self._widget.winfo_rootx() + 20
|
|
y = self._widget.winfo_rooty() + self._widget.winfo_height() + 5
|
|
|
|
self._tooltip_window = tw = ctk.CTkToplevel(self._widget)
|
|
tw.withdraw()
|
|
tw.overrideredirect(True)
|
|
|
|
label = ctk.CTkLabel(
|
|
tw,
|
|
text=self._text,
|
|
fg_color="#333333",
|
|
text_color="#EEEEEE",
|
|
corner_radius=6,
|
|
padx=8,
|
|
pady=4,
|
|
)
|
|
label.pack()
|
|
|
|
tw.update_idletasks()
|
|
|
|
# Clamp to screen bounds
|
|
screen_w = tw.winfo_screenwidth()
|
|
screen_h = tw.winfo_screenheight()
|
|
tip_w = tw.winfo_reqwidth()
|
|
tip_h = tw.winfo_reqheight()
|
|
|
|
if x + tip_w > screen_w:
|
|
x = screen_w - tip_w - 5
|
|
if y + tip_h > screen_h:
|
|
y = self._widget.winfo_rooty() - tip_h - 5
|
|
|
|
tw.geometry(f"+{x}+{y}")
|
|
tw.deiconify()
|
|
|
|
def _hide(self, event=None):
|
|
self._cancel()
|
|
if self._tooltip_window is not None:
|
|
self._tooltip_window.destroy()
|
|
self._tooltip_window = None
|
|
|
|
def _cancel(self):
|
|
if self._after_id is not None:
|
|
self._widget.after_cancel(self._after_id)
|
|
self._after_id = None
|