#if 1 #include "include.h" #include "func.h" #include "app_variable.h" #include "m_sportInfo.h" #include "tjd_char_conver.h" #define TRACE_EN 0 #if TRACE_EN #define TRACE(...) printf(__VA_ARGS__) #else #define TRACE(...) #endif static void func_smartstack_card_refresh(u8 draw, s32 move); #define DOCK_FUNC_MAX_NUM (34) //卡片内支持的总数量 #define CARD_RECT_COUNT_MAX (2) //卡片内支持的rect数量 #define CARD_ICON_COUNT_MAX (2) //卡片内支持的icon数量 #define CARD_TEXT_COUNT_MAX (1) //卡片内支持的text数量 #define AUTO_TICK_EXPIRE (10) //自动滚动单位时间 #define AUTO_MOVE_Y_EXPIRE (10) //自动滚动单位距离 #define MID_CARD_FUNC_INIT_INDEX (2) //中间卡片加载的堆栈记录索引(从1开始) #define AUTO_ROLL_MOMENT (5) //滚动惯性动量 /* 卡片标题参数 */ #define DOCK_TITLE_TEXT_X (-50) #define DOCK_TITLE_TEXT_Y (-110) #define DOCK_TITLE_TEXT_W (150) #define DOCK_TITLE_TEXT_H (30) #define DOCK_BG_SHADOW_W (5) /* 删除功能参数 */ #define DOCK_DEL_UP_CARD_OFFSET (16.0) #define DOCK_DEL_DOWN_CARD_OFFSET (60.0) // 组件ID enum { COMPO_ID_BTN_DEL = 0x10, COMPO_ID_PIC_NONE_BG, COMPO_ID_CARD_UP_BK, COMPO_ID_CARD_UP_DISP, COMPO_ID_CARD_MID, COMPO_ID_CARD_DOWN_BK, COMPO_ID_CARD_DOWN_DISP, }; // 卡片位置 enum { CARD_POS_UP, CARD_POS_MID, CARD_POS_DOWN, CARD_POS_OVER, }; // 操作卡片 enum { CARD_DRAW_REFRESH, CARD_DRAW_MOVE_X, CARD_DRAW_MOVE_Y, }; typedef struct dock_res_info_t_ { u32 func_sta; u32 img_res; u32 str_res; } dock_res_info_t; typedef struct dock_list_info_t_ { u8 func_sta_num; u32 func_sta_list[DOCK_FUNC_MAX_NUM]; } dock_list_info_t; static dock_list_info_t dock_list = {0}; // 功能结构体 typedef struct f_smartstack_t_ { /* 卡片移动参数 */ bool flag_drag; int8_t mid_index; int8_t del_index; s32 last_move_y; s32 last_move_x; s32 auto_move_y; u32 last_tick; } f_smartstack_t; /* Dock info */ static const dock_res_info_t dock_info[DOCK_FUNC_MAX_NUM] = { {FUNC_HEARTRATE, UI_BUF_ICON_HEART_RATE_BIN, STR_HEART_RATE}, //心率 {FUNC_BT, UI_BUF_ICON_MUSIC_BIN, STR_MUSIC}, //蓝牙播放器(控制手机音乐) {FUNC_ALARM_CLOCK, UI_BUF_ICON_ALARM_CLOCK_BIN, STR_ALARM_CLOCK}, //闹钟 {FUNC_BLOOD_OXYGEN, UI_BUF_ICON_BLOOD_OXYGEN_BIN, STR_BLOOD_OXYGEN}, //血氧 {FUNC_BLOOD_PRESSURE, UI_BUF_ICON_BLOOD_PRESSURE_BIN, STR_BLOOD_PRESSURE}, //血压 {FUNC_BREATHE, UI_BUF_ICON_BREATHE_BIN, STR_BREATHE}, //呼吸 {FUNC_CALCULATOR, UI_BUF_ICON_CALCULATOR_BIN, STR_CALCULATOR}, //计算器 {FUNC_CAMERA, UI_BUF_ICON_CAMERA_BIN, STR_CAMERA}, //相机 {FUNC_TIMER, UI_BUF_ICON_TIMER_BIN, STR_TIMER}, //定时器 {FUNC_SLEEP, UI_BUF_ICON_SLEEP_BIN, STR_SLEEP}, //睡眠 {FUNC_STOPWATCH, UI_BUF_ICON_STOPWATCH_BIN, STR_STOP_WATCH}, //秒表 {FUNC_WEATHER, UI_BUF_ICON_WEATHER_BIN, STR_WEATHER}, //天气 {FUNC_GAME, UI_BUF_ICON_BIRD_BIN, STR_BIRDIE_FLIGHT}, //游戏 {FUNC_MESSAGE, UI_BUF_ICON_MESSAGE_BIN, STR_MESSAGE}, //消息 {FUNC_SCAN, UI_BUF_ICON_SCAN_BIN, STR_SETTING_QR_CODE}, //扫一扫 {FUNC_VOICE, UI_BUF_ICON_VOICE_BIN, STR_VOICE}, //语音助手 {FUNC_ALIPAY, UI_BUF_ICON_ALIPAY_BIN, STR_ALIPAY}, //支付宝 {FUNC_SPORT, UI_BUF_ICON_SPORT_BIN, STR_SPORTS}, //运动 {FUNC_CALL, UI_BUF_ICON_CALL_BIN, STR_PHONE}, //电话 {FUNC_FINDPHONE, UI_BUF_ICON_FINDPHONE_BIN, STR_FIND_PHONE}, //寻找手机 {FUNC_CALENDAER, UI_BUF_ICON_CALENDAR_BIN, STR_CALENDAR}, //日历 {FUNC_ACTIVITY, UI_BUF_ICON_ACTIVITY_BIN, STR_MOTION_DATA}, //活动记录 {FUNC_FLASHLIGHT, UI_BUF_ICON_FLASHLIGHT_BIN, STR_FLASHLIGHT}, //手电筒 {FUNC_SETTING, UI_BUF_ICON_SETTING_BIN, STR_SETTING}, //设置 {FUNC_SHORT_VIDEO, UI_BUF_ICON_VIDEO_BIN, STR_SHORT_VIDEO}, //短视频 {FUNC_GESTURE_GAME, UI_BUF_ICON_GAME_BIN, STR_MOTION_SENSING_GAME}, //体感游戏 {FUNC_WORLD_CLOCK, UI_BUF_ICON_WORLD_BIN, STR_WORLD_CLOCK}, //世界时钟 {FUNC_STYLE, UI_BUF_ICON_MENU_BIN, STR_STYLE}, //菜单风格 {FUNC_RESTART, UI_BUF_ICON_RESTART_BIN, STR_SETTING_RESTART}, //重启 {FUNC_OFF, UI_BUF_ICON_OFF_BIN, STR_SETTING_OFF}, //关机 {FUNC_LANGUAGE, UI_BUF_ICON_LANGUAGE_BIN, STR_SETTING_LANGUAGE}, //语言 {FUNC_SEDENTARY, UI_BUF_ICON_SEDENTARY_BIN, STR_SEDENTARINESS }, //久坐 {FUNC_DRINK, UI_BUF_ICON_DRINK_BIN, STR_DRINK_WATER }, //喝水 {FUNC_ADDRESS_BOOK, UI_BUF_ICON_ADDRESS_BOOK_BIN, STR_CALL_LINK}, //联系人 }; /* 卡片初始位置 */ const rect_t card_bg[4] = { {.x = GUI_SCREEN_CENTER_X, .y = 124, .wid = 176, .hei = 212}, {.x = GUI_SCREEN_CENTER_X, .y = 216, .wid = 218 + DOCK_BG_SHADOW_W, .hei = 269 + DOCK_BG_SHADOW_W}, {.x = GUI_SCREEN_CENTER_X, .y = 386, .wid = 240, .hei = 296}, {.x = GUI_SCREEN_CENTER_X, .y = 386 + 179, .wid = 240, .hei = 296}, }; /* ICON初始位置 */ const rect_t card_icon = { .x = 45 - GUI_SCREEN_CENTER_X, .y = 127 - 227, .wid = 40, .hei = 40, }; /* 卡片的初始布局位置 */ const u8 card_item[] = {CARD_POS_UP, CARD_POS_UP, CARD_POS_MID, CARD_POS_DOWN, CARD_POS_OVER}; /* 初始化最近任务列表是否有符合程序坞显示窗体 */ static void func_smartstack_list_data_init(void) { memset(&dock_list, 0, sizeof(dock_list)); for (u8 idx = 0; idx < latest_task_count(); idx++) { for (u8 find = 0; find < DOCK_FUNC_MAX_NUM; find++) { if (dock_info[find].func_sta == latest_task_get(idx)) { dock_list.func_sta_list[dock_list.func_sta_num++] = latest_task_get(idx); } } } /* 首尾原地交换,保证最近一个任务位于窗体最前方 */ if (dock_list.func_sta_num) { int temp; for (int i = 0; i < dock_list.func_sta_num / 2; i++) { temp = dock_list.func_sta_list[i]; dock_list.func_sta_list[i] = dock_list.func_sta_list[dock_list.func_sta_num - 1 - i]; dock_list.func_sta_list[dock_list.func_sta_num - 1 - i] = temp; } } } /* 删除指定窗体 */ static void func_smartstack_list_sta_del(u8 idx) { u8 i = idx; if (i < dock_list.func_sta_num) { dock_list.func_sta_num--; for (; i < dock_list.func_sta_num; i++) { dock_list.func_sta_list[i] = dock_list.func_sta_list[i + 1]; } } } /* 是否正在删除状态中 */ static bool func_smartstack_card_del_underway(void) { bool sta = false; compo_cardbox_t *cardbox = compo_getobj_byid(COMPO_ID_CARD_MID); if (!dock_list.func_sta_num) { return; } if (cardbox) { rect_t rect = compo_cardbox_get_location(cardbox); if (rect.x != card_bg[CARD_POS_MID].x) { sta = true; } } return sta; } // 刷新卡片内容(以中间卡片为初始坐标和大小,移动过程中page做整体缩放) static void func_smartstack_card_content_refresh(compo_cardbox_t *cardbox, u8 pos, u8 func_sta) { char text_buf[TEXTBOX_TEXT_BUF_LEN] = {0}; u32 img_res = 0, str_res = 0; for (u8 i = 0; i < DOCK_FUNC_MAX_NUM; i++) { if (dock_info[i].func_sta == func_sta) { str_res = dock_info[i].str_res; img_res = dock_info[i].img_res; } } /* 阴影背景框 */ compo_cardbox_rect_set_location(cardbox, 0, 0, 0, card_bg[CARD_POS_MID].wid, card_bg[CARD_POS_MID].hei, 40); compo_cardbox_rect_set_color(cardbox, 0, make_color(0, 0, 0)); widget_set_alpha(cardbox->rect[0], 150); /* 背景 */ compo_cardbox_rect_set_location(cardbox, 1, 0, 0, card_bg[CARD_POS_MID].wid - DOCK_BG_SHADOW_W, card_bg[CARD_POS_MID].hei - DOCK_BG_SHADOW_W, 38); compo_cardbox_rect_set_color(cardbox, 1, make_color(56, 56, 56)); /* 设置icon */ compo_cardbox_icon_set(cardbox, 0, func_get_icon_addr(func_sta)); compo_cardbox_icon_set_location(cardbox, 0, card_icon.x, card_icon.y, card_icon.wid, card_icon.hei); /* 设置icon */ compo_cardbox_icon_set(cardbox, 1, func_get_icon_addr(func_sta)); compo_cardbox_icon_set_location(cardbox, 1, 0, 10, 80, 80); /* 标题 */ compo_cardbox_text_set_location(cardbox, 0, DOCK_TITLE_TEXT_X, DOCK_TITLE_TEXT_Y, DOCK_TITLE_TEXT_W, DOCK_TITLE_TEXT_H); compo_cardbox_text_set_align_center(cardbox, 0, false); const char *title_text = i18n[str_res]; if (utf8_string_char_count(title_text) > CARD_MAX_WORD_CNT - 4) { /* 超出文本超度部分显示"..." */ memcpy(text_buf, title_text, utf8_assign_char_length(title_text, CARD_MAX_WORD_CNT - 4)); sprintf(&text_buf[strlen(text_buf)], "%s", "..."); compo_cardbox_text_set(cardbox, 0, text_buf); } else { compo_cardbox_text_set(cardbox, 0, title_text); } compo_cardbox_set_alpha(cardbox, 255); compo_cardbox_set_visible(cardbox, true); compo_cardbox_set_location(cardbox, card_bg[pos].x, card_bg[pos].y, card_bg[pos].wid, card_bg[pos].hei); } // 创建堆栈界面 compo_form_t *func_smartstack_form_create(void) { /* 新建窗体 */ compo_form_t *frm = compo_form_create(true); func_smartstack_list_data_init(); /* 显示对应程序坞界面 */ if (dock_list.func_sta_num) { // 删除按钮 compo_button_t *btn = compo_button_create_by_image(frm, UI_BUF_DOCK_DELETE_BIN); compo_setid(btn, COMPO_ID_BTN_DEL); compo_button_set_pos(btn, GUI_SCREEN_CENTER_X + 62, GUI_SCREEN_CENTER_Y + 46); compo_button_set_alpha(btn, 0); compo_button_set_visible(btn, false); // 创建卡片和设置背景框 for (u8 i = 0; i < sizeof(card_item) / sizeof(card_item[0]); i++) { compo_cardbox_t *cardbox = compo_cardbox_create(frm, CARD_RECT_COUNT_MAX, CARD_ICON_COUNT_MAX, CARD_TEXT_COUNT_MAX, card_bg[CARD_POS_MID].wid, card_bg[CARD_POS_MID].hei); compo_setid(cardbox, COMPO_ID_CARD_UP_BK + i); compo_cardbox_rect_set_location(cardbox, 0, 0, 0, card_bg[CARD_POS_MID].wid, card_bg[CARD_POS_MID].hei, 30); compo_cardbox_set_location(cardbox, card_bg[card_item[i]].x, card_bg[card_item[i]].y, card_bg[card_item[i]].wid, card_bg[card_item[i]].hei); if (i < dock_list.func_sta_num) { func_smartstack_card_content_refresh(cardbox, card_item[i], dock_list.func_sta_list[i]); } compo_cardbox_set_visible(cardbox, false); } } else { // 无堆栈记录 compo_picturebox_t *pic = compo_picturebox_create(frm, UI_BUF_DOCK_NULL_BIN); compo_setid(pic, COMPO_ID_PIC_NONE_BG); compo_picturebox_set_pos(pic, GUI_SCREEN_CENTER_X, GUI_SCREEN_CENTER_Y - 30); compo_textbox_t *no_record = compo_textbox_create(frm, 50); compo_textbox_set_location(no_record, GUI_SCREEN_CENTER_X, GUI_SCREEN_CENTER_Y + 57, 190, 80); compo_textbox_set_multiline(no_record, true); compo_textbox_set_align_center(no_record, true); compo_textbox_set(no_record, i18n[STR_SMARTSTACK_NO_RECPRD]); } return frm; } // 卡片大小和位置为线性关系 static rect_t func_smartstack_get_size_by_y(s16 y) { rect_t rect = {0}; rect.y = y; rect.x = GUI_SCREEN_CENTER_X; if (y <= card_bg[CARD_POS_UP].y) { rect = card_bg[CARD_POS_UP]; } else if (y <= card_bg[CARD_POS_MID].y) { rect.wid = card_bg[CARD_POS_UP].wid + ((y - card_bg[CARD_POS_UP].y) / 2); // 此处2为增量差值倍数,下同 if (rect.wid > card_bg[CARD_POS_MID].wid) { rect.wid = card_bg[CARD_POS_MID].wid; } rect.hei = card_bg[CARD_POS_UP].hei + ((y - card_bg[CARD_POS_UP].y) / 2) + 4; // 此处4为增量差值倍数无法整除情况下的增益,下同 if (rect.hei > card_bg[CARD_POS_MID].hei) { rect.hei = card_bg[CARD_POS_MID].hei; } } else if (y <= card_bg[CARD_POS_DOWN].y) { rect.wid = card_bg[CARD_POS_MID].wid + ((y - card_bg[CARD_POS_MID].y) / 4); if (rect.wid > card_bg[CARD_POS_DOWN].wid) { rect.wid = card_bg[CARD_POS_DOWN].wid; } rect.hei = card_bg[CARD_POS_MID].hei + ((y - card_bg[CARD_POS_MID].y) / 2) + 2; if (rect.hei > card_bg[CARD_POS_DOWN].hei) { rect.hei = card_bg[CARD_POS_DOWN].hei; } } else { rect.wid = card_bg[CARD_POS_DOWN].wid + ((y - card_bg[CARD_POS_DOWN].y) / 4); if (rect.wid > GUI_SCREEN_WIDTH) { rect.wid = GUI_SCREEN_WIDTH; } rect.hei = card_bg[CARD_POS_DOWN].hei + ((y - card_bg[CARD_POS_DOWN].y) / 2); if (rect.hei > GUI_SCREEN_HEIGHT) { rect.hei = GUI_SCREEN_HEIGHT; } } return rect; } // 上下移动处理 static void func_smartstack_move_y_handle(compo_cardbox_t *cardbox, s32 dy) { rect_t rect = compo_cardbox_get_location(cardbox); rect.y += dy; if (rect.y < card_bg[CARD_POS_UP].y) { rect.y = card_bg[CARD_POS_UP].y; } rect = func_smartstack_get_size_by_y(rect.y); compo_cardbox_set_location(cardbox, rect.x, rect.y, rect.wid, rect.hei); } // 左右移动处理 static void func_smartstack_move_x_handle(s32 move) { f_smartstack_t *f_smartstack = (f_smartstack_t *)func_cb.f_cb; compo_cardbox_t *cardbox4 = compo_getobj_byid(COMPO_ID_CARD_UP_BK); compo_cardbox_t *cardbox1 = compo_getobj_byid(COMPO_ID_CARD_UP_DISP); compo_cardbox_t *cardbox = compo_getobj_byid(COMPO_ID_CARD_MID); compo_cardbox_t *cardbox2 = compo_getobj_byid(COMPO_ID_CARD_DOWN_BK); compo_cardbox_t *cardbox3 = compo_getobj_byid(COMPO_ID_CARD_DOWN_DISP); f_smartstack->del_index = f_smartstack->mid_index; if (cardbox) { /* 操作中间可以删除卡片 */ rect_t rect = compo_cardbox_get_location(cardbox); rect.x += move; if (rect.x > GUI_SCREEN_CENTER_X) { rect.x = GUI_SCREEN_CENTER_X; } u16 mid_card_wid = card_bg[CARD_POS_MID].wid / 2; if (rect.x < card_bg[CARD_POS_MID].x - mid_card_wid) { rect.x = card_bg[CARD_POS_MID].x - mid_card_wid; } compo_cardbox_set_location(cardbox, rect.x, rect.y, rect.wid, rect.hei); /* 移动过程透明度X轴差值 */ u8 card_alpha_x = rect.x - (card_bg[CARD_POS_MID].x - mid_card_wid); /* 操作上方卡片 */ rect_t rect1 = compo_cardbox_get_location(cardbox1); u16 up_card_offset = (mid_card_wid - card_alpha_x) * (float)(DOCK_DEL_UP_CARD_OFFSET / mid_card_wid); compo_cardbox_set_alpha(cardbox1, 255 - (mid_card_wid - card_alpha_x) * (float)(255.0 / mid_card_wid)); compo_cardbox_set_location(cardbox1, rect1.x, card_bg[CARD_POS_UP].y - up_card_offset, card_bg[CARD_POS_UP].wid - up_card_offset, card_bg[CARD_POS_UP].hei - up_card_offset); /* 操作下方卡片 */ u16 down_card_offset = (mid_card_wid - card_alpha_x) * (float)(DOCK_DEL_DOWN_CARD_OFFSET / mid_card_wid); compo_cardbox_set_location(cardbox2, card_bg[CARD_POS_DOWN].x, card_bg[CARD_POS_DOWN].y + down_card_offset, card_bg[CARD_POS_DOWN].wid, card_bg[CARD_POS_DOWN].hei); /* 其余卡片可暂时不显示 */ compo_cardbox_set_visible(cardbox4, false); compo_cardbox_set_visible(cardbox3, false); /* 删除按钮 */ compo_button_t *btn = compo_getobj_byid(COMPO_ID_BTN_DEL); if (rect.x >= GUI_SCREEN_CENTER_X) { compo_button_set_alpha(btn, 0); compo_button_set_visible(btn, false); } else { compo_button_set_alpha(btn, (mid_card_wid - card_alpha_x) * (float)(255.0 / mid_card_wid)); compo_button_set_visible(btn, true); } /* 其余卡片可根据删除位置决定是否显示 */ if (rect.x == card_bg[CARD_POS_MID].x) { func_smartstack_card_refresh(CARD_DRAW_REFRESH, 0); } } } /* 删除左右自行复位 */ static void func_smartstack_auto_move_x_handle(void) { f_smartstack_t *f_smartstack = (f_smartstack_t *)func_cb.f_cb; compo_cardbox_t *cardbox4 = compo_getobj_byid(COMPO_ID_CARD_UP_BK); compo_cardbox_t *cardbox1 = compo_getobj_byid(COMPO_ID_CARD_UP_DISP); compo_cardbox_t *cardbox = compo_getobj_byid(COMPO_ID_CARD_MID); compo_cardbox_t *cardbox2 = compo_getobj_byid(COMPO_ID_CARD_DOWN_BK); compo_cardbox_t *cardbox3 = compo_getobj_byid(COMPO_ID_CARD_DOWN_DISP); if (cardbox) { u16 mid_card_wid = card_bg[CARD_POS_MID].wid / 2; rect_t rect = compo_cardbox_get_location(cardbox); /* 已经完整显示删除按钮与卡片到达最左边无需移动 */ if (rect.x == card_bg[CARD_POS_MID].x - mid_card_wid) { return; } /* 根据卡片相对位置判断自动移动到哪一边 */ if (rect.x > card_bg[CARD_POS_MID].x - mid_card_wid / 2) { rect.x += AUTO_MOVE_Y_EXPIRE / 3; } else { rect.x -= AUTO_MOVE_Y_EXPIRE / 3; } if (rect.x > GUI_SCREEN_CENTER_X) { rect.x = GUI_SCREEN_CENTER_X; } if (rect.x < card_bg[CARD_POS_MID].x - mid_card_wid) { rect.x = card_bg[CARD_POS_MID].x - mid_card_wid; } compo_cardbox_set_location(cardbox, rect.x, rect.y, rect.wid, rect.hei); /* 移动过程透明度X轴差值 */ u8 card_alpha_x = rect.x - (card_bg[CARD_POS_MID].x - mid_card_wid); /* 操作上方卡片 */ rect_t rect1 = compo_cardbox_get_location(cardbox1); u16 up_card_offset = (mid_card_wid - card_alpha_x) * (float)(DOCK_DEL_UP_CARD_OFFSET / mid_card_wid); compo_cardbox_set_alpha(cardbox1, 255 - (mid_card_wid - card_alpha_x) * (float)(255.0 / mid_card_wid)); compo_cardbox_set_location(cardbox1, rect1.x, card_bg[CARD_POS_UP].y - up_card_offset, card_bg[CARD_POS_UP].wid - up_card_offset, card_bg[CARD_POS_UP].hei - up_card_offset); /* 操作下方卡片 */ u16 down_card_offset = (mid_card_wid - card_alpha_x) * (float)(DOCK_DEL_DOWN_CARD_OFFSET / mid_card_wid); compo_cardbox_set_location(cardbox2, card_bg[CARD_POS_DOWN].x, card_bg[CARD_POS_DOWN].y + down_card_offset, card_bg[CARD_POS_DOWN].wid, card_bg[CARD_POS_DOWN].hei); /* 删除按钮 */ compo_button_t *btn = compo_getobj_byid(COMPO_ID_BTN_DEL); if (rect.x == card_bg[CARD_POS_MID].x) { compo_button_set_alpha(btn, 0); compo_button_set_visible(btn, false); } else { compo_button_set_alpha(btn, (mid_card_wid - card_alpha_x) * (float)(255.0 / mid_card_wid)); compo_button_set_visible(btn, true); } /* 其余卡片可根据删除位置决定是否显示 */ if (rect.x == card_bg[CARD_POS_MID].x) { func_smartstack_card_refresh(CARD_DRAW_REFRESH, 0); } } } // 刷新所有卡片 static void func_smartstack_card_refresh(u8 draw, s32 move) { f_smartstack_t *f_smartstack = (f_smartstack_t *)func_cb.f_cb; int8_t start_index = f_smartstack->mid_index - 2; int8_t end_index = f_smartstack->mid_index + 2; bool refresh_flag = false; compo_cardbox_t *cardbox_mid = compo_getobj_byid(COMPO_ID_CARD_MID); rect_t mid_rect = compo_cardbox_get_location(cardbox_mid); if (CARD_DRAW_MOVE_X == draw) { func_smartstack_move_x_handle(move); return; } if (CARD_DRAW_MOVE_Y == draw) { if (f_smartstack->mid_index >= (dock_list.func_sta_num - 1) && move < 0) { return; } if (f_smartstack->mid_index == 0 && move > 0) { return; } } for (int8_t i = start_index; i <= end_index; i++) { compo_cardbox_t *cardbox = compo_getobj_byid(COMPO_ID_CARD_UP_BK + i - start_index); if (NULL == cardbox) { continue; } if (i < 0) { compo_cardbox_set_visible(cardbox, false); continue; } else if (i >= dock_list.func_sta_num) { compo_cardbox_set_visible(cardbox, false); break; } else { switch (draw) { case CARD_DRAW_REFRESH: { func_smartstack_card_content_refresh(cardbox, card_item[i - start_index], dock_list.func_sta_list[i]); } break; case CARD_DRAW_MOVE_Y: { if (i == start_index) { continue; } else if (i < f_smartstack->mid_index) { if (mid_rect.y < card_bg[CARD_POS_MID].y) continue; } else { rect_t cur_rect = compo_cardbox_get_location(cardbox); if (cur_rect.y < card_bg[CARD_POS_DOWN].y) { move *= 2; } if (!refresh_flag && i == f_smartstack->mid_index) { if (mid_rect.y > card_bg[CARD_POS_UP].y && (mid_rect.y + move) <= card_bg[CARD_POS_UP].y) { f_smartstack->mid_index++; refresh_flag = true; } else if (mid_rect.y < card_bg[CARD_POS_DOWN].y && (mid_rect.y + move) >= card_bg[CARD_POS_DOWN].y) { f_smartstack->mid_index--; refresh_flag = true; } } } func_smartstack_move_y_handle(cardbox, move); } break; default: break; } } } if (refresh_flag) { func_smartstack_card_refresh(CARD_DRAW_REFRESH, 0); return; } } // 移动 static void func_smartstack_move_process(void) { f_smartstack_t *f_smartstack = (f_smartstack_t *)func_cb.f_cb; if (f_smartstack->flag_drag) { s32 dx, dy; bool move_y = false; f_smartstack->flag_drag = ctp_get_dxy(&dx, &dy); if (f_smartstack->flag_drag) { /* 滑动方向判断 */ if (f_smartstack->last_move_x || func_smartstack_card_del_underway()) { /* 正在进行删除动作 */ move_y = false; } else if (f_smartstack->last_move_y) { move_y = true; } else { if (abs_s(dx) < abs_s(dy)) { move_y = true; } if (dx > 0) { move_y = true; } } /* 左右滑动处理 */ if (!move_y && dx != f_smartstack->last_move_x) { func_smartstack_card_refresh(CARD_DRAW_MOVE_X, dx - f_smartstack->last_move_x); f_smartstack->last_move_x = dx; } /* 上下滑动处理 */ if (move_y && dy != f_smartstack->last_move_y) { func_smartstack_card_refresh(CARD_DRAW_MOVE_Y, dy - f_smartstack->last_move_y); f_smartstack->auto_move_y = dy - f_smartstack->last_move_y; f_smartstack->last_move_y = dy; } } else { /* 开始松手 */ f_smartstack->flag_drag = false; f_smartstack->last_move_y = 0; f_smartstack->last_move_x = 0; f_smartstack->auto_move_y *= AUTO_ROLL_MOMENT; } } else if (f_smartstack->auto_move_y != 0 || func_smartstack_card_del_underway()) { if (tick_check_expire(f_smartstack->last_tick, AUTO_TICK_EXPIRE)) { f_smartstack->last_tick = tick_get(); /* 删除X轴自行移动 */ if (func_smartstack_card_del_underway()) { func_smartstack_auto_move_x_handle(); return; } /* Y轴自行移动 */ s32 dy = 0; if (f_smartstack->auto_move_y > 0) { dy = f_smartstack->auto_move_y > AUTO_MOVE_Y_EXPIRE ? AUTO_MOVE_Y_EXPIRE : f_smartstack->auto_move_y; } else { dy = f_smartstack->auto_move_y < -AUTO_MOVE_Y_EXPIRE ? -AUTO_MOVE_Y_EXPIRE : f_smartstack->auto_move_y; } f_smartstack->auto_move_y -= dy; func_smartstack_card_refresh(CARD_DRAW_MOVE_Y, dy); // 自动回正 if (!f_smartstack->auto_move_y) { func_smartstack_card_refresh(CARD_DRAW_REFRESH, 0); } } } } // 程序坞主要事件流程处理 static void func_smartstack_process(void) { if (dock_list.func_sta_num) { func_smartstack_move_process(); } func_process(); } // 单击 static void func_smartstack_click_handler(void) { compo_form_t *frm = func_cb.frm_main; f_smartstack_t *f_smartstack = (f_smartstack_t *)func_cb.f_cb; u8 max_cnt = sizeof(card_item) / sizeof(card_item[0]); if (COMPO_ID_BTN_DEL == compo_get_button_id() && func_smartstack_card_del_underway()) { compo_button_t *btn = compo_getobj_byid(COMPO_ID_BTN_DEL); compo_button_set_alpha(btn, 0); compo_button_set_visible(btn, false); latest_task_del(latest_task_find(dock_list.func_sta_list[f_smartstack->del_index])); func_smartstack_list_sta_del(f_smartstack->del_index); if (dock_list.func_sta_num) { f_smartstack->mid_index--; if (f_smartstack->mid_index < 0) { f_smartstack->mid_index = 0; } func_smartstack_card_refresh(CARD_DRAW_REFRESH, 0); } else { for (u8 i = 0; i < sizeof(card_item) / sizeof(card_item[0]); i++) { compo_cardbox_t *cardbox = compo_getobj_byid(COMPO_ID_CARD_UP_BK + i); compo_cardbox_set_visible(cardbox, false); } compo_form_destroy(frm); func_cb.frm_main = func_smartstack_form_create(); } f_smartstack->del_index = 0xff; } else { for (u8 i = 0; i < max_cnt; i++) { compo_cardbox_t *cardbox = compo_getobj_byid(COMPO_ID_CARD_UP_BK + max_cnt - i - 1); if (!compo_cardbox_get_visible(cardbox)) { continue; } if (compo_cardbox_btn_is(cardbox, ctp_get_sxy())) { int8_t index = f_smartstack->mid_index + (2 - i); if (index < dock_list.func_sta_num) { task_stack_del(task_stack_find(FUNC_SMARTSTACK)); func_switch_to(dock_list.func_sta_list[index], FUNC_SWITCH_ZOOM_FADE_ENTER | FUNC_SWITCH_AUTO); } break; } } } } // 功能消息处理 static void func_smartstack_message(size_msg_t msg) { f_smartstack_t *f_smartstack = (f_smartstack_t *)func_cb.f_cb; switch (msg) { case MSG_CTP_TOUCH: f_smartstack->flag_drag = true; break; case MSG_CTP_CLICK: if (dock_list.func_sta_num) { func_smartstack_click_handler(); } break; case MSG_CTP_SHORT_UP: case MSG_CTP_SHORT_DOWN: break; case MSG_CTP_SHORT_LEFT: case MSG_CTP_LONG: break; case MSG_CTP_SHORT_RIGHT: if (!func_smartstack_card_del_underway()) { func_back_to(); } break; case MSG_QDEC_FORWARD: f_smartstack->auto_move_y += -((card_bg[CARD_POS_MID].y - GUI_SCREEN_CENTER_Y) - (GUI_SCREEN_CENTER_Y - card_bg[CARD_POS_UP].y)) - AUTO_MOVE_Y_EXPIRE; f_smartstack->last_tick = tick_get(); break; case MSG_QDEC_BACKWARD: f_smartstack->auto_move_y += (card_bg[CARD_POS_MID].y - GUI_SCREEN_CENTER_Y) + (GUI_SCREEN_CENTER_Y - card_bg[CARD_POS_UP].y); f_smartstack->last_tick = tick_get(); break; case KL_BACK: break; case KU_LEFT: func_back_to(); break; default: func_message(msg); break; } } // 程序坞进入处理 static void func_smartstack_enter(void) { func_cb.f_cb = func_zalloc(sizeof(f_smartstack_t)); func_cb.frm_main = func_smartstack_form_create(); f_smartstack_t *f_smartstack = (f_smartstack_t *)func_cb.f_cb; if (dock_list.func_sta_num == 1) { f_smartstack->mid_index = 0; } else { f_smartstack->mid_index = dock_list.func_sta_num - MID_CARD_FUNC_INIT_INDEX; } if (dock_list.func_sta_num) func_smartstack_card_refresh(CARD_DRAW_REFRESH, 0); } // 程序坞退出处理 static void func_smartstack_exit(void) { func_cb.last = FUNC_SMARTSTACK; } // 程序坞 void func_smartstack(void) { printf("%s\n", __func__); func_smartstack_enter(); while (func_cb.sta == FUNC_SMARTSTACK) { func_smartstack_process(); func_smartstack_message(msg_dequeue()); } func_smartstack_exit(); } #endif