Files
2025-12-03 11:12:34 +08:00

2366 lines
67 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".lcd_ui_api.data.bss")
#pragma data_seg(".lcd_ui_api.data")
#pragma const_seg(".lcd_ui_api.text.const")
#pragma code_seg(".lcd_ui_api.text")
#endif
#include "app_config.h"
#include "system/includes.h"
#include "ui_api.h"
#include "ui.h"
#include "res/mem_var.h"
#include "typedef.h"
#include "app_task.h"
#include "btstack/avctp_user.h"
#include "key_event_deal.h"
#include "app_main.h"
#include "ui_resource.h"
#include "gpu_draw.h"
#include "jlui/ui_page_manager.h"
#include "jlui/ui_page_switch.h"
#include "key/key_driver.h"
#include "clock_manager/clock_manager.h"
#include "jlui/ui_measure.h"
#include "app_mode_manager/app_mode_manager.h"
#include "app_task.h"
#if CONFIG_WATCH_CASE_ENABLE
#include "res_config.h"
#include "ui_sys_param.h"
#include "jlui_app/ui_app_effect.h"
#include "gif/gif.h"
#endif
#if TCFG_VIDEO_DIAL_ENABLE
#include "avi_video.h"
#endif
#if (defined TCFG_COLOR_SCREEN_CHARGING_CASE_ENABLE) && TCFG_COLOR_SCREEN_CHARGING_CASE_ENABLE
#include "chgbox_box.h"
#include "ui_bg_manage.h"
#include "smartbox_info_manager.h"
#endif
#if (defined CONFIG_JL_UI_ENABLE && CONFIG_JL_UI_ENABLE)
#define LOG_TAG_CONST UI_TASK
#define LOG_TAG "[UI_TASK]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CHAR_ENABLE
#include "debug.h"
extern u8 get_charge_online_flag(void);
extern u8 get_charge_full_flag(void);
extern void gif_play(int elm_id, int task_id);
extern int jlgpu_scheduler_async_gpu_cache_free_resident();
extern const int JLUI_MULTI_PAGE_OVERLAY_SUPPORT;
#if (TCFG_UI_ENABLE && (TCFG_SPI_LCD_ENABLE || TCFG_LCD_OLED_ENABLE) && (!TCFG_SIMPLE_LCD_ENABLE))
#define MEM_VAR_SIZE (3*1024)
#define CURR_WINDOW_MAIN (0)
#define UI_NO_ARG (-1)
#define UI_TASK_NAME "ui"
REGISTER_UI_GLOBAL_STYLE(JL) /* 注册JL UI风格 */
enum {
UI_MSG_OTHER,
UI_MSG_KEY,
UI_MSG_TOUCH,
UI_MSG_SHOW,
UI_MSG_HIDE,
UI_TIME_TOUCH_RESUME,
UI_TIME_TOUCH_SUPEND,
UI_MSG_EXIT,
UI_MSG_GIF_PLAY,
UI_MSG_SHOW_MULTI_PAGE,
UI_MSG_HIDE_MULTI_PAGE,
};
#define USER_MASK_TYPE (BIT(16)|BIT(17))//删消息池使用
#define GIF_TYPE_OFFSET (20) //GIF偏移
#define PAGE_SWITCH_MODE_NOT_LOOP 0 //卡片滑动不循环
struct ui_card_var {
u16 move_en: 1;
u16 slide_en: 1;
u16 first_result: 6;
u16 result: 6;
s16 startx;
s16 starty;
s16 endx;
s16 endy;
s16 pos_x;
s16 pos_y;
s16 start_left;
s16 start_pos_x;
u32 page_in_touchdown;
};
struct ui_server_env {
u8 init: 1;
u8 key_lock : 1;
u8 lcd_bl_idle_flag : 1;
u8 lcd_need_keep_open: 1;
u8 open_flag: 1;
u8 ui_card_slide_dis: 1;
u8 need_password: 1; // 判断是否需要输入密码
u8 ui_card_move_mode;
u8 ui_page_slide_mode;
u8 touch_msg_counter;
u16 ui_auto_shut_down_timer;
u16 timer_id;
u16 shut_down_time;
u32 mem_id[8];
int (*touch_event_call)(void);
int touch_event_interval;
OS_SEM start_sem;
struct ui_card_var card_var;
};
static struct ui_server_env __ui_display = {0};
#define __this (&__ui_display)
#define __card (&(__this->card_var))
static DEFINE_SPINLOCK(lock);
int ui_dial_manage_init();
u8 get_standby_watch_en();
int lcd_sleep_ctrl(u8 enter);
int ui_page_num();
void ui_key_set_send_event_cb(void (*cb)(int key_event));
int ui_core_clear_pagemove_flag();
int ui_cube_ontouch(struct element_touch_event *e);
int ui_hexagon_ontouch(struct element_touch_event *e);
int ui_reflection_ontouch(struct element_touch_event *e);
int ui_cube_reflection_ontouch(struct element_touch_event *e);
int ui_relate_init();
int ui_relate_uninit();
void ui_cube_rdec(int xoffset);
int ui_cube_status();
int ui_hexagon_status();
int ui_reflection_status();
int ui_cube_reflection_status();
void ui_page_set_busy(int busy);
void menu_list_rec_clr();
extern int dial_sel_exit();
extern int ui_page_switch_effect_stop();
#if TCFG_VIDEO_DIAL_ENABLE
extern void avi_resume();
extern void *get_aviplay_handle();
#endif
//进入屏保
__attribute__((weak)) void ui_screen_saver(void *p)
{
ui_backlight_close();
}
//退出屏保
__attribute__((weak)) void ui_screen_recover(u8 recover_cur_page)
{
ui_backlight_open(recover_cur_page);
}
__attribute__((weak)) u8 get_screen_saver_status()
{
return (!lcd_backlight_status());
}
__attribute__((weak)) void set_screen_saver_status(u8 status)
{
}
__attribute__((weak)) void auto_goto_dial_timer_del()
{
}
__attribute__((weak)) void ui_sysinfo_init()
{
}
__attribute__((weak)) void sys_param_init(void)
{
}
__attribute__((weak)) void lcd_bl_open()
{
}
__attribute__((weak)) u8 ui_message_filter_hook(const char *msg, va_list argptr)
{
return 0;
}
/* __attribute__((weak)) int ui_id2remap(int id) */
/* { */
/* return id; */
/* } */
//映射id
int ui_id2remap(int id)
{
#if TCFG_UI_ENABLE
#if UI_UPGRADE_RES_ENABLE
u8 rcsp_eflash_update_flag_get(void);
u8 rcsp_eflash_flag_get(void);
int dial_num = watch_get_items_num();
if (ui_id2type(id) == CTRL_TYPE_WINDOW) {
if (rcsp_eflash_flag_get() || rcsp_eflash_update_flag_get() || (dial_num == 0)) {
log_info("id:0x%x remap to 0x%x\n", id, ID_WINDOW_UPGRADE);
return ID_WINDOW_UPGRADE;
}
}
#endif
#endif /* #if TCFG_UI_ENABLE */
return id;
}
u32 *get_ui_mem_id()
{
return __this->mem_id;
}
u32 get_ui_mem_id_size()
{
return sizeof(__this->mem_id) / sizeof(__this->mem_id[0]);
}
u8 get_ui_init_status()
{
return __this->init;
}
int key_is_ui_takeover()
{
return __this->key_lock;
}
void key_ui_takeover(u8 on)
{
__this->key_lock = !!on;
}
u8 get_need_password()
{
return __this->need_password;
}
void set_need_password(u8 flag)
{
__this->need_password = flag;
}
static int post_ui_msg(int *msg, u8 len)
{
int err = 0;
int count = 0;
if (!__this->init) {
log_error("<%s> not init\n", __func__);
return -1;
}
__retry:
err = os_taskq_post_type(UI_TASK_NAME, msg[0], len - 1, &msg[1]);
if (cpu_in_irq() || cpu_irq_disabled()) {
return err;
}
if (err) {
log_error("<%s> os_error:%d\n", __func__, err); //在os_error.h中查找错误码含义
if (!strcmp(os_current_task(), UI_TASK_NAME)) {
return err;
}
if (count > 20) {
return -1;
}
count++;
os_time_dly(1);
goto __retry;
}
return err;
}
int ui_page_memory_get(int id)
{
int mem_id_num = (int)(sizeof(__this->mem_id) / sizeof(__this->mem_id[0]));
if ((id <= 0) && (id > -1 * mem_id_num)) {
if (__this->mem_id[7 + id]) {
return __this->mem_id[7 + id];
}
}
return 0;
}
int ui_page_memory_set(int id)
{
if (__this->mem_id[7] != id) {
for (int i = 1; i <= 7; i++) {
__this->mem_id[i - 1] = __this->mem_id[i];
}
__this->mem_id[7] = id;
}
return id;
}
//=================================================================================//
// @brief: 显示主页 应用于非ui线程显示主页使用
//有针对ui线程进行处理,允许用于ui线程等同ui_show使用
//=================================================================================//
int ui_show_main(int id)
{
u32 rets;
__asm__ volatile("%0 = rets":"=r"(rets));
log_info("<%s> ID:0x%x rets:%x\n", __func__, id, rets);
static OS_SEM sem;
int msg[8];
int i;
int mem_id = ui_page_memory_get(id);
log_info("<%s>id:0x%x memid:0x%x \n", __func__, id, mem_id);
if (mem_id) {
id = mem_id;
} else {
ui_page_memory_set(id);
}
auto_goto_dial_timer_del();
u8 need_pend = 0;
if (!(cpu_in_irq() || cpu_irq_disabled())) {
if (strcmp(os_current_task(), UI_TASK_NAME)) {
need_pend = 1;
}
}
msg[0] = UI_MSG_SHOW;
msg[1] = id;
msg[2] = 0;
if (need_pend) {
os_sem_create(&sem, 0);
msg[2] = (int)&sem;
}
if (!post_ui_msg(msg, 3)) {
if (need_pend) {
os_sem_pend(&sem, 0);
}
}
if (get_screen_saver_status()) {
log_info("screen-saver ... ui_show_main_now\n");
ui_screen_recover(0);
__this->lcd_bl_idle_flag = 0;
}
return 0;
}
int ui_show_multi_page()
{
static OS_SEM sem;
int msg[8];
int i;
u8 need_pend = 0;
if (!(cpu_in_irq() || cpu_irq_disabled())) {
if (strcmp(os_current_task(), UI_TASK_NAME)) {
need_pend = 1;
}
}
msg[0] = UI_MSG_SHOW_MULTI_PAGE;
msg[1] = 0;
if (need_pend) {
os_sem_create(&sem, 0);
msg[1] = (int)&sem;
}
if (!post_ui_msg(msg, 2)) {
if (need_pend) {
os_sem_pend(&sem, 0);
}
}
return 0;
}
int ui_hide_multi_page()
{
static OS_SEM sem;
int msg[8];
int i;
auto_goto_dial_timer_del();
u8 need_pend = 0;
if (!(cpu_in_irq() || cpu_irq_disabled())) {
if (strcmp(os_current_task(), UI_TASK_NAME)) {
need_pend = 1;
}
}
msg[0] = UI_MSG_HIDE_MULTI_PAGE;
msg[1] = 0;
if (need_pend) {
os_sem_create(&sem, 0);
msg[1] = (int)&sem;
}
if (!post_ui_msg(msg, 2)) {
if (need_pend) {
os_sem_pend(&sem, 0);
}
}
return 0;
}
//=================================================================================//
// @brief: 关闭主页 应用于非ui线程关闭使用
//有针对ui线程进行处理,允许用于ui线程等同ui_hide使用
//=================================================================================//
int ui_hide_main(int id)
{
u32 rets;//, reti;
__asm__ volatile("%0 = rets":"=r"(rets));
log_info("__func__ %s %x\n", __func__, rets);
static OS_SEM sem;// = zalloc(sizeof(OS_SEM));
int msg[8];
u8 need_pend = 0;;
if (!(cpu_in_irq() || cpu_irq_disabled())) {
if (strcmp(os_current_task(), UI_TASK_NAME)) {
need_pend = 1;
}
}
/* if (!strcmp(os_current_task(), UI_TASK_NAME)) { */
/* if (CURR_WINDOW_MAIN == id) { */
/* id = ui_get_current_window_id(); */
/* } */
/* ui_hide(id); */
/* return 0; */
/* } */
msg[0] = UI_MSG_HIDE;
msg[1] = id;
msg[2] = 0;
if (need_pend) {
os_sem_create(&sem, 0);
msg[2] = (int)&sem;
}
if (!post_ui_msg(msg, 3)) {
if (need_pend) {
os_sem_pend(&sem, 0);
}
}
return 0;
}
//=================================================================================//
// @brief: 关闭当前主页 灵活使用自动判断当前主页进行关闭
//用户可以不用关心当前打开的主页,特别适用于一个任务使用了多个主页的场景
//=================================================================================//
int ui_hide_curr_main()
{
return ui_hide_main(CURR_WINDOW_MAIN);
}
//=================================================================================//
// @brief: 应用往ui发送消息,ui主页需要注册回调函数关闭当前主页
// //消息发送方法demo UI_MSG_POST("test1:a=%4,test2:bcd=%4,test3:efgh=%4,test4:hijkl=%4", 1,2,3,4);
// 往test1、test2、test3、test4发送了字符为a、bcd、efgh、hijkl,附带变量为1、2、3、4
// 每次可以只发一个消息,也可以不带数据例如:UI_MSG_POST("test1")
//=================================================================================//
//
static int msg_argc(const char *msg)
{
int ret = 0;
int step = 0;
if (*msg == '\0') {
return 0;
}
while (*msg) {
switch (step) {
case 0:
if (*msg == ':') {
step = 1;
}
break;
case 1:
switch (*msg) {
case '%':
msg++;
if (*msg >= '0' && *msg <= '9') {
ret++;
} else if (*msg == 'p') {
ret++;
}
step = 0;
break;
default:
break;
}
break;
}
msg++;
}
return ret;
}
int ui_server_msg_post(const char *msg, ...)
{
int argv[9];
argv[0] = UI_MSG_OTHER;
argv[1] = (int)msg;
va_list argptr;
va_start(argptr, msg);
int ret = msg_argc(msg);
for (int i = 0; (i < 7 && i < ret) ; i++) {
argv[i + 2] = va_arg(argptr, int);
}
va_end(argptr);
return post_ui_msg(argv, 9);
}
//=================================================================================//
// @brief: 应用往ui发送key消息,由ui控件分配
//=================================================================================//
int ui_key_msg_post(int key)
{
u8 count = 0;
int msg[8];
msg[0] = UI_MSG_KEY;
msg[1] = key;
/* touch_msg_counter++; */
return post_ui_msg(msg, 2);
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief key_event_sent_to_ui_map 按键事件映射为ui事件
*
* @param key
*/
/* ------------------------------------------------------------------------------------*/
void key_event_sent_to_ui_map(int key_event)
{
if (key_event == KEY_UI_TRIPLE_CLICK) {
#if (defined TCFG_CHARGE_BOX_ENABLE && TCFG_CHARGE_BOX_ENABLE)
app_chargebox_event_to_user(CHGBOX_EVENT_EXCHANGE_MAC);
#endif
} else if (key_event != KEY_WATCH_NO_KEY) {
if (get_screen_saver_status()) {
ui_screen_recover(1);
return;
} else {
ui_auto_shut_down_re_run();
}
ui_key_msg_post(key_event);
}
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief ui_key_event_deal_app 应用层处理ui按键事件的地方
*
* @param key_event
*
* @return true 应用层接管 false ui框架处理
*/
/* ------------------------------------------------------------------------------------*/
int ui_key_event_deal_app(int key_event)
{
/* log_info("%s key_event:%d", __func__, key_event); */
if (app_in_mode(APP_MODE_IDLE)) {
return true;
}
#if TCFG_PC_MODE_LOCK_UI_ENABLE
if (app_in_mode(APP_MODE_PC)) {
return true;
}
#endif
/* 如果在表盘选择功能,按键时先退回表盘 */
extern int dial_sel_state();
extern void dial_sel_free(struct element * elm, int touch_x, int touch_y);
if (dial_sel_state() && (key_event != KEY_UI_PLUS) && (key_event != KEY_UI_MINUS)) {
dial_sel_free(NULL, -1, -1);
return true;
}
int ret = false;
if (key_event == KEY_UI_HOME) {
ui_show_menu_page();
ret = true;
} else if (key_event == KEY_UI_SHORTCUT) {
ui_show_shortcut_key();
ret = false;
} else if (key_event == KEY_UI_POWEROFF) {
ui_key_shutdown_or_reboot(1);
ret = true;
} else if (key_event == KEY_UI_MENU_LIST) {
#if (defined TCFG_COLOR_SCREEN_CHARGING_CASE_ENABLE) && TCFG_COLOR_SCREEN_CHARGING_CASE_ENABLE
ui_key_shutdown_or_reboot(1);
ret = true;
#else
ret = ui_show_menu_list();
if (ret == false) {
ui_card_anim_next();
}
ret = true;
#endif
} else if (key_event == KEY_UI_PLUS) {
if ((ui_cube_status()) && (ui_card_get_move_mode() == PAGE_MOVE_MODE_CUBE)) {
ui_cube_rdec(20);
ret = true;
}
} else if (key_event == KEY_UI_MINUS) {
if ((ui_cube_status()) && (ui_card_get_move_mode() == PAGE_MOVE_MODE_CUBE)) {
ui_cube_rdec(-20);
ret = true;
}
} else {
ret = false;
}
return ret;
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief 应用层默认处理ui按键事件的地方,位于ui框架处理按键事件之后
*
* @param key_event
*
*/
/* ------------------------------------------------------------------------------------*/
void ui_default_key_event_deal_app(int key_event)
{
if (key_event == KEY_UI_PLUS) {
ui_show_plus();
} else if (key_event == KEY_UI_MINUS) {
ui_show_minus();
}
}
// 触摸限流降频
#define TCFG_UI_TOUCH_LIMIT_EN 0
// 动画降频
#define TCFG_UI_ANIM_LIMIT_EN 0
#define TCFG_UI_LIMIT_ENABLE (TCFG_UI_TOUCH_LIMIT_EN || TCFG_UI_ANIM_LIMIT_EN)
#if TCFG_UI_LIMIT_ENABLE
#define UI_LIMIT_TMR_MS (100) // 定时器间隔
#define UI_LIMIT_CHECK_CNT (5) // 检测间隔
#define UI_LIMIT_CHECK_MIN (1)
#define UI_LIMIT_CHECK_MAX (UI_LIMIT_CHECK_CNT - 1)
#define UI_TOUCH_LIMIT_ABANDON_SETUP (20)
struct ui_limit {
u8 block_percent; // 拥堵百分比,值越大越拥堵
u8 block_cnt_once; // 每次增加的拥堵比
u8 cnt_task;
u8 cnt_irq;
u16 timer_task;
u16 timer_irq;
#if TCFG_UI_TOUCH_LIMIT_EN
u8 touch_abandon_cnt;
#endif
#if TCFG_UI_ANIM_LIMIT_EN
u8 anim_interval_min;
u8 anim_interval_max;
#endif
};
static struct ui_limit *p_ui_limit = NULL;
static void ui_limit_task_deal(void *priv)
{
spin_lock(&lock);
if (p_ui_limit) {
p_ui_limit->cnt_task ++;
p_ui_limit->timer_task = sys_timeout_add_2_task(NULL, ui_limit_task_deal, UI_LIMIT_TMR_MS, "app_core");
/* printf("ui_limit task deal\n"); */
}
spin_unlock(&lock);
}
static void ui_limit_irq_deal(void *priv)
{
spin_lock(&lock);
if (p_ui_limit) {
p_ui_limit->cnt_irq ++;
if (p_ui_limit->cnt_irq >= UI_LIMIT_CHECK_CNT) {
u8 old_percent = p_ui_limit->block_percent;
if (p_ui_limit->cnt_task <= UI_LIMIT_CHECK_MIN) { // 阻塞
p_ui_limit->block_percent += p_ui_limit->block_cnt_once;
if (p_ui_limit->block_percent > 100) {
p_ui_limit->block_percent = 100;
}
} else if (p_ui_limit->cnt_task >= UI_LIMIT_CHECK_MAX) { // 缓解
if (p_ui_limit->block_percent > p_ui_limit->block_cnt_once) {
p_ui_limit->block_percent -= p_ui_limit->block_cnt_once;
} else {
p_ui_limit->block_percent = 0;
}
}
#if TCFG_UI_ANIM_LIMIT_EN
if (old_percent != p_ui_limit->block_percent) {
u8 anim_interval = p_ui_limit->anim_interval_min + (p_ui_limit->anim_interval_max - p_ui_limit->anim_interval_min) * p_ui_limit->block_percent / 100;
ui_anim_set_interval(anim_interval);
/* printf("ui_anim switch:%d \n", anim_interval); */
}
#endif
/* printf("ui_limit taskcnt:%d, percent:%d \n", p_ui_limit->cnt_task, p_ui_limit->block_percent); */
p_ui_limit->cnt_irq = 0;
p_ui_limit->cnt_task = 0;
}
}
spin_unlock(&lock);
}
static void ui_limit_release(void)
{
if (p_ui_limit) {
/* printf("ui_limit release\n"); */
if (p_ui_limit->timer_task) {
sys_timeout_del(p_ui_limit->timer_task);
p_ui_limit->timer_task = 0;
}
if (p_ui_limit->timer_irq) {
sys_hi_timer_del(p_ui_limit->timer_irq);
p_ui_limit->timer_irq = 0;
}
free(p_ui_limit);
p_ui_limit = NULL;
}
}
static void ui_limit_create(void)
{
if (p_ui_limit == NULL) {
p_ui_limit = zalloc(sizeof(struct ui_limit));
ASSERT(p_ui_limit);
p_ui_limit->timer_task = sys_timeout_add_2_task(NULL, ui_limit_task_deal, UI_LIMIT_TMR_MS, "app_core");
p_ui_limit->timer_irq = sys_hi_timer_add(NULL, ui_limit_irq_deal, UI_LIMIT_TMR_MS);
u32 wdt_ms = 4000; //wdt_get_time()
p_ui_limit->block_cnt_once = 100 / (wdt_ms / (UI_LIMIT_TMR_MS * UI_LIMIT_CHECK_CNT) - 1);
/* printf("ui_limit create, once:%d \n", p_ui_limit->block_cnt_once); */
#if TCFG_UI_ANIM_LIMIT_EN
#if (defined TCFG_LCD_TE_USED_PEND && TCFG_LCD_TE_USED_PEND)
p_ui_limit->anim_interval_min = lcd_get_te_frame_period_us() * 80 / 100 / 1000;
#else
p_ui_limit->anim_interval_min = 13;
#endif
p_ui_limit->anim_interval_max = 100;
ui_anim_set_interval(p_ui_limit->anim_interval_min);
/* printf("ui_anim min:%d \n", p_ui_limit->anim_interval_min); */
#endif
}
}
static void ui_limit_lcd_sleep_enter(void)
{
// 灭屏
spin_lock(&lock);
ui_limit_release();
spin_unlock(&lock);
}
static void ui_limit_lcd_sleep_exit(void)
{
// 亮屏
spin_lock(&lock);
ui_limit_create();
spin_unlock(&lock);
}
REGISTER_LCD_SLEEP_HEADLER(ui_limit_by_lcd_sleep) = {
.name = "ui_limit",
.enter = ui_limit_lcd_sleep_enter,
.exit = ui_limit_lcd_sleep_exit,
};
#if TCFG_UI_TOUCH_LIMIT_EN
static void ui_touch_limit_release(void)
{
if (p_ui_limit) {
/* printf("ui_touch release\n"); */
p_ui_limit->touch_abandon_cnt = 0;
}
}
static void ui_touch_limit_create(void)
{
}
static int ui_touch_limit_is_abandon(void)
{
if (p_ui_limit && p_ui_limit->block_percent) {
p_ui_limit->touch_abandon_cnt += UI_TOUCH_LIMIT_ABANDON_SETUP;
if (p_ui_limit->touch_abandon_cnt <= p_ui_limit->block_percent) {
/* printf("ui_touch abandon\n"); */
return true;
}
if (p_ui_limit->touch_abandon_cnt > 100) {
p_ui_limit->touch_abandon_cnt = 0;
}
/* printf("ui_touch ok\n"); */
}
return false;
}
#endif /* #if TCFG_UI_TOUCH_LIMIT_EN */
#endif /* #if TCFG_UI_LIMIT_ENABLE */
//=================================================================================//
// @brief: 应用往ui发送触摸消息,由ui控件分配
//=================================================================================//
int ui_touch_msg_post(struct touch_event *event)
{
int msg[8];
int i = 0;
int err;
ui_auto_shut_down_re_run();
if (get_screen_saver_status()) {
ui_screen_recover(1);
return 0;
}
#if TCFG_UI_TOUCH_LIMIT_EN
spin_lock(&lock);
if (event->event == ELM_EVENT_TOUCH_MOVE) {
ui_touch_limit_create();
if (ui_touch_limit_is_abandon()) {
spin_unlock(&lock);
return 0;
}
} else {
ui_touch_limit_release();
}
spin_unlock(&lock);
#endif /* #if TCFG_UI_TOUCH_LIMIT_EN */
msg[0] = UI_MSG_TOUCH;
msg[1] = (int)NULL;
memcpy(&msg[2], event, sizeof(struct touch_event));
while (1) {
spin_lock(&lock);
__this->touch_msg_counter++;
spin_unlock(&lock);
err = post_ui_msg(msg, sizeof(struct touch_event) / 4 + 2);
if (err) {
log_error("post_ui_msg err! %d, %d, %d\n", event->event, event->x, event->y);
spin_lock(&lock);
__this->touch_msg_counter--;
spin_unlock(&lock);
/* if ((event->event == ELM_EVENT_TOUCH_DOWN) || (event->event == ELM_EVENT_TOUCH_UP)) { */
/* os_time_dly(1); */
/* continue; */
/* } */
return -1;
}
break;
}
return 0;
}
//=================================================================================//
// @brief: 应用往ui发送触摸消息,由ui控件分配
//=================================================================================//
int ui_touch_msg_post_withcallback(struct touch_event *event, void (*cb)(u8 finish))
{
int msg[8];
int i = 0;
int err;
msg[0] = UI_MSG_TOUCH;
msg[1] = (int)cb;
memcpy(&msg[2], event, sizeof(struct touch_event));
if (__this->touch_msg_counter < 16) {
spin_lock(&lock);
__this->touch_msg_counter++;
spin_unlock(&lock);
err = post_ui_msg(msg, sizeof(struct touch_event) / 4 + 2);
if (err) {
log_error("post_ui_msg err! %d, %d, %d\n", event->event, event->x, event->y);
spin_lock(&lock);
__this->touch_msg_counter--;
spin_unlock(&lock);
return -1;
}
} else {
log_info("touch msg drop! %d, %d, %d\n", event->event, event->x, event->y);
return -1;
}
return 0;
}
const char *str_substr_iter(const char *str, char delim, int *iter)
{
const char *substr;
ASSERT(str != NULL);
substr = str + *iter;
if (*substr == '\0') {
return NULL;
}
for (str = substr; *str != '\0'; str++) {
(*iter)++;
if (*str == delim) {
break;
}
}
return substr;
}
int do_msg_handler(const char *msg, va_list *pargptr, int (*handler)(const char *, u32))
{
int ret = 0;
int width;
int step = 0;
u32 arg = 0x5678;
int m[16];
char *t = (char *)&m[3];
va_list argptr = *pargptr;
if (*msg == '\0') {
handler((const char *)' ', 0);
return 0;
}
while (*msg && *msg != ',') {
switch (step) {
case 0:
if (*msg == ':') {
step = 1;
}
break;
case 1:
switch (*msg) {
case '%':
msg++;
if (*msg >= '0' && *msg <= '9') {
if (*msg == '1') {
arg = va_arg(argptr, int) & 0xff;
} else if (*msg == '2') {
arg = va_arg(argptr, int) & 0xffff;
} else if (*msg == '4') {
arg = va_arg(argptr, int);
}
} else if (*msg == 'p') {
arg = va_arg(argptr, int);
}
m[2] = arg;
handler((char *)&m[3], m[2]);
t = (char *)&m[3];
step = 0;
break;
case '=':
*t = '\0';
break;
case ' ':
break;
default:
*t++ = *msg;
break;
}
break;
}
msg++;
}
*pargptr = argptr;
return ret;
}
int ui_message_handler(int id, const char *msg, va_list argptr)
{
int iter = 0;
const char *str;
const struct uimsg_handl *handler;
struct window *window = (struct window *)ui_core_get_element_by_id(id);
if (!window || !window->private_data) {
return -EINVAL;
}
handler = (const struct uimsg_handl *)window->private_data;
while ((str = str_substr_iter(msg, ',', &iter)) != NULL) {
for (; handler->msg != NULL; handler++) {
if (!memcmp(str, handler->msg, strlen(handler->msg))) {
do_msg_handler(str + strlen(handler->msg), &argptr, handler->handler);
break;
}
}
}
return 0;
}
void ui_touch_timer_delete()
{
if (!__ui_display.init) {
return;
}
int msg[8];
msg[0] = UI_TIME_TOUCH_SUPEND;
post_ui_msg(msg, 1);
#if UI_WATCH_RES_ENABLE
local_irq_disable();
if (!__ui_display.timer_id) {
local_irq_enable();
return;
}
local_irq_enable();
#endif
}
void ui_touch_timer_start()
{
if (!__ui_display.init) {
return;
}
int msg[8];
msg[0] = UI_TIME_TOUCH_RESUME;
post_ui_msg(msg, 1);
local_irq_disable();
if (__ui_display.timer_id) {
local_irq_enable();
return;
}
local_irq_enable();
}
void ui_set_touch_event(int (*touch_event)(void), int interval)
{
__ui_display.touch_event_call = touch_event;
__ui_display.touch_event_interval = interval;
}
u8 get_ui_open_flag()
{
return __this->open_flag;
}
void set_ui_open_flag(u8 flag)
{
__this->open_flag = !!flag;
}
void set_lcd_keep_open_flag(u8 flag)
{
__this->lcd_need_keep_open = !!flag;
}
extern u8 get_charge_online_flag(void);
void ui_backlight_open(u8 recover_cur_page)
{
u32 rets;//, reti;
__asm__ volatile("%0 = rets":"=r"(rets));
__this->lcd_bl_idle_flag = 0;
if (!__ui_display.init) {
return;
}
if (__this->open_flag) {
return;
}
log_info("__func__ %s %x\n", __func__, rets);
if (get_screen_saver_status()) {
__this->open_flag = 1;
/* UI_MSG_POST("ui_lp_cb:exit=%4", 1); */
/* sys_key_event_enable();//关闭按键 */
/* ui_auto_shut_down_enable(); // 如果唤醒后的界面有disable,这里会把它重新打开 */
//lcd_sleep_ctrl(0);//屏幕退出低功耗
#if UI_WATCH_RES_ENABLE
if (recover_cur_page) {
ui_auto_shut_down_enable();
u8 poweron_password = 0;
int ret = syscfg_read(USER_PASSWORD_ON, &poweron_password, sizeof(poweron_password));
if ((ret == sizeof(poweron_password)) && poweron_password) {
set_need_password(1);
UI_SHOW_WINDOW(ID_WINDOW_DIAL);
}
#if TCFG_CHARGE_ENABLE
else if (get_charge_online_flag()) {
UI_SHOW_WINDOW(ID_WINDOW_BATCHARGE);
}
#elif TCFG_CHARGE_BOX_ENABLE //彩屏仓 仓充电
else if (sbox_box_charging_get()) {
UI_SHOW_WINDOW(ID_WINDOW_BATCHARGE);
}
#endif
else {
ui_show_main(0);//恢复当前ui
}
} else {
u8 poweron_password = 0;
int ret = syscfg_read(USER_PASSWORD_ON, &poweron_password, sizeof(poweron_password));
if ((ret == sizeof(poweron_password)) && poweron_password) {
set_need_password(1);
}
}
#endif
//启用灵动岛功能的时候,亮屏显示
if (JLUI_MULTI_PAGE_OVERLAY_SUPPORT && TCFG_UI_ENABLE_SMARTWIN) {
UI_SHOW_MULTI_PAGE();
}
ui_touch_timer_start();
}
}
void ui_backlight_close(void)
{
if (!__ui_display.init) {
return;
}
__this->open_flag = 0;
if (!lcd_sleep_status()) {
/* UI_MSG_POST("ui_lp_cb:enter=%4", 0); */
/* sys_key_event_disable();//关闭按键 */
#if UI_WATCH_RES_ENABLE
ui_hide_curr_main();//关闭当前页面
#endif
if (JLUI_MULTI_PAGE_OVERLAY_SUPPORT) {
UI_HIDE_MULTI_PAGE();
}
ui_auto_shut_down_disable();
ui_touch_timer_delete();
}
}
#if TCFG_UI_SHUT_DOWN_TIME
void ui_set_shut_down_time(u16 time)
{
__ui_display.shut_down_time = time;
}
int ui_get_shut_down_time()
{
return __ui_display.shut_down_time;
}
#endif
void ui_auto_shut_down_enable(void)
{
u32 rets;
__asm__ volatile("%0 = rets":"=r"(rets));
#if TCFG_UI_SHUT_DOWN_TIME
if (!__ui_display.init) {
return;
}
#if TCFG_USER_BT_CLASSIC_ENABLE
if (bt_get_call_status() != BT_CALL_HANGUP) {
log_info("%s call_status:%d", __func__, bt_get_call_status());
return;
}
#endif
if (__this->lcd_need_keep_open) {
log_info("need keep open");
return;
}
if (__this->ui_auto_shut_down_timer == 0) {
if (__ui_display.shut_down_time == 0) {
__ui_display.shut_down_time = 10;
}
if (__ui_display.shut_down_time > 20) {
/* __ui_display.shut_down_time = 20; */
}
log_info("[%s]time:%d rets:0x%x\n", __func__, __ui_display.shut_down_time, rets);
__this->ui_auto_shut_down_timer = sys_timeout_add(NULL, ui_screen_saver, __ui_display.shut_down_time * 1000);
}
#endif
}
u8 ui_auto_shut_down_disable(void)
{
u32 rets;
__asm__ volatile("%0 = rets":"=r"(rets));
#if TCFG_UI_SHUT_DOWN_TIME
if (__this->ui_auto_shut_down_timer) {
log_info("[%s]rets:0x%x", __func__, rets);
sys_timeout_del(__this->ui_auto_shut_down_timer);
__this->ui_auto_shut_down_timer = 0;
return true;
}
return false;
#endif
return false;
}
void ui_auto_shut_down_modify(void)
{
#if TCFG_UI_SHUT_DOWN_TIME
if (__this->ui_auto_shut_down_timer) {
sys_timer_modify(__this->ui_auto_shut_down_timer, __ui_display.shut_down_time * 1000);
}
#endif
}
void ui_auto_shut_down_re_run(void)
{
#if TCFG_UI_SHUT_DOWN_TIME
if (__this->ui_auto_shut_down_timer) {
sys_timer_re_run(__this->ui_auto_shut_down_timer);
}
#endif
}
static u8 lcd_bl_idle_query(void)
{
return __this->lcd_bl_idle_flag;
}
REGISTER_LP_TARGET(lcd_backlight_lp_target) = {
.name = "lcd_backlight",
.is_idle = lcd_bl_idle_query,
};
#if(1||CONFIG_UI_STYLE == STYLE_JL_WTACH_NEW)
extern int g_cur_left;
//=================================================================================//
// @brief: 卡片滑动模式管理,用于左侧侧边栏、负一屏等效果
// 限制首页右滑、所有页面右滑和最后一页左滑
//=================================================================================//
int ui_page_manager_mode_set(u8 mode)
{
__this->ui_page_slide_mode = mode;
return __this->ui_page_slide_mode;
}
int ui_page_manager_mode_get(void)
{
return __this->ui_page_slide_mode;
}
//=================================================================================//
// @brief: 卡片管理开关
//=================================================================================//
enum ui_card_run_type ui_card_get_status()
{
struct ui_effect_module *effmod_hd = ui_effect_get_handle_by_style(ui_card_get_move_mode());
/* log_info("%s mode:%d hd:0x%x",__func__,ui_card_get_move_mode(),(u32)effmod_hd); */
if (effmod_hd && effmod_hd->get_status) {
if (effmod_hd->get_status()) {
return UI_CARD_RUN_MULTI_PAGE;
}
}
if (__card->slide_en) {
return UI_CARD_RUN_SINGLE_PAGE;
}
return UI_CARD_RUN_NULL;
}
int ui_in_effect()
{
if (ui_card_get_status()) {
return true;
} else {
return false;
}
}
void ui_card_run_stop(void)
{
struct ui_effect_module *effmod_hd = ui_effect_get_handle_by_style(ui_card_get_move_mode());
/* log_info("%s mode:%d hd:0x%x",__func__,ui_card_get_move_mode(),(u32)effmod_hd); */
if (effmod_hd && effmod_hd->uninit) {
effmod_hd->uninit();
}
if (__card->slide_en) {
ui_page_anim_stop();
__card->slide_en = false;
}
}
#if (defined TCFG_COLOR_SCREEN_CHARGING_CASE_ENABLE) && TCFG_COLOR_SCREEN_CHARGING_CASE_ENABLE
u8 is_card_enable()
{
return __this->ui_card_slide_dis;
}
#endif
void ui_card_enable()
{
__this->ui_card_slide_dis = false;
}
void ui_card_disable()
{
__this->ui_card_slide_dis = true;
}
u8 ui_card_get_move_mode()
{
return __this->ui_card_move_mode;
}
void ui_card_set_move_mode(u8 mode) // 设置卡片滑动动画
{
void jlui_malloc_ram_info_clr(u8 clr);
jlui_malloc_ram_info_clr(0x2);
__this->ui_card_move_mode = mode;
}
static void ui_card_anim_start(int curr_win)
{
}
static void ui_card_anim_stop(int curr_win)
{
__card->slide_en = false;
}
//#define UI_CARD_MOVE_MODE 3
int ui_card_ontouch(struct element_touch_event *e)
{
/* 如果在菜单返回划屏特效,直接接管触摸消息 */
extern int ui_return_page_effect_touch(struct element_touch_event * e);
extern int menu_enter_app_state();
if (ui_return_page_effect_touch(e) || menu_enter_app_state()) {
return true;
}
int page_switch_mode = ui_page_manager_mode_get();
if (__this->ui_card_slide_dis) {
log_debug("<%s> ui_card disable\n", __func__);
__card->page_in_touchdown = 0;
if (__card->slide_en) {
ui_page_anim_stop();
__card->slide_en = false;
}
return ui_event_ontouch(e);
}
struct ui_page *page = ui_page_search(ui_get_current_window_id());
int ui_card_page_num = get_ui_page_list_total_num();
/* log_info("%s page_num:%d", __func__, ui_card_page_num); */
extern int dial_sel_state();
if ((!page) || (ui_card_page_num < 2) || (dial_sel_state())) {
log_debug("<%s>page_not_search(page_id:0x%x) or page_num:%d \n", __func__, ui_get_current_window_id(), ui_card_page_num);
if (__card->slide_en) {
ui_page_anim_stop();
__card->slide_en = false;
}
__card->page_in_touchdown = 0;
return ui_event_ontouch(e);
}
int effect_ret = 0;
int xoffset, yoffset;
struct ui_effect_module *effmod_hd = ui_effect_get_handle_by_style(ui_card_get_move_mode());
if (effmod_hd && effmod_hd->ontouch) {
switch (e->event) {
case ELM_EVENT_TOUCH_ENERGY:
effect_ret = effmod_hd->ontouch(e);
break;
case ELM_EVENT_TOUCH_DOWN:
ui_page_manager_mode_set(0);
__card->startx = e->pos.x;
__card->starty = e->pos.y;
effect_ret = effmod_hd->ontouch(e);
break;
case ELM_EVENT_TOUCH_UP:
effect_ret = effmod_hd->ontouch(e);
break;
case ELM_EVENT_TOUCH_MOVE:
xoffset = e->pos.x - __card->pos_x;
yoffset = e->pos.y - __card->pos_y;
__card->pos_x = e->pos.x;
__card->pos_y = e->pos.y;
__card->result = get_direction(__card->startx, __card->starty, e->pos.x, e->pos.y);
if ((__card->first_result == DIRECTION_NOT_INIT) &&
(__card->result > DIRECTION_NONE)) {
__card->first_result = __card->result;
}
if (__card->result != __card->first_result) {
__card->startx = e->pos.x;
__card->starty = e->pos.y;
__card->first_result = __card->result;
}
__card->move_en = ui_page_move_callback_run();
//左滑侧边栏
#if(TCFG_UI_ENABLE_LEFT_MENU)
if (ui_get_current_window_id() == ID_WINDOW_DIAL && (ui_page_num() == 1)) {
if (__card->result == DIRECTION_RIGHT) {
ui_page_manager_mode_set(1);
} else {
ui_page_manager_mode_set(0);
}
} else {
/* ui_page_manager_mode_set(0); */
}
#endif
int direction_threshold = 0;
if ((abs(e->pos.x - __card->startx) > 15) || (abs(e->pos.y - __card->starty) > 15)) {
direction_threshold = 1;
}
/* log_info("%s (%d %d)(%d %d)",__func__,e->pos.x,e->pos.y,__card->startx,__card->starty); */
page_switch_mode = ui_page_manager_mode_get();
/* log_info("%s %d page:%x page_num:%d result:%d mode:%d", __func__, __LINE__, ui_get_current_window_id(), ui_page_num(), __card->result, page_switch_mode); */
if (!ui_card_get_status() && (__card->move_en != 0) && direction_threshold && ((__card->result == DIRECTION_LEFT) || (__card->result == DIRECTION_RIGHT)) && ((__card->first_result == DIRECTION_LEFT) || (__card->first_result == DIRECTION_RIGHT))) {
if (page_switch_mode) { //禁止右滑
} else { //cube滑动
effect_ret = effmod_hd->ontouch(e);
}
} else if (ui_card_get_status()) {
effect_ret = effmod_hd->ontouch(e);
}
break;
}
//特效接管
if (effect_ret || ui_card_get_status()) {
return 0;
} else {
return ui_event_ontouch(e);
}
}
struct element *p;
struct element *curr_elm = 0;
/*log_debug("<%s>event(%d)pos(%d,%d)\n", __func__, e->event, e->pos.x, e->pos.y);*/
switch (e->event) {
case ELM_EVENT_TOUCH_DOWN:
log_char('D');
ui_page_manager_mode_set(0);
ui_page_down(ui_get_current_window_id(), ui_card_get_move_mode());
if (__card->slide_en) {
ui_page_anim_stop();
#if 0 // 按下后页面还原
__card->slide_en = false;
ui_page_move_stop(ui_get_current_window_id(), ui_card_get_move_mode());
#else // 按下后从当前位置继续开始
__card->slide_en = true;
__card->pos_x = e->pos.x;
__card->pos_y = e->pos.y;
__card->startx = e->pos.x;
__card->starty = e->pos.y;
__card->start_left = g_cur_left;
__card->start_pos_x = __card->startx;
break;
#endif
}
__card->page_in_touchdown = ui_get_current_window_id();
list_for_each_child_element(p, ui_core_get_root()) {
if (!ui_multi_page_check_id(p->id)) {
ASSERT(p->id == __card->page_in_touchdown);
}
}
__card->pos_x = e->pos.x;
__card->pos_y = e->pos.y;
__card->startx = e->pos.x;
__card->starty = e->pos.y;
__card->first_result = DIRECTION_NOT_INIT;
__card->result = DIRECTION_NOT_INIT;
curr_elm = ui_core_get_element_by_id(__card->page_in_touchdown);
g_cur_left = curr_elm->css.left;
__card->start_left = g_cur_left;
__card->start_pos_x = __card->startx;
/* log_info("id:0x%x, start:%d,%d \n", __card->page_in_touchdown, __card->start_left, __card->start_pos_x); */
break;
case ELM_EVENT_TOUCH_MOVE:
IO_FRAME_HIGH();
if (__card->page_in_touchdown != page->id) {
return 0;
}
#if TCFG_PAY_ALIOS_ENABLE
if (ui_get_current_window_id() == ID_WINDOW_ALIPAY) {
extern void alipay_component_show();
alipay_component_show();
}
#endif
log_char('M');
xoffset = e->pos.x - __card->pos_x;
yoffset = e->pos.y - __card->pos_y;
__card->pos_x = e->pos.x;
__card->pos_y = e->pos.y;
{
int offset = e->pos.x - __card->start_pos_x;
int target = __card->start_left + offset;
xoffset = target - g_cur_left;
}
__card->result = get_direction(__card->startx, __card->starty, e->pos.x, e->pos.y);
if ((__card->first_result == DIRECTION_NOT_INIT) &&
(__card->result > DIRECTION_NONE)) {
__card->first_result = __card->result;
}
if (__card->result != __card->first_result) {
__card->startx = e->pos.x;
__card->starty = e->pos.y;
__card->first_result = __card->result;
}
__card->move_en = ui_page_move_callback_run();
//左滑侧边栏
#if(TCFG_UI_ENABLE_LEFT_MENU)
if (ui_get_current_window_id() == ID_WINDOW_DIAL && (ui_page_num() == 1)) {
if (__card->result == DIRECTION_LEFT) {
ui_page_manager_mode_set(1);
} else if (__card->result == DIRECTION_RIGHT) {
ui_page_manager_mode_set(1);
} else {
ui_page_manager_mode_set(0);
}
} else {
/* ui_page_manager_mode_set(0); */
}
page_switch_mode = ui_page_manager_mode_get();
#endif
/* log_info("move_en:%d x_offset:%d result:%d first_result:%d page_switch_mode:%d slide_en:%d g_cur_left:%d", */
/* __card->move_en, xoffset, __card->result, __card->first_result, page_switch_mode, __card->slide_en, g_cur_left); */
#if PAGE_SWITCH_MODE_NOT_LOOP
ui_page_manager_mode_set(SLIDE_MODE_NOT_LOOP);
page_switch_mode = ui_page_manager_mode_get();
#endif
if ((__card->move_en != 0) && (xoffset != 0) && ((__card->result == DIRECTION_LEFT) || (__card->result == DIRECTION_RIGHT)) && ((__card->first_result == DIRECTION_LEFT) || (__card->first_result == DIRECTION_RIGHT))) {
if (page_switch_mode) {//左滑侧边栏
struct ui_page *first_page = ui_page_get_first();
int first_win = first_page->id;
int last_win = ui_page_prev(first_win);
int curr_win = ui_get_current_window_id();
int prev_win = ui_page_prev(curr_win);
int next_win = ui_page_next(curr_win);
if ((page_switch_mode == SLIDE_MODE_NOT_RIGHT_ALL) && (__card->first_result == DIRECTION_RIGHT)) { //所有页面禁止右滑,单向循环
__card->slide_en = false;
} else if ((page_switch_mode == SLIDE_MODE_NOT_RIGHT_FIRST) && (__card->first_result == DIRECTION_RIGHT) && (curr_win == first_win)) { //首页禁止右滑
__card->slide_en = false;
} else if ((page_switch_mode == SLIDE_MODE_NOT_LOOP) && (((g_cur_left + xoffset > 0) && (curr_win == first_win)) || ((g_cur_left + xoffset < 0) && (next_win == first_win)))) {
xoffset = -g_cur_left;
__card->slide_en = true;
ui_page_move(ui_get_current_window_id(), xoffset, yoffset, ui_card_get_move_mode());
} else { //正常滑动
__card->slide_en = true;
ui_page_move(ui_get_current_window_id(), xoffset, yoffset, ui_card_get_move_mode());
}
curr_elm = ui_core_get_element_by_id(ui_get_current_window_id());
if ((__card->slide_en == false) && (curr_elm->css.left != 0)) {
__card->slide_en = true; //屏幕未居中时走自动居中流程,防止卡住
}
if (__card->slide_en) {
return 0;
}
} else {
__card->slide_en = true;
ui_page_move(ui_get_current_window_id(), xoffset, yoffset, ui_card_get_move_mode());
return 0;
}
}
break;
case ELM_EVENT_TOUCH_L_MOVE:
case ELM_EVENT_TOUCH_R_MOVE:
/* case ELM_EVENT_TOUCH_U_MOVE: */
/* case ELM_EVENT_TOUCH_D_MOVE: */
if (page) {
return 0;
}
break;
case ELM_EVENT_TOUCH_UP:
log_char('U');
if (__card->slide_en) {
if (e->has_energy == 0) {
ui_page_set_anim_run_time(300, 100); // 设置过渡动画最大最小时间
struct ui_page_anim_info anim_info = {0};
anim_info.curr_win = ui_get_current_window_id();
anim_info.mode = ui_card_get_move_mode();
anim_info.dir = __card->first_result;
/* anim_info.e = e; */
anim_info.anim_start = ui_card_anim_start;
anim_info.anim_stop = ui_card_anim_stop;
int ret = ui_page_anim_auto(&anim_info);
if (ret) {
__card->slide_en = 0;
}
}
} else {
ui_page_anim_stop();
ui_page_move_stop(ui_get_current_window_id(), ui_card_get_move_mode());
}
break;
case ELM_EVENT_TOUCH_ENERGY:
if (__card->slide_en) {
ui_page_set_anim_run_time(300, 100); // 设置过渡动画最大最小时间
struct ui_page_anim_info anim_info = {0};
anim_info.curr_win = ui_get_current_window_id();
anim_info.mode = ui_card_get_move_mode();
anim_info.dir = __card->first_result;
anim_info.e = e;
anim_info.anim_start = ui_card_anim_start;
anim_info.anim_stop = ui_card_anim_stop;
int ret = ui_page_anim_auto(&anim_info);
if (ret) {
__card->slide_en = 0;
}
}
break;
}
if (__card->slide_en) {
log_debug("<%s> silde_en\n", __func__);
return 0;
}
return ui_event_ontouch(e);
}
#endif
struct ui_msg {
struct list_head entry;
struct touch_event touch;
void(*msg_hook)(u8);
};
struct ui_msg msg_handle;
static void jlui_show_page(void *p)
{
log_info("@@@@@@@@@@@ JLUI SHOW MAIN PAGE...\n");
ui_show(PAGE_2);
/* wdt_enable(); */
#if 0
ui_page_add(PAGE_1);
ui_page_add(PAGE_2);
ui_page_add(PAGE_3);
#endif
}
static void jlui_sec_printf()
{
log_info("jiffies_msec:%d", (int)jiffies_msec());
wdt_clear();
/* void jlui_malloc_ram_info_dump(); */
/* jlui_malloc_ram_info_dump(); */
}
int ui_gif_msg_type_get()
{
u32 msg_type = 0;
ASSERT((UI_MSG_GIF_PLAY <= 0xf) && (UI_MSG_GIF_PLAY > 0X4));
// 只拼4bit的空间 特征值
msg_type |= (UI_MSG_GIF_PLAY << GIF_TYPE_OFFSET) | USER_MASK_TYPE;
return msg_type;
}
int ui_gif_play_post(u16 timer_id, u32 msec, u32 delay, u32 elm_id, u32 task_id)
{
OS_SEM sem;
int msg[8];
u8 need_pend = 0;
if (!(cpu_in_irq() || cpu_irq_disabled())) {
if (strcmp(os_current_task(), UI_TASK_NAME)) {
need_pend = 1;
}
}
msg[0] = ui_gif_msg_type_get() | (timer_id);
msg[1] = timer_id;
msg[2] = msec;
msg[3] = delay;
msg[4] = elm_id;
msg[5] = task_id;
msg[6] = 0;
if (need_pend) {
os_sem_create(&sem, 0);
msg[6] = (int)&sem;
}
if (!post_ui_msg(msg, 7)) {
if (need_pend) {
os_sem_pend(&sem, 0);
}
}
return 0;
}
void ui_hide_current_window_deal(u32 window)
{
if (__card->slide_en) {
ui_page_anim_stop();
ui_page_set_busy(0);
ui_core_clear_pagemove_flag();
__card->slide_en = false;
}
ui_card_run_stop();
dial_sel_exit();
ui_page_switch_effect_stop();
u32 hide_window = window ? window : ui_get_current_window_id();
if (hide_window) {
ui_hide(hide_window);
//如果还有其他页面
if (ui_get_current_window_id()) {
ui_hide(ui_get_current_window_id());
}
}
ui_disp_line_buf_uninit(); //释放绘图buf
ui_gpu_buf_release();
}
static int ui_multi_page_show(int id)
{
struct element *elm = ui_core_get_element_by_id(id);
if (elm) {
return 0;
}
int ret = window_init(id);
if (!ret) {
struct element *elm = ui_core_get_element_by_id(id);
if (!elm) {
return -EINVAL;
}
elm->dc->refresh = false;
ui_core_show(elm, true);
elm->dc->refresh = true;
}
return ret;
}
static int ui_multi_page_hide(int id)
{
struct element *elm = ui_core_get_element_by_id(id);
if (!elm) {
return 0;
}
ui_hide(id);
return 0;
}
static void ui_task(void *p)
{
int top_page_num;
log_info("<%s> init\n", __func__);
clock_lock("ui_show", clk_get_max_frequency());
int msg[32];
int ret;
mem_var_init(3 * 1024, false);
/*表盘管理初始化*/
ui_dial_manage_init();
/*内核初始化*/
ui_framework_init(p);
/*gpu绘图加速初始化*/
jlui_gpu_blend_init();
#if (defined TCFG_UI_BG_ENABLE) && TCFG_UI_BG_ENABLE
/*背景管理初始化*/
ui_csbg_res_check();
#endif
/*卡片管理初始化*/
ui_page_init();
/*设置参数初始化*/
sys_param_init();
ui_sysinfo_init();
/*注册按键事件*/
ui_key_set_send_event_cb(key_event_sent_to_ui_map);
struct ui_style style;
style.file = RES_PATH"JL/JL.sty";
ret = ui_set_style_file(&style);
if (ret) {
log_error("ui task fail!\n");
return;
}
__this->init = 1;
os_sem_post(&(__this->start_sem));
/*debug使用*/
/* sys_timeout_add(NULL, jlui_show_page, 1500); */
/* sys_timer_add(NULL, jlui_sec_printf, 1000); */
//添加自动熄屏定时器
ui_auto_shut_down_enable();
//注册tp扫描定时器
if (__this->touch_event_call && __this->touch_event_interval) {
__this->timer_id = sys_timer_add((void *)NULL, (void *)__this->touch_event_call, __this->touch_event_interval);
}
#if TCFG_UI_LIMIT_ENABLE
ui_limit_create();
#endif
/* sys_timeout_add(NULL,memtest_start,10*1000); */
struct touch_event *touch;
struct element_touch_event t;
struct element_key_event e = {0};
struct ui_msg ui_msg_move;
INIT_LIST_HEAD(&msg_handle.entry);
u8 touch_move_msg = 0;
u32 time_start = 0;
u32 time_end = 0;
while (1) {
time_end = jiffies_msec();
if (time_start && time_end) {
int run_time = time_end - time_start;
int fps = run_time ? (1000 / run_time) : 0;
log_debug("run_time:%d fps:%d ", run_time, fps);
}
ret = os_taskq_pend(NULL, msg, ARRAY_SIZE(msg));
if (ret != OS_TASKQ) {
time_start = 0;
continue;
}
time_start = jiffies_msec();
if (msg[0] == UI_MSG_TOUCH) {
touch = (struct touch_event *)&msg[2];
if (touch->event == ELM_EVENT_TOUCH_MOVE) {
touch_move_msg++;
ui_msg_move.msg_hook = (void (*)(u8))msg[1];
memcpy((u8 *)&ui_msg_move.touch, (u8 *)&msg[2], sizeof(struct touch_event));
} else {
if (touch_move_msg) {
struct ui_msg *ui_msg = (struct ui_msg *)malloc(sizeof(struct ui_msg));
ui_msg->msg_hook = ui_msg_move.msg_hook;
memcpy((u8 *)&ui_msg->touch, (u8 *)&ui_msg_move.touch, sizeof(struct touch_event));
list_add_tail(&ui_msg->entry, &msg_handle.entry);
touch_move_msg = 0;
}
struct ui_msg *ui_msg = (struct ui_msg *)malloc(sizeof(struct ui_msg));
ui_msg->msg_hook = (void (*)(u8))msg[1];
memcpy((u8 *)&ui_msg->touch, (u8 *)&msg[2], sizeof(struct touch_event));
list_add_tail(&ui_msg->entry, &msg_handle.entry);
}
spin_lock(&lock);
__this->touch_msg_counter--;
spin_unlock(&lock);
if (__this->touch_msg_counter) {
continue;
} else {
if (touch_move_msg) {
struct ui_msg *ui_msg = (struct ui_msg *)malloc(sizeof(struct ui_msg));
ui_msg->msg_hook = ui_msg_move.msg_hook;
memcpy((u8 *)&ui_msg->touch, (u8 *)&ui_msg_move.touch, sizeof(struct touch_event));
list_add_tail(&ui_msg->entry, &msg_handle.entry);
touch_move_msg = 0;
}
while (!list_empty(&msg_handle.entry)) {
struct ui_msg *ui_msg = list_first_entry(&msg_handle.entry, struct ui_msg, entry);
touch = (struct touch_event *)&ui_msg->touch;
t.event = touch->event;
t.pos.x = touch->x;
t.pos.y = touch->y;
t.has_energy = touch->has_energy;
if (ui_msg->msg_hook) {
((void(*)(u8))ui_msg->msg_hook)(0);
}
ui_card_ontouch(&t);
/* ui_event_ontouch(&t); */
if (ui_msg->msg_hook) {
((void(*)(u8))ui_msg->msg_hook)(1);
}
list_del(&ui_msg->entry);
free(ui_msg);
}
continue;
}
} else {//其他消息直接处理
if (touch_move_msg) {
struct ui_msg *ui_msg = (struct ui_msg *)malloc(sizeof(struct ui_msg));
ui_msg->msg_hook = ui_msg_move.msg_hook;
memcpy((u8 *)&ui_msg->touch, (u8 *)&ui_msg_move.touch, sizeof(struct touch_event));
list_add_tail(&ui_msg->entry, &msg_handle.entry);
touch_move_msg = 0;
}
while (!list_empty(&msg_handle.entry)) {
struct ui_msg *ui_msg = list_first_entry(&msg_handle.entry, struct ui_msg, entry);
touch = (struct touch_event *)&ui_msg->touch;
t.event = touch->event;
t.pos.x = touch->x;
t.pos.y = touch->y;
t.has_energy = touch->has_energy;
if (ui_msg->msg_hook) {
((void(*)(u8))ui_msg->msg_hook)(0);
}
ui_card_ontouch(&t);
/* ui_event_ontouch(&t); */
if (ui_msg->msg_hook) {
((void(*)(u8))ui_msg->msg_hook)(1);
}
list_del(&ui_msg->entry);
free(ui_msg);
}
}
u8 msg_type = (msg[0] & USER_MASK_TYPE) ? ((msg[0] >> GIF_TYPE_OFFSET) & 0xff) : (msg[0] & 0xff);
switch (/* msg[0] */ msg_type) { //action
case UI_MSG_EXIT:
os_sem_post((OS_SEM *)msg[1]);
os_time_dly(10000);
break;
case UI_MSG_OTHER:
#if (defined TCFG_COLOR_SCREEN_CHARGING_CASE_ENABLE) && TCFG_COLOR_SCREEN_CHARGING_CASE_ENABLE
int ret = ui_message_filter_hook((const char *)msg[1], (void *)&msg[2]);
if (ret) {
break;
}
#endif
if (ui_get_current_window_id() > 0) {
ui_message_handler(ui_get_current_window_id(), (const char *)msg[1], (void *)&msg[2]);
}
#if TCFG_UI_ENABLE_SMARTWIN
struct window *window = (struct window *)ui_core_get_element_by_id(ID_WINDOW_SMARTWIN);
if (window) {
ui_message_handler(ID_WINDOW_SMARTWIN, (const char *)msg[1], (void *)&msg[2]);
}
#endif
break;
case UI_MSG_KEY:
e.value = msg[1];
int key_event_map = 0;
/* 菜单返回划屏过程中,不响应按键事件。避免划屏中按按键跳转导致死机 */
extern int ui_return_page_effect_in_move();
extern int menu_enter_app_state();
if (ui_return_page_effect_in_move() || menu_enter_app_state()) {
break;
}
/*key lock可以使消息直接发往底层,用于部分页面接管按键,退出页面时记得解锁*/
if (!__this->key_lock) {
key_event_map = ui_key_event_deal_app(e.value);
}
/*若应用层不接管,则发给ui框架*/
if (!key_event_map) {
ret = ui_event_onkey(&e);
}
/*若ui框架不接管,则跑默认按键处理*/
if (!ret && !key_event_map) {
ui_default_key_event_deal_app(e.value);
}
break;
case UI_MSG_TOUCH:
touch = (struct touch_event *)&msg[2];
t.event = touch->event;
t.pos.x = touch->x;
t.pos.y = touch->y;
t.has_energy = touch->has_energy;
if (msg[1]) {
((void(*)(u8))msg[1])(0);
}
ui_card_ontouch(&t);
/* ui_event_ontouch(&t); */
if (msg[1]) {
((void(*)(u8))msg[1])(1);
}
break;
case UI_MSG_SHOW:
int bl_ctrl = 0;
if (lcd_sleep_status()) {
lcd_sleep_ctrl(0);//退出低功耗
bl_ctrl = 1;
}
//防止没调用ui_msg_hide
ui_hide_current_window_deal(0);
#if CONFIG_WATCH_CASE_ENABLE || CONFIG_SERIAL_HMI_DISPLAY_CASE_ENABLE
if (msg[1] == ID_WINDOW_DIAL) {
#if TCFG_UI_MENU_LIST_ENABLE
menu_list_rec_clr();
#endif
ui_return_page_effect_set_en(0);
}
UI_WINDOW_BACK_PUSH(msg[1]);
if (!__this->ui_card_slide_dis) { //从菜单进入被添加到卡片的页面时,不清除记录,用于退出
if (ui_page_search(msg[1]) || (msg[1] == ID_WINDOW_POWER_ON)) {
UI_WINDOW_BACK_CLEAN(); // 卡片
if (msg[1] != ID_WINDOW_POWER_ON) {
UI_WINDOW_BACK_PUSH(msg[1]);
}
}
} else {
/*关闭卡片功能时,在表盘清除页面记录*/
if (msg[1] == ID_WINDOW_DIAL) {
#if (defined TCFG_COLOR_SCREEN_CHARGING_CASE_ENABLE) && TCFG_COLOR_SCREEN_CHARGING_CASE_ENABLE
// UI_WINDOW_BACK_CLEAN(); // 卡片
#else
UI_WINDOW_BACK_CLEAN(); // 卡片
#endif
UI_WINDOW_BACK_PUSH(msg[1]);
}
}
#endif
#if (defined TCFG_COLOR_SCREEN_CHARGING_CASE_ENABLE) && TCFG_COLOR_SCREEN_CHARGING_CASE_ENABLE
__this->lcd_bl_idle_flag = 0;//???
#endif
ui_relate_init();
msg[1] = ui_id2remap(msg[1]);
ui_show(msg[1]);
if (bl_ctrl) {
extern void lcd_wait_busy();//等推屏完成,非同步的 */
lcd_wait_busy();
lcd_bl_open();
}
if (msg[2]) {
os_sem_post((OS_SEM *)msg[2]);
}
break;
case UI_MSG_HIDE:
ui_hide_current_window_deal(msg[1]);
void malloc_list_status_printf_all(int index, int count);
/* malloc_list_status_printf_all(0,200); */
if (msg[2]) {
os_sem_post((OS_SEM *)msg[2]);
}
break;
case UI_MSG_SHOW_MULTI_PAGE:
top_page_num = ui_multi_page_get_id_by_prio(-1, NULL);
if (top_page_num > 0) {
int *top_page_tab = (int *)malloc(top_page_num * sizeof(int));
ASSERT(top_page_tab);
ui_multi_page_get_id_by_prio(-1, top_page_tab);
int i;
for (i = 0; i < top_page_num; i++) {
ui_multi_page_show(top_page_tab[i]);
}
free(top_page_tab);
}
if (msg[1]) {
os_sem_post((OS_SEM *)msg[1]);
}
break;
case UI_MSG_HIDE_MULTI_PAGE:
top_page_num = ui_multi_page_get_id_by_prio(-1, NULL);
if (top_page_num > 0) {
int *top_page_tab = (int *)malloc(top_page_num * sizeof(int));
ASSERT(top_page_tab);
ui_multi_page_get_id_by_prio(-1, top_page_tab);
int i;
for (i = 0; i < top_page_num; i++) {
ui_multi_page_hide(top_page_tab[i]);
}
free(top_page_tab);
}
#if (defined TCFG_NANDFLASH_DEV_ENABLE && TCFG_NANDFLASH_DEV_ENABLE)
if (JLUI_MULTI_PAGE_OVERLAY_SUPPORT) {
jlgpu_scheduler_async_gpu_cache_free_resident();
}
#endif
if (msg[1]) {
os_sem_post((OS_SEM *)msg[1]);
}
break;
case UI_MSG_GIF_PLAY:
u16 timer_id = (u16)msg[1];
u32 msec = msg[2];
u32 gif_delay = msg[3];
u32 elm_id = msg[4];
u32 task_id = msg[5];
u32 delay = jiffies_msec() - msec;
int pagemove = ui_page_get_busy();
if (!pagemove && (delay < gif_delay)) {
gif_play(elm_id, task_id);
} else {
printf("drop gif frame ! pagemove %d, delay %d, gif_delay %d\n", pagemove, delay, gif_delay);
}
if (msg[6]) {
os_sem_post((OS_SEM *)msg[6]);
}
break;
case UI_TIME_TOUCH_RESUME:
#if (TCFG_UI_ENABLE&&(CONFIG_UI_STYLE == STYLE_JL_SOUNDBOX))
if (!lcd_backlight_status()) {
/* set_backlight_time(get_backlight_time_item());//防止在息屏状态下跳转到PC模式后不亮屏 */
}
#endif
if (lcd_sleep_status()) {
lcd_sleep_ctrl(false);
/* lcd_backlight_ctrl(true); */
}
set_screen_saver_status(0);
if (__ui_display.timer_id) {
break;
}
if (__ui_display.touch_event_call && __ui_display.touch_event_interval) {
__ui_display.timer_id = sys_timer_add((void *)NULL, (void *)__ui_display.touch_event_call, __ui_display.touch_event_interval); //注册按键扫描定时器
}
break;
case UI_TIME_TOUCH_SUPEND:
if (__ui_display.timer_id) {
sys_timer_del(__ui_display.timer_id);
__ui_display.timer_id = 0;
}
if (!get_standby_watch_en()) {
#if (defined TCFG_COLOR_SCREEN_CHARGING_CASE_ENABLE) && TCFG_COLOR_SCREEN_CHARGING_CASE_ENABLE
// lcd_clear(0, 0, lcd_get_screen_width() - 1, 0, lcd_get_screen_height() - 1);
#else
lcd_clear(0, 0, lcd_get_screen_width() - 1, 0, lcd_get_screen_height() - 1);
#endif
lcd_sleep_ctrl(true);
ui_relate_uninit();
__this->lcd_bl_idle_flag = 1;
/* malloc_list_status_printf_all(200); */
//lcd_backlight_ctrl(false);
}
set_screen_saver_status(1);
break;
default:
break;
}
}
}
int lcd_ui_init(void *arg)
{
int err = 0;
/* clock_alloc("ui_clk", 159 * 1000000UL); */
mem_var_init(MEM_VAR_SIZE, false);
os_sem_create(&(__this->start_sem), 0);
err = task_create(ui_task, arg, UI_TASK_NAME);
os_sem_pend(&(__this->start_sem), 0);
if (err) {
log_error("<%s> error:%d\n", __func__, err);
} else {
log_info("<%s> succ\n", __func__);
}
return err;
}
static void lcd_poweroff_uninit()
{
#if TCFG_UI_ENABLE
if (get_ui_init_status()) { // 判断是否初始化了ui
if (lcd_sleep_status() == 0) {
UI_HIDE_CURR_WINDOW();
lcd_sleep_ctrl(1);
struct lcd_interface *lcd = lcd_get_hdl();
if (lcd->power_ctrl) {
lcd->power_ctrl(false);
}
}
}
#endif
}
platform_uninitcall(lcd_poweroff_uninit);
#if (defined TCFG_COLOR_SCREEN_CHARGING_CASE_ENABLE) && TCFG_COLOR_SCREEN_CHARGING_CASE_ENABLE
/**
* @brief 彩屏仓,重新切换背景图片时候
* 先hide页面 -> 先资源释放 加载新资源 -> show原来页面
*
*/
void csbg_reload_handler(void)
{
int cur_id;
log_info("<%s>", __func__);
/*参考UI_MSG_HIDE消息处理 隐藏当前页面*/
if (__card->slide_en) {
ui_page_anim_stop();
ui_page_set_busy(0);
ui_core_clear_pagemove_flag();
__card->slide_en = false;
}
cur_id = UI_GET_WINDOW_ID();
if (cur_id != -1) {
ui_hide(cur_id);
}
if (UI_GET_WINDOW_ID() != -1) {
ui_hide(UI_GET_WINDOW_ID());
}
log_info("cur_id:%x", cur_id);
/*更新图片资源*/
csbg_change_handler(CSBG_TYPE_WALLPAPER);
/*参考UI_MSG_SHOW消息处理 隐藏当前页面*/
if (__card->slide_en) {
ui_page_anim_stop();
ui_page_set_busy(0);
ui_core_clear_pagemove_flag();
__card->slide_en = false;
}
if (cur_id == -1) {
goto __end;
}
ui_show(cur_id);
__end:
return;
}
static int nowcardpage = 0;
int ui_page_set_curr_deal(int curr_id)
{
log_info("%s %d", __func__, __LINE__);
nowcardpage = curr_id;
return 0;
}
bool cpc_is_card_page(int mem_id)
{
extern u32 ui_show_page_list[20];
for (int i = 0; i < ARRAY_SIZE(ui_show_page_list); i++) {
if (ui_show_page_list[i] == mem_id) {
return true;
}
}
return false;
}
void cpc_go_to_history_card()
{
ui_card_enable();
if (nowcardpage != 0) {
UI_WINDOW_BACK_CLEAN(); // 卡片
UI_HIDE_CURR_WINDOW();
UI_SHOW_WINDOW(nowcardpage);
return;
}
UI_WINDOW_BACK_CLEAN(); // 卡片
UI_HIDE_CURR_WINDOW();
UI_SHOW_WINDOW(ID_WINDOW_MUSIC_PLAYER);
}
#else//watch
int ui_page_set_curr_deal(int curr_id)
{
#if TCFG_VIDEO_DIAL_ENABLE
if (curr_id == ID_WINDOW_DIAL) {
if (get_aviplay_handle() != NULL) {
/* avi_resume(avi_player->st); */
avi_resume();
}
}
#endif
UI_WINDOW_BACK_CLEAN(); // 卡片
UI_WINDOW_BACK_PUSH(curr_id);
return 0;
}
#endif
#else
int key_is_ui_takeover()
{
return 0;
}
void key_ui_takeover(u8 on)
{
}
int ui_key_msg_post(int key)
{
return 0;
}
int ui_touch_msg_post(struct touch_event *event)
{
return 0;
}
int ui_touch_msg_post_withcallback(struct touch_event *event, void (*cb)(u8 finish))
{
return 0;
}
void ui_touch_timer_delete()
{
}
void ui_touch_timer_start()
{
}
void ui_backlight_ctrl(u8 lcd_open_flag)
{
}
void ui_auto_shut_down_re_run(void)
{
}
#endif
#endif