添加中文支持
CI / setup (all) (push) Canceled after 0s
CI / setup (check) (push) Canceled after 0s
CI / version (push) Canceled after 0s
CI / check (${{ fromJson(needs.setup.outputs.check) }}) (push) Canceled after 0s
CI / build (${{ fromJson(needs.setup.outputs.all) }}) (push) Canceled after 0s
Build Debian Source Package / build-debian-src (push) Canceled after 0s
Package PlatformIO Library Dependencies / pkg-pio-libdeps (push) Canceled after 0s
Run Tests on Native platform / Generate Test Reports (push) Canceled after 0s
Run Tests on Native platform / Native PlatformIO Tests (push) Canceled after 0s
Run Tests on Native platform / Native Simulator Tests (push) Canceled after 0s
CI / gather-artifacts (esp32) (push) Canceled after 0s
CI / gather-artifacts (esp32c3) (push) Canceled after 0s
CI / gather-artifacts (esp32c6) (push) Canceled after 0s
CI / gather-artifacts (esp32s3) (push) Canceled after 0s
CI / gather-artifacts (nrf52840) (push) Canceled after 0s
CI / gather-artifacts (rp2040) (push) Canceled after 0s
CI / gather-artifacts (rp2350) (push) Canceled after 0s
CI / gather-artifacts (stm32) (push) Canceled after 0s
CI / firmware-size-report (push) Canceled after 0s
CI / release-artifacts (push) Canceled after 0s
CI / release-firmware (esp32) (push) Canceled after 0s
CI / release-firmware (esp32c3) (push) Canceled after 0s
CI / release-firmware (esp32c6) (push) Canceled after 0s
CI / release-firmware (esp32s3) (push) Canceled after 0s
CI / release-firmware (nrf52840) (push) Canceled after 0s
CI / release-firmware (rp2040) (push) Canceled after 0s
CI / release-firmware (rp2350) (push) Canceled after 0s
CI / release-firmware (stm32) (push) Canceled after 0s
CI / publish-firmware (push) Canceled after 0s
CI / build-debian-src (push) Canceled after 0s
CI / MacOS (15) (push) Canceled after 0s
CI / MacOS (26) (push) Canceled after 0s
Build MacOS Binary / build-MacOS (push) Canceled after 0s
CI / package-pio-deps-native-tft (push) Canceled after 0s
CI / test-native (push) Canceled after 0s
CI / docker (alpine, native, linux/amd64) (push) Canceled after 0s
CI / docker (alpine, native, linux/arm64) (push) Canceled after 0s
CI / docker (alpine, native-tft, linux/amd64) (push) Canceled after 0s
CI / docker (debian, native, linux/amd64) (push) Canceled after 0s
CI / docker (debian, native, linux/arm/v7) (push) Canceled after 0s
CI / docker (debian, native, linux/arm64) (push) Canceled after 0s
CI / docker (debian, native-tft, linux/amd64) (push) Canceled after 0s
Build Docker / docker-build (push) Canceled after 0s

