本站动态:
MainMenuWidget简介
作者:shosh 日期:2010-04-23
之前开发了一个MainMenuWidget,主要用于主菜单的12宫格。它具有以下功能:
1、宫格数可以由用户确定,最大宫格数由宏由MW_ITEM_ROW_MAX_NUM和MW_ITEM_COL_MAX_NUM控制。工程中使用的MainMenuWidget支持n * m宫格(n <= MW_ITEM_ROW_MAX_NUM && m <= MW_ITEM_COL_MAX_NUM)的任意组合。
2、任意一个宫格都可以设置是否支持可选中状态。
3、可以有动画移动效果,也可以关闭动画移动效果。
4、每个选中的宫格都支持animation动画,也可以关闭该功能。各个宫格的动画帧数可以不一致,也可以设置animation动画的播放次数(0次到无限)
5、可以设置移动选中Item到达边界后移向哪里(不再移动/回到同行另一端/移动到上一行/移动到下一行)
6、用户可以通过IWIDGET_SetFocusIndex()和IWIDGET_SelectIndex()设置focus的item或快速进入某个item。
7、Widget通过用户注册的函数通知用户focus发生了移动或某个Item被用户选中了(一般情况下用户只关心选中事件):
- typedef enum {
- EVT_Select = 0x00,
- EVT_MOVE_FROM_LEFT = 0x01,
- EVT_MOVE_FROM_RIGHT = 0x02,
- EVT_MOVE_FROM_UP = 0x04,
- EVT_MOVE_FROM_DOWN = 0x08,
- //EVT_MOVE will be sent when the event is not generated by key pressing,
- //eg. Set property of PROP_FOCUSINDEX or PROP_SelectINDEX, or by touching screen if supported
- EVT_MOVE = 0x0F //You can use it to check whether it is a move event via (evt & EVT_MOVE)
- } mmwEvent;
- typedef void (*PFNMMWSelectHANDLER)(void* pCtx, mmwEvent evt, mmwItemPos* pos);
8、在设计之初MainMenuWidget是不支持触摸屏的,不过后来加了二三十行代码让它支持了。这里使用的方法是将触摸屏事件转化为对PROP_SelectINDEX和PROP_FOCUSINDEX进行设置的EVT_WDG_SETPROPERTY事件。当初在设计的时候考虑了多种方案,最后想到了该方案,个人非常喜欢这样的设计,代码如下:
- #ifdef FEATURE_TOUCH_PANEL
- //if it is an touch event, we translate it to non-touch event in order to let it support touch events
- //we will calculate the point position and translate it to mmwItemPos which will be saved to *pIp,
- //and let dwParam point to pIp
- static void MainMenuWidget_TranslateTouchEvt(MainMenuWidget* me, AEEEvent* evt,
- uint16* wParam, uint32* dwParam, mmwItemPos* pIp)
- {
- if (TRUE == me->bNapping)
- return;
- switch (*evt)
- {
- case EVT_POINTER_MOVE: //set focus index
- case EVT_POINTER_DOWN: //set focus index
- case EVT_POINTER_UP: //set selected index
- //set mmwItemPos values
- pIp->indexCol = (*dwParam >> 16) / me->mdt->itemWidth;
- pIp->indexRow = (*dwParam & 0xFFFF) / me->mdt->itemHeight;
- //point to mmwItemPos
- *dwParam = (uint32)pIp;
- //change wParam value, MUST be BEFORE changing event code
- if (EVT_POINTER_UP == *evt)
- *wParam = (uint16)PROP_SelectINDEX;
- else
- *wParam = (uint16)PROP_FOCUSINDEX;
- //change event code
- *evt = EVT_WDG_SETPROPERTY;
- break;
- default:
- break;
- }
- }
- #endif
- static boolean MainMenuWidget_HandleEvent(IWidget *po, AEEEvent evt,
- uint16 wParam, uint32 dwParam)
- {
- MainMenuWidget* me = IWIDGET_TO_MW_WIDGET(po);
- ……
- #ifdef FEATURE_TOUCH_PANEL
- mmwItemPos ip = {0};
- MainMenuWidget_TranslateTouchEvt(me, &evt, &wParam, &dwParam, &ip);
- #endif
- ……
- else if (EVT_WDG_SETPROPERTY == evt)
- {
- switch (wParam)
- {
- case PROP_FOCUSINDEX: //use the same code with PROP_SelectINDEX
- case PROP_SelectINDEX: //user wanna select the item
- {
- mmwItemPos *ps = (mmwItemPos*)dwParam;
- me->eMovingStep = MOVING_STEP_NONE;
- me->eMovingDirect = MOVING_NONE;
- //if it is napping, we do not take any action
- if (TRUE == me->bNapping)
- break;
- //check whether is right pos
- if (ps->indexCol >= me->mdt->itemColNum)
- ps->indexCol = me->mdt->itemColNum - 1;
- if (ps->indexRow >= me->mdt->itemRowNum)
- ps->indexRow = me->mdt->itemRowNum - 1;
- if (FALSE == MW_CAN_ITEM_TAKE_FOCUS(*ps))
- {
- #if 0
- int i, j;
- for (i = 0; i < me->mdt->itemRowNum ; i++)
- {
- for(j = 0; j < me->mdt->itemColNum ; j++)
- {
- if (TRUE == me->mdt->arrActiveItemData[i][j].bCanTakeFocus)
- {
- ps->indexCol = j;
- ps->indexRow = i;
- break;
- }
- }
- }
- #else
- //couldn't set focus to the item, just ignore it, so we break it.
- break; //break switch (wParam)
- #endif
- }
- if (me->newFocusItemPos.indexCol != ps->indexCol
- || me->newFocusItemPos.indexRow != ps->indexRow)
- MW_SEND_EVENT(EVT_MOVE, &me->newFocusItemPos);
- me->newFocusItemPos = *ps;
- me->oldFocusItemPos = me->newFocusItemPos;
- SET_RECT_BY_POS(me->newFocusItemRect, me->newFocusItemPos);
- me->oldFocusItemRect = me->newFocusItemRect;
- MW_SET_ANIMATION_POS(me->newFocusItemPos);
- #if defined MW_PRELOAD_IMAGES && defined MW_PRELOAD_ANIMATION
- MW_MOVE_ANI_LIST(me->oldAnimateList, me->newAnimateList);
- MW_LOAD_ANI_LIST_DEFAULT(me->animatingItemPos);
- me->bDrawImageFromNewList = TRUE;
- #endif
- //draw new active item immediately
- //WidgetBase_Invalidate(CAST(IWidget*, me), ICIF_REDRAW);
- //start its animation
- ISHELL_Resume(me->piShell, &me->cbkItemAnimation);
- //defer to call user's callback function
- if (PROP_SelectINDEX == wParam)
- {
- me->userSelectedPos = me->newFocusItemPos;
- me->bNapping = TRUE;
- ISHELL_SetTimer(me->piShell, 100, MainMenuWidget_SelectItem, (void*)me);
- }
- }
- break;
- ……
- }
- }
- ……
- }
以上为触摸屏添加的代码都用宏FEATURE_TOUCH_PANEL控制起来了。
正因为MainMenuWidget的灵活性,所以各个工程中各个使用到它的地方,可以很方便的(用宏)控制或切换效果。
注:网站后台程序会自动将Select转化为Select,代码中的PFNMMWSelectHANDLER、EVT_Select和PROP_SelectINDEX应为全部大写。
上一篇
下一篇

文章来自:
Tags:
相关日志:






