Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
283b3da
i18n(he): add first MaterialCraft Hebrew UI catalog
nocturney Nov 11, 2026
ea3a964
i18n(he): register Hebrew language and assert locale/RTL/catalog keys
nocturney Nov 11, 2026
c193a47
docs(i18n): document partial Hebrew coverage and remaining font QA
nocturney Nov 11, 2026
5bfc0d7
style(i18n): rustfmt Hebrew catalog source
nocturney Nov 11, 2026
071dc5d
i18n(he): align Redo term with shared ArtCraft Hebrew glossary
nocturney Nov 11, 2026
1069514
test(i18n): exercise Hebrew native save/reopen and UI screenshot
nocturney Nov 11, 2026
40ba9a9
feat(i18n): complete Hebrew menu labels for MaterialCraft
Nov 11, 2026
8c30c28
fix(i18n): align native Hebrew menu bar right-to-left
Nov 11, 2026
4a4feaf
fix(i18n): mirror Hebrew inspector headers and parameter controls
Nov 11, 2026
a1a760e
fix(i18n): reserve non-overlapping RTL inspector action columns
Nov 11, 2026
6cfbbf7
i18n(he): translate Native Home and Preferences workflow labels
Nov 11, 2026
49383ef
test(he): isolate native round-trip package from screenshot output
nocturney Nov 11, 2026
cc02abc
test(he): verify round-trip fixture uniqueness and cleanup
nocturney Nov 11, 2026
1428295
style(test): rustfmt isolated Hebrew native smoke fixture
nocturney Nov 11, 2026
615ef16
i18n(he): localize graph inspector attribute and size labels
Nov 11, 2026
b01206d
fix(ui): let RTL inspector literal rows grow to fit editors
Nov 11, 2026
bce6051
test(i18n): isolate Hebrew menu geometry from global locale
Nov 11, 2026
939bc08
fix(i18n): mirror Expose Parameter modal actions in Hebrew
Nov 11, 2026
1befb56
i18n(he): translate Expose Parameter dialog and validation
Nov 11, 2026
0f87ef5
i18n(he): localize visible Native empty-state and library help
Nov 11, 2026
a5e877b
fix(i18n): mirror Hebrew unsaved dialog and isolate mixed-script names
Nov 11, 2026
6c219c8
i18n(he): translate native toolbar and file-export feedback
Nov 11, 2026
96713b8
fix(i18n): avoid duplicate Hebrew warning key and format catalog
Nov 11, 2026
56f8225
i18n(he): localize native library and graph navigation controls
Nov 11, 2026
d5fe61c
feat(i18n): translate Hebrew 3D view and material export controls
Nov 11, 2026
e42c2d4
fix(i18n): mirror 3D view menu bar for Hebrew
Nov 11, 2026
88c89fa
fix(he): align graph node titles to RTL reading edge
Nov 12, 2026
0f1c53c
fix(he): align graph attribute captions to RTL reading edge
Nov 12, 2026
72673b2
feat(he): cover native graph, annotation and file actions
Nov 12, 2026
e48482c
fix(he): mirror material inspector node name editor
Nov 12, 2026
3b6ae57
Localize exposed parameter type labels in Hebrew UI
Nov 12, 2026
eec57e1
fix: mirror parameter color and text rows in Hebrew
Nov 12, 2026
7a7b7fe
fix(ui): mirror graph input and preset rows in Hebrew
Nov 12, 2026
1b65c5f
fix(ui): mirror MaterialCraft export controls in Hebrew
nocturney Nov 13, 2026
b362ce0
style(ui): format Hebrew export and native smoke test
nocturney Nov 13, 2026
7033382
fix(i18n): recognize legacy iw Hebrew locale and RTL in MaterialCraft
nocturney Nov 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 46 additions & 3 deletions crates/ui-egui/src/i18n.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::sync::OnceLock;
use std::sync::atomic::{AtomicUsize, Ordering};

mod ar;
mod he;

