mirror of
https://github.com/storytold/filmcraft.git
synced 2026-10-14 19:26:59 -04:00
Help menu: say where each item goes; keep the address when no browser opens
Hovering a Help menu item now tells you what it does: the links (ArtCraft Discord, website, app page, GitHub, Report an Issue, FilmCraft Help) show "Opens in your web browser: <address>", and Reveal Log Files, System Compatibility Report and About FilmCraft say they stay in FilmCraft (no web page). When the host can't open a browser, the click was only logged. Now the address is copied to the clipboard and the status bar names the reason and the address. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
9432300f0e
commit
3f5d4385dd
5 files changed
+72
-3
No files matched your search
@@ -3586,3 +3586,8 @@
|
||||
Export the labels to a preset file… Exportar las etiquetas a un archivo de ajuste preestablecido…
|
||||
Show the presets folder Mostrar la carpeta de ajustes preestablecidos
|
||||
Delete this preset Eliminar este ajuste preestablecido
|
||||
Opens in your web browser: {url} Se abre en el navegador web: {url}
|
||||
Saves this session's log and shows it in your file manager (no web page). Guarda el registro de esta sesión y lo muestra en el explorador de archivos (no abre ninguna página web).
|
||||
Shows a report on this computer in a FilmCraft window (no web page). Muestra un informe sobre este equipo en una ventana de FilmCraft (no abre ninguna página web).
|
||||
Shows the version, community links and credits in a FilmCraft window (no web page). Muestra la versión, los enlaces de la comunidad y los créditos en una ventana de FilmCraft (no abre ninguna página web).
|
||||
Couldn't open your web browser ({error}). The address is copied to the clipboard: {url} No se pudo abrir el navegador web ({error}). La dirección se ha copiado al portapapeles: {url}
|
||||
|
Can't render this file because it contains an unexpected character in line 3 and column 95.
|
@@ -3588,3 +3588,8 @@
|
||||
Export the labels to a preset file… ラベルをプリセットファイルに書き出し…
|
||||
Show the presets folder プリセットフォルダーを表示
|
||||
Delete this preset このプリセットを削除
|
||||
Opens in your web browser: {url} ウェブブラウザーで開きます:{url}
|
||||
Saves this session's log and shows it in your file manager (no web page). このセッションのログを保存し、ファイルマネージャーで表示します(ウェブページは開きません)。
|
||||
Shows a report on this computer in a FilmCraft window (no web page). このコンピューターのレポートを FilmCraft のウィンドウに表示します(ウェブページは開きません)。
|
||||
Shows the version, community links and credits in a FilmCraft window (no web page). バージョン、コミュニティへのリンク、クレジットを FilmCraft のウィンドウに表示します(ウェブページは開きません)。
|
||||
Couldn't open your web browser ({error}). The address is copied to the clipboard: {url} ウェブブラウザーを開けませんでした({error})。アドレスをクリップボードにコピーしました:{url}
|
||||
|
Can't render this file because it contains an unexpected character in line 11 and column 59.
|
@@ -3564,3 +3564,8 @@
|
||||
Export the labels to a preset file… 将标签导出为预设文件…
|
||||
Show the presets folder 显示预设文件夹
|
||||
Delete this preset 删除此预设
|
||||
Opens in your web browser: {url} 在网页浏览器中打开:{url}
|
||||
Saves this session's log and shows it in your file manager (no web page). 保存本次会话的日志并在文件管理器中显示(不打开网页)。
|
||||
Shows a report on this computer in a FilmCraft window (no web page). 在 FilmCraft 窗口中显示本机的报告(不打开网页)。
|
||||
Shows the version, community links and credits in a FilmCraft window (no web page). 在 FilmCraft 窗口中显示版本、社区链接和致谢(不打开网页)。
|
||||
Couldn't open your web browser ({error}). The address is copied to the clipboard: {url} 无法打开网页浏览器({error})。地址已复制到剪贴板:{url}
|
||||
|
Can't render this file because it contains an unexpected character in line 3 and column 95.
|
@@ -31,15 +31,39 @@ pub fn url_for(command: &str) -> Option<&'static str> {
|
||||
ALL.iter().find(|(id, _, _)| *id == command).map(|(_, _, u)| *u)
|
||||
}
|
||||
|
||||
/// What a Help menu item does, shown when the pointer rests on it: the address a link opens in
|
||||
/// the web browser, or that the item stays inside FilmCraft.
|
||||
pub fn menu_hint(command: &str) -> Option<String> {
|
||||
let url = if command == "help.filmcraftHelp" { Some(crate::panels::keyboard::HELP_URL) } else { url_for(command) };
|
||||
if let Some(url) = url {
|
||||
return Some(tlf!("Opens in your web browser: {url}", url));
|
||||
}
|
||||
Some(
|
||||
match command {
|
||||
"help.revealLogFiles" => tl!("Saves this session's log and shows it in your file manager (no web page)."),
|
||||
"help.systemCompatibilityReport" => tl!("Shows a report on this computer in a FilmCraft window (no web page)."),
|
||||
"app.about" => tl!("Shows the version, community links and credits in a FilmCraft window (no web page)."),
|
||||
_ => return None,
|
||||
}
|
||||
.to_string(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Open `url` in the system browser (a new tab on the web). The desktop host's
|
||||
/// [`HostHooks::open_url`](crate::HostHooks::open_url) opens it; without the hook, or when it
|
||||
/// fails, it goes through `ctx.open_url`, which only does something on the web: the native egui
|
||||
/// backend is built without its `links` feature, so there it would only log (#642).
|
||||
/// backend is built without its `links` feature, so there it would only log (#642). When the
|
||||
/// host can't open a browser, the address goes to the clipboard and the status bar says so, so
|
||||
/// the click is never silently lost.
|
||||
pub fn open(app: &mut crate::FilmcraftApp, ctx: &egui::Context, url: &str) {
|
||||
if let Some(f) = app.hooks.open_url.as_mut() {
|
||||
match f(url) {
|
||||
Ok(()) => return,
|
||||
Err(e) => log::warn!("can't open {url} in the browser: {e}"),
|
||||
Err(error) => {
|
||||
log::warn!("can't open {url} in the browser: {error}");
|
||||
ctx.copy_text(url.to_string());
|
||||
app.ui.status = tlf!("Couldn't open your web browser ({error}). The address is copied to the clipboard: {url}", error, url);
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx.open_url(egui::OpenUrl::new_tab(url));
|
||||
@@ -87,5 +111,31 @@ mod tests {
|
||||
let fallback: Vec<String> =
|
||||
ctx.output(|o| o.commands.iter().filter_map(|c| if let egui::OutputCommand::OpenUrl(u) = c { Some(u.url.clone()) } else { None }).collect());
|
||||
assert_eq!(fallback, [ISSUES]);
|
||||
// ... and keeps the address at hand: copied, and named in the status bar with the reason
|
||||
let copied: Vec<String> =
|
||||
ctx.output(|o| o.commands.iter().filter_map(|c| if let egui::OutputCommand::CopyText(t) = c { Some(t.clone()) } else { None }).collect());
|
||||
assert_eq!(copied, [ISSUES]);
|
||||
assert!(app.ui.status.contains(ISSUES) && app.ui.status.contains("no browser"), "{}", app.ui.status);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn help_menu_items_say_where_they_go() {
|
||||
// links name their address; the other Help items say they stay inside FilmCraft
|
||||
for (id, _, url) in ALL {
|
||||
let hint = menu_hint(id).unwrap();
|
||||
assert!(hint.contains(url) && hint.contains("web browser"), "{id}: {hint}");
|
||||
}
|
||||
assert!(menu_hint("help.filmcraftHelp").unwrap().contains(crate::panels::keyboard::HELP_URL));
|
||||
let help_items: Vec<String> = crate::menus::menu_items(&crate::FilmcraftApp::new(filmcraft_engine::Session::default()))
|
||||
.into_iter()
|
||||
.filter(|it| it.path.first().map(String::as_str) == Some("Help"))
|
||||
.map(|it| it.id)
|
||||
.collect();
|
||||
assert!(help_items.len() >= ALL.len() + 3, "{help_items:?}");
|
||||
for id in &help_items {
|
||||
let hint = menu_hint(id).unwrap_or_else(|| panic!("{id} has no hover hint"));
|
||||
assert!(hint.contains("web browser") || hint.contains("no web page"), "{id}: {hint}");
|
||||
}
|
||||
assert_eq!(menu_hint("edit.undo"), None);
|
||||
}
|
||||
}
|
||||
@@ -931,7 +931,11 @@ fn menu_entry(ui: &mut egui::Ui, it: &MenuItem, auto: &mut crate::automation::Re
|
||||
if let Some(s) = &it.shortcut {
|
||||
b = b.shortcut_text(shortcut_text(s));
|
||||
}
|
||||
let r = ui.add_enabled(it.enabled, b);
|
||||
let mut r = ui.add_enabled(it.enabled, b);
|
||||
// Help items say whether they open the web browser (and which address) or stay in FilmCraft
|
||||
if let Some(hint) = crate::links::menu_hint(&it.id) {
|
||||
r = r.on_hover_text(hint);
|
||||
}
|
||||
auto.add(&format!("menu.{}", it.id), r.rect, &it.label);
|
||||
if let Some(color) = swatch {
|
||||
paint_swatch(ui, r.rect, color);
|
||||
|
||||
Reference in new issue
Block a user