mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Merge pull request #2581 from Muratv07/feature/turkish-localization
i18n: add Turkish (tr) localization
This commit is contained in:
@@ -154,6 +154,7 @@ pub const LANGUAGES: &[(&str, Quotes)] = &[
|
||||
("Polish", Quotes { double: ['„', '”'], single: ['‚', '’'] }),
|
||||
("Czech", Quotes { double: ['„', '“'], single: ['‚', '‘'] }),
|
||||
("Russian", Quotes { double: ['«', '»'], single: ['„', '“'] }),
|
||||
("Turkish", Quotes { double: ['“', '”'], single: ['‘', '’'] }),
|
||||
("Japanese", Quotes { double: ['「', '」'], single: ['『', '』'] }),
|
||||
("Chinese", Quotes { double: ['“', '”'], single: ['‘', '’'] }),
|
||||
];
|
||||
|
||||
@@ -78,6 +78,7 @@ fn unit(d: &Dialog) -> Unit {
|
||||
Unit::named(&d.str("units")).unwrap_or_default()
|
||||
}
|
||||
|
||||
/// The General tab of Document Setup (units, bleed, artboard editing, options).
|
||||
fn general(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool {
|
||||
let units: Vec<(&str, &str)> = Unit::ALL.iter().map(|u| (u.label(), u.label())).collect();
|
||||
choice(ui, d, "units", tl!("Units:"), &units);
|
||||
@@ -88,7 +89,7 @@ fn general(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool
|
||||
let mut close = false;
|
||||
widgets::label_row(ui, "", LABEL, |ui| {
|
||||
// Applies the settings, then edits the artboards with the Artboard tool.
|
||||
if widgets::flat_button(ui, tl!("Edit Artboards"), 120.0).clicked() && confirm(app, d).is_ok() {
|
||||
if widgets::flat_button_fit(ui, tl!("Edit Artboards"), 120.0).clicked() && confirm(app, d).is_ok() {
|
||||
app.select_tool("artboard");
|
||||
// The shared frame restores its working copy after drawing the body. Tell it to
|
||||
// close too, otherwise it reopens the dialog that confirm just closed.
|
||||
|
||||
@@ -94,7 +94,7 @@ fn plural_polish(n: u64) -> usize {
|
||||
}
|
||||
|
||||
/// The registry. English first: it is the fallback and the source language.
|
||||
pub static LANGUAGES: [LangInfo; 24] = [
|
||||
pub static LANGUAGES: [LangInfo; 25] = [
|
||||
LangInfo { code: "en", name: "English", source: "", plural: plural_one_other, complete_menus: false, catalog: OnceLock::new() },
|
||||
// Greek: the whole interface and the status and error messages, keeping the same names in
|
||||
// English as Spanish; every `el-*` locale (including `el-GR` and `el-CY`) resolves here.
|
||||
@@ -263,6 +263,10 @@ pub static LANGUAGES: [LangInfo; 24] = [
|
||||
// English as Spanish; one/other plurals with the partitive after any number but 1 ("2 tasoa").
|
||||
// Every `fi-*` locale resolves here.
|
||||
LangInfo { code: "fi", name: "Suomi", source: include_str!("fi.tsv"), plural: plural_one_other, complete_menus: true, catalog: OnceLock::new() },
|
||||
// Turkish: the whole interface and the status and error messages, keeping the same names in
|
||||
// English as Spanish; a count takes the singular ("3 katman"), so plurals have one form. Every
|
||||
// `tr-*` locale (including `tr-TR` and `tr-CY`) resolves here.
|
||||
LangInfo { code: "tr", name: "Türkçe", source: include_str!("tr.tsv"), plural: plural_none, complete_menus: true, catalog: OnceLock::new() },
|
||||
];
|
||||
|
||||
impl LangInfo {
|
||||
|
||||
@@ -870,7 +870,7 @@ fn cs() -> Lang {
|
||||
}
|
||||
|
||||
/// Languages whose catalogs leave [`MENU_KEEP_AS_IS`] in English.
|
||||
const KEEPS_MENU_NAMES: [&str; 17] = ["cs", "de", "el", "es", "fr", "hu", "it", "ja", "ka", "ko", "pl", "pt-br", "ru", "sv", "uk", "vi", "fi"];
|
||||
const KEEPS_MENU_NAMES: [&str; 18] = ["cs", "de", "el", "es", "fr", "hu", "it", "ja", "ka", "ko", "pl", "pt-br", "ru", "sv", "uk", "vi", "fi", "tr"];
|
||||
|
||||
/// Menu labels the menu-complete catalogs (Czech, German, Spanish, Italian, Japanese, Brazilian Portuguese) show as they are: the product name, a format name, the built-in workspace
|
||||
/// names and the perspective grid presets (names, shown untranslated wherever else they appear).
|
||||
@@ -1190,6 +1190,41 @@ fn finnish_reads_as_finnish() {
|
||||
assert_eq!(message(fi(), nested), "komento `object.group` ei ole nyt käytettävissä: mitään ei ole valittu");
|
||||
}
|
||||
|
||||
/// The Turkish catalog registers under `tr`, claims complete menus and messages, and passes
|
||||
/// locale resolution, vocabulary and count formatting checks.
|
||||
#[test]
|
||||
fn turkish_reads_as_turkish() {
|
||||
assert_eq!(tr_lang().name(), "Türkçe");
|
||||
assert!(tr_lang().complete_menus());
|
||||
assert_eq!(Lang::from_pref("tr"), tr_lang());
|
||||
assert_eq!(Lang::from_pref("TR"), tr_lang());
|
||||
for tag in ["tr", "tr-TR", "tr_TR.UTF-8", "TR-tr", "tr-CY"] {
|
||||
assert_eq!(lang_from_tag(tag), Some(tr_lang()), "{tag}");
|
||||
}
|
||||
for (en, want) in [
|
||||
("Artboard Tool", "Çalışma Yüzeyi Aracı"),
|
||||
("Swatches", "Renk Örnekleri"),
|
||||
("Stroke", "Kontur"),
|
||||
("Fill", "Dolgu"),
|
||||
("Direct Selection Tool", "Doğrudan Seçim Aracı"),
|
||||
("Save As…", "Farklı Kaydet…"),
|
||||
("Undo", "Geri Al"),
|
||||
("Close", "Kapat"),
|
||||
] {
|
||||
assert_eq!(tr(tr_lang(), en), want);
|
||||
}
|
||||
for n in [0, 1, 3, 21] {
|
||||
assert_eq!(trn(tr_lang(), n, "{n} Layer", "{n} Layers"), format!("{n} Katman"));
|
||||
}
|
||||
let nested = "command `object.group` is not available right now: nothing selected";
|
||||
assert_eq!(message(tr_lang(), nested), "`object.group` komutu şu anda kullanılamıyor: hiçbir şey seçilmedi");
|
||||
}
|
||||
|
||||
/// The [`Lang`] handle for the Turkish catalog.
|
||||
fn tr_lang() -> Lang {
|
||||
Lang::from_code("tr").expect("tr registered")
|
||||
}
|
||||
|
||||
/// Ambiguous English terms keep their intended Vietnamese meaning across UI contexts.
|
||||
#[test]
|
||||
fn vietnamese_domain_terms_are_consistent() {
|
||||
@@ -2104,7 +2139,7 @@ fn shared_param_check_errors_are_translated() {
|
||||
|
||||
/// Languages whose catalogs cover every status and error message.
|
||||
const COMPLETE_MESSAGES: &[&str] =
|
||||
&["cs", "de", "el", "es", "fr", "hu", "it", "ja", "ka", "ko", "pl", "pt-br", "ru", "sv", "uk", "vi", "zh-hans", "zh-hant", "fi"];
|
||||
&["cs", "de", "el", "es", "fr", "hu", "it", "ja", "ka", "ko", "pl", "pt-br", "ru", "sv", "uk", "vi", "zh-hans", "zh-hant", "fi", "tr"];
|
||||
|
||||
/// Crates whose error and status messages reach the status bar.
|
||||
const MESSAGE_CRATES: &[&str] = &["ui-egui", "engine", "doc", "format", "svg", "pdf", "eps", "text", "plugins", "metafile", "cad", "trace"];
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -44,6 +44,20 @@ pub fn flat_button(ui: &mut Ui, text: &str, width: f32) -> Response {
|
||||
resp
|
||||
}
|
||||
|
||||
/// A [`flat_button`] that expands to fit localized labels wider than `min_width`.
|
||||
pub fn flat_button_fit(ui: &mut Ui, text: &str, min_width: f32) -> Response {
|
||||
let t = Tokens::get(ui.ctx());
|
||||
let galley = ui.painter().layout_no_wrap(tl!(text).to_string(), egui::FontId::proportional(12.5), t.text_strong);
|
||||
let width = (galley.size().x + 24.0).max(min_width);
|
||||
let (rect, resp) = ui.allocate_exact_size(vec2(width, 24.0), Sense::click());
|
||||
let rect = rect.shrink2(vec2(0.0, 0.5));
|
||||
ui.painter().rect_filled(rect, CornerRadius::same(5), t.button);
|
||||
flat_fill(ui, rect, &resp);
|
||||
ui.painter().with_clip_rect(rect).text(rect.center(), egui::Align2::CENTER_CENTER, tl!(text), egui::FontId::proportional(12.5), t.text_strong);
|
||||
resp.widget_info(|| egui::WidgetInfo::labeled(egui::WidgetType::Button, ui.is_enabled(), tl!(text)));
|
||||
resp
|
||||
}
|
||||
|
||||
/// Width of a [`split_button`]'s arrow.
|
||||
pub const SPLIT_ARROW: f32 = 18.0;
|
||||
|
||||
@@ -2845,3 +2859,24 @@ mod combo_keyboard_tests {
|
||||
assert!(!egui::Popup::is_any_open(&ctx), "the list closes after a keyboard pick");
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod button_tests {
|
||||
use super::*;
|
||||
|
||||
/// [`flat_button_fit`] preserves minimum width for short labels and expands for long ones.
|
||||
#[test]
|
||||
fn flat_button_fit_expands_for_long_text() {
|
||||
let ctx = egui::Context::default();
|
||||
crate::theme::install_fonts(&ctx);
|
||||
let raw = egui::RawInput::default();
|
||||
let mut out = ctx.run_ui(raw, |ui| {
|
||||
let resp_short = flat_button_fit(ui, "OK", 100.0);
|
||||
assert_eq!(resp_short.rect.width(), 100.0);
|
||||
|
||||
let resp_long = flat_button_fit(ui, "Çalışma Yüzeylerini Düzenle", 100.0);
|
||||
assert!(resp_long.rect.width() > 160.0);
|
||||
});
|
||||
out.textures_delta.clear();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user