feat(app): gpui action/keymap shortcut system, full main menu, context menus

Port the C++ menu/shortcut architecture (origin/main) to the Rust shell:

- src/actions.rs: action registry (123 entries with stable C++ ids,
  i18n keys, default key bindings, routing targets) driving both the
  menu bar and App::bind_keys; src/shortcuts.rs flat table removed.
- src/panels/commands.rs: PanelCommandHandler trait routing playback,
  editing, zoom, markers etc. to the currently focused panel.
- make_menus rebuilt from the registry: full File/Edit/View/Playback/
  Sequence/Window/Tools/Help trees aligned with the C++ main menu.
- src/menus/: shared context-menu infrastructure; right-click menus
  for timeline (clip/empty/track head/ruler), project explorer,
  viewers, node editor, inspector effect stack, with i18n EN/ZH.

Synchronize/Proxy/Multi-Cam entries exist but stay disabled pending
their engine wiring phases.
This commit is contained in:
2026-08-18 17:15:00 +08:00
parent 6576113a69
commit 9daa266189
23 changed files with 4822 additions and 551 deletions
+15 -2
View File
@@ -23,12 +23,13 @@
use gpui::colors::DefaultColors;
use gpui::dock::{DockPanel, PanelEvent};
use gpui::{
div, prelude::*, AnyElement, App, ClickEvent, Context, Entity, EventEmitter, Render,
SharedString, Window,
div, prelude::*, AnyElement, App, ClickEvent, Context, Entity, EventEmitter, MouseButton,
Render, SharedString, Window,
};
use crate::i18n;
use crate::oakui::AppEngine;
use crate::panels::commands::PanelCommandHandler;
use crate::panels::ids::EFFECT_LIBRARY;
/// The effect library panel.
@@ -46,6 +47,10 @@ impl<E: AppEngine> EffectLibraryPanel<E> {
}
}
/// The effect library implements no focused-panel commands: everything
/// falls through to the shell's global handler.
impl<E: AppEngine> PanelCommandHandler for EffectLibraryPanel<E> {}
impl<E: AppEngine> Render for EffectLibraryPanel<E> {
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let colors = cx.default_colors().clone();
@@ -95,6 +100,14 @@ impl<E: AppEngine> Render for EffectLibraryPanel<E> {
.size_full()
.flex()
.flex_col()
// Any click inside the panel makes it the focused panel (the
// dock re-emits this as `DockEvent::PanelFocused`, which the
// shell uses to route focused-panel commands).
.on_mouse_down(MouseButton::Left, {
cx.listener(|_this, _event: &gpui::MouseDownEvent, _window, cx| {
cx.emit(PanelEvent::Focused);
})
})
.child(list)
.child(
div()