replace tooltip animation with exist tooltip, redundancy reduced, search optimized, add new icons copy and stair (for path folllow)

This commit is contained in:
2025-08-13 01:05:57 +02:00
parent dc51bf6f2c
commit ba6ef7385a
7 changed files with 150 additions and 631 deletions

View File

@@ -452,6 +452,12 @@ class Tooltip:
if self.state_var:
self.state_var.trace_add("write", self.update_bindings)
# Add bindings to the top-level window to hide the tooltip when the
# main window loses focus or is iconified.
toplevel = self.widget.winfo_toplevel()
toplevel.bind("<FocusOut>", self.leave, add="+")
toplevel.bind("<Unmap>", self.leave, add="+")
def update_bindings(self, *args):
"""
Updates the event bindings for the widget based on the current state_var.
@@ -472,13 +478,12 @@ class Tooltip:
Handles the <Enter> event. Schedules the tooltip to be shown after a delay
if tooltips are enabled (via state_var).
"""
try:
# Check if a modal dialog has the grab on the entire application
if self.winfo_toplevel().grab_current() is not None:
return
except Exception:
# This can happen if no grab is active. We can safely ignore it.
pass
# Do not show tooltips if a grab is active on a different window.
# This prevents tooltips from appearing over other modal dialogs.
toplevel = self.widget.winfo_toplevel()
grab_widget = toplevel.grab_current()
if grab_widget is not None and grab_widget != toplevel:
return
if self.state_var is None or self.state_var.get():
self.schedule()
@@ -513,15 +518,26 @@ class Tooltip:
Displays the tooltip window. The tooltip is a Toplevel window containing a ttk.Label.
It is positioned near the widget and styled for readability.
"""
if self.tooltip_window or not self.text:
if self.tooltip_window:
return
x, y, _, _ = self.widget.bbox("insert")
x += self.widget.winfo_rootx() + 25
y += self.widget.winfo_rooty() + 20
text_to_show = self.text() if callable(self.text) else self.text
if not text_to_show:
return
try:
# Position the tooltip just below the widget.
# Using winfo_rootx/y is more reliable than bbox.
x = self.widget.winfo_rootx()
y = self.widget.winfo_rooty() + self.widget.winfo_height() + 5
except tk.TclError:
# This can happen if the widget is destroyed while the tooltip is scheduled.
return
self.tooltip_window = tw = tk.Toplevel(self.widget)
tw.wm_overrideredirect(True)
tw.wm_geometry(f"+" + str(x) + "+" + str(y))
label = ttk.Label(tw, text=self.text, justify=tk.LEFT, background="#FFFFE0", foreground="black",
label = ttk.Label(tw, text=text_to_show, justify=tk.LEFT, background="#FFFFE0", foreground="black",
relief=tk.SOLID, borderwidth=1, wraplength=self.wraplength, padding=(4, 2, 4, 2))
label.pack(ipadx=1)
@@ -617,6 +633,8 @@ class IconManager:
'back': '32/arrow-left.png',
'forward': '32/arrow-right.png',
'up': '32/arrow-up.png',
'copy': '32/copy.png',
'stair': '32/stair.png',
'audio_small': '32/audio.png',
'icon_view': '32/carrel.png',
'computer_small': '32/computer.png',
@@ -675,6 +693,8 @@ class IconManager:
'back_large': '48/arrow-left.png',
'forward_large': '48/arrow-right.png',
'up_large': '48/arrow-up.png',
'copy': '48/copy.png',
'stair': '48/stair.png',
'icon_view_large': '48/carrel.png',
'computer_large': '48/computer.png',
'device_large': '48/device.png',
@@ -722,6 +742,8 @@ class IconManager:
'back_extralarge': '64/arrow-left.png',
'forward_extralarge': '64/arrow-right.png',
'up_extralarge': '64/arrow-up.png',
'copy': '64/copy.png',
'stair': '64/stair.png',
'audio_large': '64/audio.png',
'icon_view_extralarge': '64/carrel.png',
'computer_extralarge': '64/computer.png',