#include "include.h" #include "func.h" #include "m_storage.h" #define TRACE_EN 1 #if TRACE_EN #define TRACE(...) printf(__VA_ARGS__) #else #define TRACE(...) #endif #define SEC_TO_HOUR(s) (s / 3600) //总秒数转换为时分秒(时) #define SEC_TO_MIN(s) ((s % 3600) / 60) //总秒数转换为时分秒(分) #define SEC_TO_SEC(s) (s % 60) //总秒数转换为时分秒(秒) //显示页面 enum { TIMER_PAGE_SELECT, //选择计时器 6个小圆一个自定义 TIMER_PAGE_CUSTOM, //自定义设置界面加减 TIMER_PAGE_COUNTDOWN, //计时进行中 播放暂停重启 }; //计时状态 enum { TIMER_STA_IDLE, TIMER_STA_WORKING, TIMER_STA_PAUSE, TIMER_STA_DONE, TIMER_STA_RESET, }; //组件ID enum { ///PAGE_SELECT //按键 COMPO_ID_BTN_1MIN = 1, COMPO_ID_BTN_2MIN = 2, COMPO_ID_BTN_3MIN = 3, COMPO_ID_BTN_5MIN = 5, COMPO_ID_BTN_10MIN = 10, COMPO_ID_BTN_30MIN = 30, COMPO_ID_BTN_CUSTOM, ///PAGE_CUSTOM //按键 COMPO_ID_BTN_HOUR_INC, //时+ COMPO_ID_BTN_MIN_INC, //分+ COMPO_ID_BTN_SEC_INC, //秒+ COMPO_ID_BTN_HOUR_RED, //时- COMPO_ID_BTN_MIN_RED, //分- COMPO_ID_BTN_SEC_RED, //秒- COMPO_ID_BTN_OK, //ok //数字 COMPO_ID_NUM_CUSTOM, ///PAGE_COUNTDOWN //按键 COMPO_ID_BTN_START, COMPO_ID_BTN_NO, //数字 COMPO_ID_NUM_COUNTDOWN, }; typedef struct f_timer_t_ { u8 page_disp; s8 hour; s8 min; s8 sec; } f_timer_t; //item列表,创建时遍历一下 typedef struct timer_btn_item_t_ { u32 res_addr; u16 btn_id; s16 x; s16 y; bool visible_en; } timer_btn_item_t; typedef struct timer_txt_item_t_ { const char *text; u16 max_word_cnt; s16 x; s16 y; bool visible_en; } timer_txt_item_t; typedef struct timer_pic_item_t_ { u32 res_addr; u16 pic_id; s16 x; s16 y; bool visible_en; } timer_pic_item_t; static co_timer_t timer_timer; //PAGE_SELECT #define TIMER_BTN_ITEM_CNT ((int)(sizeof(tbl_timer_btn_item) / sizeof(tbl_timer_btn_item[0]))) static const timer_btn_item_t tbl_timer_btn_item[] = { {UI_BUF_COMMON_START_BIN, COMPO_ID_BTN_1MIN, 22, 28+20, true}, {UI_BUF_COMMON_START_BIN, COMPO_ID_BTN_2MIN, 64, 28+20, true}, {UI_BUF_COMMON_START_BIN, COMPO_ID_BTN_3MIN, 106, 28+20, true}, {UI_BUF_COMMON_START_BIN, COMPO_ID_BTN_5MIN, 22, 75+20, true}, {UI_BUF_COMMON_START_BIN, COMPO_ID_BTN_10MIN, 64, 75+20, true}, {UI_BUF_COMMON_START_BIN, COMPO_ID_BTN_30MIN, 106, 75+20, true}, {UI_BUF_COMMON_START_BIN, COMPO_ID_BTN_CUSTOM, 64, 122+13, true}, }; #define TIMER_TXT_ITEM_CNT ((int)(sizeof(tbl_timer_txt_item) / sizeof(tbl_timer_txt_item[0]))) static const timer_txt_item_t tbl_timer_txt_item[] = { {"1", 4, 22, 28+20, true}, {"2", 4, 64, 28+20, true}, {"3", 4, 106, 28+20, true}, {"5", 4, 22, 75+20, true}, {"10", 5, 64, 75+20, true}, {"30", 5, 106, 75+20, true}, {"Custom", 30, 64, 122+13, true}, }; //PAGE_CUSTOM #define TIMER_CUSTOM_BTN_ITEM_CNT ((int)(sizeof(tbl_timer_custom_btn_item) / sizeof(tbl_timer_custom_btn_item[0]))) static const timer_btn_item_t tbl_timer_custom_btn_item[] = { {UI_BUF_COMMON_INCREASE_BIN, COMPO_ID_BTN_HOUR_INC, 22, 43, true}, {UI_BUF_COMMON_INCREASE_BIN, COMPO_ID_BTN_MIN_INC, 64, 43, true}, {UI_BUF_COMMON_INCREASE_BIN, COMPO_ID_BTN_SEC_INC, 106, 43, true}, {UI_BUF_COMMON_REDUCE_BIN, COMPO_ID_BTN_HOUR_RED, 22, 95, true}, {UI_BUF_COMMON_REDUCE_BIN, COMPO_ID_BTN_MIN_RED, 64, 95, true}, {UI_BUF_COMMON_REDUCE_BIN, COMPO_ID_BTN_SEC_RED, 106, 95, true}, {UI_BUF_COMMON_REDUCE_BIN, COMPO_ID_BTN_OK, 64, 135, true}, }; static u32 func_timer_tick_get(void) { return sys_cb.timer_tick; } static u32 func_timer_tick_reset(void) { sys_cb.timer_tick = 0; } //创建定时器窗体,文件内调用 static compo_form_t *func_timer_form_create_by_type(u8 page_type) { u8 hour, min, sec; u32 res_addr; char str_buff[30]; compo_button_t *btn; compo_textbox_t *txt; compo_shape_t *shape; //新建窗体和背景 compo_form_t *frm = compo_form_create(true); //设置标题栏 compo_form_set_mode(frm, COMPO_FORM_MODE_SHOW_TITLE | COMPO_FORM_MODE_SHOW_TIME); compo_form_set_title(frm, i18n[STR_TIMER]); switch (page_type) { case TIMER_PAGE_SELECT: for (u8 idx = 0; idx < TIMER_BTN_ITEM_CNT; idx++) { if(idx != (TIMER_BTN_ITEM_CNT-1)) { //创建圆形 shape = compo_radius_shape_create(frm, COMPO_SHAPE_TYPE_ROUNDED_RECTANGLE,20); compo_shape_set_color(shape, make_color(75, 75, 75)); compo_shape_set_location(shape, tbl_timer_btn_item[idx].x, tbl_timer_btn_item[idx].y, 40, 40); //创建按钮 btn = compo_button_create(frm); compo_setid(btn, tbl_timer_btn_item[idx].btn_id); compo_button_set_location(btn, tbl_timer_btn_item[idx].x, tbl_timer_btn_item[idx].y, 40, 40); } else { //创建下方矩形 shape = compo_radius_shape_create(frm, COMPO_SHAPE_TYPE_ROUNDED_RECTANGLE,16); compo_shape_set_color(shape, make_color(30, 230, 150)); compo_shape_set_location(shape, tbl_timer_btn_item[idx].x, tbl_timer_btn_item[idx].y, 114, 26); //创建按钮 btn = compo_button_create(frm); compo_setid(btn, tbl_timer_btn_item[idx].btn_id); compo_button_set_location(btn, tbl_timer_btn_item[idx].x, tbl_timer_btn_item[idx].y, 114, 26); } } // 创建文本 for (u8 idx = 0; idx < TIMER_TXT_ITEM_CNT; idx++) { txt = compo_textbox_create(frm, tbl_timer_txt_item[idx].max_word_cnt); compo_textbox_set_pos(txt, tbl_timer_txt_item[idx].x, tbl_timer_txt_item[idx].y); if(idx == (TIMER_TXT_ITEM_CNT - 1) ) { compo_textbox_set(txt, i18n[STR_CUSTOM]); } else{ snprintf(str_buff, sizeof(str_buff), "%s%s", tbl_timer_txt_item[idx].text, i18n[STR_MIN_SIMPLY]); compo_textbox_set(txt, str_buff); } compo_textbox_set_visible(txt, tbl_timer_txt_item[idx].visible_en); } break; case TIMER_PAGE_CUSTOM: //创建按钮 for (u8 idx = 0; idx < TIMER_CUSTOM_BTN_ITEM_CNT; idx++) { if(idx != (TIMER_CUSTOM_BTN_ITEM_CNT-1)){ btn = compo_button_create_by_image(frm, tbl_timer_custom_btn_item[idx].res_addr); compo_setid(btn, tbl_timer_custom_btn_item[idx].btn_id); compo_button_set_pos(btn, tbl_timer_custom_btn_item[idx].x, tbl_timer_custom_btn_item[idx].y); compo_button_set_visible(btn, tbl_timer_custom_btn_item[idx].visible_en); } else{ //创建下方矩形 shape = compo_radius_shape_create(frm, COMPO_SHAPE_TYPE_ROUNDED_RECTANGLE,16); compo_shape_set_color(shape, make_color(30, 230, 150)); compo_shape_set_location(shape, tbl_timer_custom_btn_item[idx].x, tbl_timer_custom_btn_item[idx].y, 114, 26); //创建按钮 btn = compo_button_create(frm); compo_setid(btn, tbl_timer_custom_btn_item[idx].btn_id); compo_button_set_location(btn, tbl_timer_custom_btn_item[idx].x, tbl_timer_custom_btn_item[idx].y, 114, 26); } } //创建数字 hour = SEC_TO_HOUR(sys_cb.timer_custom_sec); min = SEC_TO_MIN(sys_cb.timer_custom_sec); sec = SEC_TO_SEC(sys_cb.timer_custom_sec); txt = compo_textbox_create(frm, 12); compo_setid(txt, COMPO_ID_NUM_CUSTOM); compo_textbox_set_pos(txt, GUI_SCREEN_CENTER_X, GUI_SCREEN_CENTER_Y-14); compo_textbox_set_font(txt, UI_BUF_0FONT_FONT_DIN_PRO_NUM_20_BIN); snprintf(str_buff, sizeof(str_buff), "%02d:%02d:%02d", hour, min, sec); compo_textbox_set(txt, str_buff); //创建文本 txt = compo_textbox_create(frm, 3); compo_textbox_set_pos(txt, GUI_SCREEN_CENTER_X, 135); compo_textbox_set(txt, "OK"); break; case TIMER_PAGE_COUNTDOWN: //新建按钮 res_addr = sys_cb.timer_sta == TIMER_STA_WORKING ? UI_BUF_COMMON_PAUSE_BIN : (sys_cb.timer_sta == TIMER_STA_DONE ? UI_BUF_COMMON_RESET_BIN : UI_BUF_COMMON_START_BIN); btn = compo_button_create_by_image(frm, res_addr); //start/pause/again compo_setid(btn, COMPO_ID_BTN_START); compo_button_set_pos(btn, 100, GUI_SCREEN_HEIGHT-29); btn = compo_button_create_by_image(frm, UI_BUF_COMMON_BACK_BIN); //close compo_setid(btn, COMPO_ID_BTN_NO); compo_button_set_pos(btn, 28, GUI_SCREEN_HEIGHT-29); //新建数字 hour = SEC_TO_HOUR(sys_cb.timer_left_sec); min = SEC_TO_MIN(sys_cb.timer_left_sec); sec = SEC_TO_SEC(sys_cb.timer_left_sec); txt = compo_textbox_create(frm, 50); compo_setid(txt, COMPO_ID_NUM_COUNTDOWN); // compo_textbox_set_pos(txt, GUI_SCREEN_CENTER_X, GUI_SCREEN_CENTER_Y-14); compo_textbox_set_location(txt, GUI_SCREEN_CENTER_X, 57+9, GUI_SCREEN_WIDTH-10, GUI_SCREEN_HEIGHT/3); compo_textbox_set_font(txt, UI_BUF_0FONT_FONT_DIN_PRO_NUM_20_BIN); snprintf(str_buff, sizeof(str_buff), "%02d:%02d:%02d", hour, min, sec); compo_textbox_set(txt, str_buff); break; default: break; } return frm; } //创建定时器窗体,创建窗体中不要使用功能结构体 func_cb.f_cb compo_form_t *func_timer_form_create(void) { compo_form_t *frm = NULL; switch (sys_cb.timer_sta) { case TIMER_STA_IDLE: frm = func_timer_form_create_by_type(TIMER_PAGE_SELECT); break; case TIMER_STA_WORKING: case TIMER_STA_PAUSE: case TIMER_STA_DONE: case TIMER_STA_RESET: frm = func_timer_form_create_by_type(TIMER_PAGE_COUNTDOWN); break; default: break; } return frm; } //触摸按钮效果处理 static void func_timer_button_touch_handle(void) { compo_button_t *btn; int id = compo_get_button_id(); switch (id) { case COMPO_ID_BTN_START: btn = compo_getobj_byid(COMPO_ID_BTN_START); if (sys_cb.timer_sta == TIMER_STA_WORKING) { // compo_button_set_bgimg(btn, UI_BUF_COMMON_PAUSE_CLICK_BIN); } else if (sys_cb.timer_sta == TIMER_STA_DONE) { ; } else { // compo_button_set_bgimg(btn, UI_BUF_COMMON_START_CLICK_BIN); } break; case COMPO_ID_BTN_NO: btn = compo_getobj_byid(COMPO_ID_BTN_NO); // compo_button_set_bgimg(btn, UI_BUF_COMMON_NO_CLICK_BIN); break; default: break; } } //释放按钮效果处理 static void func_timer_button_release_handle(void) { u32 res_addr; compo_button_t *btn; if ((btn = compo_getobj_byid(COMPO_ID_BTN_START)) != NULL) { res_addr = sys_cb.timer_sta == TIMER_STA_WORKING ? UI_BUF_COMMON_PAUSE_BIN : (sys_cb.timer_sta == TIMER_STA_DONE ? UI_BUF_COMMON_RESET_BIN : UI_BUF_COMMON_START_BIN); compo_button_set_bgimg(btn, res_addr); } if ((btn = compo_getobj_byid(COMPO_ID_BTN_NO)) != NULL) { compo_button_set_bgimg(btn, UI_BUF_COMMON_BACK_BIN); } } //100ms计时器秒数刷新回调函数 static void timer_100ms_pro(co_timer_t *timer, void *param) { bool done = false; if (sys_cb.timer_sta == TIMER_STA_WORKING) { if (sys_cb.timer_left_sec == 0) { done = true; } /* 1s更新时间 */ sys_cb.timer_left_sec = sys_cb.timer_total_sec - ((func_timer_tick_get() + sys_cb.timer_temp_tick) / 1000); if (sys_cb.timer_left_sec <= 0) { done = true; } } if (done) { printf(">>>TIMER_DONE\n"); sys_cb.timer_sta = TIMER_STA_DONE; if (sys_cb.gui_sleep_sta) { sys_cb.gui_need_wakeup = 1; } sys_cb.motor_flag = 1; set_func_motor(80, 10, 0, 1); } } //单击按钮 static void func_timer_button_click(void) { f_timer_t *f_timer = (f_timer_t*)func_cb.f_cb; u8 page_next = f_timer->page_disp; int id = compo_get_button_id(); switch (f_timer->page_disp) { case TIMER_PAGE_SELECT: switch (id) { case COMPO_ID_BTN_1MIN: case COMPO_ID_BTN_2MIN: case COMPO_ID_BTN_3MIN: case COMPO_ID_BTN_5MIN: case COMPO_ID_BTN_10MIN: case COMPO_ID_BTN_30MIN: sys_cb.timer_temp_tick = 0; sys_cb.timer_left_sec = sys_cb.timer_total_sec = id * 60; sys_cb.timer_sta = TIMER_STA_RESET; page_next = TIMER_PAGE_COUNTDOWN; break; case COMPO_ID_BTN_CUSTOM: f_timer->hour = SEC_TO_HOUR(sys_cb.timer_custom_sec); f_timer->min = SEC_TO_MIN(sys_cb.timer_custom_sec); f_timer->sec = SEC_TO_SEC(sys_cb.timer_custom_sec); page_next = TIMER_PAGE_CUSTOM; break; default: break; } break; case TIMER_PAGE_CUSTOM: switch (id) { case COMPO_ID_BTN_HOUR_INC: case COMPO_ID_BTN_HOUR_RED: f_timer->hour = (f_timer->hour + (id == COMPO_ID_BTN_HOUR_INC ? 1 : -1)) % 24; f_timer->hour = f_timer->hour < 0 ? 23 : f_timer->hour; break; case COMPO_ID_BTN_MIN_INC: case COMPO_ID_BTN_MIN_RED: f_timer->min = (f_timer->min + (id == COMPO_ID_BTN_MIN_INC ? 1 : -1)) % 60; f_timer->min = f_timer->min < 0 ? 59 : f_timer->min; break; case COMPO_ID_BTN_SEC_INC: case COMPO_ID_BTN_SEC_RED: f_timer->sec = (f_timer->sec + (id == COMPO_ID_BTN_SEC_INC ? 1 : -1)) % 60; f_timer->sec = f_timer->sec < 0 ? 59 : f_timer->sec; break; case COMPO_ID_BTN_OK: sys_cb.timer_temp_tick = 0; sys_cb.timer_left_sec = sys_cb.timer_total_sec = sys_cb.timer_custom_sec = f_timer->hour * 3600 + f_timer->min * 60 + f_timer->sec; if(sys_cb.timer_left_sec ==0 && sys_cb.timer_total_sec == 0 && sys_cb.timer_custom_sec == 0) { return; } sys_cb.timer_sta = TIMER_STA_RESET; page_next = TIMER_PAGE_COUNTDOWN; break; default: break; } break; case TIMER_PAGE_COUNTDOWN: switch (id) { case COMPO_ID_BTN_START: if (sys_cb.timer_sta == TIMER_STA_WORKING) { sys_cb.timer_sta = TIMER_STA_PAUSE; sys_cb.timer_temp_tick += func_timer_tick_get(); } else if (sys_cb.timer_sta == TIMER_STA_DONE) { sys_cb.timer_left_sec = sys_cb.timer_total_sec; sys_cb.timer_temp_tick = 0; sys_cb.timer_sta = TIMER_STA_RESET; } else { if (sys_cb.timer_sta == TIMER_STA_RESET) { co_timer_set(&timer_timer, 100, TIMER_REPEAT, LEVEL_LOW_PRI, timer_100ms_pro, NULL); } sys_cb.timer_sta = TIMER_STA_WORKING; func_timer_tick_reset(); } break; case COMPO_ID_BTN_NO: co_timer_del(&timer_timer); sys_cb.timer_sta = TIMER_STA_IDLE; sys_cb.timer_left_sec = sys_cb.timer_total_sec = 0; page_next = TIMER_PAGE_SELECT; break; default: break; } break; default: break; } func_timer_button_release_handle(); if (page_next != f_timer->page_disp) { f_timer->page_disp = page_next; compo_form_destroy(func_cb.frm_main); func_cb.frm_main = func_timer_form_create_by_type(f_timer->page_disp); } // TRACE("page[%d] sta[%d]\n", f_timer->page_disp, sys_cb.timer_sta); } //定时器功能事件处理 static void func_timer_process(void) { u8 hour, min, sec; char str_buff[24] = {0}; char done_buff[80] = {0}; compo_textbox_t *txt_num; compo_button_t *btn; f_timer_t *f_timer = (f_timer_t*)func_cb.f_cb; switch (f_timer->page_disp) { case TIMER_PAGE_CUSTOM: txt_num = compo_getobj_byid(COMPO_ID_NUM_CUSTOM); snprintf(str_buff, sizeof(str_buff), "%02d:%02d:%02d", f_timer->hour, f_timer->min, f_timer->sec); compo_textbox_set(txt_num, str_buff); break; case TIMER_PAGE_COUNTDOWN: hour = SEC_TO_HOUR(sys_cb.timer_left_sec); min = SEC_TO_MIN(sys_cb.timer_left_sec); sec = SEC_TO_SEC(sys_cb.timer_left_sec); if (f_timer->sec != sec || f_timer->min != min || f_timer->hour != hour) { f_timer->sec = sec; f_timer->min = min; f_timer->hour = hour; txt_num = compo_getobj_byid(COMPO_ID_NUM_COUNTDOWN); if (sys_cb.timer_sta == TIMER_STA_DONE) { compo_textbox_set_font(txt_num, UI_BUF_0FONT_FONT_BIN); snprintf(str_buff, sizeof(str_buff), "%02d:%02d:%02d", SEC_TO_HOUR(sys_cb.timer_total_sec), SEC_TO_MIN(sys_cb.timer_total_sec), SEC_TO_SEC(sys_cb.timer_total_sec)); snprintf(done_buff, sizeof(done_buff), i18n[STR_COUNTDOWN_ENDS], str_buff); compo_textbox_set(txt_num, done_buff); } else { compo_textbox_set_font(txt_num, UI_BUF_0FONT_FONT_DIN_PRO_NUM_20_BIN); snprintf(str_buff, sizeof(str_buff), "%02d:%02d:%02d", f_timer->hour, f_timer->min, f_timer->sec); compo_textbox_set(txt_num, str_buff); } } if (sys_cb.timer_sta == TIMER_STA_DONE) { btn = compo_getobj_byid(COMPO_ID_BTN_START); compo_button_set_bgimg(btn, UI_BUF_COMMON_RESET_BIN); } break; default: break; } func_process(); } static void timer_data_reset(void) { f_timer_t *f_timer = (f_timer_t *)func_cb.f_cb; u8 page_next = f_timer->page_disp; if (co_timer_handle_is_valid(&timer_timer)) { co_timer_del(&timer_timer); } page_next = TIMER_PAGE_SELECT; sys_cb.timer_sta = TIMER_STA_IDLE; sys_cb.timer_left_sec = sys_cb.timer_total_sec = 0; sys_cb.timer_temp_tick = 0; func_timer_button_release_handle(); } //定时器功能消息处理 static void func_timer_message(size_msg_t msg) { f_timer_t *f_timer = (f_timer_t*)func_cb.f_cb; u8 page_next = f_timer->page_disp; switch (msg) { case MSG_CTP_TOUCH: func_timer_button_touch_handle(); break; case MSG_CTP_CLICK: func_timer_button_click(); break; case KU_BACK: case KU_LEFT: if (sys_cb.timer_sta == TIMER_STA_WORKING) { sys_cb.timer_sta = TIMER_STA_PAUSE; sys_cb.timer_temp_tick += func_timer_tick_get(); func_timer_button_release_handle(); } else { func_message(msg); if (func_cb.sta != FUNC_TIMER) { timer_data_reset(); } } break; case KU_RIGHT: break; case MSG_CTP_SHORT_UP: case MSG_CTP_SHORT_DOWN: case MSG_CTP_LONG: func_timer_button_release_handle(); if (func_cb.flag_sort) { func_message(msg); } break; case MSG_CTP_SHORT_LEFT: case MSG_CTP_SHORT_RIGHT: if (sys_cb.timer_sta == TIMER_STA_WORKING) { sys_cb.timer_sta = TIMER_STA_PAUSE; sys_cb.timer_temp_tick += func_timer_tick_get(); func_timer_button_release_handle(); } else { func_message(msg); if (func_cb.sta != FUNC_TIMER) { timer_data_reset(); } } break; default: func_message(msg); break; } } //进入定时器功能 static void func_timer_enter(void) { func_cb.f_cb = func_zalloc(sizeof(f_timer_t)); func_cb.frm_main = func_timer_form_create(); f_timer_t *f_timer = (f_timer_t*)func_cb.f_cb; f_timer->page_disp = sys_cb.timer_sta == TIMER_STA_IDLE ? TIMER_PAGE_SELECT : TIMER_PAGE_COUNTDOWN; } //退出定时器功能 static void func_timer_exit(void) { bsp_motor_stop(MOTOR_PORT); } //定时器功能 void func_timer(void) { printf("%s\n", __func__); func_timer_enter(); while (func_cb.sta == FUNC_TIMER) { func_timer_process(); func_timer_message(msg_dequeue()); } func_timer_exit(); }