This commit is contained in:
不吃油炸鸡
2026-02-26 17:20:03 +08:00
parent 558bec4003
commit 495baa3905
1214 changed files with 825897 additions and 0 deletions

View File

@@ -0,0 +1,235 @@
#include "./lv_i18n.h"
////////////////////////////////////////////////////////////////////////////////
// Define plural operands
// http://unicode.org/reports/tr35/tr35-numbers.html#Operands
// Integer version, simplified
#define UNUSED(x) (void)(x)
static inline uint32_t op_n(int32_t val) { return (uint32_t)(val < 0 ? -val : val); }
static inline uint32_t op_i(uint32_t val) { return val; }
// always zero, when decimal part not exists.
static inline uint32_t op_v(uint32_t val) { UNUSED(val); return 0;}
static inline uint32_t op_w(uint32_t val) { UNUSED(val); return 0; }
static inline uint32_t op_f(uint32_t val) { UNUSED(val); return 0; }
static inline uint32_t op_t(uint32_t val) { UNUSED(val); return 0; }
static lv_i18n_phrase_t en_singulars[] = {
{"press to Step Adjust", "press to Step Adjust"},
{"press here to Fixed Set", "press here to Fixed Set"},
{"press here to close PD", "press here to close PD"},
{"Screen Brightness :", "Screen Brightness :"},
{"Enable key sound", "Enable key sound"},
{"Enable Chinese", "Enable Chinese"},
{"Chose Rotation", "Chose Rotation"},
{"PD Sink", "PD Sink"},
{"Please reboot to apply\nall changes!", "Please reboot to apply\nall changes!"},
{NULL, NULL} // End mark
};
static uint8_t en_plural_fn(int32_t num)
{
uint32_t n = op_n(num); UNUSED(n);
uint32_t i = op_i(n); UNUSED(i);
uint32_t v = op_v(n); UNUSED(v);
if ((i == 1 && v == 0)) return LV_I18N_PLURAL_TYPE_ONE;
return LV_I18N_PLURAL_TYPE_OTHER;
}
static const lv_i18n_lang_t en_lang = {
.locale_name = "en",
.singulars = en_singulars,
.locale_plural_fn = en_plural_fn
};
static lv_i18n_phrase_t zh_cn_singulars[] = {
{"press to Step Adjust", "进 入 步 进 调 节"},
{"press here to Fixed Set", "进 入 固 定 调 节"},
{"press here to close PD", "关 闭 PD 诱 骗"},
{"Screen Brightness :", "屏 幕 亮 度 :"},
{"Enable key sound", "按 键 声 音"},
{"Enable Chinese", "中 英 文 切 换"},
{"Chose Rotation", "旋 转 角 度 :"},
{"PD Sink", "PD 诱 骗"},
{"Please reboot to apply\nall changes!", "请重启以应用\n所有更改!"},
{NULL, NULL} // End mark
};
static uint8_t zh_cn_plural_fn(int32_t num)
{
return LV_I18N_PLURAL_TYPE_OTHER;
}
static const lv_i18n_lang_t zh_cn_lang = {
.locale_name = "zh-cn",
.singulars = zh_cn_singulars,
.locale_plural_fn = zh_cn_plural_fn
};
const lv_i18n_language_pack_t lv_i18n_language_pack[] = {
&en_lang,
&zh_cn_lang,
NULL // End mark
};
////////////////////////////////////////////////////////////////////////////////
// Internal state
static const lv_i18n_language_pack_t * current_lang_pack;
static const lv_i18n_lang_t * current_lang;
/**
* Reset internal state. For testing.
*/
void __lv_i18n_reset(void)
{
current_lang_pack = NULL;
current_lang = NULL;
}
/**
* Set the languages for internationalization
* @param langs pointer to the array of languages. (Last element has to be `NULL`)
*/
int lv_i18n_init(const lv_i18n_language_pack_t * langs)
{
if(langs == NULL) return -1;
if(langs[0] == NULL) return -1;
current_lang_pack = langs;
current_lang = langs[0]; /*Automatically select the first language*/
return 0;
}
/**
* Change the localization (language)
* @param l_name name of the translation locale to use. E.g. "en-GB"
*/
int lv_i18n_set_locale(const char * l_name)
{
if(current_lang_pack == NULL) return -1;
uint16_t i;
for(i = 0; current_lang_pack[i] != NULL; i++) {
// Found -> finish
if(strcmp(current_lang_pack[i]->locale_name, l_name) == 0) {
current_lang = current_lang_pack[i];
return 0;
}
}
return -1;
}
static const char * __lv_i18n_get_text_core(lv_i18n_phrase_t * trans, const char * msg_id)
{
uint16_t i;
for(i = 0; trans[i].msg_id != NULL; i++) {
if(strcmp(trans[i].msg_id, msg_id) == 0) {
/*The msg_id has found. Check the translation*/
if(trans[i].translation) return trans[i].translation;
}
}
return NULL;
}
/**
* Get the translation from a message ID
* @param msg_id message ID
* @return the translation of `msg_id` on the set local
*/
const char * lv_i18n_get_text(const char * msg_id)
{
if(current_lang == NULL) return msg_id;
const lv_i18n_lang_t * lang = current_lang;
const void * txt;
// Search in current locale
if(lang->singulars != NULL) {
txt = __lv_i18n_get_text_core(lang->singulars, msg_id);
if (txt != NULL) return txt;
}
// Try to fallback
if(lang == current_lang_pack[0]) return msg_id;
lang = current_lang_pack[0];
// Repeat search for default locale
if(lang->singulars != NULL) {
txt = __lv_i18n_get_text_core(lang->singulars, msg_id);
if (txt != NULL) return txt;
}
return msg_id;
}
/**
* Get the translation from a message ID and apply the language's plural rule to get correct form
* @param msg_id message ID
* @param num an integer to select the correct plural form
* @return the translation of `msg_id` on the set local
*/
const char * lv_i18n_get_text_plural(const char * msg_id, int32_t num)
{
if(current_lang == NULL) return msg_id;
const lv_i18n_lang_t * lang = current_lang;
const void * txt;
lv_i18n_plural_type_t ptype;
// Search in current locale
if(lang->locale_plural_fn != NULL) {
ptype = lang->locale_plural_fn(num);
if(lang->plurals[ptype] != NULL) {
txt = __lv_i18n_get_text_core(lang->plurals[ptype], msg_id);
if (txt != NULL) return txt;
}
}
// Try to fallback
if(lang == current_lang_pack[0]) return msg_id;
lang = current_lang_pack[0];
// Repeat search for default locale
if(lang->locale_plural_fn != NULL) {
ptype = lang->locale_plural_fn(num);
if(lang->plurals[ptype] != NULL) {
txt = __lv_i18n_get_text_core(lang->plurals[ptype], msg_id);
if (txt != NULL) return txt;
}
}
return msg_id;
}
/**
* Get the name of the currently used locale.
* @return name of the currently used locale. E.g. "en-GB"
*/
const char * lv_i18n_get_current_locale(void)
{
if(!current_lang) return NULL;
return current_lang->locale_name;
}

