mirror of
https://github.com/storytold/lightcraft.git
synced 2026-11-10 10:29:55 -06:00
fix(i18n): translate masking context menu actions
This commit is contained in:
@@ -296,7 +296,7 @@ pub fn show(app: &mut LightcraftApp, ui: &mut egui::Ui, id: PhotoId) {
|
||||
let (kind, icon) = kind_label(&c.shape);
|
||||
let label = c.name.clone().unwrap_or_else(|| match &c.shape {
|
||||
MaskShape::Prompt { text, .. } => format!("“{text}”"),
|
||||
_ => kind.to_string(),
|
||||
_ => menu_label(kind).to_string(),
|
||||
});
|
||||
ui.horizontal(|ui| {
|
||||
let (r, _) = ui.allocate_exact_size(vec2(16.0, 16.0), Sense::hover());
|
||||
@@ -403,10 +403,15 @@ pub fn show(app: &mut LightcraftApp, ui: &mut egui::Ui, id: PhotoId) {
|
||||
let _ = Stroke::NONE;
|
||||
}
|
||||
|
||||
/// Translate fixed action labels, but never mutate or translate user-entered mask names.
|
||||
fn menu_label(source: &str) -> &str {
|
||||
crate::i18n::tr(source)
|
||||
}
|
||||
|
||||
/// The right-click menu of a mask in the Masks list.
|
||||
fn mask_menu(app: &mut LightcraftApp, ui: &mut egui::Ui, id: u32, name: &str, visible: bool, index: usize, count: usize) {
|
||||
let mut run = |ui: &mut egui::Ui, label: &str, enabled: bool, cmd: &str, p: serde_json::Value| {
|
||||
if ui.add_enabled(enabled, egui::Button::new(label)).clicked() {
|
||||
if ui.add_enabled(enabled, egui::Button::new(menu_label(label))).clicked() {
|
||||
let _ = app.run(cmd, p);
|
||||
ui.close();
|
||||
}
|
||||
@@ -439,10 +444,10 @@ fn overlay_options(app: &mut LightcraftApp, ui: &mut egui::Ui) {
|
||||
let view = MaskView::parse(&app.ui.mask_overlay_mode).unwrap_or_default();
|
||||
ui.horizontal(|ui| {
|
||||
ui.label(egui::RichText::new(crate::i18n::tr("Overlay")).color(t.text_dim));
|
||||
let r = crate::widgets::dropdown(ui, "maskOverlayMode", view.label(), t.font(12.5), t.text_label);
|
||||
let r = crate::widgets::dropdown(ui, "maskOverlayMode", menu_label(view.label()), t.font(12.5), t.text_label);
|
||||
egui::Popup::menu(&r).show(|ui| {
|
||||
for v in MaskView::ALL {
|
||||
if ui.selectable_label(v == view, v.label()).clicked() {
|
||||
if ui.selectable_label(v == view, menu_label(v.label())).clicked() {
|
||||
let _ = app.run("view.maskOverlayMode", json!({"mode": v.name()}));
|
||||
}
|
||||
}
|
||||
@@ -633,7 +638,7 @@ fn range_controls(app: &mut LightcraftApp, ui: &mut egui::Ui, comp: usize, shape
|
||||
/// The right-click / "…" menu of one component of the selected mask.
|
||||
fn component_row_menu(app: &mut LightcraftApp, ui: &mut egui::Ui, mask: u32, k: usize, label: &str, count: usize) {
|
||||
let mut run = |ui: &mut egui::Ui, text: &str, p: serde_json::Value| {
|
||||
if ui.button(text).clicked() {
|
||||
if ui.button(menu_label(text)).clicked() {
|
||||
let mut p = p;
|
||||
p["id"] = json!(mask);
|
||||
p["component"] = json!(k);
|
||||
@@ -799,7 +804,7 @@ fn component_menu(app: &mut LightcraftApp, ui: &mut egui::Ui, op: &str) {
|
||||
if kind == "brush" && op == "intersect" {
|
||||
continue;
|
||||
}
|
||||
let b = ui.button(label);
|
||||
let b = ui.button(menu_label(label));
|
||||
register(ui.ctx(), format!("maskComp:{op}:{kind}"), b.rect);
|
||||
if b.clicked() {
|
||||
if kind == "brush" {
|
||||
@@ -853,6 +858,25 @@ fn brush_settings(app: &mut LightcraftApp, ui: &mut egui::Ui) {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn masking_context_actions_use_catalog_translations() {
|
||||
let saved = crate::i18n::language();
|
||||
crate::i18n::set_language(crate::i18n::Locale::Fr);
|
||||
for (english, translated) in [
|
||||
("Duplicate Mask", "Dupliquer le masque"),
|
||||
("Invert Mask", "Inverser le masque"),
|
||||
("Hide Mask", "Masquer le masque"),
|
||||
("Move Up", "Monter"),
|
||||
("Brush", "Pinceau"),
|
||||
("Luminance Range", "Plage de luminance"),
|
||||
] {
|
||||
assert_eq!(menu_label(english), translated, "{english}");
|
||||
}
|
||||
// An arbitrary user name has no catalog entry and is left unchanged.
|
||||
assert_eq!(menu_label("My custom mask"), "My custom mask");
|
||||
crate::i18n::set_language(saved);
|
||||
}
|
||||
|
||||
/// The grid keeps four 52 pt tiles when the labels fit, and gives a long (translated) label
|
||||
/// room by dropping a column rather than drawing it past its tile.
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user