@
目录前言
上一篇文章TP屏幕适配--驱动篇 介绍了TP屏幕底层驱动处理以及按键处理上报,这篇文章主要讲到UI界面如何对TP底层上报的按键手势等信息响应处理。
TP的上报处理流程
TP触屏信息上报的函数处理流程如下图所示:
graph LR start[开始]-->B(底层上报TP触屏信息) B-->C(TPCallBackFunc) C-->|当触屏在LCD屏内|D(MMK_DispatchExtSig P_TPP 正常发tp消息) C-->|当触屏在LCD屏外|E(MMK_DispatchExtSig KPDSVR 转成物理按键消息) D-->|LCD屏内坐标处理|F(MMK_DispatchMSGTp) E-->|按键码处理|G(MMK_DispatchMSGKbd) F-->|按下|F1(DispatchMSGTpDown) F-->|抬起|F2(DispatchMSGTpUp) F-->|移动|F3(DispatchMSGTpMove) G-->DEAL F1-->DEAL F2-->DEAL F3-->DEAL DEAL(各个UI窗口处理) DEAL-->|处理完成|END[结束]LCD屏内函数处理
分析下各个函数内部,实现了哪些操作
DispatchMSGTpDown
LOCAL void DispatchMSGTpDown(uint16 x, uint16 y)
{
MMI_HANDLE_T win_handle = 0;
MMI_HANDLE_T root_handle = 0;
MMI_HANDLE_T ctrl_handle = 0;
GUI_POINT_T point = {0};
MMI_MULTI_KEY_TP_MSG_PARAM_T para = {0};
MMI_RESULT_E tp_handle_result = MMI_RESULT_FALSE;
MMI_MESSAGE_ID_E msg_id = MSG_TP_PRESS_DOWN;
MMI_HANDLE_T focus_win = MMK_GetFocusWinHandle();
MMI_HANDLE_T old_handle = MMK_GetProcMsgHandle();
s_tp_status = MMI_TP_DOWN;
point.x = x;
point.y = y;
para.cur_tp_point.x = x;
para.cur_tp_point.y = y;
GetMultiKeyParam(¶); //处理同时多个按下
//根据点击的坐标点 获取当前窗口句柄
if (!MMK_GetHandleByPos(point, TRUE, &win_handle, &ctrl_handle, 0))
{
s_tp_dblclk_state = TP_DBLCLK_NONE;
return;
}
MMK_SetTPDownWin(win_handle);
if (MMK_GetWinDisplayStyleState(MMK_GerFocusMainWinHandle(), WS_NEED_DBLCLK))
{
if (TP_DBLCLK_NONE == s_tp_dblclk_state)
{
MMK_ReInitDblClkState(TRUE);
}
#if !defined RELEASE_INFO
{
static uint32 s_tp_down_tick = 0;
uint32 cur_tp_down_tick = SCI_GetTickCount();
SCI_TRACE_ID(TRACE_TOOL_CONVERT, MMK_TP_690_112_2_18_3_22_47_27, (uint8 *)"u",
cur_tp_down_tick - s_tp_down_tick);
s_tp_down_tick = cur_tp_down_tick;
}
#endif
//双击功能实现
if (TP_DBLCLK_NONE == s_tp_dblclk_state)
{
msg_id = MSG_TP_PRESS_DOWN;
s_tp_dblclk_state = TP_DBLCLK_PRE;
}
else if (TP_DBLCLK_PRE == s_tp_dblclk_state && focus_win == s_tp_down_win &&
abs(x - s_tp_point_x) <= MMI_TP_DBLCLK_MOVE && abs(y - s_tp_point_y) <= MMI_TP_DBLCLK_MOVE)
{
//如果两次点击在一定的区域范围内 认为是双击
MMK_ReInitDblClkState(FALSE);
msg_id = MSG_TP_PRESS_DOUBLE;
s_tp_dblclk_state = TP_DBLCLK_DONE;
}
else
{
MMK_ReInitDblClkState(TRUE);
msg_id = MSG_TP_PRESS_DOWN;
s_tp_dblclk_state = TP_DBLCLK_PRE;
}
s_tp_down_win = focus_win;
}
// set tp Tigger mode
MMITHEME_SetTiggerMode(MMITHEME_TRIGGER_MODE_TP);
MMK_SetProcMsgHandle(win_handle);
// check whether user hook handler
tp_handle_result = MMK_RunWinHookProc(win_handle, msg_id, (DPARAM)¶);
if (MMI_RESULT_FALSE != tp_handle_result)
{
SetTPDownCtrl(0);
}
else
{
// get root form control handle
root_handle = MMK_GetRootFormCtrlHandle(win_handle);
if (!(MMK_PosIsCtrl(root_handle, point) && MMK_IsResponseToClick(root_handle)))
{
root_handle = 0;
}
if (0 != root_handle)
{
SetTPDownCtrl(root_handle);
tp_handle_result = MMK_RunCtrlProc(root_handle, msg_id, (DPARAM)¶);
}
}
//以下分别通知UI控件进行处理
if (MMI_RESULT_FALSE == tp_handle_result)
{
if (0 != ctrl_handle)
{
SetTPDownCtrl(ctrl_handle);
MMK_SetAtvCtrl(win_handle, ctrl_handle);
tp_handle_result = MMK_RunCtrlProc(ctrl_handle, msg_id, (DPARAM)¶);
}
else
{
SetTPDownCtrl(0);
// call the default proces function to
tp_handle_result = DefaultProcessWinTPMsg(win_handle, msg_id, (DPARAM)¶);
}
}
// check window callback handler
if (MMI_RESULT_FALSE == tp_handle_result)
{
// dispatch the window
tp_handle_result = MMK_RunWinProc(win_handle, msg_id, (DPARAM)¶);
}
MMK_SetProcMsgHandle(old_handle);
}
DispatchMSGTpUp
LOCAL void DispatchMSGTpUp(uint16 x, uint16 y)
{
MMI_HANDLE_T win_handle = 0;
GUI_POINT_T point = {0};
MMI_RESULT_E tp_handle_result = MMI_RESULT_FALSE;
MMI_MULTI_KEY_TP_MSG_PARAM_T para = {0};
MMI_MESSAGE_ID_E msg_id = MSG_TP_PRESS_UP;
MMI_HANDLE_T old_handle = MMK_GetProcMsgHandle();
s_tp_status = MMI_TP_NONE;
s_is_tp_move = FALSE;
s_is_delay_tp_move = FALSE;
point.x = x;
point.y = y;
para.cur_tp_point.x = x;
para.cur_tp_point.y = y;
//获取同时按下的 多个按键参数
GetMultiKeyParam(¶);
//根据坐标 获取当前窗口的句柄
if (!MMK_GetHandleByPos(point, TRUE, &win_handle, PNULL, 0))
{
// 如果没有找到 则返回NONE
s_tp_dblclk_state = TP_DBLCLK_NONE;
return;
}
//检查TP是否成对
if (!CheckTPPair(win_handle))
{
return;
}
// 检查判断是不是双击
if (MMK_GetWinDisplayStyleState(MMK_GerFocusMainWinHandle(), WS_NEED_DBLCLK))
{
if (TP_DBLCLK_DONE == s_tp_dblclk_state)
{
msg_id = MSG_TP_PRESS_DBLCLK_UP;
s_tp_dblclk_state = TP_DBLCLK_NONE;
// SCI_TRACE_LOW:"@DBLCLK, MSG_TP_PRESS_DBLCLK_UP"
SCI_TRACE_ID(TRACE_TOOL_CONVERT, MMK_TP_881_112_2_18_3_22_47_34, (uint8 *)"");
}
else
{
// SCI_TRACE_LOW:"@DBLCLK, MSG_TP_PRESS_UP"
SCI_TRACE_ID(TRACE_TOOL_CONVERT, MMK_TP_885_112_2_18_3_22_47_35, (uint8 *)"");
}
}
//设置需要处理消息的窗口 s_proc_msg_handle
MMK_SetProcMsgHandle(win_handle);
// check whether user hook handler
tp_handle_result = MMK_RunWinHookProc(win_handle, msg_id, (DPARAM)¶);
// check ctrl handler
if (MMI_RESULT_FALSE == tp_handle_result)
{
tp_handle_result = DefaultProcessTPMsg(win_handle, msg_id, (DPARAM)¶);
}
//关掉TP按下控制 即成对处理完成
SetTPDownCtrl(0);
MMK_SetTPDownWin(0);
//以下分别通知UI控件进行处理
if (MMI_RESULT_FALSE == tp_handle_result)
{
// dispatch the window
tp_handle_result = MMK_RunWinProc(win_handle, msg_id, (DPARAM)¶);
if (MMI_RESULT_FALSE == tp_handle_result)
{
tp_handle_result = DefaultProcessWinTPMsg(win_handle, msg_id, (DPARAM)¶);
}
}
MMK_SetProcMsgHandle(old_handle);
}
DispatchMSGTpMove
LOCAL void DispatchMSGTpMove(uint16 pre_point_x, uint16 pre_point_y, uint16 cur_point_x, uint16 cur_point_y)
{
MMI_HANDLE_T win_handle = 0;
GUI_POINT_T point = {0};
MMI_RESULT_E tp_handle_result = MMI_RESULT_FALSE;
MMI_MULTI_KEY_TP_MSG_PARAM_T para = {0};
MMI_HANDLE_T old_handle = MMK_GetProcMsgHandle();
s_is_tp_move = TRUE;
// set point
point.x = cur_point_x;
point.y = cur_point_y;
// set parameter
para.cur_tp_point.x = cur_point_x;
para.cur_tp_point.y = cur_point_y;
para.pre_tp_point.x = pre_point_x;
para.pre_tp_point.y = pre_point_y;
GetMultiKeyParam(¶);
//获取坐标所在的句柄
if (!MMK_GetHandleByPos(point, TRUE, &win_handle, PNULL, 0))
{
return;
}
//检查是否成对
if (!CheckTPPair(win_handle))
{
return;
}
//设置当前使用的句柄
MMK_SetProcMsgHandle(win_handle);
//以下分别通知UI控件进行处理
tp_handle_result = MMK_RunWinHookProc(win_handle, MSG_TP_PRESS_MOVE, (DPARAM)¶);
// check ctrl handler
if (MMI_RESULT_FALSE == tp_handle_result)
{
tp_handle_result = DefaultProcessTPMsg(win_handle, MSG_TP_PRESS_MOVE, (DPARAM)¶);
}
// check window callback handler
if (MMI_RESULT_FALSE == tp_handle_result)
{
tp_handle_result = MMK_RunWinProc(win_handle, MSG_TP_PRESS_MOVE, (DPARAM)¶);
}
MMK_SetProcMsgHandle(old_handle);
}
UI界面
主菜单界面
主菜单界面的实现由mmi_mainmenu_matrix.c里面MatrixMenuHandle函数来处理
LOCAL MMI_RESULT_E MatrixMenuHandle(void *pm_data_ptr, MMI_MESSAGE_ID_E msg_id, DPARAM param)
{
#ifdef UI_MULTILAYER_SUPPORT
GUI_LCD_DEV_INFO lcd_dev_info = {0};
#endif
MMI_RESULT_E result = MMI_RESULT_TRUE;
MMIMAINMENU_MATRIX_DATA_T *menu_ctrl_ptr = (MMIMAINMENU_MATRIX_DATA_T *)pm_data_ptr;
GUI_POINT_T point = {0};
if (PNULL == menu_ctrl_ptr)
{
return MMI_RESULT_FALSE;
}
switch (msg_id)
{
//... 省略部分代码
#if defined(TOUCH_PANEL_SUPPORT) || defined(TOUCH_PANEL_CTRL_SUPPORT_MMI)
case MSG_TP_PRESS_DOWN:
point.x = MMK_GET_TP_X(param);
point.y = MMK_GET_TP_Y(param);
MMITheme_StopControlText();
//进行区域计算等处理
HandleMatrixMenuTpDown(&point, menu_ctrl_ptr);
HandleTextToSpeech(menu_ctrl_ptr);
break;
case MSG_TP_PRESS_UP:
point.x = MMK_GET_TP_X(param);
point.y = MMK_GET_TP_Y(param);
HandleMatrixMenuTpUp(&point, menu_ctrl_ptr);
HandleTextToSpeech(menu_ctrl_ptr);
break;
case MSG_TP_PRESS_MOVE:
point.x = MMK_GET_TP_X(param);
point.y = MMK_GET_TP_Y(param);
HandleMatrixMenuTpMove(&point, menu_ctrl_ptr);
break;
case MSG_TP_PRESS_LONG:
case MSG_TP_PRESS_SHORT:
// 处理tp short 消息
HandleMatrixMenuSpecialMsg(menu_ctrl_ptr, msg_id, param);
break;
#endif
//... 省略部分代码
default:
result = MMI_RESULT_FALSE;
break;
}
return result;
}
Softkey界面
Softkey界面由ctrlsoftkey.c里面的GUISOFTKEY_HandleMsg函数来进行处理
LOCAL MMI_RESULT_E GUISOFTKEY_HandleMsg(CTRLBASE_OBJ_T *ctrl_ptr, MMI_MESSAGE_ID_E msg_id, DPARAM param)
{
#if defined(TOUCH_PANEL_SUPPORT) || defined(TOUCH_PANEL_CTRL_SUPPORT_MMI)
GUI_POINT_T point = {0};
#endif
int16 i = 0;
CTRLSOFTKEY_OBJ_T *softkey_ptr = PNULL;
MMI_RESULT_E recode = MMI_RESULT_TRUE;
if (PNULL == ctrl_ptr)
{
return MMI_RESULT_FALSE;
}
softkey_ptr = (CTRLSOFTKEY_OBJ_T *)ctrl_ptr;
if (!softkey_ptr->is_visible)
{
return MMI_RESULT_FALSE;
}
switch (msg_id)
{
case MSG_CTL_OPEN:
break;
case MSG_CTL_PAINT:
DrawSoftkey(softkey_ptr);
break;
case MSG_NOTIFY_UPDATE:
if (IsButtonStyle(softkey_ptr->style))
{
GUIBUTTONSOFTKEY_DrawBg(softkey_ptr, (GUI_RECT_T *)param);
}
break;
case MSG_CTL_LOSE_FOCUS:
if (!IsButtonStyle(softkey_ptr->style))
{
for (i = 0; i < GUISOFTKEY_BUTTON_NUM; i++)
{
SetWinSKBButtonPressed(softkey_ptr, i, FALSE);
}
SetWinSKBPressed(softkey_ptr, FALSE);
}
break;
#if defined(TOUCH_PANEL_SUPPORT) || defined(TOUCH_PANEL_CTRL_SUPPORT_MMI)
case MSG_TP_PRESS_DOWN:
case MSG_TP_PRESS_UP:
case MSG_TP_PRESS_LONG:
case MSG_TP_PRESS_MOVE:
if (!IsButtonStyle(softkey_ptr->style))
{
point.x = MMK_GET_TP_X(param);
point.y = MMK_GET_TP_Y(param);
//传入坐标,处理TP事件
recode = HandleSoftkeyBarTPMsg(softkey_ptr, msg_id, point);
}
break;
#endif
default:
recode = MMI_RESULT_FALSE;
break;
}
return recode;
}
// HandleSoftkeyBarTPMsg 对按下,移动,抬起 进行详细处理
LOCAL MMI_RESULT_E HandleSoftkeyBarTPMsg(CTRLSOFTKEY_OBJ_T *softkey_ptr, MMI_MESSAGE_ID_E msg_id, GUI_POINT_T point)
{
MMI_RESULT_E result = MMI_RESULT_FALSE;
#if defined(TOUCH_PANEL_SUPPORT) || defined(TOUCH_PANEL_CTRL_SUPPORT_MMI)
BOOLEAN is_send_msg = FALSE;
MMI_MESSAGE_ID_E send_msg_id = 0;
int16 i = 0;
GUI_RECT_T softkey_rect = {0};
MMI_RESULT_E pre_result = MMI_RESULT_FALSE;
MMI_HANDLE_T win_handle = 0;
MMI_HANDLE_T ctrl_handle = 0;
BOOLEAN is_press_long = FALSE;
CTRLBASE_OBJ_T *ctrl_ptr = (CTRLBASE_OBJ_T *)softkey_ptr;
static BOOLEAN s_tplong_handle = FALSE; //如果tp long消息被处理了,则tp up消息不再处理
if (PNULL == softkey_ptr)
{
return MMI_RESULT_FALSE;
}
win_handle = softkey_ptr->win_handle;
softkey_rect = ctrl_ptr->rect;
//因为窗口表里面定义了Txt_null,表明不需要softkey的,但是系统已经把区域给了,所以这里特殊处理下。(使系统不处理tp)
if (MSG_TP_PRESS_DOWN == msg_id && GUI_PointIsInRect(point, MMITHEME_GetSoftkeyRect(MIDDLE_BUTTON)) &&
GUISK_DATA_TEXT_ID == softkey_ptr->button_arr[MIDDLE_BUTTON].content.data_type &&
MMITHEME_IsMidkeyNull(softkey_ptr->button_arr[MIDDLE_BUTTON].content.data_u.text_id))
{
return MMI_RESULT_FALSE;
}
//先确认按键是否可见
if (!softkey_ptr->tp_disable)
{
//如果tp long消息被窗口处理了,则tp up消息不再处理
if (MSG_TP_PRESS_DOWN == msg_id)
{
s_tplong_handle = FALSE;
}
else if (MSG_TP_PRESS_UP == msg_id && s_tplong_handle)
{
s_tplong_handle = FALSE;
return MMI_RESULT_TRUE;
}
if (MSG_TP_PRESS_DOWN == msg_id)
{
if (GUI_PointIsInRect(point, softkey_rect))
{
SetWinSKBPressed(softkey_ptr, TRUE);
}
else
{
//点击区域不在softkey内
return MMI_RESULT_FALSE;
}
}
else if (!GetWinSKBPressed(softkey_ptr))
{
// softkey 未按下
return MMI_RESULT_FALSE;
}
}
else
{
//窗口无softkey
return MMI_RESULT_FALSE;
}
switch (msg_id)
{
case MSG_TP_PRESS_DOWN:
SetWinSKBPressed(softkey_ptr, TRUE);
//是否点中软键区的某个button 图标
for (i = 0; i < GUISOFTKEY_BUTTON_NUM; i++)
{
//处理按下了 左中右哪个按键
SetWinSKBButtonPressed(softkey_ptr, i, FALSE);
if (softkey_ptr->button_arr[i].is_show && GUI_PointIsInRect(point, softkey_ptr->button_arr[i].rect) &&
!softkey_ptr->button_arr[i].is_gray)
{
//画按下的效果
DrawPressedSoftkey(softkey_ptr, point, TRUE);
SetWinSKBButtonPressed(softkey_ptr, i, TRUE);
break;
}
}
result = MMI_RESULT_TRUE;
break;
case MSG_TP_PRESS_UP:
if (GetWinSKBPressed(softkey_ptr))
{
result = HandleSoftkeyBar(softkey_ptr, point); // handle the softkey
for (i = 0; i < GUISOFTKEY_BUTTON_NUM; i++)
{
if (softkey_ptr->button_arr[i].is_show && softkey_ptr->button_arr[i].is_pressed)
{
SetWinSKBButtonPressed(softkey_ptr, i, FALSE);
DrawSoftkeyByIndex(softkey_ptr, i, FALSE);
}
}
SetWinSKBPressed(softkey_ptr, FALSE);
if (MMI_RESULT_FALSE == result)
{
result = MMI_RESULT_TRUE;
}
}
break;
case MSG_TP_PRESS_LONG:
if (GetWinSKBPressed(softkey_ptr))
{
//是否在软键区内,并进行处理
result = HandleSoftkeyBar(softkey_ptr, point); // handle the softkey
for (i = 0; i < GUISOFTKEY_BUTTON_NUM; i++)
{
if (softkey_ptr->button_arr[i].is_pressed &&
GUI_PointIsInRect(point, softkey_ptr->button_arr[i].rect) &&
softkey_ptr->button_arr[i].is_long_press)
{
SetWinSKBButtonPressed(softkey_ptr, i, FALSE);
DrawSoftkeyByIndex(softkey_ptr, i, FALSE);
s_tplong_handle = TRUE;
SetWinSKBPressed(softkey_ptr, FALSE);
}
}
if (!s_tplong_handle)
{
result = MMI_RESULT_TRUE;
}
}
break;
case MSG_TP_PRESS_MOVE:
if (GetWinSKBPressed(softkey_ptr))
{
for (i = 0; i < GUISOFTKEY_BUTTON_NUM; i++)
{
if (softkey_ptr->button_arr[i].is_pressed &&
!GUI_PointIsInRect(point, softkey_ptr->button_arr[i].rect))
{
SetWinSKBButtonPressed(softkey_ptr, i, FALSE);
DrawSoftkeyByIndex(softkey_ptr, i, FALSE);
}
else if (softkey_ptr->button_arr[i].is_show &&
GUI_PointIsInRect(point, softkey_ptr->button_arr[i].rect) &&
!softkey_ptr->button_arr[i].is_pressed && !softkey_ptr->button_arr[i].is_gray)
{
DrawPressedSoftkey(softkey_ptr, point, TRUE);
SetWinSKBButtonPressed(softkey_ptr, i, TRUE);
}
}
result = MMI_RESULT_TRUE;
}
break;
default:
result = MMI_RESULT_FALSE;
break;
}
if (MMI_RESULT_FALSE != result && MSG_TP_PRESS_LONG == msg_id)
{
is_press_long = TRUE;
}
// handle the softkey bar
pre_result = result;
switch (result)
{
case GUI_RESULT_CTLOK:
if (!is_press_long)
{
is_send_msg = TRUE;
send_msg_id = MSG_APP_OK;
}
break;
case GUI_RESULT_CTLCANCEL:
is_send_msg = TRUE;
if (!is_press_long)
{
send_msg_id = MSG_APP_CANCEL;
}
else
{
send_msg_id = MSG_KEYLONG_CANCEL;
}
break;
case GUI_RESULT_CTLMDL:
if (!is_press_long)
{
is_send_msg = TRUE;
send_msg_id = MSG_APP_WEB;
}
break;
default:
break;
}
// get active control handle
ctrl_handle = MMK_GetActiveCtrl(win_handle);
if ((0 != ctrl_handle) && (is_send_msg))
{
result = MMK_RunCtrlProc(ctrl_handle, send_msg_id, PNULL);
if (!result)
{
// get parent handle
ctrl_handle = MMK_GetParentCtrlHandle(ctrl_handle);
while (0 != ctrl_handle)
{
result = MMK_RunCtrlProc(ctrl_handle, send_msg_id, PNULL);
if (result)
{
break;
}
ctrl_handle = MMK_GetParentCtrlHandle(ctrl_handle);
}
}
}
if ((MMI_RESULT_FALSE == result) || (pre_result == result))
{
result = MMK_RunWinProc(win_handle, send_msg_id, PNULL);
}
#endif
return result;
}
标签:handle,point,--,适配,TP,MMI,UI,softkey,ptr
From: https://www.cnblogs.com/Wei-Ting/p/17182210.html