#include "include.h" #define TRACE_EN 0 #if TRACE_EN #define TRACE(...) printf(__VA_ARGS__) #else #define TRACE(...) #endif /** * @brief 创建一个转盘组件 * @param[in] frm : 窗体指针 * @param[in] pic_array : 图片集合 * @param[in] pic_cnt : 图片数量 * @param[in] disp_cnt : 显示的转盘个数 * @return 返回转盘指针 **/ compo_rotary_t *compo_rotary_create(compo_form_t *frm, u32 const *pic_array, u8 pic_cnt, u8 disp_cnt) { int i; compo_rotary_t *rotary = compo_create(frm, COMPO_TYPE_ROTARY); widget_page_t *page = widget_page_create(frm->page_body); widget_set_location(page, GUI_SCREEN_CENTER_X, GUI_SCREEN_CENTER_Y, GUI_SCREEN_WIDTH, GUI_SCREEN_HEIGHT); rotary->cx = GUI_SCREEN_CENTER_X; rotary->cy = GUI_SCREEN_CENTER_Y; rotary->page = page; if (disp_cnt <= 0 || disp_cnt > ROTARY_DISP_ITEM_MAX) { halt(HALT_GUI_COMPO_ROTARY_CREATE); } if (pic_cnt < disp_cnt) { halt(HALT_GUI_COMPO_ROTARY_CREATE); } rotary->disp_cnt = disp_cnt; if (pic_cnt > ROTARY_PIC_ITEM_MAX) { pic_cnt = ROTARY_PIC_ITEM_MAX; } rotary->pic_cnt = pic_cnt; memcpy(rotary->res_addr, pic_array, pic_cnt * sizeof(rotary->res_addr[0])); for (i = 0; i < disp_cnt; i++) { widget_image_t *img = widget_image_create(page, 0); rotary->item_img[i] = img; widget_image_set_rotation_mode(img, ROT_MODE_X); } return rotary; } /** * @brief 获取对应图片索引 * @param[in] rotary : 转盘组件 * @param[in] res_addr : 图片地址 * @return 图片索引 **/ static u8 compo_rotary_get_cur_index(compo_rotary_t *rotary, u32 res_addr) { int i = 0; for (i = 0; i < sizeof(rotary->res_addr) / sizeof(rotary->res_addr[0]); i++) { if (res_addr == rotary->res_addr[i]) { return i; } } return 0; } /** * @brief 更新转盘Widget * @param[in] rotary : 转盘指针 **/ void compo_rotary_update(compo_rotary_t *rotary, bool frist) { int i; int sidx; int s_angle = rotary->angle; s32 ea = 150; s32 eb = 60; s32 x, y; s_angle += 900; if (s_angle < 1800) { s_angle += 3600; } /* sidx为最低下的控件 */ sidx = ((s_angle - 1800) * rotary->disp_cnt) / 3600; s_angle -= 3600 * sidx / rotary->disp_cnt; sidx = (sidx == 0) ? 0 : (rotary->disp_cnt - sidx); if (frist) { TRACE("rotary->pic_index:%d\n",rotary->pic_index); for (i = 0; i < rotary->disp_cnt; i++) { rotary->disp_res_addr[i] = rotary->res_addr[(rotary->pic_index + i) % rotary->pic_cnt]; } rotary->disp_res_addr[rotary->disp_cnt - 1] = rotary->res_addr[(rotary->pic_index - 1 + rotary->pic_cnt) % rotary->pic_cnt]; rotary->disp_res_addr[rotary->disp_cnt / 2] = rotary->res_addr[(rotary->pic_cnt / 2 + rotary->pic_index) % rotary->pic_cnt]; rotary->sidx = sidx; } if(sidx != rotary->sidx) { int8_t dir = 0; TRACE("rotary->sidx:%d,sidx:%d,disp_cnt:%d,rotary->angle:%d\n",rotary->sidx,sidx,rotary->disp_cnt,rotary->angle); if ((sidx > rotary->sidx)) { dir = -1; if ((sidx - rotary->sidx) == (rotary->disp_cnt - 1)) { dir = 1; } } else { dir = 1; if ((sidx - rotary->sidx) == (1 - rotary->disp_cnt)) { dir = -1; } } if (-1 == dir) { //逆时针 int idx = (sidx - 1 + rotary->disp_cnt) % rotary->disp_cnt; u8 pic_index = compo_rotary_get_cur_index(rotary, rotary->disp_res_addr[idx]); pic_index = (pic_index + 1) % rotary->pic_cnt; rotary->disp_res_addr[sidx] = rotary->res_addr[pic_index]; } else if(1 == dir) { //顺时针 int idx = sidx + 2; if (idx >= rotary->disp_cnt) { idx -= rotary->disp_cnt; } u8 pic_index = compo_rotary_get_cur_index(rotary, rotary->disp_res_addr[idx]); idx = sidx + 1; if (idx >= rotary->disp_cnt) { idx -= rotary->disp_cnt; } pic_index = (pic_index + rotary->pic_cnt - 1) % rotary->pic_cnt; rotary->disp_res_addr[idx] = rotary->res_addr[pic_index]; } //获取最上面的控件 int sidx_tmp = (sidx + rotary->disp_cnt - 1) % rotary->disp_cnt; rotary->pic_index = compo_rotary_get_cur_index(rotary, rotary->disp_res_addr[sidx_tmp]); TRACE("cur_index:%d\n",rotary->pic_index); rotary->sidx = sidx; } for (i = 0; i < rotary->disp_cnt; i++) { int idx = sidx + i; s32 angle = s_angle + 3600 * i / rotary->disp_cnt; if (idx >= rotary->disp_cnt) { idx -= rotary->disp_cnt; } widget_image_t *img = rotary->item_img[i]; widget_image_set(img, rotary->disp_res_addr[idx]); x = muls_shift16(ea, COS(angle)); y = muls_shift16(eb, SIN(angle)); widget_set_pos(img, rotary->cx + x, rotary->cy + y); widget_image_set_rotation_bypos(img, y * ea * ea / (eb * eb), x); } } /** * @brief 设置转盘的旋转角度 (0 ~ 3599) * @param[in] rotary : 转盘指针 * @param[in] angle : 旋转角度 **/ void compo_rotary_set_rotation(compo_rotary_t *rotary, s16 angle) { if (angle < 0 || angle >= 3600) { halt(HALT_GUI_COMPO_ROTARY_ANGLE); } rotary->angle = angle; }