View File

@@ -0,0 +1,85 @@
#ifndef LV_I18N_H
#define LV_I18N_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <string.h>
typedef enum {
LV_I18N_PLURAL_TYPE_ZERO,
LV_I18N_PLURAL_TYPE_ONE,
LV_I18N_PLURAL_TYPE_TWO,
LV_I18N_PLURAL_TYPE_FEW,
LV_I18N_PLURAL_TYPE_MANY,
LV_I18N_PLURAL_TYPE_OTHER,
_LV_I18N_PLURAL_TYPE_NUM,
} lv_i18n_plural_type_t;
typedef struct {
const char * msg_id;
const char * translation;
} lv_i18n_phrase_t;
typedef struct {
const char * locale_name;
lv_i18n_phrase_t * singulars;
lv_i18n_phrase_t * plurals[_LV_I18N_PLURAL_TYPE_NUM];
uint8_t (*locale_plural_fn)(int32_t num);
} lv_i18n_lang_t;
// Null-terminated list of languages. First one used as default.
typedef const lv_i18n_lang_t * lv_i18n_language_pack_t;
extern const lv_i18n_language_pack_t lv_i18n_language_pack[];
/**
* Set the languages for internationalization
* @param langs pointer to the array of languages. (Last element has to be `NULL`)
*/
int lv_i18n_init(const lv_i18n_language_pack_t * langs);
/**
* Change the localization (language)
* @param l_name name of the translation locale to use. E.g. "en_GB"
*/
int lv_i18n_set_locale(const char * l_name);
/**
* Get the translation from a message ID
* @param msg_id message ID
* @return the translation of `msg_id` on the set local
*/
const char * lv_i18n_get_text(const char * msg_id);
/**
* Get the translation from a message ID and apply the language's plural rule to get correct form
* @param msg_id message ID
* @param num an integer to select the correct plural form
* @return the translation of `msg_id` on the set local
*/
const char * lv_i18n_get_text_plural(const char * msg_id, int32_t num);
/**
* Get the name of the currently used localization.
* @return name of the currently used localization. E.g. "en_GB"
*/
const char * lv_i18n_get_current_locale(void);
void __lv_i18n_reset(void);
#define _(text) lv_i18n_get_text(text)
#define _p(text, num) lv_i18n_get_text_plural(text, num)
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_LANG_H*/

