feat(locale): add Fluent translations

Default to the platform language with persisted overrides across native and web builds.

Refs #630
This commit is contained in:
Hakan Seven committed 2026-08-02 18:53:38 +03:00
1 parent e102887000
commit b90b3e3ecf
26 files changed
+1581 -112

No files matched your search

+4 -7
View File
@@ -111,8 +111,8 @@ pub enum EntryKind {
impl CommandLine {
pub fn new() -> Self {
let mut cl = Self::default();
cl.push_info("Open CAD Studio ready.");
cl.push_info("Type a command or use the ribbon. Open OBJ: INSERT tab.");
cl.push_info(&crate::tr!("command-line-ready"));
cl.push_info(&crate::tr!("command-line-hint"));
cl
}
@@ -430,7 +430,7 @@ impl CommandLine {
}
});
let prompt = container(
text("Command:").size(11).style(|theme: &Theme| iced::widget::text::Style {
text(crate::tr!("command-line-label")).size(11).style(|theme: &Theme| iced::widget::text::Style {
color: Some(theme.palette().success.base.color),
}),
)
@@ -467,10 +467,7 @@ impl CommandLine {
..Default::default()
}
});
let literal_tip = container(
text("Literal spaces: Space stays in the line instead of running the command (same as typing a leading '>'). Stays on until toggled off.")
.size(11),
)
let literal_tip = container(text(crate::tr!("command-line-literal-spaces")).size(11))
.padding([3, 6])
.style(container::bordered_box);
let literal_btn = tooltip(literal_btn, literal_tip, tooltip::Position::Top).gap(4);
+1 -1
View File
@@ -253,7 +253,7 @@ pub fn backdrop<'a>(
/// title bar; pass `Vector::ZERO` to keep it centred.
pub fn modal<'a>(
base: impl Into<Element<'a, Message>>,
title: &'a str,
title: impl iced::widget::text::IntoFragment<'a>,
content: impl Into<Element<'a, Message>>,
on_close: Message,
offset: Vector,
+1 -1
View File
@@ -422,7 +422,7 @@ impl Ribbon {
let is_active = i == self.active;
let is_contextual = module.id() == "layout";
let btn = container(
button(text(module.title()).size(12))
button(text(crate::i18n::ribbon_module_title(module.id(), module.title())).size(12))
.on_press(Message::RibbonSelectTab(i))
.style(move |theme: &Theme, status| {
let palette = theme.palette();
+29 -17
View File
@@ -9,6 +9,7 @@ pub fn view_window<'a>(
default_save_format: &'a str,
ui_theme: &'a UiThemeConfig,
theme_color_inputs: &'a [String; 6],
language: crate::i18n::Language,
sizing: crate::ui::modal::ModalSizing,
) -> Element<'a, Message> {
let selected_format = crate::io::SAVE_FORMAT_OPTIONS
@@ -25,12 +26,12 @@ pub fn view_window<'a>(
let palette = ui_theme.palette.to_iced();
let colors = [
("Background", palette.background),
("Text", palette.text),
("Primary", palette.primary),
("Success", palette.success),
("Warning", palette.warning),
("Danger", palette.danger),
(crate::tr!("options-color-background"), palette.background),
(crate::tr!("options-color-text"), palette.text),
(crate::tr!("options-color-primary"), palette.primary),
(crate::tr!("options-color-success"), palette.success),
(crate::tr!("options-color-warning"), palette.warning),
(crate::tr!("options-color-danger"), palette.danger),
];
let mut color_controls = column![].spacing(8);
@@ -60,16 +61,31 @@ pub fn view_window<'a>(
);
}
let close = button(text("Close").size(12))
let close = button(text(crate::tr!("action-close")).size(12))
.on_press(Message::CloseModal)
.padding([6, 18])
.style(button::secondary);
let content = column![
text("Open and Save").size(15),
text(crate::tr!("options-language-section")).size(15),
Space::new().height(10),
row![
text("Default save format:").size(12).width(150),
text(crate::tr!("options-language-label")).size(12).width(150),
iced::widget::pick_list(
Some(language),
crate::i18n::Language::ALL,
|value| value.to_string(),
)
.on_select(Message::LanguageChanged)
.width(sizing.width),
]
.spacing(12)
.align_y(iced::Center),
Space::new().height(22),
text(crate::tr!("options-open-save-section")).size(15),
Space::new().height(10),
row![
text(crate::tr!("options-default-save-format-label")).size(12).width(150),
iced::widget::pick_list(
selected_format,
crate::io::SAVE_FORMAT_OPTIONS,
@@ -81,16 +97,14 @@ pub fn view_window<'a>(
.spacing(12)
.align_y(iced::Center),
Space::new().height(8),
text(
"Used for the first save of a new drawing. Existing drawings keep their file type and version."
)
text(crate::tr!("options-default-save-format-help"))
.size(11)
.width(sizing.width),
Space::new().height(22),
text("Theme").size(15),
text(crate::tr!("options-theme-section")).size(15),
Space::new().height(10),
row![
text("Iced theme:").size(12).width(150),
text(crate::tr!("options-theme-label")).size(12).width(150),
iced::widget::pick_list(
selected_theme,
theme_options,
@@ -102,9 +116,7 @@ pub fn view_window<'a>(
.spacing(12)
.align_y(iced::Center),
Space::new().height(8),
text(
"Changing a base colour switches to Custom. Iced generates every component shade from these six colours."
)
text(crate::tr!("options-theme-help"))
.size(11)
.width(sizing.width),
Space::new().height(12),