172 lines
5.5 KiB
C
172 lines
5.5 KiB
C
#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;
|
|
}
|
|
|