MTK的高亮机制
1、 对于MTK平台中高亮事件的简单分析,仅涉及MMI层的应用
牵涉函数:
void SetHiliteHandler( U16 itemid, FuncPtr hiliteFuncPtr );
void RegisterHighlightHandler( void (*f)(S32 item_index) );
void ExecuteCurrHiliteHandler( S32 hiliteid );
原理: 1. RegisterHighlightHandler(ExecuteCurrHiliteHandler)
A. ExecuteCurrHiliteHandler函数
通过当前高亮菜单的ID : hiliteItemID
执行与此ID关联的执行函数: maxHiliteInfo[hiliteItemID].entryFuncPtr
B. RegisterHighlightHandler函数
将上述函数指针(句柄)传给全局变量 MMI_list_highlight_handler 以便调用
通过RegisterHighligtHnder函数我们就可以知道,对于不同类型的菜单会有不同的全局变量,通过才这样的全局变量,系统其他部分的代码就可以直接使用该全局变量进行对高亮函数的调用。要注意的是对于每一个屏幕来说index都是从零开始的。
/*****************************************************************************
* FUNCTION
* RegisterHighlightHandler
* DESCRIPTION
* Registers the highlight handler to be called in menu screens
* PARAMETERS
* f [IN] Is a pointer to a highlight handler function
* This(?) [IN] Is a zero based index of the highlighted menuitem.
* RETURNS
* void
*****************************************************************************/
void RegisterHighlightHandler(void (*f) (S32 item_index))
{
MMI_list_highlight_handler = f;
MMI_matrix_highlight_handler = f;
MMI_circular_3D_highlight_handler = f;
}
/*****************************************************************************
* FUNCTION
* ExecuteCurrHiliteHandler
* DESCRIPTION
* This function finds out the current highlight menu item's handler and
* executes it with clear KEY_RIGHT_ARROW key handler. Sometimes the sub menu
* items may be hidden and the sub menu item index will be different. This
* function also handle this case.
* PARAMETERS
* hiliteid [IN] ID of the item for which highlight handler needs to
* be executed.
* RETURNS
* void
*****************************************************************************/
void ExecuteCurrHiliteHandler(S32 hiliteid)
{
/* To avoid the arrow left key to entry unexpected function, while other APP need they shall register
again as BY request. */
ClearKeyHandler(KEY_RIGHT_ARROW, KEY_EVENT_DOWN);
ExecuteCurrHiliteHandler_Ext(hiliteid);
}
通过该函数的注释就可以知道:当在一个菜单窗口中移动光标时,光标每动到一个菜单项时,系统(可能是Framwork模块)就会调用该函数找到对于菜单项的高亮处理函数并执行;因为ExecuteCurrHiliteHandler是去找该高亮函数,说明该函数已经在系统注册好了,那么该菜单项的高亮处理函数是在什么被注册的呢?就是在每个模块的初始化函数中,例如闹钟模块的 AlmInit()初始化函数。
另外注意的一点时,ExecuteCurrHiliteHandler只用于静态菜单,所谓静态菜单,就是在枚举GLOBALMENUITEMSID中有明确ID定义的菜单项。
还有一点是,该函数在查找子菜单项时会自动忽略掉那些隐藏的菜单项;如果你在你的业务逻辑中使用了如下的语句:
RegisterHighlightHandler(ExecuteCurrHiliteHandler);
则,如果你要获得KEY_RIGHT_ARROW键的功能 就必须重新向framework模块注册。否则KEY_RIGHT_ARROW键是没有任何相应的,因为每当高亮一个菜单项时ExecuteCurrHiliteHandler就被执行一次,同时KEY_RIGHT_ARROW键的功能也就没clear一次。那么在那里重新加入KEY_RIGHT_ARROW键的功能能,就在每个菜单项的高亮相应函数中,注意该菜单中每个菜单项高亮相应函数中都必须加入重新设置KEY_RIGHT_ARROW键的功能函数。
2. 关联高亮ID与执行函数
void SetHiliteHandler(U16 itemid, FuncPtr hiliteFuncPtr)
该函数将ID与函数关联:
maxHiliteInfo[itemid].entryFuncPtr = hiliteFuncPtr ;
itemid是传入的菜单ID, hiliteFuncPtr是传入的高亮执行函数
Note: Please distinguish the function SetHiliteHandler from
RegisterHighlightHandler() which is provided by UI layer.
SetHiliteHandler() is for single menu item;
RegisterHighlightHandler() is global for all menu items.
2、SetHintHandler()
DESCRIPTION
This function is used for register the handler for the menu item. If the
menu items are pre-definable, the applications use this function to set
the highlight handlers.(注意处的注释,说明了要用此函数向framework注册高亮函数,则该菜单项ID必须
已经提前被定义好了,也就是说必须是静态菜单项)。
Note: Please distinguish the function from RegisterHighlightHandler()
which is provided by UI layer. SetHiliteHandler() is for single
menu item; RegisterHighlightHandler() is global for all menu items.
[注意]
请注意 void SetHiliteHandler(U16 itemid, FuncPtr hiliteFuncPtr) 与
void ExecuteCurrHiliteHandler(S32 hiliteid)函数的参数区别,前者是itemid而后者是hiliteid,后者使用高亮菜单索引hiliteid和currParentID取得真正的itemid。参加如下代码:
void ExecuteCurrHiliteHandler_Ext(S32 hiliteid)
{
FuncPtr currFuncPtr = NULL;
S32 hiliteItemID;
currHiliteID = (U16) hiliteid;
if (currParentID == 0)
{
return;
}
/* check if menuitem is hidden */
hiliteItemID = GetSeqItemId_Ext((U16) currParentID, (S16) hiliteid); //返回真正的菜单项ID
currFuncPtr = maxHiliteInfo[hiliteItemID].entryFuncPtr
if (currFuncPtr)
{
(*currFuncPtr) ();
}
}
会先执行SetHintHandler注册的函数,然后执行
RegisterHighlightHandler注册的函数。注意SetHintHandler注册的函数是在ConstructHintsList()中被调用执行的,并不是在菜单高亮时被执行的,菜单高亮时只执行了RegisterHighlightHandler注册的函数。ConstructHintList将APP传入的指针数组于全局数组hintData[idx]相关联;而SetHitHandler注册的函数完成对全局数组hintData[idx]的赋值。
3 、ConstructHintsList()
Constructs Hint List for a static menu screen
void ConstructHintsList(U16 parentID, U8 **hintArray)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
U8 i, noOfChild;
U16 hiliteItemID[MAX_SUB_MENUS];
U8 idx = 0;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
noOfChild = (U8) GetNumOfChild(parentID);
for (i = 0; i < noOfChild; i++)
{
hiliteItemID[i] = GetSeqItemId((U16) parentID, (S16) i);
/* check if menuitem is hidden */
if (!mmi_frm_test_menu_item_hide(hiliteItemID[i])) /* the menuitem is not hidden */
{
if (maxHiliteInfo[hiliteItemID[i]].hintFuncPtr)
{
(*maxHiliteInfo[hiliteItemID[i]].hintFuncPtr) (idx);//SetHintHandler注册的函数的函数在此被执行
hintArray[idx] = hintData[idx];//该语句是该函数的核心,就是将全局变量hintData[idx]数组地址
//赋给用户传过来的指针数组;至于hintData[idx]中是否有数据不
//管;hintData[idx]的数据会在调用SetHintHandler注册的函数时对其
//进行初始化;要记住SetHintHandler注册的函数在SetHiliteHandler注册的
//函数之前执行。
idx++;
}
else
{
hintArray[idx++] = NULL;
}
}
}
}