mcu_ab568x/app/projects/AB5681F_240_64M/functions/func_smartstack.c
2025-05-30 18:03:10 +08:00

868 lines
31 KiB
C
Raw 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.

#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