Skip to content

Commit 8eae363

Browse files
authored
Update ui_extras.py
1 parent 97d82fd commit 8eae363

File tree

1 file changed

+73
-131
lines changed

1 file changed

+73
-131
lines changed

ui_extras.py

Lines changed: 73 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -1,160 +1,102 @@
11
from __future__ import annotations
2+
23
from pathlib import Path
3-
from typing import Optional, Callable, Dict
4-
import platform, subprocess, sys
4+
from typing import Callable
5+
56
import tkinter as tk
6-
from tkinter import ttk, messagebox, simpledialog
7-
from tkinter.scrolledtext import ScrolledText
7+
from tkinter import ttk, messagebox
88

9-
# Always use the project's full Help/About implementation
109
from help_window import open_help_window, show_about_dialog, set_app_meta
11-
from tooltips import set_tooltip_delay, set_tooltip_wrap, get_tooltip_settings
1210

13-
def _t(parent: tk.Misc, key: str, default: str, get_text: Optional[Callable[[str, str], str]]) -> str:
14-
try:
15-
if get_text:
16-
return get_text(key, default)
17-
if hasattr(parent, "lang") and hasattr(parent.lang, "get"):
18-
v = parent.lang.get(key)
19-
if isinstance(v, str) and v:
20-
return v
21-
except Exception:
22-
pass
23-
return default
11+
# Re-exported tooltip settings; if not available, provide fallbacks.
12+
try:
13+
from tooltips import set_tooltip_delay, set_tooltip_wrap, get_tooltip_settings # type: ignore
14+
except Exception: # pragma: no cover
15+
def set_tooltip_delay(_ms: int) -> None: # noqa: D401 - trivial shim
16+
"""No-op when tooltips module not present."""
17+
return
2418

25-
def _copy_diagnostics(parent: tk.Misc) -> None:
26-
lines = []
27-
# Try to pull app name/version if the caller set it in About
28-
app = getattr(parent, "title", lambda: "Application")()
29-
try:
30-
# Pull VERSION attr from parent/App if present
31-
ver = getattr(parent, "VERSION", "")
32-
if not ver and hasattr(parent, "title"):
33-
ver = ""
34-
except Exception:
35-
ver = ""
36-
if ver:
37-
lines.append(f"{app} {ver}")
38-
else:
39-
lines.append(app)
40-
41-
lines.append(f"Python: {sys.version.splitlines()[0]}")
42-
lines.append(f"OS: {platform.system()} {platform.release()}")
43-
44-
for tool, args in [("yt-dlp", ["--version"]), ("ffmpeg", ["-version"]), ("ffprobe", ["-version"]), ("mp3gain", ["-v"])]:
45-
try:
46-
p = subprocess.run([tool, *args], capture_output=True, text=True, timeout=3)
47-
first = p.stdout.splitlines()[0] if p.stdout.strip() else (p.stderr.splitlines()[0] if p.stderr.strip() else "(no output)")
48-
lines.append(f"{tool}: {first}")
49-
except Exception as e:
50-
lines.append(f"{tool}: error: {e}")
19+
def set_tooltip_wrap(_chars: int) -> None: # noqa: D401 - trivial shim
20+
"""No-op when tooltips module not present."""
21+
return
5122

23+
def get_tooltip_settings() -> tuple[int, int]:
24+
return (600, 60)
25+
26+
27+
def _t(parent: tk.Misc, key: str, default: str, get_text: Callable[[str, str], str] | None) -> str:
28+
if get_text is None:
29+
return default
5230
try:
53-
parent.clipboard_clear(); parent.clipboard_append("\n".join(lines))
54-
messagebox.showinfo("Diagnostics copied", "Diagnostic info copied to clipboard.")
31+
return get_text(key, default)
5532
except Exception:
56-
pass
33+
return default
34+
5735

5836
def add_help_right_aligned_menu(
5937
parent: tk.Misc,
6038
app_name: str,
6139
version: str,
62-
help_md_path: Optional[Path] = None,
63-
get_text: Optional[Callable[[str, str], str]] = None,
64-
locales: Optional[Dict[str, Path]] = None,
65-
on_switch_language: Optional[Callable[[str], None]] = None
40+
help_md_path: Path | None = None,
41+
get_text: Callable[[str, str], str] | None = None,
42+
locales: dict[str, Path] | None = None,
43+
on_switch_language: Callable[[str], None] | None = None,
6644
) -> tk.Frame:
6745
"""
68-
Create a simple right-aligned strip with a Help menubutton.
69-
Always opens the project's full Help/About windows.
46+
Adds a right-aligned toolbar-style frame with Help/About and optional Language menu.
47+
Returns the frame so callers can pack/grid/place it as needed.
7048
"""
71-
# Make a thin bar at the top
72-
bar = ttk.Frame(parent)
73-
bar.pack(side="top", fill="x", padx=0, pady=(0, 6))
49+
set_app_meta(app_name, version)
7450

75-
# Right-aligned Help menu
76-
btn = ttk.Menubutton(bar, text=_t(parent, "menu.help", "Help", get_text))
77-
btn.pack(side="right", padx=(0, 6), pady=(6, 0))
78-
menu = tk.Menu(btn, tearoff=0)
79-
80-
# Open Help
81-
menu.add_command(
82-
label=_t(parent, "menu.open_help", "Open Help", get_text),
83-
command=lambda: open_help_window(parent, help_md_path, get_text=get_text),
84-
)
51+
frame = ttk.Frame(parent)
52+
menubtn = ttk.Menubutton(frame, text=_t(parent, "menu.help", "Help", get_text))
53+
menu = tk.Menu(menubtn, tearoff=False)
8554