pub struct Language {
/// BCP 47 code ("en", "ar").
Expand All @@ -21,10 +22,13 @@ pub struct Language {
pub table: &'static [(&'static str, &'static str)],
}

const COUNT: usize = 2;
const COUNT: usize = 3;

pub static LANGUAGES: [Language; COUNT] =
[Language { code: "en", name: "English", english: "English", table: &[] }, Language { code: "ar", name: "العربية", english: "Arabic", table: ar::TABLE }];
pub static LANGUAGES: [Language; COUNT] = [
Language { code: "en", name: "English", english: "English", table: &[] },
Language { code: "ar", name: "العربية", english: "Arabic", table: ar::TABLE },
Language { code: "he", name: "עברית", english: "Hebrew", table: he::TABLE },
];

static MAPS: [OnceLock<HashMap<&'static str, &'static str>>; COUNT] = [const { OnceLock::new() }; COUNT];
static CURRENT: AtomicUsize = AtomicUsize::new(0);
Expand Down Expand Up @@ -115,10 +119,49 @@ mod tests {
assert_eq!(language_for_locale("ar"), "ar");
assert_eq!(language_for_locale("ar-EG"), "ar");
assert_eq!(language_for_locale("ar_SA.UTF-8"), "ar");
assert_eq!(language_for_locale("he"), "he");
assert_eq!(language_for_locale("he-IL"), "he");
assert_eq!(language_for_locale("he_IL.UTF-8"), "he");
assert!(is_rtl_code("he"));
assert_eq!(language_for_locale("en-US"), "en");
assert_eq!(language_for_locale("fr-FR"), "en");
}

#[test]
fn hebrew_table_has_no_duplicate_keys() {
let mut seen = std::collections::HashSet::new();
for (k, _) in he::TABLE {
assert!(seen.insert(*k), "duplicate key in he::TABLE: {k:?}");
}
}

#[test]
fn hebrew_placeholders_match_source() {
for (k, v) in he::TABLE {
let mut kp: Vec<&str> = k.split('{').skip(1).filter_map(|s| s.split_once('}').map(|(p, _)| p)).collect();
let mut vp: Vec<&str> = v.split('{').skip(1).filter_map(|s| s.split_once('}').map(|(p, _)| p)).collect();
kp.sort();
vp.sort();
assert_eq!(kp, vp, "mismatched placeholders in {k:?} vs {v:?}");
}
}

#[test]
fn hebrew_main_menus_and_file_workflow_are_localized() {
// Prevent untranslated top-level menus and primary file actions
// from slipping back into the Native Hebrew UI.
let essential =
["File", "Edit", "Tools", "Windows", "Help", "Open...", "Save", "Save as...", "Preferences...", "Snap to grid", "Import vector graphics..."];
for source in essential {
let translated = he::TABLE
.iter()
.find(|(key, _)| *key == source)
.map(|(_, translated)| *translated)
.unwrap_or_else(|| panic!("missing Hebrew menu translation: {source}"));
assert_ne!(translated, source, "untranslated Native menu item: {source}");
}
}

#[test]
fn arabic_table_has_no_duplicate_keys() {
let mut seen = std::collections::HashSet::new();
Expand Down
228 changes: 228 additions & 0 deletions crates/ui-egui/src/i18n/he.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
//! First Hebrew UI catalog for MaterialCraft.
//! AI-assisted, clean-room translation from MaterialCraft's English source labels.
//! Partial draft: missing labels deliberately fall back to English; native-speaker review pending.

pub const TABLE: &[(&str, &str)] = &[
("16 bits", "16 סיביות"),
("2D View", "תצוגת דו־ממד"),
("3D View", "תצוגת תלת־ממד"),
("8 bits", "8 סיביות"),
("About MaterialCraft", "אודות MaterialCraft"),
("About MaterialCraft...", "אודות MaterialCraft..."),
("Absolute", "מוחלט"),
("Accent color", "צבע הדגשה"),
("Actual pixels", "פיקסלים בפועל"),
("Add", "הוספה"),
("Add comment", "הוספת הערה"),
("Add Comment", "הוספת הערה"),
("Add Frame", "הוספת מסגרת"),
("Add frame around selection", "הוספת מסגרת מסביב לבחירה"),
("Add navigation pin", "הוספת סמן ניווט"),
("Add node", "הוספת צומת"),
("Align centers horizontally", "יישור מרכזים אופקית"),
("Align centers vertically", "יישור מרכזים אנכית"),
("Align left", "יישור לשמאל"),
("Align top", "יישור למעלה"),
("All", "הכול"),
("All nodes", "כל הצמתים"),
("Apply", "החלה"),
("ArtCraft website...", "אתר ArtCraft..."),
("As JSON", "כ־JSON"),
("Attributes", "מאפיינים"),
("Automatic export when outputs change", "ייצוא אוטומטי כאשר הפלטים משתנים"),
("Autosave every (minutes, 0 = off)", "שמירה אוטומטית בכל (דקות, 0 = כבוי)"),
("Base parameters", "פרמטרים בסיסיים"),
("Batch", "אצווה"),
("Bit depth", "עומק סיביות"),
("Blends", "מצבי מיזוג"),
("Blue", "כחול"),
("Brightness", "בהירות"),
("Cache", "מטמון"),
("Camera", "מצלמה"),
("Cancel", "ביטול"),
("Check at least one output to export", "יש לבחור לפחות פלט אחד לייצוא"),
("Check for updates...", "בדיקת עדכונים..."),
("Choose a folder to export to", "בחירת תיקיית יעד לייצוא"),
("Choose...", "בחירה..."),
("Clear cache", "ניקוי מטמון"),
("Clear nodes thumbnails", "ניקוי תמונות ממוזערות של צמתים"),
("Clear recent packages", "ניקוי רשימת החבילות האחרונות"),
("Close", "סגירה"),
("Close all", "סגירת הכול"),
("color space", "מרחב צבע"),
("Community (Discord)", "קהילה (Discord)"),
("Comparison", "השוואה"),
("Compute graph", "חישוב גרף"),
("Compute nodes thumbnails", "חישוב תמונות ממוזערות של צמתים"),
("Computing...", "מחשב..."),
("Console", "מסוף"),
("Constant", "קבוע"),
("Control", "בקרה"),
("Copy", "העתקה"),
("Copy selection", "העתקת הבחירה"),
("Create", "יצירה"),
("Create graph from selection", "יצירת גרף מהבחירה"),
("Create graph in", "יצירת גרף בתוך"),
("Cube", "קובייה"),
("Cut", "גזירה"),
("Dark", "כהה"),
("Default", "ברירת מחדל"),
("Delete and relink", "מחיקה וחיבור מחדש"),
("Delete", "מחיקה"),
("Delete input", "מחיקת קלט"),
("Delete preset", "מחיקת הגדרה קבועה מראש"),
("Delete selection", "מחיקת הבחירה"),
("Destination", "יעד"),
("Display", "תצוגה"),
("Distribute horizontally", "פיזור אופקי"),
("Distribute vertically", "פיזור אנכי"),
("Documentation", "תיעוד"),
("Documentation...", "תיעוד..."),
("Downloaded", "הורד"),
("Duplicate", "שכפול"),
("Duplicate selection", "שכפול הבחירה"),
("Edit node graph", "עריכת גרף הצמתים"),
("Edit", "עריכה"),
("Empty", "ריק"),
("Empty package", "חבילה ריקה"),
("Environment", "סביבה"),
("Exit", "יציאה"),
("Explorer", "סייר"),
("Export", "ייצוא"),
("Export material...", "ייצוא חומר..."),
("Export outputs", "ייצוא פלטים"),
("Export outputs...", "ייצוא פלטים..."),
("Export settings saved", "הגדרות הייצוא נשמרו"),
("Exported", "יוצא"),
("File", "קובץ"),
("File names", "שמות קבצים"),
("Filters", "מסננים"),
("Fit", "התאמה"),
("Folder", "תיקייה"),
("Format", "תבנית"),
("Frame all", "הצגת הכול במסגרת"),
("From graph", "מהגרף"),
("Full size", "גודל מלא"),
("Function Graph...", "גרף פונקציות..."),
("Function", "פונקציה"),
("Function graph", "גרף פונקציות"),
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
("Graph", "גרף"),
("Graph instance", "מופע גרף"),
("Graph name", "שם הגרף"),
("Graph...", "גרף..."),
("Graphs in this package", "גרפים בחבילה זו"),
("Help", "עזרה"),
("Histogram", "היסטוגרמה"),
("History", "היסטוריה"),
("Home screen...", "מסך הבית..."),
("Home", "בית"),
("Import bitmap...", "ייבוא תמונת מפת סיביות..."),
("Import vector graphics...", "ייבוא גרפיקה וקטורית..."),
("Imported", "יובא"),
("Input parameters", "פרמטרי קלט"),
("Input previews", "תצוגות מקדימות של קלט"),
("Interface scale", "קנה מידה של הממשק"),
("Join the community (Discord)...", "הצטרפות לקהילה (Discord)..."),
("Language", "שפה"),
("Last compute", "חישוב אחרון"),
("Library", "ספרייה"),
("Light", "בהיר"),
("Link width and height", "קישור רוחב וגובה"),
("List", "רשימה"),
("Load mesh...", "טעינת רשת תלת־ממד..."),
("Material filters", "מסנני חומרים"),
("Name", "שם"),
("New", "חדש"),
("New graph", "גרף חדש"),
("New graph...", "גרף חדש..."),
("Next pin", "סיכת ניווט הבאה"),
("No graph is open", "אין גרף פתוח"),
("No graph with outputs", "אין גרף עם פלטים"),
("No matching node", "לא נמצא צומת מתאים"),
("No presets yet", "עדיין אין הגדרות קבועות מראש"),
("No recent packages", "אין חבילות אחרונות"),
("Noises", "רעשים"),
("None", "ללא"),
("Normal", "רגיל"),
("Open", "פתיחה"),
("Open graph", "פתיחת גרף"),
("Open package...", "פתיחת חבילה..."),
("Open...", "פתיחה..."),
("Opened", "נפתח"),
("Output format", "תבנית פלט"),
("Output size", "גודל הפלט"),
("Outputs", "פלטים"),
("Pan the camera", "הזזת המצלמה"),
("Pan the graph", "הזזת הגרף"),
("Parent graph", "גרף אב"),
("Paste", "הדבקה"),
("Pattern", "דוגמה"),
("Patterns", "דוגמאות"),
("Preferences", "העדפות"),
("Preferences...", "העדפות..."),
("Preset name", "שם ההגדרה הקבועה מראש"),
("Presets", "הגדרות קבועות מראש"),
("Preview", "תצוגה מקדימה"),
("Preview size", "גודל התצוגה המקדימה"),
("Previous pin", "סיכת ניווט קודמת"),
("Properties", "מאפיינים"),
("Random seed", "ערך התחלתי אקראי"),
("Recent", "אחרונים"),
("Recent packages", "חבילות אחרונות"),
("Redo", "ביצוע מחדש"),
("Reload resources", "טעינה מחדש של משאבים"),
("Render time", "זמן עיבוד"),
("Renderer", "מנוע עיבוד"),
("Report a bug...", "דיווח על תקלה..."),
("Reset and view outputs in 3D view", "איפוס והצגת פלטים בתצוגת תלת־ממד"),
("Reset layout", "איפוס פריסה"),
("Reset parameters", "איפוס פרמטרים"),
("Reset scene", "איפוס סצנה"),
("Reset to default", "איפוס לברירת מחדל"),
("Resolution", "רזולוציה"),
("Resources", "משאבים"),
("Revert", "שחזור למצב הקודם"),
("Rotation", "סיבוב"),
("Save", "שמירה"),
("Save (Ctrl+S)", "שמירה (Ctrl+S)"),
("Save as...", "שמירה בשם..."),
("Save image...", "שמירת תמונה..."),
("Save package", "שמירת חבילה"),
("Save preset", "שמירת הגדרה קבועה מראש"),
("Save settings", "שמירת הגדרות"),
("Saved", "נשמר"),
("Scene", "סצנה"),
("Search", "חיפוש"),
("Search nodes...", "חיפוש צמתים..."),
("Select all", "בחירת הכול"),
("Select downstream nodes", "בחירת צמתים במורד הזרימה"),
("Select upstream nodes", "בחירת צמתים במעלה הזרימה"),
("Send to TextureCraft", "שליחה אל TextureCraft"),
("Shortcuts", "קיצורי מקשים"),
("Shortcuts list...", "רשימת קיצורי מקשים..."),
("Show at startup", "הצגה בעת הפעלה"),
("Show in the 2D view", "הצגה בתצוגת הדו־ממד"),
("Show node thumbnails", "הצגת תמונות ממוזערות לצמתים"),
("Size", "גודל"),
("Snap to grid", "הצמדה לרשת"),
("Specific parameters", "פרמטרים ייחודיים"),
("Start export", "התחלת ייצוא"),
("Templates", "תבניות"),
("Text", "טקסט"),
("Textures", "טקסטורות"),
("This package", "החבילה הזו"),
("Tiling", "ריצוף"),
("Tools", "כלים"),
("Transforms", "טרנספורמציות"),
("Unbind", "ביטול קישור"),
("Undo", "ביטול פעולה"),
("Undo (Ctrl+Z)", "ביטול פעולה (Ctrl+Z)"),
("Use as result", "שימוש כתוצאה"),
("Variables", "משתנים"),
("Version", "גרסה"),
("View in 2D view", "הצגה בתצוגת הדו־ממד"),
("View outputs in 3D view", "הצגת פלטים בתצוגת תלת־ממד"),
("Welcome to MaterialCraft", "ברוכים הבאים ל־MaterialCraft"),
("Windows", "חלונות"),
("Zoom the graph and the views", "שינוי התקריב של הגרף והתצוגות"),
];
Loading