mmi培训资料自定义模板.docx
《mmi培训资料自定义模板.docx》由会员分享,可在线阅读,更多相关《mmi培训资料自定义模板.docx(14页珍藏版)》请在冰豆网上搜索。
mmi培训资料自定义模板
mtk平台mmi培训资料(中文)
2008-06-0621:
48
本文详细说明了如何建设一个自定义列表窗体模板。
原理部分请参见《MTK平台
(1)——如何添加一个窗体模板》。
最终实现的是一个字典输入界面。
布局为:
该模板不包含业务逻辑,仅提供页面显示和InputBox框输入事件后的ListBox的Redraw事件的注册,以及基本的输入法设置、清空后的返回函数。
一、添加用户自定义列表模板的过程
(一)在g_categories_controls_map[]中加入:
{MMI_CATEGORY_CUSTOM_LIST,(U8*)custom_define_list,(s16*)coordinate_custom_list,NULL}
constU8custom_define_list[]=
{
5,
DM_BASE_LAYER_START,
DM_SCR_BG,
DM_BASE_CONTROL_SET1,
DM_SINGLELINE_INPUTBOX1,
DM_LIST1
};
constS16coordinate_custom_list[]=
DM_FULL_SCREEN_COORDINATE_FLAG,
DM_CUSTOM_DEFINE_INPUTBOX, //需要定义
DM_CUSTOM_DEFINE_LIST //需要定义
(二)在dm_get_coordinates()函数中加入:
//设定列表位置和大小(不要忘记全局变量MMI_custom_Listbox_x等的定义)
elseif(*UICtrlAccessPtr_p==DM_CUSTOM_DEFINE_LIST)
dm_coordinate_info->s16X=MMI_custom_Listbox_x;
dm_coordinate_info->s16Y=MMI_custom_Listbox_y; dm_coordinate_info->s16Width=MMI_custom_Listbox_width; dm_coordinate_info->s16Height=MMI_custom_Listbox_height;
dm_coordinate_info->Flags=DM_NO_FLAGS;
UICtrlAccessPtr_p++;
}
//设定输入框位置和大小
elseif(*UICtrlAccessPtr_p==DM_CUSTOM_DEFINE_INPUTBOX)
dm_coordinate_info->s16X=MMI_custom_inputbox_x;
dm_coordinate_info->s16Y=MMI_custom_inputbox_y;
dm_coordinate_info->s16Width=MMI_custom_inputbox_width;
dm_coordinate_info->s16Height=MMI_custom_inputbox_height; dm_coordinate_info->Flags=DM_SINGLE_LINE_INPUTBOX_SPECIFIC_HEIGHT;
(三)在Wgui_category.c中定义模板显示函数
voidShowCategoryCustomListScreen(
U8*title,
U16title_icon,
U16left_softkey,
U16left_softkey_icon,
U16right_softkey,
U16right_softkey_icon,
S32number_of_items,
U8**list_of_items,
U16*list_of_icons,
S32flags,
S32highlighted_item,
U8*history_buffer)
/*----------------------------------------------------------------*/
/*LocalVariables */
dm_data_structdm_data;
S32i;
U8h_flag;
/*CodeBody */
gdi_layer_lock_frame_buffer();
SetupCategoryKeyHandlers();
MMI_title_string=(UI_string_type)title;
MMI_title_icon=(PU8)get_image(title_icon);
change_left_softkey(left_softkey,left_softkey_icon);
change_right_softkey(right_softkey,right_softkey_icon);
//CreateList
create_fixed_icontext_menuitems();
associate_fixed_icontext_list();
ShowListCategoryScreen(
(UI_string_type)title,
get_image(title_icon),
get_string(left_softkey),
get_image(left_softkey_icon),
get_string(right_softkey),
get_image(right_softkey_icon),
number_of_items);
for(i=0;i { add_fixed_icontext_item((UI_string_type)list_of_items[i],wgui_get_list_menu_icon(i,list_of_icons[i])); } h_flag=set_list_menu_category_history(MMI_CATEGORY_CUSTOM_LIST,history_buffer); if(h_flag) { fixed_list_goto_item_no_redraw(MMI_fixed_list_menu.highlighted_item); } else { fixed_list_goto_item_no_redraw(highlighted_item); }//CreateInputbox memset(custom_single_input_buffer,0,100); pfnUnicodeStrcpy(custom_single_input_buffer,L"CustomCategory"); wgui_setup_singleline_inputbox( 0, 0, 240, 320, custom_single_input_buffer, pfnUnicodeStrlen(custom_single_input_buffer), MMI_CATEGORY_CUSTOM_LIST, get_string(right_softkey), get_image(right_softkey_icon), INPUT_TYPE_ALPHANUMERIC_LOWERCASE|INPUT_TYPE_USE_ONLY_ENGLISH_MODES, history_buffer, 0); register_hide_multitap(wgui_hide_multitap); gdi_layer_unlock_frame_buffer(); ExitCategoryFunction=ExitCategoryCustomListScreen; dm_setup_category_functions(dm_redraw_category_screen,dm_get_category_history,dm_get_category_history_size); dm_data.s32ScrId=(S32)GetActiveScreenId(); dm_data.s32CatId=MMI_CATEGORY_CUSTOM_LIST; //不要忘记该常量MMI_CATEGORY_CUSTOM_LIST的定义 dm_data.s32flags|=DM_CLEAR_SCREEN_BACKGROUND; //dm_data.s32flags|=DM_SHOW_VKPAD; dm_register_vkpad_callback(CustomList_virtual_keypad_callback); dm_setup_data(&dm_data); dm_redraw_category_screen();} /*endofShowCategory353Screen*/voidCustomList_virtual_keypad_callback(void){#ifdefined(__MMI_TOUCH_SCREEN__) mmi_pen_editor_clear_and_show_virtual_keyboard_area();#endif gui_show_transparent_image(0,200,GetImage(IMG_H_SELECT_LEFT),0);}voidExitCategoryCustomListScreen(){wgui_close_singleline_inputbox();}(四)在singleline_inputbox_multitap_input()函数中添加用户处理key_0~key_9的按键事件的函数:void(*singleline_inputbox_custom_input_callback)(void)=UI_dummy_function;voidsingleline_inputbox_multitap_input(UI_character_typec){ /*----------------------------------------------------------------*/ /*LocalVariables */ /*----------------------------------------------------------------*/ /*----------------------------------------------------------------*/ /*CodeBody */ /*----------------------------------------------------------------*/ if(MMI_singleline_inputbox.flags&UI_SINGLE_LINE_INPUT_BOX_PLUS_CHARACTER_HANDLING) { if((MMI_singleline_inputbox.text[0]=='+')&& (MMI_singleline_inputbox.current_text_p==MMI_singleline_inputbox.text)&& (MMI_singleline_inputbox.text_length>=(MMI_singleline_inputbox.available_length-ENCODING_LENGTH))) { return; } } gui_single_line_input_box_insert_multitap_character(&MMI_singleline_inputbox,c); redraw_singleline_inputbox(); singleline_inputbox_input_callback(); singleline_inputbox_custom_input_callback();}(五)Wgui_Category.c中添加用户事件定义接口//右键事件注册voidSetCategoryCustomListRightSoftkeyFunction(void(*f)(void)){ wgui_singleline_inputbox_RSK_function=f;}//key_0到key_9按下时的事件注册externvoid(*singleline_inputbox_custom_input_callback)(void);voidSetCategoryCustomListNumKeyFunction(void(*f)(void)){singleline_inputbox_custom_input_callback=f;}//设置InputBox大小voidSetCustomList_Inputbox_Size(S32p_x,S32p_y,S32p_width,S32p_height){MMI_custom_inputbox_x=p_x;MMI_custom_inputbox_y=p_y;MMI_custom_inputbox_width=p_width;MMI_custom_inputbox_height=p_height;}//设置ListBox大小voidSetCustomList_Listbox_Size(S32p_x,S32p_y,S32p_width,S32p_height){MMI_custom_Listbox_x=p_x;MMI_custom_Listbox_y=p_y;MMI_custom_Listbox_width=p_width;MMI_custom_Listbox_height=p_height;}二、自定义列表模板的使用方法1、调用SetCustomList_Inputbox_Size和SetCustomList_Listbox_Size设置列表框和输入框的大小。2、调用显示窗体的接口ShowCategoryCustomListScreen。3、调用右键事件注册函数,注册文本框被清空后的事件(如返回等)SetCategoryCustomListRightSoftkeyFunction。4、调用key_0至key_9的事件注册函数,SetCategoryCustomListNumKeyFunction()。三、参数详细说明①voidSetCustomList_Inputbox_Size(S32p_x,S32p_y,S32p_width,S32p_height)与 voidSetCustomList_Listbox_Size(S32p_x,S32p_y,S32p_width,S32p_height)p_x,p_y:起始位置p_width,p_height:大小。②voidSetCategoryCustomListRightSoftkeyFunction(void(*f)(void)) voidSetCategoryCustomListNumKeyFunction(void(*f)(void)) f(void):函数地址。③voidShowCategoryCustomListScreen( U8*title, //标题文本指针 U16title_icon, //标题图标ID U16left_softkey, //左键文本ID U16left_softkey_icon, //左键图标ID U16right_softkey, //右键文本ID U16right_softkey_icon, //右键图标ID U8*custom_single_input_buffer,//Input输入Buffer S32number_of_items, //列表条目数 U8**list_of_items, //列表项文本指针数组 U16*list_of_icons, //列表项Icon S32highlighted_item, //当前高亮显示的列表条目 U8*history_buffer) //历史记录Buffer附:所需更改的文件wgui.cwgui_categories.cwgui_draw_manager.cwgui_inputs.cwgui.hwgui_categories_defs.hwgui_draw_manager.hCustCoordinate.c一、什么是History管理 对于我们上层用户而言,经常接触到的History管理是这样的: voidEntryFunc(){U8*guiBuffer; EntryNewScreen(Screen_ID,Exit_Func,Entry_Func,NULL); guiBuffer=GetCurrGuiBuffer(SCR_ID_WORDMAIN_LIST); ShowCategroyXXScreen(Title_ID,…,guiBuffer); }但是,无论是EntryNewScreen的调用,还是guiBuffer的传入,我们都很少考虑过对这些指针和函数在GUI的管理起到了什么样的作用。下面我们就要了解,以上的代码与History管理之间存在的关系。 在MTK环境中,每当我们进入一个窗口,系统将先提取前一个窗口需保留的数据。这些数据包括:1. 窗口ID;2. 进入窗口时调用的函数和退出调用的函数--Exit_Func和Entry_Func;3. 组成窗体的控件的属性(如,列表控件当前高亮显示的条目、当前屏的首末条目等)。举例说明这些数据在实际中是如何被使用的。假设存在AB两个窗口,A窗口需要保留的数据为data_A。我们先从A窗口进入到B窗口。data_A将在B窗口调用EntryNewScreen()的时候,被压入一个结构类似于栈的数据存储区域;当从B调用GoBackHistory()返回A时,data_A从栈顶被弹出,然后A利用data_A将自身还原到其进入B之前的状态。这就是History管理的作用。简言之,就是要保持窗口的外观状态。二、History管理的机制 现在,我们来了解一下前面所说的data_A的数据结构是什么样的。typedefstruct_history{ U16scrnID; //(1)ScreenID(窗口号) FuncPtrentryFuncPtr; //(2)EntryNewScreen时要进入的Entry_Func U8inputBuffer[MAX_INPUT_BUFFER]; //(3)没遇到过其使用,都是NULL。 U8guiBuffer[MAX_GUI_BUFFER]; //(4)窗体中控件的一些需保存的信息的Buffer,通常//在使用时被转化成各控件自定义的结构体如:list_menu_category_history。}history; 而存放data_A的类似于堆栈的数据区则以全局变量的形式定义在系统中:historyNodehistoryData[MAX_HISTORY];(MAX_HISTORY=50):设当前窗口A所对应的数据是historyData[EntryScreenNum–1],那么它是何时、是如何被赋值的?又是何时、如何被使用的?经过跟踪调试,我们已经知道,在由窗口A进入到窗口B(调用EntryNewScreen)的时候,我们
add_fixed_icontext_item((UI_string_type)list_of_items[i],wgui_get_list_menu_icon(i,list_of_icons[i]));
h_flag=set_list_menu_category_history(MMI_CATEGORY_CUSTOM_LIST,history_buffer);
if(h_flag)
fixed_list_goto_item_no_redraw(MMI_fixed_list_menu.highlighted_item);
else
fixed_list_goto_item_no_redraw(highlighted_item);
//CreateInputbox
memset(custom_single_input_buffer,0,100);
pfnUnicodeStrcpy(custom_single_input_buffer,L"CustomCategory");
wgui_setup_singleline_inputbox(
0,
240,
320,
custom_single_input_buffer,
pfnUnicodeStrlen(custom_single_input_buffer),
MMI_CATEGORY_CUSTOM_LIST,
INPUT_TYPE_ALPHANUMERIC_LOWERCASE|INPUT_TYPE_USE_ONLY_ENGLISH_MODES,
history_buffer,
0);
register_hide_multitap(wgui_hide_multitap);
gdi_layer_unlock_frame_buffer();
ExitCategoryFunction=ExitCategoryCustomListScreen;
dm_setup_category_functions(dm_redraw_category_screen,dm_get_category_history,dm_get_category_history_size);
dm_data.s32ScrId=(S32)GetActiveScreenId();
dm_data.s32CatId=MMI_CATEGORY_CUSTOM_LIST;
//不要忘记该常量MMI_CATEGORY_CUSTOM_LIST的定义
dm_data.s32flags|=DM_CLEAR_SCREEN_BACKGROUND;
//dm_data.s32flags|=DM_SHOW_VKPAD;
dm_register_vkpad_callback(CustomList_virtual_keypad_callback);
dm_setup_data(&dm_data);
dm_redraw_category_screen();
} /*endofShowCategory353Screen*/
voidCustomList_virtual_keypad_callback(void)
#ifdefined(__MMI_TOUCH_SCREEN__)
mmi_pen_editor_clear_and_show_virtual_keyboard_area();
#endif
gui_show_transparent_image(0,200,GetImage(IMG_H_SELECT_LEFT),0);
voidExitCategoryCustomListScreen()
wgui_close_singleline_inputbox();
(四)在singleline_inputbox_multitap_input()函数中添加用户处理key_0~key_9的按键事件的函数:
void(*singleline_inputbox_custom_input_callback)(void)=UI_dummy_function;
voidsingleline_inputbox_multitap_input(UI_character_typec)
if(MMI_singleline_inputbox.flags&UI_SINGLE_LINE_INPUT_BOX_PLUS_CHARACTER_HANDLING)
if((MMI_singleline_inputbox.text[0]=='+')&&
(MMI_singleline_inputbox.current_text_p==MMI_singleline_inputbox.text)&&
(MMI_singleline_inputbox.text_length>=(MMI_singleline_inputbox.available_length-ENCODING_LENGTH)))
return;
gui_single_line_input_box_insert_multitap_character(&MMI_singleline_inputbox,c);
redraw_singleline_inputbox();
singleline_inputbox_input_callback();
singleline_inputbox_custom_input_callback();
(五)Wgui_Category.c中添加用户事件定义接口
//右键事件注册
voidSetCategoryCustomListRightSoftkeyFunction(void(*f)(void))
wgui_singleline_inputbox_RSK_function=f;
//key_0到key_9按下时的事件注册
externvoid(*singleline_inputbox_custom_input_callback)(void);
voidSetCategoryCustomListNumKeyFunction(void(*f)(void))
singleline_inputbox_custom_input_callback=f;
//设置InputBox大小
voidSetCustomList_Inputbox_Size(S32p_x,S32p_y,S32p_width,S32p_height)
MMI_custom_inputbox_x=p_x;
MMI_custom_inputbox_y=p_y;
MMI_custom_inputbox_width=p_width;
MMI_custom_inputbox_height=p_height;
//设置ListBox大小
voidSetCustomList_Listbox_Size(S32p_x,S32p_y,S32p_width,S32p_height)
MMI_custom_Listbox_x=p_x;
MMI_custom_Listbox_y=p_y;
MMI_custom_Listbox_width=p_width;
MMI_custom_Listbox_height=p_height;
二、自定义列表模板的使用方法
1、调用SetCustomList_Inputbox_Size和SetCustomList_Listbox_Size设置列表框和输入框的大小。
2、调用显示窗体的接口ShowCategoryCustomListScreen。
3、调用右键事件注册函数,注册文本框被清空后的事件(如返回等)SetCategoryCustomListRightSoftkeyFunction。
4、调用key_0至key_9的事件注册函数,SetCategoryCustomListNumKeyFunction()。
三、参数详细说明
①voidSetCustomList_Inputbox_Size(S32p_x,S32p_y,S32p_width,S32p_height)与
p_x,p_y:
起始位置
p_width,p_height:
大小。
②voidSetCategoryCustomListRightSoftkeyFunction(void(*f)(void))
f(void):
函数地址。
③voidShowCategoryCustomListScreen(
U8*title, //标题文本指针
U16title_icon, //标题图标ID
U16left_softkey, //左键文本ID
U16left_softkey_icon, //左键图标ID
U16right_softkey, //右键文本ID
U16right_softkey_icon, //右键图标ID
U8*custom_single_input_buffer,//Input输入Buffer
S32number_of_items, //列表条目数
U8**list_of_items, //列表项文本指针数组
U16*list_of_icons, //列表项Icon
S32highlighted_item, //当前高亮显示的列表条目
U8*history_buffer) //历史记录Buffer
附:
所需更改的文件
wgui.c
wgui_categories.c
wgui_draw_manager.c
wgui_inputs.c
wgui.h
wgui_categories_defs.h
wgui_draw_manager.h
CustCoordinate.c
一、什么是History管理
对于我们上层用户而言,经常接触到的History管理是这样的:
voidEntryFunc()
U8*guiBuffer;
EntryNewScreen(Screen_ID,Exit_Func,Entry_Func,NULL);
guiBuffer=GetCurrGuiBuffer(SCR_ID_WORDMAIN_LIST);
ShowCategroyXXScreen(Title_ID,…,guiBuffer);
但是,无论是EntryNewScreen的调用,还是guiBuffer的传入,我们都很少考虑过对这些指针和函数在GUI的管理起到了什么样的作用。
下面我们就要了解,以上的代码与History管理之间存在的关系。
在MTK环境中,每当我们进入一个窗口,系统将先提取前一个窗口需保留的数据。
这些数据包括:
1. 窗口ID;
2. 进入窗口时调用的函数和退出调用的函数--Exit_Func和Entry_Func;
3. 组成窗体的控件的属性(如,列表控件当前高亮显示的条目、当前屏的首末条目等)。
举例说明这些数据在实际中是如何被使用的。
假设存在AB两个窗口,A窗口需要保留的数据为data_A。
我们先从A窗口进入到B窗口。
data_A将在B窗口调用EntryNewScreen()的时候,被压入一个结构类似于栈的数据存储区域;当从B调用GoBackHistory()返回A时,data_A从栈顶被弹出,然后A利用data_A将自身还原到其进入B之前的状态。
这就是History管理的作用。
简言之,就是要保持窗口的外观状态。
二、History管理的机制
现在,我们来了解一下前面所说的data_A的数据结构是什么样的。
typedefstruct_history
U16scrnID; //
(1)ScreenID(窗口号)
FuncPtrentryFuncPtr; //
(2)EntryNewScreen时要进入的Entry_Func
U8inputBuffer[MAX_INPUT_BUFFER];
//(3)没遇到过其使用,都是NULL。
U8guiBuffer[MAX_GUI_BUFFER];
//(4)窗体中控件的一些需保存的信息的Buffer,通常//在使用时被转化成各控件自定义的结构体如:
list_menu_category_history。
}history;
而存放data_A的类似于堆栈的数据区则以全局变量的形式定义在系统中:
historyNodehistoryData[MAX_HISTORY];(MAX_HISTORY=50):
设当前窗口A所对应的数据是historyData[EntryScreenNum–1],那么它是何时、是如何被赋值的?
又是何时、如何被使用的?
经过跟踪调试,我们已经知道,在由窗口A进入到窗口B(调用EntryNewScreen)的时候,我们
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1