mirror of
https://github.com/storytold/effectcraft.git
synced 2026-11-02 14:38:21 -06:00
Merge PR #2691
This commit is contained in:
+11
-11
@@ -8,7 +8,7 @@ use crate::EffectcraftApp;
|
||||
/// Effect names, keyed by effect id (#821).
|
||||
pub(crate) mod effects;
|
||||
/// Translations for the panels, tooltips and dialogs below the menu bar (see the module docs).
|
||||
mod ui;
|
||||
pub(crate) mod ui;
|
||||
use effectcraft_engine::menus::{MenuEntry, MenuNode};
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub(crate) use ui::catalog_characters;
|
||||
@@ -2912,16 +2912,16 @@ const JAPANESE: &[(&str, &str, &str)] = &[
|
||||
("view.shareViewOptions", "Share View Options", "表示オプションを共有"),
|
||||
("", "Switch 3D View", "3Dビューを切り替え"),
|
||||
("view.3d.activeCamera", "Active Camera", "アクティブカメラ"),
|
||||
("view.3d.default", "Default", "初期設定"),
|
||||
("view.3d.front", "Front", "フロント"),
|
||||
("view.3d.left", "Left", "レフト"),
|
||||
("view.3d.top", "Top", "トップ"),
|
||||
("view.3d.back", "Back", "バック"),
|
||||
("view.3d.right", "Right", "ライト"),
|
||||
("view.3d.bottom", "Bottom", "ボトム"),
|
||||
("view.3d.custom1", "Custom View 1", "カスタムビュー1"),
|
||||
("view.3d.custom2", "Custom View 2", "カスタムビュー2"),
|
||||
("view.3d.custom3", "Custom View 3", "カスタムビュー3"),
|
||||
("view.3d.default", "Default", "デフォルト"),
|
||||
("view.3d.front", "Front", "フロントビュー"),
|
||||
("view.3d.left", "Left", "レフトビュー"),
|
||||
("view.3d.top", "Top", "トップビュー"),
|
||||
("view.3d.back", "Back", "バックビュー"),
|
||||
("view.3d.right", "Right", "ライトビュー"),
|
||||
("view.3d.bottom", "Bottom", "ボトムビュー"),
|
||||
("view.3d.custom1", "Custom View 1", "カスタムビュー 1"),
|
||||
("view.3d.custom2", "Custom View 2", "カスタムビュー 2"),
|
||||
("view.3d.custom3", "Custom View 3", "カスタムビュー 3"),
|
||||
("", "Assign Shortcut to 3D View", "3Dビューにショートカットを割り当て"),
|
||||
("view.3d.last", "Switch to Last 3D View", "最後の3Dビューに切り替え"),
|
||||
("view.lookAtSelected", "Look at Selected Layers", "選択したレイヤーを見る"),
|
||||
|
||||
@@ -194,6 +194,7 @@ const JAPANESE: &[(&str, &str)] = &[
|
||||
("About...", "情報..."),
|
||||
("Active", "使用中"),
|
||||
("Active Camera", "アクティブカメラ"),
|
||||
("Active Camera ({})", "アクティブカメラ({})"),
|
||||
("Alpha", "アルファ"),
|
||||
("Adapt Feature On Every Frame", "フレームごとに特徴を更新"),
|
||||
("Adaptive Sample Limit:", "適応サンプル数の上限:"),
|
||||
|
||||
@@ -18,6 +18,27 @@ use crate::state::Tool;
|
||||
use crate::theme::Tokens;
|
||||
use crate::{EffectcraftApp, widgets};
|
||||
|
||||
/// A 3D view's name in the interface's language: the View menu's row for its `view.3d.*` command,
|
||||
/// else the panel catalog, else the English source. The menu's rows carry After Effects' words —
|
||||
/// フロントビュー rather than フロント — so the viewer's dropdown and the comp's view label read
|
||||
/// the same names as View ▸ Switch 3D View.
|
||||
pub(crate) fn view3d_label(v: View3D) -> &'static str {
|
||||
let id = match v {
|
||||
View3D::ActiveCamera => "view.3d.activeCamera",
|
||||
View3D::Default => "view.3d.default",
|
||||
View3D::Front => "view.3d.front",
|
||||
View3D::Left => "view.3d.left",
|
||||
View3D::Top => "view.3d.top",
|
||||
View3D::Back => "view.3d.back",
|
||||
View3D::Right => "view.3d.right",
|
||||
View3D::Bottom => "view.3d.bottom",
|
||||
View3D::Custom1 => "view.3d.custom1",
|
||||
View3D::Custom2 => "view.3d.custom2",
|
||||
View3D::Custom3 => "view.3d.custom3",
|
||||
};
|
||||
crate::i18n::command_label(id, v.label())
|
||||
}
|
||||
|
||||
/// Viewer mapping published each frame (for the control channel and other panels).
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct ViewerMap {
|
||||
@@ -756,8 +777,8 @@ fn phase_rigs(app: &mut EffectcraftApp, ui: &mut egui::Ui, ectx: &EvalCtx, v: &m
|
||||
draw_rigs(app, &painter, &map, ectx, &selected, cam_state(ectx), through_active, None);
|
||||
let view = app.session.state.views3d.get(&cid).map(|v| v.current).unwrap_or_default();
|
||||
let label = match (view, comp.active_camera(time)) {
|
||||
(View3D::ActiveCamera, Some(c)) => format!("Active Camera ({})", c.name),
|
||||
(v, _) => v.label().to_string(),
|
||||
(View3D::ActiveCamera, Some(c)) => crate::i18n::tr_args("Active Camera ({})", &[&c.name]),
|
||||
(v, _) => view3d_label(v).to_string(),
|
||||
};
|
||||
painter.text(area.left_top() + vec2(12.0, 10.0), Align2::LEFT_TOP, label, Tokens::ui(12.0), t.text_dim);
|
||||
}
|
||||
|
||||
@@ -151,3 +151,14 @@ fn edge_pan_speed_moves_toward_the_edge() {
|
||||
let corner = edge_pan_speed(area, pos2(950.0, 700.0));
|
||||
assert!(corner.x < 0.0 && corner.y < 0.0, "{corner:?}");
|
||||
}
|
||||
|
||||
/// Every 3D view names its own `view.3d.*` command: a typo in that mapping would fall back to the
|
||||
/// English label silently, which is what the viewer showed before (#2691).
|
||||
#[test]
|
||||
fn every_3d_view_finds_its_japanese_row() {
|
||||
crate::i18n::ui::set_current("ja");
|
||||
for v in View3D::ALL {
|
||||
assert_ne!(view3d_label(v), v.label(), "{v:?} has no Japanese row");
|
||||
}
|
||||
crate::i18n::ui::set_current("en");
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ pub(super) fn aux_views(
|
||||
let map = ViewerMap { origin: cr.min, zoom: fit, comp: [cw, ch], area: r };
|
||||
draw_rigs(app, &p.with_clip_rect(r), &map, &ectx, &selected, cam, through_active, Some(v.id()));
|
||||
}
|
||||
let label = if comp.has_3d() { v.label() } else { crate::i18n::tr("Active Camera") };
|
||||
let label = if comp.has_3d() { super::view3d_label(v) } else { crate::i18n::tr("Active Camera") };
|
||||
p.text(r.left_bottom() + vec2(8.0, -8.0), Align2::LEFT_BOTTOM, label, Tokens::ui(11.0), Color32::from_white_alpha(200));
|
||||
app.auto.add(&format!("viewer.view.{}", v.id()), r, label);
|
||||
if comp.has_3d()
|
||||
@@ -124,7 +124,7 @@ fn pane_selector(app: &mut EffectcraftApp, ui: &mut egui::Ui, pane: usize, area:
|
||||
let t = app.tokens;
|
||||
let r = Rect::from_min_size(area.min + vec2(6.0, 6.0), vec2(124.0, 20.0));
|
||||
let pid = egui::Id::unique(("viewer-pane-view", pane));
|
||||
let response = widgets::dropdown(ui, r, crate::i18n::tr(current.label()), &t, pid);
|
||||
let response = widgets::dropdown(ui, r, super::view3d_label(current), &t, pid);
|
||||
if response.clicked() {
|
||||
let open = widgets::popup_is_open(ui, pid);
|
||||
ui.data_mut(|d| d.insert_temp(pid.with("open"), !open));
|
||||
@@ -137,7 +137,7 @@ fn pane_selector(app: &mut EffectcraftApp, ui: &mut egui::Ui, pane: usize, area:
|
||||
ui.set_min_width(124.0);
|
||||
let mut chosen = None;
|
||||
for (k, v) in View3D::ALL.iter().enumerate() {
|
||||
let item = ui.selectable_label(*v == current, crate::i18n::tr(v.label()));
|
||||
let item = ui.selectable_label(*v == current, super::view3d_label(*v));
|
||||
app.auto.add(&format!("viewer.view.{pane}.typeItem.{k}"), item.rect, v.label());
|
||||
if item.clicked() {
|
||||
chosen = Some(*v);
|
||||
|
||||
@@ -896,13 +896,13 @@ fn bottom_bar_contents(app: &mut EffectcraftApp, ui: &mut egui::Ui, bar: Rect, z
|
||||
let cid = app.session.active_comp_id();
|
||||
let cur = cid.and_then(|c| app.session.state.views3d.get(&c)).map(|v| v.current).unwrap_or_default();
|
||||
let r = Rect::from_min_size(pos2(x, cy - 10.0), vec2(118.0, 20.0));
|
||||
let response = widgets::dropdown(ui, r, cur.label(), &t, egui::Id::unique("vw-cam"));
|
||||
let response = widgets::dropdown(ui, r, crate::panels::viewer::view3d_label(cur), &t, egui::Id::unique("vw-cam"));
|
||||
if response.clicked() {
|
||||
toggle_popup(ui, "vw-cam-pop");
|
||||
}
|
||||
app.auto.add_response("viewer.view3d", &response, "3D View");
|
||||
use effectcraft_engine::render::three_d::View3D;
|
||||
let items: Vec<(String, bool)> = View3D::ALL.iter().map(|v| (v.label().to_string(), *v == cur)).collect();
|
||||
let items: Vec<(String, bool)> = View3D::ALL.iter().map(|v| (crate::panels::viewer::view3d_label(*v).to_string(), *v == cur)).collect();
|
||||
if let Some(i) = popup(app, ui, "vw-cam-pop", r, &items, "view3dItem") {
|
||||
let _ = app.session.execute("view.set3DView", json!({"view": View3D::ALL[i].id()}));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user