View File

@@ -0,0 +1,58 @@
#include "lv_lib_animation.h"
void lv_lib_anim_callback_set_x(void * var, int32_t v)
{
lv_obj_set_x(var, v);
}
void lv_lib_anim_callback_set_y(void * var, int32_t v)
{
lv_obj_set_y(var, v);
}
void lv_lib_anim_callback_set_hight(void * var, int32_t v)
{
lv_obj_set_height(var, v);
}
void lv_lib_anim_callback_set_width(void * var, int32_t v)
{
lv_obj_set_width(var, v);
}
void lv_lib_anim_callback_set_image_angle(void * var, int32_t v)
{
lv_image_set_rotation(var, v);
}
void lv_lib_anim_callback_set_scale(void * var, int32_t v)
{
lv_image_set_scale(var, v);
}
void lv_lib_anim_callback_set_opacity(void * var, int32_t v)
{
lv_obj_set_style_opa(var, v, LV_PART_MAIN | LV_STATE_DEFAULT);
}
void lv_lib_anim_user_animation(lv_obj_t * TagetObj, uint16_t delay, uint16_t time, int16_t start_value, int16_t end_value,
uint16_t playback_delay, uint16_t playback_time, uint16_t repeat_delay, uint16_t repeat_count,
lv_anim_path_cb_t path_cb, lv_anim_exec_xcb_t exec_cb, lv_anim_completed_cb_t completed_cb)
{
lv_anim_t Animation;
lv_anim_init(&Animation);
lv_anim_set_var(&Animation, TagetObj);
lv_anim_set_time(&Animation, time);
lv_anim_set_values(&Animation, start_value, end_value);
lv_anim_set_exec_cb(&Animation, exec_cb);
lv_anim_set_path_cb(&Animation, path_cb);
lv_anim_set_delay(&Animation, delay);
lv_anim_set_playback_time(&Animation, playback_time);
lv_anim_set_playback_delay(&Animation, playback_delay);
lv_anim_set_repeat_count(&Animation, repeat_count);
lv_anim_set_repeat_delay(&Animation, repeat_delay);
lv_anim_set_early_apply(&Animation, false);
lv_anim_set_completed_cb(&Animation, completed_cb);
lv_anim_start(&Animation);
}

View File

@@ -0,0 +1,18 @@
#ifndef LV_LIB_ANIMATION_H
#define LV_LIB_ANIMATION_H
#include "lvgl.h"
void lv_lib_anim_callback_set_x(void * var, int32_t v);
void lv_lib_anim_callback_set_y(void * var, int32_t v);
void lv_lib_anim_callback_set_hight(void * var, int32_t v);
void lv_lib_anim_callback_set_width(void * var, int32_t v);
void lv_lib_anim_callback_set_image_angle(void * var, int32_t v);
void lv_lib_anim_callback_set_scale(void * var, int32_t v);
void lv_lib_anim_callback_set_opacity(void * var, int32_t v);
// user set animation
void lv_lib_anim_user_animation(lv_obj_t * TagetObj, uint16_t delay, uint16_t time, int16_t start_value, int16_t end_value,
uint16_t playback_delay, uint16_t playback_time, uint16_t repeat_delay, uint16_t repeat_count,
lv_anim_path_cb_t path_cb, lv_anim_exec_xcb_t exec_cb, lv_anim_completed_cb_t completed_cb);
#endif // LV_LIB_ANIMATION_H

View File

