//! Minimalna, zależnościowo „lekka" lokalizacja PL/EN. //! //! Świadomie NIE używamy `fluent`, `gettext` ani plików `.po`: dla toolkitu //! wystarczy statyczna tablica napisów. Dzięki temu: //! //! * zero dodatkowych zależności i zero kodu generowanego w czasie budowy, //! * `tr()` jest w pełni `const`-owalne (zwraca `&'static str`), //! * rozbudowa to dopisanie jednego wariantu w [`MsgKey`] i trzech napisów w [`tr`]. //! //! Język wybieramy ze zmiennej środowiskowej `PAGAN_LANG` (`pl` / `en`). /// Obsługiwane języki interfejsu. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Locale { /// Polski. Pl, /// Angielski (domyślny, bezpieczny fallback). En, } impl Default for Locale { fn default() -> Self { Locale::En } } /// Klucze komunikatów UI. Dodawanie nowych napisów zaczyna się tutaj. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum MsgKey { /// Tytuł okna demo. WindowTitle, /// Etykieta przycisku „Menu". Menu, /// Pozycja paska menu: plik. MenuFile, /// Pozycja paska menu: edycja. MenuEdit, /// Pozycja paska menu: widok. MenuView, /// Pozycja paska menu: pomoc. MenuHelp, /// Etykieta/tooltip przycisku zamykania. Close, /// Etykieta/tooltip przycisku minimalizacji. Minimize, /// Etykieta/tooltip przycisku maksymalizacji. Maximize, /// Etykieta/tooltip przywrócenia rozmiaru. Restore, /// Log: zamykanie okna. LogClosing, /// Log: rozpoczęto przeciąganie okna. LogDrag, /// Log: rozpoczęto zmianę rozmiaru za krawędź/róg. LogResize, /// Log: otwarto/zamknięto menu. LogMenu, /// Log: zakończono pętlę zdarzeń. LogExit, /// Log: zmieniono stan maksymalizacji. LogMaximize, } /// Zwraca przetłumaczony napis dla pary `(język, klucz)`. /// /// Funkcja jest czysta (brak stanu, brak alokacji) i zwraca `&'static str`, /// więc można ją wywoływać bez obaw w każdym miejscu, także w kodzie rysującym. pub fn tr(locale: Locale, key: MsgKey) -> &'static str { match locale { Locale::Pl => match key { MsgKey::WindowTitle => "Pagan Toolkit — okno demo", MsgKey::Menu => "Menu", MsgKey::MenuFile => "Plik", MsgKey::MenuEdit => "Edycja", MsgKey::MenuView => "Widok", MsgKey::MenuHelp => "Pomoc", MsgKey::Close => "Zamknij", MsgKey::Minimize => "Minimalizuj", MsgKey::Maximize => "Maksymalizuj", MsgKey::Restore => "Przywróć", MsgKey::LogClosing => "Zamykanie okna na życzenie użytkownika.", MsgKey::LogDrag => "Rozpoczęto przeciąganie okna (xdg_toplevel.move).", MsgKey::LogResize => "Rozpoczęto zmianę rozmiaru okna (xdg_toplevel.resize).", MsgKey::LogMenu => "Naciśnięto przycisk menu.", MsgKey::LogExit => "Pętla zdarzeń zakończona. Do zobaczenia!", MsgKey::LogMaximize => "Zmieniono stan maksymalizacji okna.", }, Locale::En => match key { MsgKey::WindowTitle => "Pagan Toolkit — demo window", MsgKey::Menu => "Menu", MsgKey::MenuFile => "File", MsgKey::MenuEdit => "Edit", MsgKey::MenuView => "View", MsgKey::MenuHelp => "Help", MsgKey::Close => "Close", MsgKey::Minimize => "Minimize", MsgKey::Maximize => "Maximize", MsgKey::Restore => "Restore", MsgKey::LogClosing => "Closing the window at user request.", MsgKey::LogDrag => "Started interactive move (xdg_toplevel.move).", MsgKey::LogResize => "Started interactive resize (xdg_toplevel.resize).", MsgKey::LogMenu => "Menu button pressed.", MsgKey::LogExit => "Event loop finished. Goodbye!", MsgKey::LogMaximize => "Toggled window maximize state.", }, } } impl From<&str> for Locale { /// Mapuje dowolny string (np. z `PAGAN_LANG`) na język. Nieznane wartości → /// [`Locale::En`], żeby aplikacja nigdy nie wyświetlała pustych napisów. fn from(value: &str) -> Self { let normalized = value.trim().to_ascii_lowercase(); match normalized.as_str() { "pl" | "pol" | "polski" | "pl_pl" | "pl-pl" => Locale::Pl, _ => Locale::En, } } } impl From for Locale { fn from(value: String) -> Self { Locale::from(value.as_str()) } } impl Locale { /// Odczytuje język ze zmiennej środowiskowej `PAGAN_LANG`. pub fn from_env() -> Self { std::env::var("PAGAN_LANG") .map(|value| Locale::from(value.as_str())) .unwrap_or_default() } }