86-
# Copy diagnostics
55+
if help_md_path is not None:
56+
menu.add_command(
57+
label=_t(parent, "menu.help.view", "View Help", get_text),
58+
command=lambda: open_help_window(parent, help_md_path, get_text or (lambda _k, d: d)),
59+
)
8760
menu.add_command(
88-
label=_t(parent, "menu.copy_diagnostics", "Copy diagnostic info", get_text),
89-
command=lambda: _copy_diagnostics(parent),
61+
label=_t(parent, "menu.help.about", "About", get_text),
62+
command=lambda: show_about_dialog(parent, help_md_path or Path("HELP.md"), get_text or (lambda _k, d: d)),
9063
)
91-
# Tooltips submenu
92-
tips_menu = tk.Menu(menu, tearoff=0)
93-
def _set_delay():
94-
cur_delay, _cur_wrap = get_tooltip_settings()
95-
val = simpledialog.askinteger(
96-
title=_t(parent, "menu.tooltips.delay", "Tooltip delay", get_text),
97-
prompt=_t(parent, "menu.tooltips.delay", "Tooltip delay (ms):", get_text),
98-
initialvalue=int(cur_delay),
99-
minvalue=0
100-
)
101-
if val is not None:
102-
set_tooltip_delay(val)
103-
try:
104-
getattr(parent, '_save_config')()
105-
except Exception:
106-
pass
107-
108-
def _set_wrap():
109-
_cur_delay, cur_wrap = get_tooltip_settings()
110-
val = simpledialog.askinteger(
111-
title=_t(parent, "menu.tooltips.wrap", "Tooltip wrap", get_text),
112-
prompt=_t(parent, "menu.tooltips.wrap", "Wrap length (px):", get_text),
113-
initialvalue=int(cur_wrap),
114-
minvalue=0
115-
)
116-
if val is not None:
117-
set_tooltip_wrap(val)
118-
try:
119-
getattr(parent, '_save_config')()
120-
except Exception:
121-
pass
12264

123-
tips_menu.add_command(label=_t(parent, "menu.tooltips.delay", "Tooltip delay…", get_text), command=_set_delay)
124-
tips_menu.add_command(label=_t(parent, "menu.tooltips.wrap", "Tooltip wrap…", get_text), command=_set_wrap)
125-
menu.add_cascade(label=_t(parent, "menu.tooltips", "Tooltips", get_text), menu=tips_menu)
126-
127-
128-
# Language submenu (optional)
65+
# Optional language submenu
12966
if locales and on_switch_language:
130-
lang_menu = tk.Menu(menu, tearoff=0)
131-
current = tk.StringVar(value=getattr(parent, "current_language", "en"))
132-
for code in sorted(locales.keys()):
133-
lang_menu.add_radiobutton(
67+
lang_menu = tk.Menu(menu, tearoff=False)
68+
for code in sorted(locales):
69+
lang_menu.add_command(
13470
label=code,
135-
variable=current,
136-
value=code,
13771
command=lambda c=code: on_switch_language(c),
13872
)
139-
menu.add_cascade(label=_t(parent, "menu.language", "Language", get_text), menu=lang_menu)
140-
141-
# About: set metadata then show
142-
def _about():
143-
try:
144-
set_app_meta(app_name, version)
145-
except Exception:
146-
pass
147-
show_about_dialog(parent, help_md_path, get_text=get_text)
148-
149-
menu.add_separator()
150-
menu.add_command(label=_t(parent, "menu.about", "About", get_text), command=_about)
151-
152-
btn.configure(menu=menu)
73+
menu.add_cascade(label=_t(parent, "menu.help.language", "Language", get_text), menu=lang_menu)
74+
75+
# Optional tooltip submenu
76+
tip_menu = tk.Menu(menu, tearoff=False)
77+
delay, wrap = get_tooltip_settings()
78+
def _set_delay(ms: int) -> None:
79+
set_tooltip_delay(ms)
80+
messagebox.showinfo(
81+
_t(parent, "tooltips.title", "Tooltips", get_text),
82+
_t(parent, "tooltips.delay_set", f"Delay set to {ms} ms.", get_text),
83+
parent=parent,
84+
)
85+
for ms in (0, 300, 600, 1000):
86+
tip_menu.add_command(label=f"Delay: {ms} ms", command=lambda x=ms: _set_delay(x))
87+
88+
def _set_wrap(ch: int) -> None:
89+
set_tooltip_wrap(ch)
90+
messagebox.showinfo(
91+
_t(parent, "tooltips.title", "Tooltips", get_text),
92+
_t(parent, "tooltips.wrap_set", f"Wrap set to {ch} chars.", get_text),
93+
parent=parent,
94+
)
95+
for ch in (40, 60, 80):
96+
tip_menu.add_command(label=f"Wrap: {ch} chars", command=lambda x=ch: _set_wrap(x))
15397

154-
# F1 opens full help
155-
try:
156-
parent.bind_all("<F1>", lambda e: open_help_window(parent, help_md_path, get_text=get_text))
157-
except Exception:
158-
pass
98+
menu.add_cascade(label=_t(parent, "menu.help.tooltips", "Tooltips", get_text), menu=tip_menu)
15999

160-
return bar
100+
menubtn["menu"] = menu
101+
menubtn.pack(side="right")
102+
return frame

0 commit comments

Comments
 (0)