@@ -0,0 +1,142 @@
#include "./lv_lib_pm.h"
#include <string.h>
// 定义全局实例
PageManager_t PageManager;
/**
* 初始化页面管理器
*/
void lv_lib_pm_Init(void) {
memset(&PageManager, 0, sizeof(PageManager));
}
/**
* load init screen
*/
void lv_lib_pm_load_init_screen(void) {
if (PageManager.count == 0) return;
Page_t* initial_page = PageManager.pages[0];
if (initial_page->init) initial_page->init();
lv_screen_load_anim(*initial_page->page_obj, LV_SCR_LOAD_ANIM_MOVE_LEFT, 200, 0, true);
PageManager.current_index = 0;
}
/**
* 注册一个新页面
* @param page 页面结构体指针
*/
void lv_lib_pm_register(Page_t* page) {
if (PageManager.count >= MAX_PAGES) {
LV_LOG_WARN("PageManager: page list is full!");
return;
}
PageManager.pages[PageManager.count++] = page;
}
/**
* 切换到数组中下一个页面(循环)
*/
void lv_lib_pm_next(void) {
if (PageManager.count == 0) return;
Page_t* prev = PageManager.pages[PageManager.current_index];
Page_t* next = PageManager.pages[(PageManager.current_index + 1) % PageManager.count];
// 初始化新页面并切换
if (next->init) next->init();
lv_screen_load_anim(*next->page_obj, LV_SCR_LOAD_ANIM_MOVE_LEFT, 200, 0, true);
// 反初始化前页
if (prev->deinit) prev->deinit();
// 更新索引
PageManager.current_index = (PageManager.current_index + 1) % PageManager.count;
}
/**
* 切换到数组中上一个页面(循环)
*/
void lv_lib_pm_prev(void) {
if (PageManager.count == 0) return;
Page_t* current = PageManager.pages[PageManager.current_index];
uint8_t prev_index = (PageManager.current_index == 0) ? PageManager.count - 1 : PageManager.current_index - 1;
Page_t* prev = PageManager.pages[prev_index];
if (prev->init) prev->init();
lv_screen_load_anim(*prev->page_obj, LV_SCR_LOAD_ANIM_MOVE_RIGHT, 200, 0, true);
if (current->deinit) current->deinit();
PageManager.current_index = prev_index;
}
/**
* 跳转到指定索引页面
* @param page_name 页面名称,传入 NULL 则根据索引跳转
* @param index 目标页面索引,如果 page_name 不为 NULL 则忽略该参数
*/
void lv_lib_pm_goto(const char* page_name, uint8_t index) {
if (page_name != NULL) {
bool found = false;
// 根据页面名称查找索引
for (uint8_t i = 0; i < PageManager.count; i++) {
if (strcmp(PageManager.pages[i]->name, page_name) == 0) {
index = i;
found = true;
break;
}
}
// 如果根据名称查找但未找到,则直接返回,不执行任何跳转
if (!found) {
LV_LOG_WARN("Page '%s' not found.", page_name);
return;
}
}
if(index >= PageManager.count || PageManager.count == 0) return;
Page_t* current = PageManager.pages[PageManager.current_index];
Page_t* target = PageManager.pages[index];
if (current != target) {
if (current->deinit) current->deinit();
PageManager.current_index = index;
if (target->init) target->init();
lv_screen_load_anim(*target->page_obj, LV_SCR_LOAD_ANIM_MOVE_LEFT, 200, 0, true);
}
}
/**
* 跳转到首页面
*/
void lv_lib_pm_goto_first(void) {
lv_lib_pm_goto(NULL, 0);
}
/**
* 获取当前页面
* @return 当前页面指针
*/
Page_t* lv_lib_pm_get_current_page(void) {
if (PageManager.count == 0) return NULL;
return PageManager.pages[PageManager.current_index];
}
/**
* 处理按键事件,调用当前页面的按键事件处理函数
* @param key_id 按键ID
*/
void lv_lib_pm_handle_key_event(void* key_event) {
Page_t* current_page = lv_lib_pm_get_current_page();
if (current_page && current_page->key_event_handler) {
current_page->key_event_handler(key_event); // 调用当前页面的按键事件处理函数
} else {
LV_LOG_WARN("No key event handler for current page\n");
}
}

View File

@@ -0,0 +1,39 @@
#ifndef PAGE_MANAGER_H
#define PAGE_MANAGER_H
#include "lvgl.h"
// 最大支持页面数量
#define MAX_PAGES 5
// 页面结构体
typedef struct {
void (*init)(void);
void (*deinit)(void);
lv_obj_t** page_obj; // 指向页面对象指针的指针
void (*key_event_handler)(void* key_event); // 按键事件处理函数
const char* name; // 可选:用于调试
} Page_t;
// 页面管理器结构体
typedef struct {
Page_t* pages[MAX_PAGES];
uint8_t count;
uint8_t current_index;
} PageManager_t;
// 全局管理器实例(声明)
extern PageManager_t PageManager;
// API 函数声明
void lv_lib_pm_Init(void);
void lv_lib_pm_register(Page_t* page);
void lv_lib_pm_load_init_screen(void);
void lv_lib_pm_next(void);
void lv_lib_pm_prev(void);
void lv_lib_pm_goto(const char* page_name, uint8_t index);
void lv_lib_pm_goto_first(void);
Page_t* lv_lib_pm_get_current_page(void);
void lv_lib_pm_handle_key_event(void* key_event);
#endif // PAGE_MANAGER_H