This commit is contained in:
2026-06-25 21:00:37 +08:00
parent ae62affeec
commit bc241481b1
15 changed files with 1338 additions and 251 deletions
+1
View File
@@ -62,6 +62,7 @@ build_flags = -Wno-missing-field-initializers
-D MAX_THREADS=40 ; As we've split modules, we have more threads to manage
#-DBUILD_EPOCH=$UNIX_TIME ; set in platformio-custom.py now
#-D OLED_PL=1
#-D OLED_ZH=1 ; uncomment for compile-time Chinese font (runtime switching works without this on TFT)
#-D DEBUG_HEAP=1 ; uncomment to add free heap space / memory leak debugging logs
#-D DEBUG_LOOP_TIMING=1 ; uncomment to add main loop timing logs
+282 -1
View File
@@ -39,6 +39,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "draw/NodeListRenderer.h"
#include "draw/NotificationRenderer.h"
#include "draw/UIRenderer.h"
#include "graphics/fonts/OLEDDisplayFontsZH.h"
#include "graphics/TFTColorRegions.h"
#include "modules/CannedMessageModule.h"
#include "security/LockdownDisplay.h"
@@ -60,6 +61,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "graphics/TFTPalette.h"
#include "graphics/emotes.h"
#include "graphics/images.h"
#include "graphics/l10n/Strings.h"
#include "input/TouchScreenImpl1.h"
#include "main.h"
#include "mesh-pb-constants.h"
@@ -731,7 +733,10 @@ void Screen::setup()
// Enable display rendering
useDisplay = true;
// Load saved brightness from UI config
// Set the runtime display language from persisted config
meshtastic::l10n::currentDisplayLanguage = uiconfig.language;
// Load brightness from UI config
// For OLED displays (SSD1306), default brightness is 255 if not set
if (uiconfig.screen_brightness == 0) {
#if defined(USE_OLED) || defined(USE_SSD1306) || defined(USE_SH1106) || defined(USE_SH1107)
@@ -819,6 +824,9 @@ void Screen::setup()
// Enable UTF-8 to display mapping
dispdev->setFontTableLookupFunction(customFontTableLookup);
// Load CJK (Chinese) font if language requires it
loadCJKFontIfNeeded();
#ifdef USERPREFS_OEM_TEXT
logo_timeout *= 2; // Give more time for branded boot logos
#endif
@@ -985,6 +993,13 @@ int32_t Screen::runOnce()
return RUN_SAME;
}
// Detect language changes from remote config (phone app)
if (uiconfig.language != meshtastic::l10n::currentDisplayLanguage) {
meshtastic::l10n::currentDisplayLanguage = uiconfig.language;
loadCJKFontIfNeeded();
setFrames(FOCUS_PRESERVE);
}
if (displayHeight == 0) {
displayHeight = dispdev->getHeight();
}
@@ -2210,6 +2225,272 @@ bool Screen::isOverlayBannerShowing()
return NotificationRenderer::isOverlayBannerShowing();
}
char Screen::customFontTableLookup(const uint8_t ch)
{
static uint8_t LASTCHAR;
static bool SKIPREST;
static int8_t cjkRemaining = 0;
if (cjkRemaining > 0) {
cjkRemaining--;
LASTCHAR = ch;
return (uint8_t)0;
}
if (ch < 128) {
LASTCHAR = 0;
SKIPREST = false;
cjkRemaining = 0;
return ch;
}
uint8_t last = LASTCHAR;
LASTCHAR = ch;
switch (last) {
case 0xC2: {
SKIPREST = false;
return (uint8_t)ch;
}
case 0xC3: {
SKIPREST = false;
return (uint8_t)(ch | 0xC0);
}
}
if (ch == 0xC2 || ch == 0xC3)
return (uint8_t)0;
#if defined(OLED_PL)
switch (last) {
case 0xC3: {
if (ch == 147)
return (uint8_t)(ch);
else if (ch == 179)
return (uint8_t)(148);
else
return (uint8_t)(ch | 0xC0);
break;
}
case 0xC4: {
SKIPREST = false;
return (uint8_t)(ch);
}
case 0xC5: {
SKIPREST = false;
if (ch == 132)
return (uint8_t)(136);
else if (ch == 186)
return (uint8_t)(137);
else
return (uint8_t)(ch);
break;
}
}
if (ch == 0xC2 || ch == 0xC3 || ch == 0xC4 || ch == 0xC5)
return (uint8_t)0;
#endif
#if defined(OLED_UA) || defined(OLED_RU)
switch (last) {
case 0xC3: {
SKIPREST = false;
return (uint8_t)(ch | 0xC0);
}
case 0xD0: {
SKIPREST = false;
if (ch == 132)
return (uint8_t)(170);
if (ch == 134)
return (uint8_t)(178);
if (ch == 135)
return (uint8_t)(175);
if (ch == 129)
return (uint8_t)(168);
if (ch > 143 && ch < 192)
return (uint8_t)(ch + 48);
break;
}
case 0xD1: {
SKIPREST = false;
if (ch == 148)
return (uint8_t)(186);
if (ch == 150)
return (uint8_t)(179);
if (ch == 151)
return (uint8_t)(191);
if (ch == 145)
return (uint8_t)(184);
if (ch > 127 && ch < 144)
return (uint8_t)(ch + 112);
break;
}
case 0xD2: {
SKIPREST = false;
if (ch == 144)
return (uint8_t)(165);
if (ch == 145)
return (uint8_t)(180);
break;
}
}
if (ch == 0xC2 || ch == 0xC3 || ch == 0x82 || ch == 0xD0 || ch == 0xD1)
return (uint8_t)0;
#endif
#if defined(OLED_CS)
switch (last) {
case 0xC2: {
SKIPREST = false;
return (uint8_t)ch;
}
case 0xC3: {
SKIPREST = false;
return (uint8_t)(ch | 0xC0);
}
case 0xC4: {
SKIPREST = false;
if (ch == 140)
return (uint8_t)(129);
if (ch == 141)
return (uint8_t)(138);
if (ch == 142)
return (uint8_t)(130);
if (ch == 143)
return (uint8_t)(139);
if (ch == 154)
return (uint8_t)(131);
if (ch == 155)
return (uint8_t)(140);
if (ch == 185)
return (uint8_t)(147);
if (ch == 186)
return (uint8_t)(148);
if (ch == 189)
return (uint8_t)(149);
if (ch == 190)
return (uint8_t)(150);
break;
}
case 0xC5: {
SKIPREST = false;
if (ch == 135)
return (uint8_t)(132);
if (ch == 136)
return (uint8_t)(141);
if (ch == 152)
return (uint8_t)(133);
if (ch == 153)
return (uint8_t)(142);
if (ch == 160)
return (uint8_t)(134);
if (ch == 161)
return (uint8_t)(143);
if (ch == 164)
return (uint8_t)(135);
if (ch == 165)
return (uint8_t)(144);
if (ch == 174)
return (uint8_t)(136);
if (ch == 175)
return (uint8_t)(145);
if (ch == 189)
return (uint8_t)(137);
if (ch == 190)
return (uint8_t)(146);
if (ch == 148)
return (uint8_t)(151);
if (ch == 149)
return (uint8_t)(152);
break;
}
}
if (ch == 0xC2 || ch == 0xC3 || ch == 0xC4 || ch == 0xC5)
return (uint8_t)0;
#endif
#if defined(OLED_GR)
switch (last) {
case 0xC3: {
SKIPREST = false;
return (uint8_t)(ch | 0xC0);
}
case 0xCE: {
SKIPREST = false;
if (ch >= 145 && ch <= 161)
return (uint8_t)(ch + 48);
else if (ch >= 163 && ch <= 169)
return (uint8_t)(ch + 48);
else if (ch >= 177 && ch <= 193)
return (uint8_t)(ch + 48);
break;
}
case 0xCF: {
SKIPREST = false;
if (ch >= 130 && ch <= 137)
return (uint8_t)(ch + 112);
break;
}
}
if (ch == 0xC2 || ch == 0xC3 || ch == 0xCE || ch == 0xCF)
return (uint8_t)0;
#endif
if (ch >= 0xE2 && ch <= 0xEF) {
cjkRemaining = 2;
return (uint8_t)0;
}
if (SKIPREST)
return (uint8_t)0;
SKIPREST = true;
return (uint8_t)191;
}
void Screen::drawTextL10n(int16_t x, int16_t y, const char *text, OLEDDISPLAY_TEXT_ALIGNMENT alignment)
{
if (!dispdev || !text)
return;
#if defined(ST7735_CS) || defined(ST7789_CS) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || \
defined(HX8357_CS) || defined(ILI9488_CS) || defined(ST7796_CS) || defined(RAK14014)
if (meshtastic::l10n::currentDisplayLanguage == meshtastic_Language_SIMPLIFIED_CHINESE ||
meshtastic::l10n::currentDisplayLanguage == meshtastic_Language_TRADITIONAL_CHINESE) {
TFTDisplay *tftDisp = static_cast<TFTDisplay *>(dispdev);
if (tftDisp->hasCJKFont()) {
tftDisp->drawStringCJK(x, y, text);
return;
}
}
#endif
dispdev->setFont(FONT_SMALL);
dispdev->setTextAlignment(alignment);
dispdev->drawString(x, y, text);
}
void Screen::setFontL10n(const uint8_t *fontData)
{
if (!dispdev)
return;
dispdev->setFont(fontData);
}
void Screen::loadCJKFontIfNeeded()
{
#if defined(ST7735_CS) || defined(ST7789_CS) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || \
defined(HX8357_CS) || defined(ILI9488_CS) || defined(ST7796_CS) || defined(RAK14014)
if (meshtastic::l10n::currentDisplayLanguage == meshtastic_Language_SIMPLIFIED_CHINESE ||
meshtastic::l10n::currentDisplayLanguage == meshtastic_Language_TRADITIONAL_CHINESE) {
TFTDisplay *tftDisp = static_cast<TFTDisplay *>(dispdev);
if (!tftDisp->hasCJKFont()) {
tftDisp->loadCJKFont(FontZH_CN_16, FontZH_CN_16_size);
}
}
#endif
}
} // namespace graphics
#else
+5 -247
View File
@@ -366,255 +366,13 @@ class Screen : public concurrency::OSThread
enqueueCmd(ScreenCmd{.cmd = Cmd::NOOP});
}
/// Overrides the default utf8 character conversion, to replace empty space with question marks
static char customFontTableLookup(const uint8_t ch)
{
// UTF-8 to font table index converter
// Code from http://playground.arduino.cc/Main/Utf8ascii
static uint8_t LASTCHAR;
static bool SKIPREST; // Only display a single unconvertable-character symbol per sequence of unconvertable characters
static char customFontTableLookup(const uint8_t ch);
if (ch < 128) { // Standard ASCII-set 0..0x7F handling
LASTCHAR = 0;
SKIPREST = false;
return ch;
}
void drawTextL10n(int16_t x, int16_t y, const char *text, OLEDDISPLAY_TEXT_ALIGNMENT alignment = TEXT_ALIGN_LEFT);
void setFontL10n(const uint8_t *fontData);
uint8_t last = LASTCHAR; // get last char
LASTCHAR = ch;
switch (last) {
case 0xC2: {
SKIPREST = false;
return (uint8_t)ch;
}
case 0xC3: {
SKIPREST = false;
return (uint8_t)(ch | 0xC0);
}
}
// We want to strip out prefix chars for two-byte char formats
if (ch == 0xC2 || ch == 0xC3)
return (uint8_t)0;
#if defined(OLED_PL)
switch (last) {
case 0xC3: {
if (ch == 147)
return (uint8_t)(ch); // Ó
else if (ch == 179)
return (uint8_t)(148); // ó
else
return (uint8_t)(ch | 0xC0);
break;
}
case 0xC4: {
SKIPREST = false;
return (uint8_t)(ch);
}
case 0xC5: {
SKIPREST = false;
if (ch == 132)
return (uint8_t)(136); // ń
else if (ch == 186)
return (uint8_t)(137); // ź
else
return (uint8_t)(ch);
break;
}
}
// We want to strip out prefix chars for two-byte char formats
if (ch == 0xC2 || ch == 0xC3 || ch == 0xC4 || ch == 0xC5)
return (uint8_t)0;
#endif
#if defined(OLED_UA) || defined(OLED_RU)
switch (last) {
case 0xC3: {
SKIPREST = false;
return (uint8_t)(ch | 0xC0);
}
// map UTF-8 cyrillic chars to it Windows-1251 (CP-1251) ASCII codes
// note: in this case we must use compatible font - provided ArialMT_Plain_10/16/24 by 'ThingPulse/esp8266-oled-ssd1306'
// library have empty chars for non-latin ASCII symbols
case 0xD0: {
SKIPREST = false;
if (ch == 132)
return (uint8_t)(170); // Є
if (ch == 134)
return (uint8_t)(178); // І
if (ch == 135)
return (uint8_t)(175); // Ї
if (ch == 129)
return (uint8_t)(168); // Ё
if (ch > 143 && ch < 192)
return (uint8_t)(ch + 48);
break;
}
case 0xD1: {
SKIPREST = false;
if (ch == 148)
return (uint8_t)(186); // є
if (ch == 150)
return (uint8_t)(179); // і
if (ch == 151)
return (uint8_t)(191); // ї
if (ch == 145)
return (uint8_t)(184); // ё
if (ch > 127 && ch < 144)
return (uint8_t)(ch + 112);
break;
}
case 0xD2: {
SKIPREST = false;
if (ch == 144)
return (uint8_t)(165); // Ґ
if (ch == 145)
return (uint8_t)(180); // ґ
break;
}
}
// We want to strip out prefix chars for two-byte char formats
if (ch == 0xC2 || ch == 0xC3 || ch == 0x82 || ch == 0xD0 || ch == 0xD1)
return (uint8_t)0;
#endif
#if defined(OLED_CS)
switch (last) {
case 0xC2: {
SKIPREST = false;
return (uint8_t)ch;
}
case 0xC3: {
SKIPREST = false;
return (uint8_t)(ch | 0xC0);
}
case 0xC4: {
SKIPREST = false;
if (ch == 140)
return (uint8_t)(129); // Č
if (ch == 141)
return (uint8_t)(138); // č
if (ch == 142)
return (uint8_t)(130); // Ď
if (ch == 143)
return (uint8_t)(139); // ď
if (ch == 154)
return (uint8_t)(131); // Ě
if (ch == 155)
return (uint8_t)(140); // ě
// Slovak specific glyphs
if (ch == 185)
return (uint8_t)(147); // Ĺ
if (ch == 186)
return (uint8_t)(148); // ĺ
if (ch == 189)
return (uint8_t)(149); // Ľ
if (ch == 190)
return (uint8_t)(150); // ľ
break;
}
case 0xC5: {
SKIPREST = false;
if (ch == 135)
return (uint8_t)(132); // Ň
if (ch == 136)
return (uint8_t)(141); // ň
if (ch == 152)
return (uint8_t)(133); // Ř
if (ch == 153)
return (uint8_t)(142); // ř
if (ch == 160)
return (uint8_t)(134); // Š
if (ch == 161)
return (uint8_t)(143); // š
if (ch == 164)
return (uint8_t)(135); // Ť
if (ch == 165)
return (uint8_t)(144); // ť
if (ch == 174)
return (uint8_t)(136); // Ů
if (ch == 175)
return (uint8_t)(145); // ů
if (ch == 189)
return (uint8_t)(137); // Ž
if (ch == 190)
return (uint8_t)(146); // ž
// Slovak specific glyphs
if (ch == 148)
return (uint8_t)(151); // Ŕ
if (ch == 149)
return (uint8_t)(152); // ŕ
break;
}
}
// We want to strip out prefix chars for two-byte char formats
if (ch == 0xC2 || ch == 0xC3 || ch == 0xC4 || ch == 0xC5)
return (uint8_t)0;
#endif
#if defined(OLED_GR)
switch (last) {
case 0xC3: {
SKIPREST = false;
return (uint8_t)(ch | 0xC0);
}
// Map UTF-8 Greek chars to Windows-1253 (CP-1253) ASCII codes
case 0xCE: {
SKIPREST = false;
// Uppercase Greek: Α-Ρ (U+0391-U+03A1) -> CP-1253 193-209
if (ch >= 145 && ch <= 161)
return (uint8_t)(ch + 48);
// Uppercase Greek: Σ-Ω (U+03A3-U+03A9) -> CP-1253 211-217
else if (ch >= 163 && ch <= 169)
return (uint8_t)(ch + 48);
// Lowercase Greek: α-ρ (U+03B1-U+03C1) -> CP-1253 225-241
else if (ch >= 177 && ch <= 193)
return (uint8_t)(ch + 48);
break;
}
case 0xCF: {
SKIPREST = false;
// Lowercase Greek: ς-ω (U+03C2-U+03C9) -> CP-1253 242-249
if (ch >= 130 && ch <= 137)
return (uint8_t)(ch + 112);
break;
}
}
// We want to strip out prefix chars for two-byte Greek char formats
if (ch == 0xC2 || ch == 0xC3 || ch == 0xCE || ch == 0xCF)
return (uint8_t)0;
#endif
// If we already returned an unconvertable-character symbol for this unconvertable-character sequence, return NULs for the
// rest of it
if (SKIPREST)
return (uint8_t)0;
SKIPREST = true;
return (uint8_t)191; // otherwise: return ¿ if character can't be converted (note that the font map we're using doesn't
// stick to standard EASCII codes)
}
// Load CJK font if language requires it (called from setup & on language change)
void loadCJKFontIfNeeded();
/// Returns a handle to the DebugInfo screen.
//
+4
View File
@@ -20,6 +20,10 @@
#include "graphics/fonts/OLEDDisplayFontsGR.h"
#endif
#ifdef OLED_ZH
#include "graphics/fonts/OLEDDisplayFontsZH.h"
#endif
#if (defined(CROWPANEL_ESP32S3_5_EPAPER) || defined(T5_S3_EPAPER_PRO)) && defined(USE_EINK)
#include "graphics/fonts/EinkDisplayFonts.h"
#endif
+31
View File
@@ -1636,4 +1636,35 @@ bool TFTDisplay::connect()
return true;
}
bool TFTDisplay::loadCJKFont(const uint8_t *vlwData, uint32_t vlwDataLen)
{
if (!tft || !vlwData || vlwDataLen == 0)
return false;
cjkFontLoaded = tft->loadFont(vlwData);
if (cjkFontLoaded) {
LOG_INFO("CJK font loaded (%u bytes)", vlwDataLen);
} else {
LOG_WARN("Failed to load CJK font");
}
return cjkFontLoaded;
}
void TFTDisplay::drawStringCJK(int16_t x, int16_t y, const char *text)
{
if (!tft || !text || !cjkFontLoaded)
return;
concurrency::LockGuard g(spiLock);
uint16_t fgColor = getThemeDefaultOnColor();
tft->setTextColor(fgColor, getThemeDefaultOffColor());
tft->setCursor(x, y);
tft->print(text);
}
int16_t TFTDisplay::getStringWidthCJK(const char *text)
{
if (!tft || !text || !cjkFontLoaded)
return 0;
return tft->textWidth(text);
}
#endif // USE_TFTDISPLAY
+7
View File
@@ -38,6 +38,12 @@ class TFTDisplay : public OLEDDisplay
// Functions for changing display brightness
void setDisplayBrightness(uint8_t);
// CJK (Chinese/Japanese/Korean) text rendering via LovyanGFX
bool loadCJKFont(const uint8_t *vlwData, uint32_t vlwDataLen);
void drawStringCJK(int16_t x, int16_t y, const char *text);
int16_t getStringWidthCJK(const char *text);
bool hasCJKFont() const { return cjkFontLoaded; }
/**
* shim to make the abstraction happy
*
@@ -64,4 +70,5 @@ class TFTDisplay : public OLEDDisplay
uint16_t *linePixelBuffer = nullptr;
uint16_t *repaintChunkBuffer = nullptr;
bool cjkFontLoaded = false;
};
+54 -3
View File
@@ -13,6 +13,7 @@
#include "graphics/Screen.h"
#include "graphics/SharedUIDisplay.h"
#include "graphics/TFTColorRegions.h"
#include "graphics/l10n/Strings.h"
#include "graphics/draw/MessageRenderer.h"
#include "graphics/draw/UIRenderer.h"
#include "input/RotaryEncoderInterruptImpl1.h"
@@ -2377,9 +2378,9 @@ void menuHandler::screenOptionsMenu()
bool hasSupportBrightness = false;
#endif
enum optionsNumbers { Back, Brightness, FrameToggles, DisplayUnits, MessageBubbles, Theme };
static const char *optionsArray[7] = {"Back"};
static int optionsEnumArray[7] = {Back};
enum optionsNumbers { Back, Brightness, FrameToggles, DisplayUnits, MessageBubbles, Theme, LangPicker };
static const char *optionsArray[8] = {"Back"};
static int optionsEnumArray[8] = {Back};
int options = 1;
// Only show brightness for B&W displays
@@ -2402,6 +2403,12 @@ void menuHandler::screenOptionsMenu()
optionsEnumArray[options++] = Theme;
#endif
#if defined(ST7735_CS) || defined(ST7789_CS) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || \
defined(HX8357_CS) || defined(ILI9488_CS) || defined(ST7796_CS) || defined(RAK14014)
optionsArray[options] = "Language";
optionsEnumArray[options++] = LangPicker;
#endif
BannerOverlayOptions bannerOptions;
bannerOptions.message = "Display Options";
bannerOptions.optionsArrayPtr = optionsArray;
@@ -2423,6 +2430,9 @@ void menuHandler::screenOptionsMenu()
} else if (selected == Theme) {
menuHandler::menuQueue = menuHandler::ThemeMenu;
screen->runNow();
} else if (selected == LangPicker) {
menuHandler::menuQueue = menuHandler::LanguagePicker;
screen->runNow();
} else {
menuQueue = SystemBaseMenu;
screen->runNow();
@@ -2903,6 +2913,9 @@ void menuHandler::handleMenuSwitch(OLEDDisplay *display)
case ThemeMenu:
themeMenu();
break;
case LanguagePicker:
languagePickerMenu();
break;
case HamModeConfirm:
hamModeConfirmMenu();
break;
@@ -2913,6 +2926,44 @@ void menuHandler::handleMenuSwitch(OLEDDisplay *display)
menuQueue = MenuNone;
}
void menuHandler::languagePickerMenu()
{
enum optionsNumbers { Back, English, Chinese };
static const char *optionsArray[3] = {"Back"};
static int optionsEnumArray[3] = {Back};
int options = 1;
optionsArray[options] = "English";
optionsEnumArray[options++] = English;
optionsArray[options] = "Chinese";
optionsEnumArray[options++] = Chinese;
BannerOverlayOptions bannerOptions;
bannerOptions.message = "Language";
bannerOptions.optionsArrayPtr = optionsArray;
bannerOptions.optionsCount = options;
bannerOptions.optionsEnumPtr = optionsEnumArray;
bannerOptions.bannerCallback = [](int selected) -> void {
if (selected == English) {
uiconfig.language = meshtastic_Language_ENGLISH;
meshtastic::l10n::currentDisplayLanguage = meshtastic_Language_ENGLISH;
saveUIConfig();
} else if (selected == Chinese) {
uiconfig.language = meshtastic_Language_SIMPLIFIED_CHINESE;
meshtastic::l10n::currentDisplayLanguage = meshtastic_Language_SIMPLIFIED_CHINESE;
saveUIConfig();
#if defined(ST7735_CS) || defined(ST7789_CS) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || \
defined(HX8357_CS) || defined(ILI9488_CS) || defined(ST7796_CS) || defined(RAK14014)
screen->loadCJKFontIfNeeded();
#endif
}
menuQueue = ScreenOptionsMenu;
screen->runNow();
};
screen->showOverlayBanner(bannerOptions);
}
void menuHandler::saveUIConfig()
{
nodeDB->saveProto("/prefs/uiconfig.proto", meshtastic_DeviceUIConfig_size, &meshtastic_DeviceUIConfig_msg, &uiconfig);
+2
View File
@@ -56,6 +56,7 @@ class menuHandler
DisplayUnits,
MessageBubblesMenu,
ThemeMenu,
LanguagePicker,
HamModeConfirm,
LicensedToNormalConfirm
};
@@ -107,6 +108,7 @@ class menuHandler
static void wifiBaseMenu();
static void wifiToggleMenu();
static void screenOptionsMenu();
static void languagePickerMenu();
static void powerMenu();
static void nodeNameLengthMenu();
static void frameTogglesMenu();
+10
View File
@@ -13,6 +13,7 @@
#include "graphics/SharedUIDisplay.h"
#include "graphics/TFTColorRegions.h"
#include "graphics/TFTPalette.h"
#include "graphics/l10n/Strings.h"
#include "graphics/TimeFormatters.h"
#include "graphics/emotes.h"
#include "main.h"
@@ -75,6 +76,15 @@ void scrollDown()
void drawStringWithEmotes(OLEDDisplay *display, int x, int y, const std::string &line, const Emote *emotes, int emoteCount)
{
#if defined(ST7735_CS) || defined(ST7789_CS) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || \
defined(HX8357_CS) || defined(ILI9488_CS) || defined(ST7796_CS) || defined(RAK14014) || defined(USE_ST7789) || \
defined(USE_ST7796)
if (meshtastic::l10n::currentDisplayLanguage == meshtastic_Language_SIMPLIFIED_CHINESE ||
meshtastic::l10n::currentDisplayLanguage == meshtastic_Language_TRADITIONAL_CHINESE) {
screen->drawTextL10n(x, y, line.c_str());
return;
}
#endif
graphics::EmoteRenderer::drawStringWithEmotes(display, x, y, line, FONT_HEIGHT_SMALL, emotes, emoteCount);
}
+46
View File
@@ -0,0 +1,46 @@
// Chinese font data (VLW format) for OLEDDisplay-based TFT rendering via LovyanGFX.
//
// HOW TO GENERATE FONT DATA:
//
// Option 1: Adafruit GFX fontconvert (simpler, fewer glyphs)
// brew install adafruitnrf52-gfx-fontconvert # macOS
// fontconvert NotoSansSC-Regular.ttf 16 > zh_cn_16.h
// The output is a GFXfont struct. LovyanGFX can use this via ft_gfx type.
//
// Option 2: LovyanGFX VLW format (recommended, more features)
// Use the LovyanGFX font converter script to generate a .vlw file from TTF
// Then embed the .vlw binary as a byte array using xxd:
// xxd -i zh_font_16.vlw > zh_font_16_data.h
//
// Option 3: Use BDF fonts (free, text-based)
// WenQuanYi bitmap fonts: http://wenq.org/
// Convert BDF to VLW using LovyanGFX tools
//
// FONT SIZE GUIDELINES:
// - 16px: Minimum readable Chinese on 320x240 TFT (~20 chars per line)
// - 20px: Better readability, ~16 chars per line
// - 24px: Title/header text, ~13 chars per line
//
// CHARACTER SET RECOMMENDATIONS:
// - GB2312 Level 1: 3755 commonly used simplified Chinese characters
// - Plus ASCII 0x20-0x7E for punctuation and Latin characters
//
// PLACEHOLDER DATA - Replace with generated font binary:
#include "OLEDDisplayFontsZH.h"
// Placeholder font data.
// Replace with actual generated VLW/Gfx font binary from a Chinese TTF file.
// The array below is intentionally minimal - it won't render any characters
// until real font data is provided.
const uint8_t FontZH_CN_16[] = {
// VLW font file magic header would go here
// Format: 0x00 0x00 ...
// Replace with output from: xxd -i your_chinese_font.vlw
};
const uint32_t FontZH_CN_16_size = sizeof(FontZH_CN_16);
const uint8_t FontZH_TW_16[] = {
// Traditional Chinese VLW font data placeholder
};
const uint32_t FontZH_TW_16_size = sizeof(FontZH_TW_16);
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#include <cstdint>
// Chinese Simplified font - VLW format (to be generated from TTF)
//
// HOW TO GENERATE:
// 1. Download NotoSansSC-Regular.ttf (or any open-source Chinese font)
// 2. Use Adafruit fontconvert tool:
// ./fontconvert NotoSansSC-Regular.ttf 16 > zh_cn_16_pt.h
// 3. Copy the resulting binary data (GFXfont struct bytes) into the array below
//
// For LovyanGFX VLW font format, use:
// - The binary VLW file can be embedded as a const uint8_t[] array
// - Loaded with tft->loadFont(zh_font_data_array)
extern const uint8_t FontZH_CN_16[];
extern const uint32_t FontZH_CN_16_size;
// Chinese Traditional font (VLW format)
extern const uint8_t FontZH_TW_16[];
extern const uint32_t FontZH_TW_16_size;
+20
View File
@@ -0,0 +1,20 @@
#include "Strings.h"
#include "Strings_EN.h"
#include "Strings_ZH.h"
namespace meshtastic
{
namespace l10n
{
meshtastic_Language currentDisplayLanguage = meshtastic_Language_ENGLISH;
const char *getString(StringKey key, meshtastic_Language lang)
{
if (lang == meshtastic_Language_SIMPLIFIED_CHINESE || lang == meshtastic_Language_TRADITIONAL_CHINESE)
return getStringZH(key);
return getStringEN(key);
}
} // namespace l10n
} // namespace meshtastic
+138
View File
@@ -0,0 +1,138 @@
#pragma once
#include "mesh/generated/meshtastic/device_ui.pb.h"
namespace meshtastic
{
namespace l10n
{
enum class StringKey : uint8_t {
Back,
OK,
GotIt,
WelcomeToMeshtastic,
SwipeToNavigate,
ClickToNavigate,
UseSelectButton,
DeviceRole,
RadioPreset,
FrequencySlot,
LoRaRegion,
Client,
ClientMute,
LostAndFound,
Tracker,
Hour12,
Hour24,
ClockAction,
ClockFace,
TimeFormat,
Timezone,
MessageAction,
Reply,
ViewChats,
UnmuteChannel,
MuteChannel,
Delete,
ReadAloud,
Brightness,
FrameVisibility,
DisplayUnits,
MessageBubbles,
Theme,
Reboot,
Shutdown,
SwitchToMUI,
DisplayOptions,
Language,
Chinese,
English,
NoGPS,
GPSoff,
GPSnotPresent,
GPSisDisabled,
Node,
Hop,
USB,
BT_off,
WiFi,
WiFiNotConnected,
WiFiConnected,
SSID,
LoRaInfo,
LoRa,
Role,
Freq,
ChUtil,
System,
Heap,
PSRAM,
Flash,
SD,
Ver,
Up,
ClientApp,
NoConnected,
LOCKED,
ConnectToUnlock,
Battery,
Resuming,
LastHeard,
HopsSig,
HopsSignal,
Nodes,
Distance,
Bearings,
CreatingSSLCert,
PleaseWait,
CriticalFault,
ForHelpVisit,
Updating,
PleaseBePatient,
RebootInProgress,
PowerMenu,
SystemMenu,
ScreenOptions,
WifiToggle,
BluetoothToggle,
NodeDbReset,
ManageNode,
RemoveFavorite,
AddFavorite,
TestMenu,
TraceRoute,
ThrottleMessage,
MessageViewMode,
DeleteMessages,
NodeNameLength,
GPSMenu,
GPSToggle,
GPSFormat,
GPSSmartPosition,
GPSUpdateInterval,
GPSPositionBroadcast,
CompassNorth,
BuzzerMode,
HamModeConfirm,
LicensedToNormal,
KeyVerification,
FinalPrompt,
RegionUnset,
SelectRegionMessage,
Rebooting,
COUNT
};
extern meshtastic_Language currentDisplayLanguage;
const char *getString(StringKey key, meshtastic_Language lang);
inline const char *getString(StringKey key)
{
extern meshtastic_Language currentDisplayLanguage;
return getString(key, currentDisplayLanguage);
}
} // namespace l10n
} // namespace meshtastic
+360
View File
@@ -0,0 +1,360 @@
#pragma once
#include "Strings.h"
namespace meshtastic
{
namespace l10n
{
// English string table
// The strings are stored as const arrays to save RAM on constrained devices.
// Each locale file defines the same set of strings in its own language.
static const char STR_BACK_EN[] = "Back";
static const char STR_OK_EN[] = "OK";
static const char STR_GOT_IT_EN[] = "Got it!";
static const char STR_WELCOME_TO_MESHTASTIC_EN[] = "Welcome to Meshtastic!";
static const char STR_SWIPE_TO_NAVIGATE_EN[] = "Swipe to navigate.";
static const char STR_CLICK_TO_NAVIGATE_EN[] = "Click to navigate.";
static const char STR_USE_SELECT_BUTTON_EN[] = "Use the Select button.";
static const char STR_DEVICE_ROLE_EN[] = "Device Role";
static const char STR_RADIO_PRESET_EN[] = "Radio Preset";
static const char STR_FREQUENCY_SLOT_EN[] = "Frequency Slot";
static const char STR_LORA_REGION_EN[] = "LoRa Region";
static const char STR_CLIENT_EN[] = "Client";
static const char STR_CLIENT_MUTE_EN[] = "Client Mute";
static const char STR_LOST_AND_FOUND_EN[] = "Lost and Found";
static const char STR_TRACKER_EN[] = "Tracker";
static const char STR_12HOUR_EN[] = "12-hour";
static const char STR_24HOUR_EN[] = "24-hour";
static const char STR_CLOCK_ACTION_EN[] = "Clock Action";
static const char STR_CLOCK_FACE_EN[] = "Clock Face";
static const char STR_TIME_FORMAT_EN[] = "Time Format";
static const char STR_TIMEZONE_EN[] = "Timezone";
static const char STR_MESSAGE_ACTION_EN[] = "Message Action";
static const char STR_REPLY_EN[] = "Reply";
static const char STR_VIEW_CHATS_EN[] = "View Chats";
static const char STR_UNMUTE_CHANNEL_EN[] = "Unmute Channel";
static const char STR_MUTE_CHANNEL_EN[] = "Mute Channel";
static const char STR_DELETE_EN[] = "Delete";
static const char STR_READ_ALOUD_EN[] = "Read Aloud";
static const char STR_BRIGHTNESS_EN[] = "Brightness";
static const char STR_FRAME_VISIBILITY_EN[] = "Frame Visibility";
static const char STR_DISPLAY_UNITS_EN[] = "Display Units";
static const char STR_MESSAGE_BUBBLES_EN[] = "Message Bubbles";
static const char STR_THEME_EN[] = "Theme";
static const char STR_REBOOT_EN[] = "Reboot";
static const char STR_SHUTDOWN_EN[] = "Shutdown";
static const char STR_SWITCH_TO_MUI_EN[] = "Switch to MUI";
static const char STR_DISPLAY_OPTIONS_EN[] = "Display Options";
static const char STR_LANGUAGE_EN[] = "Language";
static const char STR_CHINESE_EN[] = "Chinese";
static const char STR_ENGLISH_EN[] = "English";
static const char STR_NO_GPS_EN[] = "No GPS";
static const char STR_GPS_OFF_EN[] = "GPS off";
static const char STR_GPS_NOT_PRESENT_EN[] = "GPS not present";
static const char STR_GPS_IS_DISABLED_EN[] = "GPS is disabled";
static const char STR_NODE_EN[] = "Node";
static const char STR_HOP_EN[] = "Hop:";
static const char STR_USB_EN[] = "USB";
static const char STR_BT_OFF_EN[] = "BT off";
static const char STR_WIFI_EN[] = "WiFi";
static const char STR_WIFI_NOT_CONNECTED_EN[] = "WiFi: Not Connected";
static const char STR_WIFI_CONNECTED_EN[] = "WiFi: Connected";
static const char STR_SSID_EN[] = "SSID:";
static const char STR_LORA_INFO_EN[] = "LoRa Info";
static const char STR_LORA_EN[] = "LoRa";
static const char STR_ROLE_EN[] = "Role:";
static const char STR_FREQ_EN[] = "Freq:";
static const char STR_CHUTIL_EN[] = "ChUtil";
static const char STR_SYSTEM_EN[] = "System";
static const char STR_HEAP_EN[] = "Heap:";
static const char STR_PSRAM_EN[] = "PSRAM:";
static const char STR_FLASH_EN[] = "Flash:";
static const char STR_SD_EN[] = "SD:";
static const char STR_VER_EN[] = "Ver:";
static const char STR_UP_EN[] = "Up:";
static const char STR_CLIENT_APP_EN[] = "Client";
static const char STR_NO_CONNECTED_EN[] = "No Connected";
static const char STR_LOCKED_EN[] = "LOCKED";
static const char STR_CONNECT_TO_UNLOCK_EN[] = "Connect to unlock";
static const char STR_BATTERY_EN[] = "Battery";
static const char STR_RESUMING_EN[] = "Resuming...";
static const char STR_LAST_HEARD_EN[] = "Last Heard";
static const char STR_HOPS_SIG_EN[] = "Hops/Sig";
static const char STR_HOPS_SIGNAL_EN[] = "Hops/Signal";
static const char STR_NODES_EN[] = "Nodes";
static const char STR_DISTANCE_EN[] = "Distance";
static const char STR_BEARINGS_EN[] = "Bearings";
static const char STR_CREATING_SSL_EN[] = "Creating SSL certificate";
static const char STR_PLEASE_WAIT_EN[] = "Please wait . . .";
static const char STR_CRITICAL_FAULT_EN[] = "Critical fault";
static const char STR_FOR_HELP_VISIT_EN[] = "For help, please visit";
static const char STR_UPDATING_EN[] = "Updating";
static const char STR_PLEASE_BE_PATIENT_EN[] = "Please be patient and do not power off.";
static const char STR_REBOOT_IN_PROGRESS_EN[] = "Reboot in progress...";
static const char STR_POWER_MENU_EN[] = "Power";
static const char STR_SYSTEM_MENU_EN[] = "System";
static const char STR_SCREEN_OPTIONS_EN[] = "Screen";
static const char STR_WIFI_TOGGLE_EN[] = "WiFi";
static const char STR_BLUETOOTH_TOGGLE_EN[] = "Bluetooth";
static const char STR_NODE_DB_RESET_EN[] = "Reset NodeDB";
static const char STR_MANAGE_NODE_EN[] = "Manage Node";
static const char STR_REMOVE_FAVORITE_EN[] = "Remove Favorite";
static const char STR_ADD_FAVORITE_EN[] = "Add Favorite";
static const char STR_TEST_MENU_EN[] = "Test";
static const char STR_TRACE_ROUTE_EN[] = "Trace Route";
static const char STR_THROTTLE_MSG_EN[] = "Message Throttled";
static const char STR_MSG_VIEW_MODE_EN[] = "View Mode";
static const char STR_DELETE_MESSAGES_EN[] = "Delete Messages";
static const char STR_NODE_NAME_LENGTH_EN[] = "Name Length";
static const char STR_GPS_MENU_EN[] = "GPS";
static const char STR_GPS_TOGGLE_EN[] = "GPS Toggle";
static const char STR_GPS_FORMAT_EN[] = "GPS Format";
static const char STR_GPS_SMART_POS_EN[] = "Smart Position";
static const char STR_GPS_UPDATE_INTERVAL_EN[] = "Update Interval";
static const char STR_GPS_POS_BCAST_EN[] = "Position Broadcast";
static const char STR_COMPASS_NORTH_EN[] = "Compass North";
static const char STR_BUZZER_MODE_EN[] = "Buzzer";
static const char STR_HAM_MODE_EN[] = "Ham Mode";
static const char STR_LICENSED_NORMAL_EN[] = "Normal Mode";
static const char STR_KEY_VERIFY_EN[] = "Verify Key";
static const char STR_REGION_UNSET_EN[] = "Select a Region";
static const char STR_SELECT_REGION_EN[] = "Please select your LoRa region:";
static const char STR_REBOOTING_EN[] = "Rebooting...";
inline const char *getStringEN(StringKey key)
{
switch (key) {
case StringKey::Back:
return STR_BACK_EN;
case StringKey::OK:
return STR_OK_EN;
case StringKey::GotIt:
return STR_GOT_IT_EN;
case StringKey::WelcomeToMeshtastic:
return STR_WELCOME_TO_MESHTASTIC_EN;
case StringKey::SwipeToNavigate:
return STR_SWIPE_TO_NAVIGATE_EN;
case StringKey::ClickToNavigate:
return STR_CLICK_TO_NAVIGATE_EN;
case StringKey::UseSelectButton:
return STR_USE_SELECT_BUTTON_EN;
case StringKey::DeviceRole:
return STR_DEVICE_ROLE_EN;
case StringKey::RadioPreset:
return STR_RADIO_PRESET_EN;
case StringKey::FrequencySlot:
return STR_FREQUENCY_SLOT_EN;
case StringKey::LoRaRegion:
return STR_LORA_REGION_EN;
case StringKey::Client:
return STR_CLIENT_EN;
case StringKey::ClientMute:
return STR_CLIENT_MUTE_EN;
case StringKey::LostAndFound:
return STR_LOST_AND_FOUND_EN;
case StringKey::Tracker:
return STR_TRACKER_EN;
case StringKey::Hour12:
return STR_12HOUR_EN;
case StringKey::Hour24:
return STR_24HOUR_EN;
case StringKey::ClockAction:
return STR_CLOCK_ACTION_EN;
case StringKey::ClockFace:
return STR_CLOCK_FACE_EN;
case StringKey::TimeFormat:
return STR_TIME_FORMAT_EN;
case StringKey::Timezone:
return STR_TIMEZONE_EN;
case StringKey::MessageAction:
return STR_MESSAGE_ACTION_EN;
case StringKey::Reply:
return STR_REPLY_EN;
case StringKey::ViewChats:
return STR_VIEW_CHATS_EN;
case StringKey::UnmuteChannel:
return STR_UNMUTE_CHANNEL_EN;
case StringKey::MuteChannel:
return STR_MUTE_CHANNEL_EN;
case StringKey::Delete:
return STR_DELETE_EN;
case StringKey::ReadAloud:
return STR_READ_ALOUD_EN;
case StringKey::Brightness:
return STR_BRIGHTNESS_EN;
case StringKey::FrameVisibility:
return STR_FRAME_VISIBILITY_EN;
case StringKey::DisplayUnits:
return STR_DISPLAY_UNITS_EN;
case StringKey::MessageBubbles:
return STR_MESSAGE_BUBBLES_EN;
case StringKey::Theme:
return STR_THEME_EN;
case StringKey::Reboot:
return STR_REBOOT_EN;
case StringKey::Shutdown:
return STR_SHUTDOWN_EN;
case StringKey::SwitchToMUI:
return STR_SWITCH_TO_MUI_EN;
case StringKey::DisplayOptions:
return STR_DISPLAY_OPTIONS_EN;
case StringKey::Language:
return STR_LANGUAGE_EN;
case StringKey::Chinese:
return STR_CHINESE_EN;
case StringKey::English:
return STR_ENGLISH_EN;
case StringKey::NoGPS:
return STR_NO_GPS_EN;
case StringKey::GPSoff:
return STR_GPS_OFF_EN;
case StringKey::GPSnotPresent:
return STR_GPS_NOT_PRESENT_EN;
case StringKey::GPSisDisabled:
return STR_GPS_IS_DISABLED_EN;
case StringKey::Node:
return STR_NODE_EN;
case StringKey::Hop:
return STR_HOP_EN;
case StringKey::USB:
return STR_USB_EN;
case StringKey::BT_off:
return STR_BT_OFF_EN;
case StringKey::WiFi:
return STR_WIFI_EN;
case StringKey::WiFiNotConnected:
return STR_WIFI_NOT_CONNECTED_EN;
case StringKey::WiFiConnected:
return STR_WIFI_CONNECTED_EN;
case StringKey::SSID:
return STR_SSID_EN;
case StringKey::LoRaInfo:
return STR_LORA_INFO_EN;
case StringKey::LoRa:
return STR_LORA_EN;
case StringKey::Role:
return STR_ROLE_EN;
case StringKey::Freq:
return STR_FREQ_EN;
case StringKey::ChUtil:
return STR_CHUTIL_EN;
case StringKey::System:
return STR_SYSTEM_EN;
case StringKey::Heap:
return STR_HEAP_EN;
case StringKey::PSRAM:
return STR_PSRAM_EN;
case StringKey::Flash:
return STR_FLASH_EN;
case StringKey::SD:
return STR_SD_EN;
case StringKey::Ver:
return STR_VER_EN;
case StringKey::Up:
return STR_UP_EN;
case StringKey::ClientApp:
return STR_CLIENT_APP_EN;
case StringKey::NoConnected:
return STR_NO_CONNECTED_EN;
case StringKey::LOCKED:
return STR_LOCKED_EN;
case StringKey::ConnectToUnlock:
return STR_CONNECT_TO_UNLOCK_EN;
case StringKey::Battery:
return STR_BATTERY_EN;
case StringKey::Resuming:
return STR_RESUMING_EN;
case StringKey::LastHeard:
return STR_LAST_HEARD_EN;
case StringKey::HopsSig:
return STR_HOPS_SIG_EN;
case StringKey::HopsSignal:
return STR_HOPS_SIGNAL_EN;
case StringKey::Nodes:
return STR_NODES_EN;
case StringKey::Distance:
return STR_DISTANCE_EN;
case StringKey::Bearings:
return STR_BEARINGS_EN;
case StringKey::CreatingSSLCert:
return STR_CREATING_SSL_EN;
case StringKey::PleaseWait:
return STR_PLEASE_WAIT_EN;
case StringKey::CriticalFault:
return STR_CRITICAL_FAULT_EN;
case StringKey::ForHelpVisit:
return STR_FOR_HELP_VISIT_EN;
case StringKey::Updating:
return STR_UPDATING_EN;
case StringKey::PleaseBePatient:
return STR_PLEASE_BE_PATIENT_EN;
case StringKey::RebootInProgress:
return STR_REBOOT_IN_PROGRESS_EN;
case StringKey::PowerMenu:
return STR_POWER_MENU_EN;
case StringKey::SystemMenu:
return STR_SYSTEM_MENU_EN;
case StringKey::ScreenOptions:
return STR_SCREEN_OPTIONS_EN;
case StringKey::WifiToggle:
return STR_WIFI_TOGGLE_EN;
case StringKey::BluetoothToggle:
return STR_BLUETOOTH_TOGGLE_EN;
case StringKey::NodeDbReset:
return STR_NODE_DB_RESET_EN;
case StringKey::ManageNode:
return STR_MANAGE_NODE_EN;
case StringKey::RemoveFavorite:
return STR_REMOVE_FAVORITE_EN;
case StringKey::AddFavorite:
return STR_ADD_FAVORITE_EN;
case StringKey::TestMenu:
return STR_TEST_MENU_EN;
case StringKey::TraceRoute:
return STR_TRACE_ROUTE_EN;
case StringKey::ThrottleMessage:
return STR_THROTTLE_MSG_EN;
case StringKey::MessageViewMode:
return STR_MSG_VIEW_MODE_EN;
case StringKey::DeleteMessages:
return STR_DELETE_MESSAGES_EN;
case StringKey::NodeNameLength:
return STR_NODE_NAME_LENGTH_EN;
case StringKey::GPSMenu:
return STR_GPS_MENU_EN;
case StringKey::GPSToggle:
return STR_GPS_TOGGLE_EN;
case StringKey::GPSFormat:
return STR_GPS_FORMAT_EN;
case StringKey::GPSSmartPosition:
return STR_GPS_SMART_POS_EN;
case StringKey::GPSUpdateInterval:
return STR_GPS_UPDATE_INTERVAL_EN;
case StringKey::GPSPositionBroadcast:
return STR_GPS_POS_BCAST_EN;
case StringKey::CompassNorth:
return STR_COMPASS_NORTH_EN;
case StringKey::BuzzerMode:
return STR_BUZZER_MODE_EN;
case StringKey::HamModeConfirm:
return STR_HAM_MODE_EN;
case StringKey::LicensedToNormal:
return STR_LICENSED_NORMAL_EN;
case StringKey::KeyVerification:
return STR_KEY_VERIFY_EN;
case StringKey::RegionUnset:
return STR_REGION_UNSET_EN;
case StringKey::SelectRegionMessage:
return STR_SELECT_REGION_EN;
case StringKey::Rebooting:
return STR_REBOOTING_EN;
default:
return "?";
}
}
} // namespace l10n
} // namespace meshtastic
+356
View File
@@ -0,0 +1,356 @@
#pragma once
#include "Strings.h"
namespace meshtastic
{
namespace l10n
{
static const char STR_BACK_ZH[] = "\xe8\xbf\x94\xe5\x9b\x9e";
static const char STR_OK_ZH[] = "\xe7\xa1\xae\xe5\xae\x9a";
static const char STR_GOT_IT_ZH[] = "\xe7\x9f\xa5\xe9\x81\x93\xe4\xba\x86";
static const char STR_WELCOME_TO_MESHTASTIC_ZH[] = "\xe6\xac\xa2\xe8\xbf\x8e\xe4\xbd\xbf\xe7\x94\xa8 Meshtastic\xef\xbc\x81";
static const char STR_SWIPE_TO_NAVIGATE_ZH[] = "\xe6\xbb\x91\xe5\x8a\xa8\xe4\xbb\xa5\xe5\xaf\xbc\xe8\x88\xaa\xe3\x80\x82";
static const char STR_CLICK_TO_NAVIGATE_ZH[] = "\xe7\x82\xb9\xe5\x87\xbb\xe4\xbb\xa5\xe5\xaf\xbc\xe8\x88\xaa\xe3\x80\x82";
static const char STR_USE_SELECT_BUTTON_ZH[] = "\xe4\xbd\xbf\xe7\x94\xa8\xe9\x80\x89\xe6\x8b\xa9\xe6\x8c\x89\xe9\x92\xae\xe3\x80\x82";
static const char STR_DEVICE_ROLE_ZH[] = "\xe8\xae\xbe\xe5\xa4\x87\xe8\xa7\x92\xe8\x89\xb2";
static const char STR_RADIO_PRESET_ZH[] = "\xe6\x97\xa0\xe7\xba\xbf\xe9\xa2\x84\xe8\xae\xbe";
static const char STR_FREQUENCY_SLOT_ZH[] = "\xe9\xa2\x91\xe7\x8e\x87\xe6\xa7\xbd\xe4\xbd\x8d";
static const char STR_LORA_REGION_ZH[] = "LoRa \xe5\x9c\xb0\xe5\x8c\xba";
static const char STR_CLIENT_ZH[] = "\xe5\xae\xa2\xe6\x88\xb7\xe7\xab\xaf";
static const char STR_CLIENT_MUTE_ZH[] = "\xe9\x9d\x99\xe9\x9f\xb3\xe5\xae\xa2\xe6\x88\xb7\xe7\xab\xaf";
static const char STR_LOST_AND_FOUND_ZH[] = "\xe5\xa4\xb1\xe7\x89\xa9\xe6\x8b\x9b\xe9\xa2\x86";
static const char STR_TRACKER_ZH[] = "\xe8\xbf\xbd\xe8\xb8\xaa\xe5\x99\xa8";
static const char STR_12HOUR_ZH[] = "12 \xe5\xb0\x8f\xe6\x97\xb6\xe5\x88\xb6";
static const char STR_24HOUR_ZH[] = "24 \xe5\xb0\x8f\xe6\x97\xb6\xe5\x88\xb6";
static const char STR_CLOCK_ACTION_ZH[] = "\xe6\x97\xb6\xe9\x92\x9f\xe6\x93\x8d\xe4\xbd\x9c";
static const char STR_CLOCK_FACE_ZH[] = "\xe6\x97\xb6\xe9\x92\x9f\xe6\xa0\xb7\xe5\xbc\x8f";
static const char STR_TIME_FORMAT_ZH[] = "\xe6\x97\xb6\xe9\x97\xb4\xe6\xa0\xbc\xe5\xbc\x8f";
static const char STR_TIMEZONE_ZH[] = "\xe6\x97\xb6\xe5\x8c\xba";
static const char STR_MESSAGE_ACTION_ZH[] = "\xe6\xb6\x88\xe6\x81\xaf\xe6\x93\x8d\xe4\xbd\x9c";
static const char STR_REPLY_ZH[] = "\xe5\x9b\x9e\xe5\xa4\x8d";
static const char STR_VIEW_CHATS_ZH[] = "\xe6\x9f\xa5\xe7\x9c\x8b\xe8\x81\x8a\xe5\xa4\xa9";
static const char STR_UNMUTE_CHANNEL_ZH[] = "\xe5\x8f\x96\xe6\xb6\x88\xe9\x9d\x99\xe9\x9f\xb3";
static const char STR_MUTE_CHANNEL_ZH[] = "\xe9\x9d\x99\xe9\x9f\xb3\xe9\xa2\x91\xe9\x81\x93";
static const char STR_DELETE_ZH[] = "\xe5\x88\xa0\xe9\x99\xa4";
static const char STR_READ_ALOUD_ZH[] = "\xe5\xa4\xa7\xe5\xa3\xb0\xe6\x9c\x97\xe8\xaf\xbb";
static const char STR_BRIGHTNESS_ZH[] = "\xe4\xba\xae\xe5\xba\xa6";
static const char STR_FRAME_VISIBILITY_ZH[] = "\xe9\xa1\xb5\xe9\x9d\xa2\xe5\x8f\xaf\xe8\xa7\x81\xe6\x80\xa7";
static const char STR_DISPLAY_UNITS_ZH[] = "\xe6\x98\xbe\xe7\xa4\xba\xe5\x8d\x95\xe4\xbd\x8d";
static const char STR_MESSAGE_BUBBLES_ZH[] = "\xe6\xb6\x88\xe6\x81\xaf\xe6\xb0\x94\xe6\xb3\xa1";
static const char STR_THEME_ZH[] = "\xe4\xb8\xbb\xe9\xa2\x98";
static const char STR_REBOOT_ZH[] = "\xe9\x87\x8d\xe5\x90\xaf";
static const char STR_SHUTDOWN_ZH[] = "\xe5\x85\xb3\xe6\x9c\xba";
static const char STR_SWITCH_TO_MUI_ZH[] = "\xe5\x88\x87\xe6\x8d\xa2\xe5\x88\xb0 MUI";
static const char STR_DISPLAY_OPTIONS_ZH[] = "\xe6\x98\xbe\xe7\xa4\xba\xe9\x80\x89\xe9\xa1\xb9";
static const char STR_LANGUAGE_ZH[] = "\xe8\xaf\xad\xe8\xa8\x80";
static const char STR_CHINESE_ZH[] = "\xe4\xb8\xad\xe6\x96\x87";
static const char STR_ENGLISH_ZH[] = "\xe8\x8b\xb1\xe6\x96\x87";
static const char STR_NO_GPS_ZH[] = "\xe6\x97\xa0 GPS";
static const char STR_GPS_OFF_ZH[] = "GPS \xe5\xb7\xb2\xe5\x85\xb3\xe9\x97\xad";
static const char STR_GPS_NOT_PRESENT_ZH[] = "GPS \xe4\xb8\x8d\xe5\xad\x98\xe5\x9c\xa8";
static const char STR_GPS_IS_DISABLED_ZH[] = "GPS \xe5\xb7\xb2\xe7\xa6\x81\xe7\x94\xa8";
static const char STR_NODE_ZH[] = "\xe8\x8a\x82\xe7\x82\xb9";
static const char STR_HOP_ZH[] = "\xe8\xb7\xb3\xe6\x95\xb0:";
static const char STR_USB_ZH[] = "USB";
static const char STR_BT_OFF_ZH[] = "\xe8\x93\x9d\xe7\x89\x99\xe5\xb7\xb2\xe5\x85\xb3";
static const char STR_WIFI_ZH[] = "WiFi";
static const char STR_WIFI_NOT_CONNECTED_ZH[] = "WiFi: \xe6\x9c\xaa\xe8\xbf\x9e\xe6\x8e\xa5";
static const char STR_WIFI_CONNECTED_ZH[] = "WiFi: \xe5\xb7\xb2\xe8\xbf\x9e\xe6\x8e\xa5";
static const char STR_SSID_ZH[] = "SSID:";
static const char STR_LORA_INFO_ZH[] = "LoRa \xe4\xbf\xa1\xe6\x81\xaf";
static const char STR_LORA_ZH[] = "LoRa";
static const char STR_ROLE_ZH[] = "\xe8\xa7\x92\xe8\x89\xb2:";
static const char STR_FREQ_ZH[] = "\xe9\xa2\x91\xe7\x8e\x87:";
static const char STR_CHUTIL_ZH[] = "\xe4\xbf\xa1\xe9\x81\x93\xe5\x88\xa9\xe7\x94\xa8";
static const char STR_SYSTEM_ZH[] = "\xe7\xb3\xbb\xe7\xbb\x9f";
static const char STR_HEAP_ZH[] = "\xe5\xa0\x86:";
static const char STR_PSRAM_ZH[] = "PSRAM:";
static const char STR_FLASH_ZH[] = "Flash:";
static const char STR_SD_ZH[] = "SD:";
static const char STR_VER_ZH[] = "\xe7\x89\x88\xe6\x9c\xac:";
static const char STR_UP_ZH[] = "\xe8\xbf\x90\xe8\xa1\x8c:";
static const char STR_CLIENT_APP_ZH[] = "\xe5\xae\xa2\xe6\x88\xb7\xe7\xab\xaf";
static const char STR_NO_CONNECTED_ZH[] = "\xe6\x9c\xaa\xe8\xbf\x9e\xe6\x8e\xa5";
static const char STR_LOCKED_ZH[] = "\xe5\xb7\xb2\xe9\x94\x81\xe5\xae\x9a";
static const char STR_CONNECT_TO_UNLOCK_ZH[] = "\xe8\xbf\x9e\xe6\x8e\xa5\xe4\xbb\xa5\xe8\xa7\xa3\xe9\x94\x81";
static const char STR_BATTERY_ZH[] = "\xe7\x94\xb5\xe6\xb1\xa0";
static const char STR_RESUMING_ZH[] = "\xe6\xad\xa3\xe5\x9c\xa8\xe6\x81\xa2\xe5\xa4\x8d...";
static const char STR_LAST_HEARD_ZH[] = "\xe6\x9c\x80\xe5\x90\x8e\xe5\x90\xac\xe5\x88\xb0";
static const char STR_HOPS_SIG_ZH[] = "\xe8\xb7\xb3\xe6\x95\xb0/\xe4\xbf\xa1\xe5\x8f\xb7";
static const char STR_HOPS_SIGNAL_ZH[] = "\xe8\xb7\xb3\xe6\x95\xb0/\xe4\xbf\xa1\xe5\x8f\xb7";
static const char STR_NODES_ZH[] = "\xe8\x8a\x82\xe7\x82\xb9";
static const char STR_DISTANCE_ZH[] = "\xe8\xb7\x9d\xe7\xa6\xbb";
static const char STR_BEARINGS_ZH[] = "\xe6\x96\xb9\xe4\xbd\x8d";
static const char STR_CREATING_SSL_ZH[] = "\xe6\xad\xa3\xe5\x9c\xa8\xe5\x88\x9b\xe5\xbb\xba SSL \xe8\xaf\x81\xe4\xb9\xa6";
static const char STR_PLEASE_WAIT_ZH[] = "\xe8\xaf\xb7\xe7\xa8\x8d\xe5\x80\x99 . . .";
static const char STR_CRITICAL_FAULT_ZH[] = "\xe4\xb8\xa5\xe9\x87\x8d\xe6\x95\x85\xe9\x9a\x9c";
static const char STR_FOR_HELP_VISIT_ZH[] = "\xe8\xaf\xb7\xe8\xae\xbf\xe9\x97\xae\x4ee5\xb8\xae\xe5\x8a\xa9";
static const char STR_UPDATING_ZH[] = "\xe6\xad\xa3\xe5\x9c\xa8\xe6\x9b\xb4\xe6\x96\xb0";
static const char STR_PLEASE_BE_PATIENT_ZH[] = "\xe8\xaf\xb7\xe8\x80\x90\xe5\xbf\x83\xe7\xad\x89\xe5\xbe\x85\xef\xbc\x8c\xe4\xb8\x8d\xe8\xa6\x81\xe5\x85\xb3\xe9\x97\xad\xe7\x94\xb5\xe6\xba\x90\xe3\x80\x82";
static const char STR_REBOOT_IN_PROGRESS_ZH[] = "\xe6\xad\xa3\xe5\x9c\xa8\xe9\x87\x8d\xe5\x90\xaf...";
static const char STR_POWER_MENU_ZH[] = "\xe7\x94\xb5\xe6\xba\x90";
static const char STR_SYSTEM_MENU_ZH[] = "\xe7\xb3\xbb\xe7\xbb\x9f";
static const char STR_SCREEN_OPTIONS_ZH[] = "\xe5\xb1\x8f\xe5\xb9\x95";
static const char STR_WIFI_TOGGLE_ZH[] = "WiFi";
static const char STR_BLUETOOTH_TOGGLE_ZH[] = "\xe8\x93\x9d\xe7\x89\x99";
static const char STR_NODE_DB_RESET_ZH[] = "\xe9\x87\x8d\xe7\xbd\xae\xe8\x8a\x82\xe7\x82\xb9\xe5\xba\x93";
static const char STR_MANAGE_NODE_ZH[] = "\xe7\xae\xa1\xe7\x90\x86\xe8\x8a\x82\xe7\x82\xb9";
static const char STR_REMOVE_FAVORITE_ZH[] = "\xe5\x8f\x96\xe6\xb6\x88\xe6\x94\xb6\xe8\x97\x8f";
static const char STR_ADD_FAVORITE_ZH[] = "\xe6\xb7\xbb\xe5\x8a\xa0\xe6\x94\xb6\xe8\x97\x8f";
static const char STR_TEST_MENU_ZH[] = "\xe6\xb5\x8b\xe8\xaf\x95";
static const char STR_TRACE_ROUTE_ZH[] = "\xe8\xb7\xaf\xe7\x94\xb1\xe8\xbf\xbd\xe8\xb8\xaa";
static const char STR_THROTTLE_MSG_ZH[] = "\xe6\xb6\x88\xe6\x81\xaf\xe5\xb7\xb2\xe9\x99\x90\xe6\xb5\x81";
static const char STR_MSG_VIEW_MODE_ZH[] = "\xe6\x9f\xa5\xe7\x9c\x8b\xe6\xa8\xa1\xe5\xbc\x8f";
static const char STR_DELETE_MESSAGES_ZH[] = "\xe5\x88\xa0\xe9\x99\xa4\xe6\xb6\x88\xe6\x81\xaf";
static const char STR_NODE_NAME_LENGTH_ZH[] = "\xe5\x90\x8d\xe7\xa7\xb0\xe9\x95\xbf\xe5\xba\xa6";
static const char STR_GPS_MENU_ZH[] = "GPS";
static const char STR_GPS_TOGGLE_ZH[] = "GPS \xe5\xbc\x80\xe5\x85\xb3";
static const char STR_GPS_FORMAT_ZH[] = "GPS \xe6\xa0\xbc\xe5\xbc\x8f";
static const char STR_GPS_SMART_POS_ZH[] = "\xe6\x99\xba\xe8\x83\xbd\xe5\xae\x9a\xe4\xbd\x8d";
static const char STR_GPS_UPDATE_INTERVAL_ZH[] = "\xe6\x9b\xb4\xe6\x96\xb0\xe9\x97\xb4\xe9\x9a\x94";
static const char STR_GPS_POS_BCAST_ZH[] = "\xe4\xbd\x8d\xe7\xbd\xae\xe5\xb9\xbf\xe6\x92\xad";
static const char STR_COMPASS_NORTH_ZH[] = "\xe6\x8c\x87\xe5\x8d\x97\xe9\x92\x88";
static const char STR_BUZZER_MODE_ZH[] = "\xe8\x9c\x82\xe9\xb8\xa3\xe5\x99\xa8";
static const char STR_HAM_MODE_ZH[] = "Ham \xe6\xa8\xa1\xe5\xbc\x8f";
static const char STR_LICENSED_NORMAL_ZH[] = "\xe6\x99\xae\xe9\x80\x9a\xe6\xa8\xa1\xe5\xbc\x8f";
static const char STR_KEY_VERIFY_ZH[] = "\xe9\xaa\x8c\xe8\xaf\x81\xe5\xaf\x86\xe9\x92\xa5";
static const char STR_REGION_UNSET_ZH[] = "\xe8\xaf\xb7\xe9\x80\x89\xe6\x8b\xa9\xe5\x9c\xb0\xe5\x8c\xba";
static const char STR_SELECT_REGION_ZH[] = "\xe8\xaf\xb7\xe9\x80\x89\xe6\x8b\xa9\xe6\x82\xa8\xe7\x9a\x84 LoRa \xe5\x8c\xba\xe5\x9f\x9f:";
static const char STR_REBOOTING_ZH[] = "\xe6\xad\xa3\xe5\x9c\xa8\xe9\x87\x8d\xe5\x90\xaf...";
inline const char *getStringZH(StringKey key)
{
switch (key) {
case StringKey::Back:
return STR_BACK_ZH;
case StringKey::OK:
return STR_OK_ZH;
case StringKey::GotIt:
return STR_GOT_IT_ZH;
case StringKey::WelcomeToMeshtastic:
return STR_WELCOME_TO_MESHTASTIC_ZH;
case StringKey::SwipeToNavigate:
return STR_SWIPE_TO_NAVIGATE_ZH;
case StringKey::ClickToNavigate:
return STR_CLICK_TO_NAVIGATE_ZH;
case StringKey::UseSelectButton:
return STR_USE_SELECT_BUTTON_ZH;
case StringKey::DeviceRole:
return STR_DEVICE_ROLE_ZH;
case StringKey::RadioPreset:
return STR_RADIO_PRESET_ZH;
case StringKey::FrequencySlot:
return STR_FREQUENCY_SLOT_ZH;
case StringKey::LoRaRegion:
return STR_LORA_REGION_ZH;
case StringKey::Client:
return STR_CLIENT_ZH;
case StringKey::ClientMute:
return STR_CLIENT_MUTE_ZH;
case StringKey::LostAndFound:
return STR_LOST_AND_FOUND_ZH;
case StringKey::Tracker:
return STR_TRACKER_ZH;
case StringKey::Hour12:
return STR_12HOUR_ZH;
case StringKey::Hour24:
return STR_24HOUR_ZH;
case StringKey::ClockAction:
return STR_CLOCK_ACTION_ZH;
case StringKey::ClockFace:
return STR_CLOCK_FACE_ZH;
case StringKey::TimeFormat:
return STR_TIME_FORMAT_ZH;
case StringKey::Timezone:
return STR_TIMEZONE_ZH;
case StringKey::MessageAction:
return STR_MESSAGE_ACTION_ZH;
case StringKey::Reply:
return STR_REPLY_ZH;
case StringKey::ViewChats:
return STR_VIEW_CHATS_ZH;
case StringKey::UnmuteChannel:
return STR_UNMUTE_CHANNEL_ZH;
case StringKey::MuteChannel:
return STR_MUTE_CHANNEL_ZH;
case StringKey::Delete:
return STR_DELETE_ZH;
case StringKey::ReadAloud:
return STR_READ_ALOUD_ZH;
case StringKey::Brightness:
return STR_BRIGHTNESS_ZH;
case StringKey::FrameVisibility:
return STR_FRAME_VISIBILITY_ZH;
case StringKey::DisplayUnits:
return STR_DISPLAY_UNITS_ZH;
case StringKey::MessageBubbles:
return STR_MESSAGE_BUBBLES_ZH;
case StringKey::Theme:
return STR_THEME_ZH;
case StringKey::Reboot:
return STR_REBOOT_ZH;
case StringKey::Shutdown:
return STR_SHUTDOWN_ZH;
case StringKey::SwitchToMUI:
return STR_SWITCH_TO_MUI_ZH;
case StringKey::DisplayOptions:
return STR_DISPLAY_OPTIONS_ZH;
case StringKey::Language:
return STR_LANGUAGE_ZH;
case StringKey::Chinese:
return STR_CHINESE_ZH;
case StringKey::English:
return STR_ENGLISH_ZH;
case StringKey::NoGPS:
return STR_NO_GPS_ZH;
case StringKey::GPSoff:
return STR_GPS_OFF_ZH;
case StringKey::GPSnotPresent:
return STR_GPS_NOT_PRESENT_ZH;
case StringKey::GPSisDisabled:
return STR_GPS_IS_DISABLED_ZH;
case StringKey::Node:
return STR_NODE_ZH;
case StringKey::Hop:
return STR_HOP_ZH;
case StringKey::USB:
return STR_USB_ZH;
case StringKey::BT_off:
return STR_BT_OFF_ZH;
case StringKey::WiFi:
return STR_WIFI_ZH;
case StringKey::WiFiNotConnected:
return STR_WIFI_NOT_CONNECTED_ZH;
case StringKey::WiFiConnected:
return STR_WIFI_CONNECTED_ZH;
case StringKey::SSID:
return STR_SSID_ZH;
case StringKey::LoRaInfo:
return STR_LORA_INFO_ZH;
case StringKey::LoRa:
return STR_LORA_ZH;
case StringKey::Role:
return STR_ROLE_ZH;
case StringKey::Freq:
return STR_FREQ_ZH;
case StringKey::ChUtil:
return STR_CHUTIL_ZH;
case StringKey::System:
return STR_SYSTEM_ZH;
case StringKey::Heap:
return STR_HEAP_ZH;
case StringKey::PSRAM:
return STR_PSRAM_ZH;
case StringKey::Flash:
return STR_FLASH_ZH;
case StringKey::SD:
return STR_SD_ZH;
case StringKey::Ver:
return STR_VER_ZH;
case StringKey::Up:
return STR_UP_ZH;
case StringKey::ClientApp:
return STR_CLIENT_APP_ZH;
case StringKey::NoConnected:
return STR_NO_CONNECTED_ZH;
case StringKey::LOCKED:
return STR_LOCKED_ZH;
case StringKey::ConnectToUnlock:
return STR_CONNECT_TO_UNLOCK_ZH;
case StringKey::Battery:
return STR_BATTERY_ZH;
case StringKey::Resuming:
return STR_RESUMING_ZH;
case StringKey::LastHeard:
return STR_LAST_HEARD_ZH;
case StringKey::HopsSig:
return STR_HOPS_SIG_ZH;
case StringKey::HopsSignal:
return STR_HOPS_SIGNAL_ZH;
case StringKey::Nodes:
return STR_NODES_ZH;
case StringKey::Distance:
return STR_DISTANCE_ZH;
case StringKey::Bearings:
return STR_BEARINGS_ZH;
case StringKey::CreatingSSLCert:
return STR_CREATING_SSL_ZH;
case StringKey::PleaseWait:
return STR_PLEASE_WAIT_ZH;
case StringKey::CriticalFault:
return STR_CRITICAL_FAULT_ZH;
case StringKey::ForHelpVisit:
return STR_FOR_HELP_VISIT_ZH;
case StringKey::Updating:
return STR_UPDATING_ZH;
case StringKey::PleaseBePatient:
return STR_PLEASE_BE_PATIENT_ZH;
case StringKey::RebootInProgress:
return STR_REBOOT_IN_PROGRESS_ZH;
case StringKey::PowerMenu:
return STR_POWER_MENU_ZH;
case StringKey::SystemMenu:
return STR_SYSTEM_MENU_ZH;
case StringKey::ScreenOptions:
return STR_SCREEN_OPTIONS_ZH;
case StringKey::WifiToggle:
return STR_WIFI_TOGGLE_ZH;
case StringKey::BluetoothToggle:
return STR_BLUETOOTH_TOGGLE_ZH;
case StringKey::NodeDbReset:
return STR_NODE_DB_RESET_ZH;
case StringKey::ManageNode:
return STR_MANAGE_NODE_ZH;
case StringKey::RemoveFavorite:
return STR_REMOVE_FAVORITE_ZH;
case StringKey::AddFavorite:
return STR_ADD_FAVORITE_ZH;
case StringKey::TestMenu:
return STR_TEST_MENU_ZH;
case StringKey::TraceRoute:
return STR_TRACE_ROUTE_ZH;
case StringKey::ThrottleMessage:
return STR_THROTTLE_MSG_ZH;
case StringKey::MessageViewMode:
return STR_MSG_VIEW_MODE_ZH;
case StringKey::DeleteMessages:
return STR_DELETE_MESSAGES_ZH;
case StringKey::NodeNameLength:
return STR_NODE_NAME_LENGTH_ZH;
case StringKey::GPSMenu:
return STR_GPS_MENU_ZH;
case StringKey::GPSToggle:
return STR_GPS_TOGGLE_ZH;
case StringKey::GPSFormat:
return STR_GPS_FORMAT_ZH;
case StringKey::GPSSmartPosition:
return STR_GPS_SMART_POS_ZH;
case StringKey::GPSUpdateInterval:
return STR_GPS_UPDATE_INTERVAL_ZH;
case StringKey::GPSPositionBroadcast:
return STR_GPS_POS_BCAST_ZH;
case StringKey::CompassNorth:
return STR_COMPASS_NORTH_ZH;
case StringKey::BuzzerMode:
return STR_BUZZER_MODE_ZH;
case StringKey::HamModeConfirm:
return STR_HAM_MODE_ZH;
case StringKey::LicensedToNormal:
return STR_LICENSED_NORMAL_ZH;
case StringKey::KeyVerification:
return STR_KEY_VERIFY_ZH;
case StringKey::RegionUnset:
return STR_REGION_UNSET_ZH;
case StringKey::SelectRegionMessage:
return STR_SELECT_REGION_ZH;
case StringKey::Rebooting:
return STR_REBOOTING_ZH;
default:
return "?";
}
}
} // namespace l10n
} // namespace meshtastic