From 9d598fd77ead14307403e4b5ca564d0c616a6cfc Mon Sep 17 00:00:00 2001 From: zitann2020 Date: Sat, 31 Oct 2026 02:02:35 +0900 Subject: [PATCH] ui: the workspace menu offers all four options, as After Effects does Co-Authored-By: DeepSeek V4.1 Flash --- crates/ui-egui/src/header.rs | 29 ++++++++++++++++++++++++++--- crates/ui-egui/src/i18n.rs | 18 +++++++++++++++++- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/crates/ui-egui/src/header.rs b/crates/ui-egui/src/header.rs index 0e6ab3d2b..55b37e4e9 100644 --- a/crates/ui-egui/src/header.rs +++ b/crates/ui-egui/src/header.rs @@ -381,6 +381,9 @@ fn workspace_tabs(app: &mut EffectcraftApp, ui: &mut egui::Ui, p: &egui::Painter app.set_workspace(name); } rx = r.min.x - 2.0; + // Right-clicking a workspace opens the same options as the » button, which is where After + // Effects keeps them (reset, save, save a copy, edit). + resp.context_menu(|ui| ws_menu(app, ui)); } } @@ -816,13 +819,33 @@ fn ws_menu(app: &mut EffectcraftApp, ui: &mut egui::Ui) { } } ui.separator(); - if ui.button(tr("Reset to Saved Layout")).clicked() { - let n = app.ui.workspace.clone(); - app.set_workspace(&n); + // The workspace options After Effects puts at the foot of its workspace menu, in its order and + // grouping: reset the current layout, save over it, save a copy, then edit the list. All four + // are engine commands, so a script drives the same things from the command line. + for (id, source) in [ + ("window.resetWorkspace", "Reset to Saved Layout"), + ("window.saveWorkspace", "Save Changes to this Workspace"), + ("window.saveWorkspaceAs", "Save as New Workspace..."), + ] { + if ui.button(crate::i18n::command_label(id, source)).clicked() { + run_workspace_command(app, ui, id); + ui.close(); + } + } + ui.separator(); + if ui.button(crate::i18n::command_label("window.editWorkspaces", "Edit Workspaces...")).clicked() { + run_workspace_command(app, ui, "window.editWorkspaces"); ui.close(); } } +/// Runs a workspace command, showing a failure in the status line as the menu bar does. +fn run_workspace_command(app: &mut EffectcraftApp, ui: &egui::Ui, id: &str) { + if let Err(e) = crate::menus::invoke(app, ui.ctx(), id, json!({})) { + app.ui.status = e; + } +} + /// The ArtCraft mark as supplied in `docs/brand` (the README's and getartcraft.com's logo; used /// unmodified, see `docs/brand/LICENSE-brand.txt`). static ARTCRAFT_MARK: &[u8] = include_bytes!("../../../docs/brand/artcraft-mark.png"); diff --git a/crates/ui-egui/src/i18n.rs b/crates/ui-egui/src/i18n.rs index 9eed465e4..bbdf845f7 100644 --- a/crates/ui-egui/src/i18n.rs +++ b/crates/ui-egui/src/i18n.rs @@ -2288,7 +2288,7 @@ const JAPANESE: &[(&str, &str, &str)] = &[ ("window.workspace", "Text", "テキスト"), ("window.workspace", "Undocked Panels", "ドッキング解除したパネル"), ("window.resetWorkspace", "Reset to Saved Layout", "保存したレイアウトにリセット"), - ("window.saveWorkspace", "Save Changes to this Workspace", "このワークスペースの変更を保存"), + ("window.saveWorkspace", "Save Changes to this Workspace", "このワークスペースへの変更を保存"), ("window.saveWorkspaceAs", "Save as New Workspace...", "新規ワークスペースとして保存..."), ("window.editWorkspaces", "Edit Workspaces...", "ワークスペースを編集..."), ("", "Assign Shortcut to Workspace", "ワークスペースにショートカットを割り当て"), @@ -8089,6 +8089,22 @@ mod tests { use serde_json::json; use std::collections::BTreeSet; + /// The four options at the foot of the header's workspace menu say what After Effects says, + /// read from its workspace button on 2026-10-31: reset, save over this one, save a copy, then + /// edit the list. + #[test] + fn the_workspace_menu_options_use_after_effects_words() { + set_current("ja"); + for (id, en, ja) in [ + ("window.resetWorkspace", "Reset to Saved Layout", "保存したレイアウトにリセット"), + ("window.saveWorkspace", "Save Changes to this Workspace", "このワークスペースへの変更を保存"), + ("window.saveWorkspaceAs", "Save as New Workspace...", "新規ワークスペースとして保存..."), + ("window.editWorkspaces", "Edit Workspaces...", "ワークスペースを編集..."), + ] { + assert_eq!(command_label(id, en), ja, "{id}"); + } + } + /// Labels drawn outside the menu bar take the menu bar's row for their command (with `…` for /// `...`), else the panel catalog's row, else stay as they are. #[test]