From 4e8cde92bc8a6de983c3f64b870b80c05e3584ea Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 12 Jan 2021 06:12:24 +0800 Subject: [PATCH 1/3] Allow customl 10n resources in AppLauncher --- druid/src/app.rs | 21 +++++++++++++++- druid/src/env.rs | 65 +++++++++++++++++++++++++++++++----------------- 2 files changed, 62 insertions(+), 24 deletions(-) diff --git a/druid/src/app.rs b/druid/src/app.rs index 9e15cbe888..abb813e07b 100644 --- a/druid/src/app.rs +++ b/druid/src/app.rs @@ -33,6 +33,7 @@ type EnvSetupFn = dyn FnOnce(&mut Env, &T); pub struct AppLauncher { windows: Vec>, env_setup: Option>>, + l10n_resources: Option<(Vec, String)>, delegate: Option>>, ext_event_host: ExtEventHost, } @@ -107,6 +108,7 @@ impl AppLauncher { AppLauncher { windows: vec![window], env_setup: None, + l10n_resources: None, delegate: None, ext_event_host: ExtEventHost::new(), } @@ -146,6 +148,19 @@ impl AppLauncher { self } + /// Use custom localization resource + /// + /// `resources` is a list of file names that contain strings. `base_dir` + /// is a path to a directory that includes per-locale subdirectories. + /// + /// This directory should be of the structure `base_dir/{locale}/{resource}`, + /// where '{locale}' is a valid BCP47 language tag, and {resource} is a `.ftl` + /// included in `resources`. + pub fn localization_resources(mut self, resources: Vec, base_dir: String) -> Self { + self.l10n_resources = Some((resources, base_dir)); + self + } + /// Returns an [`ExtEventSink`] that can be moved between threads, /// and can be used to submit commands back to the application. /// @@ -161,7 +176,11 @@ impl AppLauncher { pub fn launch(mut self, data: T) -> Result<(), PlatformError> { let app = Application::new()?; - let mut env = Env::default(); + let mut env = self + .l10n_resources + .map(|it| Env::with_i10n(it.0, &it.1)) + .unwrap_or_default(); + if let Some(f) = self.env_setup.take() { f(&mut env, &data); } diff --git a/druid/src/env.rs b/druid/src/env.rs index 9cc651fdf5..9a75e7efdd 100644 --- a/druid/src/env.rs +++ b/druid/src/env.rs @@ -467,37 +467,56 @@ impl Data for EnvImpl { } } +// Colors are from https://sashat.me/2017/01/11/list-of-20-simple-distinct-colors/ +// They're picked for visual distinction and accessbility (99 percent) +const DEBUG_COLOR: &[Color] = &[ + Color::rgb8(230, 25, 75), + Color::rgb8(60, 180, 75), + Color::rgb8(255, 225, 25), + Color::rgb8(0, 130, 200), + Color::rgb8(245, 130, 48), + Color::rgb8(70, 240, 240), + Color::rgb8(240, 50, 230), + Color::rgb8(250, 190, 190), + Color::rgb8(0, 128, 128), + Color::rgb8(230, 190, 255), + Color::rgb8(170, 110, 40), + Color::rgb8(255, 250, 200), + Color::rgb8(128, 0, 0), + Color::rgb8(170, 255, 195), + Color::rgb8(0, 0, 128), + Color::rgb8(128, 128, 128), + Color::rgb8(255, 255, 255), + Color::rgb8(0, 0, 0), +]; + impl Default for Env { fn default() -> Self { let l10n = L10nManager::new(vec!["builtin.ftl".into()], "./resources/i18n/"); - // Colors are from https://sashat.me/2017/01/11/list-of-20-simple-distinct-colors/ - // They're picked for visual distinction and accessbility (99 percent) - let debug_colors = vec![ - Color::rgb8(230, 25, 75), - Color::rgb8(60, 180, 75), - Color::rgb8(255, 225, 25), - Color::rgb8(0, 130, 200), - Color::rgb8(245, 130, 48), - Color::rgb8(70, 240, 240), - Color::rgb8(240, 50, 230), - Color::rgb8(250, 190, 190), - Color::rgb8(0, 128, 128), - Color::rgb8(230, 190, 255), - Color::rgb8(170, 110, 40), - Color::rgb8(255, 250, 200), - Color::rgb8(128, 0, 0), - Color::rgb8(170, 255, 195), - Color::rgb8(0, 0, 128), - Color::rgb8(128, 128, 128), - Color::rgb8(255, 255, 255), - Color::rgb8(0, 0, 0), - ]; + let inner = EnvImpl { + l10n: Arc::new(l10n), + map: HashMap::new(), + debug_colors: DEBUG_COLOR.into(), + }; + + let env = Env(Arc::new(inner)) + .adding(Env::DEBUG_PAINT, false) + .adding(Env::DEBUG_WIDGET_ID, false) + .adding(Env::DEBUG_WIDGET, false); + + crate::theme::add_to_env(env) + } +} + +impl Env { + pub(crate) fn with_i10n(resources: Vec, base_dir: &str) -> Self { + let l10n = L10nManager::new(resources, base_dir); let inner = EnvImpl { l10n: Arc::new(l10n), map: HashMap::new(), - debug_colors, + debug_colors: DEBUG_COLOR.into(), }; let env = Env(Arc::new(inner)) From dd6ba650f7d85321822d4d75e4837b2f73f6bd88 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 12 Jan 2021 06:12:41 +0800 Subject: [PATCH 2/3] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b3922d4c1..e56bded61b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ You can find its changes [documented below](#070---2021-01-01). - WindowCloseRequested/WindowDisconnected event when a window is closing ([#1254] by [@rjwittams]) - RichTextBuilder ([#1520] by [@Maan2003]) - `get_external_handle` on `DelegateCtx` ([#1526] by [@Maan2003]) +- `AppLauncher::localization_resources` to use custom l10n resources. ([#1528] by [@edwin0cheng]) ### Changed From b5176cee4b56eba53784a655cde535fe5ad72583 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 12 Jan 2021 06:50:00 +0800 Subject: [PATCH 3/3] Refactor Env::default --- druid/src/env.rs | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/druid/src/env.rs b/druid/src/env.rs index 9a75e7efdd..31d75fa334 100644 --- a/druid/src/env.rs +++ b/druid/src/env.rs @@ -492,20 +492,7 @@ const DEBUG_COLOR: &[Color] = &[ impl Default for Env { fn default() -> Self { - let l10n = L10nManager::new(vec!["builtin.ftl".into()], "./resources/i18n/"); - - let inner = EnvImpl { - l10n: Arc::new(l10n), - map: HashMap::new(), - debug_colors: DEBUG_COLOR.into(), - }; - - let env = Env(Arc::new(inner)) - .adding(Env::DEBUG_PAINT, false) - .adding(Env::DEBUG_WIDGET_ID, false) - .adding(Env::DEBUG_WIDGET, false); - - crate::theme::add_to_env(env) + Env::with_i10n(vec!["builtin.ftl".into()], "./resources/i18n/") } }