MTK 功能机 互动

开始

  • 互动

MMI之根本就是互动。互动分为两边–人机互动和机人互动:
  人机互动:即用户输入,通常有键盘输入与触摸屏输入两种
  机人互动:即机器反馈,最常见的是画面反馈与声音反馈。
从写程序的概念来说,我们把互动分为三个等级:
  原始级:程序接受用户输入后,以基础的绘画反馈用户。
  控件级:程序创建控件,由控件接管部分用户输入,并由控件自行反馈用户。
  屏幕级:由屏幕模版全盘控制用户输入与画面反馈。
 此部分主要讲述控件级与屏幕级互动。

控件分为GUI Control与WGUI Control两种,GUI Control加上输入控制就成了WGUI Control,所以先以”GUI Control+键盘输入+触摸输入=WGUI Control”的方式为大家讲述。

接下来会演示如何将现有的程序整理成一个屏幕模版,并将屏幕模版嵌入到Draw Manager及Touch Screen中。

系统中常见控件:

系统中常见屏幕:

  • 基础画面
//为了便于演示,先修改输出画面
void mmi_myapp_entry(void)
{
    S32 x,y,w,h;
    color text_color={255,255,0,100};

    EntryNewScreen(SCR_MYAPP_MAIN,mmi_myapp_exit,NULL,NULL);
    gui_lock_double_buffer();
    entry_full_screen();
    clear_screen();

    gui_set_text_color(text_color);
    gui_set_text_border_color(UI_COLOR_GREEN);
    gui_measure_string((UI_string_type)GetString(STR_MYAPP_HELLO),&w,&h);
    x=(UI_device_width-w)/2;
    y=MMI_title_y;
    gui_move_text_cursor(x,y);
    gui_print_bordered_text((UI_string_type)GetString(STR_MYAPP_HELLO));

    gui_unlock_double_buffer();
    gui_BLT_double_buffer(0,0,UI_device_width-1,UI_device_height-1);
    SetKeyHandler(GoBackHistory,KEY_RSK,KEY_EVENT_UP);
}

控件

  • GUI Control
    因控件种类多,无法一一演示,下面以”文本图标列表菜单”为示范。
    控件使用一般有三个步骤:
      创建:基本上就是创建一个此控件的结构体对象,一般都是申明一个全局对象,我们很少用动态对象,一是系统动态内存管理不是很成熟,二是我们的屏幕中控件数量比较少,用全局的比较方便。另外要注意一点,我们系统中控件一般都会有一个类如gui_create_control_name()的函数,此函数不是用来创建控件,而是初始化控件对象的。
      设置:形如gui_create_XXX,gui_set_XXX,gui_resize_XXX之类的都是控件设置类接口。
      显示:显示接口一般都类似于gui_show_control_name()。
    菜单是由菜单框架及n个菜单项组成,所以”文本图标列表菜单”要创建两种控件:Fixed list menu及Fixed icontext menuitem。

  • 菜单框架

//创建一个列表菜单框架
fixed_list_menu My_fixed_list_menul;
void mmi_myapp_entry(void)
{
    .....
    gui_move_text_cursor(x,y);
    gui_print_border_text((UI_string_type)GetString(STR_MYAPP_HELLO));

    //开始显示菜单
    memset(&Myfixed_list_menu,0,sizeof(fixed_list_menu));
    //初始菜单框架基本属性
    gui_create_fixed_list_menu(&My_fixed_list_menu,20,MMI_content_y+5,136,MMI_content_height-50);
    //全局标志,用来标志当前菜单显示风格
    MMI_current_menu_type=LIST_MENU;

    //显示菜单结束
    gui_BLT_double_buffer(0,0,UI_device_width-1,UI_device_height-1);
    SetKeyHandler(GoBackHistory,KEY_RSK,KEY_EVENT_UP);
}

菜单框显示效果如下:

  • 菜单项公共属性
    创建菜单项,菜单项有两种属性,一是公共属性,我们把所有菜单项属性中值完全相同的属性都合在一起,如每项宽高等,这样既方便控制又节省空间。二是单项属性(每项都不同),如菜单项的文本图标等。
fixed_icontext_menuitem My_fixed_icontext_menuitem_common;  //菜单项公共属性
void mmi_myapp_entry(void)
{
    .....
    //开始显示菜单
    .....
    memset(&My_fixed_icontext_menuitem_common,0,sizeof(fixed_icontext_menuitem));
    gui_create_fixed_icontext_menuitem(&My_fixed_icontext_menuitem_common,136,18);      //宽高
    gui_fixed_icontext_menuitem_set_text_position(&My_fixed_icontext_menuitem_common,24,0);     //文本偏移距离
    My_fixed_icontext_menuitem_common.flags |= UI_MENUITEM_DISABLE_BACKGROUND;  //统一标志符
    //显示菜单结束
}
  • 菜单项单项属性
初始化菜单项单项属性前,先添加文本字符串资源
typedef enum
{
    STR_MYAPP_HELLO=MYAPP_BASE+1,
    STR_MYAPP_HELLO_MTK,
    STR_MYAPP_HELLO_TIBET,
    STR_MYAPP_HELLO_LHASA,
    STR_MYAPP_HELLO_SINKIANG,
    STR_MYAPP_HELLO_MONGOLIA,
    STR_MYAPP_HELLO_SIAN,
    STR_MYAPP_HELLO_CHENGTU,
}STRINGID_LIST_MYAPP;
//需要在相应txt文件中加入文本

菜单创建方法如下:

.....
#define My_fixed_list_n_items  (8);     //菜单项项数
fixed_icontext_menuitem_type My_fixed_list_menuitems[My_fixed_list_n_items];    //icontext型菜单项列表
void *My_fixed_menuitem_pointers[My_fixed_list_n_items];    //指向菜单项列表的索引列表

void mmi_myapp_entry(void)
{
    S32 i;
    ......
    //开始显示菜单
    ......
    memset(&My_fixed_list_menuitems,0,sizeof(fixed_icontext_menuitem_type)*My_fixed_list_n_items);
    for(i=0;i<My_fixed_list_n_items;i++)
    {
        My_fixed_list_menuitems[i].item_text=(UI_string_type)GetString(STR_MYAPP_HELLO+i);//菜单项文本
        My_fixed_list_menuitems[i].icon=(PU8)GetImage(IMG_GLOBAL_L1+i);//菜单项图标
        My_fixed_list_menuitems[i].flags=(UI_MENUITEM_CENTER_TEXT_Y|I_MENUITEM_CENTER_ICON_Y);
        My_fixed_list_menuitems[i].item_icon_handle=GDI_ERROR_HANDLE;
        //指向菜单项中每一项的索引列表,主要用来通知菜单框架每一个菜单项的数据地址
        My_fixed_menuitem_pointers[i]=(void*)&My_fixed_list_menuitems[i];//给索引列表赋值
    }
    //显示菜单结束
    .....
}
  • 联合菜单框架与菜单项

联合就是将菜单项的相关属性传递给菜单框架,要传递的属性有:菜单项索引列表,菜单公共属性,菜单项项数,菜单项接口功能等。

void mmi_myapp_entry(void)
{
    ......
    //开始显示菜单
    ......
    //菜单项索引列表
    My_fixed_list_menu.items=My_fixed_menuitem_pointers;
    //菜单项公共属性
    My_fixed_list_menu.common_item_data=(void*)&My_fixed_icontext_menuitem_common;
    //菜单项项数
    My_fixed_list_menu.n_items=My_fixed_list_n_items;

    gui_set_fixed_list_menu_item_functions(&My_fixed_list_menu, //菜单项功能接口
        gui_show_fixed_icontext_menuitem,//显示菜单项函数
        gui_measure_fixed_icontext_menuitem,//测量菜单项函数
        gui_highlight_fixed_icontext_menuitem,//高亮函数
        gui_remove_highlight_fixed_icontext_menuitem,//失去高亮函数
        gui_hide_fixed_icontext_menuitem,//菜单项隐藏函数
        NULL                        //菜单项重设大小函数
    );
    //显示菜单结束
    ......
}

菜单框架是依靠传递过来的功能接口控制所有菜单项的,当要控制某一项的时候,就把菜单项索引值传入相应的功能接口,也就是所说菜单框架之人接口不认菜单项。因每种类型的菜单项都有自己的一套接口,所以不管什么类型的菜单项,只要照上面这样联合起来,菜单框架都是能控制的。

  • 显示菜单
//最后是显示菜单
S32 My_fixed_list_highlight_item=0;
void mmi_myapp_entry(void)
{
    ......
    //开始显示菜单
    ......
    //菜单高亮项索引,此为菜单框架内部属性值,在跳转之前一定要设为-1
    My_fixed_list_menu.highlighted_item=-1;
    //在显示之前要先设置好菜单的高亮项,否则菜单会显示不正常
    gui_fixed_list_menu_goto_item(&My_fixed_list_menu,My_fixed_list_highlight_item);
    gui_show_fixed_list_menu(&My_fixed_list_menu);
    //显示菜单结束
    ......
}


//当菜单项文本过长,高亮时会自动滚动,所以我们退出菜单后还要手动通知所有菜单项停止滚动
void mmi_myapp_exit(void)
{
    gui_fixed_icontext_menuitem_stop_scroll();
}

最终显示结果为:

键盘

手机键盘虽然模样多变,但其基本功能基本上固定,如下为常见标准的手机键盘:

系统内部会给每种功能的按键一个代号,不管键盘外观及布局如何变,只要按键功能不变,其按键代码就不必改变。如果有新功能按键出现,我们就为其增加一个新的代码:

下面对每个功能按键的描述:

按键的操作方式有很多,其分别描述如下(为某个按键设置响应函数我们一般用SetKeyHandler,其第一个参数是响应函数的地址,第二个参数是按键代码,第三个参数是按键操作方式。):

  • 代码准备
    为使演示更直观,我们为菜单加上一项功能:当高亮菜单某一项里,上方主文本区将显示此项的文本串。
    首先得将主文本显示代码提取出来以方便文本串刷新:
void mmi_myapp_draw_text(S32 index)     //显示主文本区函数,index为菜单高亮项的序号
{
     S32 x,y,w,h;
    color text_color={255,255,0,100};

    gui_lock_double_buffer();

    gui_reset_clip();
    gui_set_text_color(text_color);
    gui_set_text_border_color(UI_COLOR_GREEN);
    gui_measure_string((UI_string_type)GetString(STR_MYAPP_HELLO+index),&w,&h);
    x=(UI_device_width-w)/2;
    y=MMI_title_y;
    gui_move_text_cursor(x,y);

    gui_fill_rectangle(0,y,UI_device_width-1,y+h,UI_COLOR_WHITE);
    gui_print_bordered_text((UI_string_type)GetString(STR_MYAPP_HELLO+index));

    gui_unlock_double_buffer();
    gui_BLT_double_buffer(0,y,UI_device_width-1,y+h);
}


void mmi_myapp_highlight_handler(S32 item_index)    //菜单项高亮时被系统调用的回调函数
{
    mmi_myapp_draw_text(item_index);
}

void mmi_myapp_entry(void)
{
    ......
    mmi_myapp_draw_text(0);
    //开始显示菜单
    ......
    //此处item_highlighted与钱买年菜单项功能接口中的高亮接口不是一个概念,菜单项功能接口由GUI内部提供。
    //此处item_highlighted是由应用提供的,当菜单高亮时菜单框架会一次呼叫这两个函数。
    My_fixed_list_menu.item_highlighted=mmi_myapp_highlight_handler;
    gui_show_fixed_list_menu(&My_fixed_list_menu);
    //显示菜单结束
    ......
}
  • 按键操作
//为上下方向键加上按键响应
void my_fixed_list_goto_previous_item(void) //跳到菜单的前一项
{
    gui_lock_double_buffer();
    //菜单框架将跳到前一项
    gui_fixed_list_menu_goto_previous_item(&My_fixed_list_menu);
    gui_show_fixed_list_menu(&My_fixed_list_menu);
    gui_unlock_double_buffer();
    gui_BLT_double_buffer(My_fixed_lsit_menu.x,My_fixed_lsit_menu.y,
        My_fixed_list_menu.x+My_fixed_list_menu.width,My_fixed_lsit_menu.y+My_fixed_lsit_menu.height);
}

void my_fixed_list_goto_next_item(void)  //跳到菜单的下一项
{
    gui_lock_double_buffer();
    //菜单框架将跳到下一项
    gui_fixed_list_menu_goto_next_item(&My_fixed_list_menu);
    gui_unlock_double_buffer();
    gui_BLT_double_buffer(My_fixed_lsit_menu.x,My_fixed_lsit_menu.y,
        My_fixed_list_menu.x+My_fixed_list_menu.width,My_fixed_lsit_menu.y+My_fixed_lsit_menu.height);
}

void mmi_myapp_entry(void)
{
    ......
    //开始显示菜单
    ......
    //显示菜单结束
    SetKeyHandler(my_fixed_list_goto_previous_item,KEY_UP_ARROW,KEY_EVENT_DOWN);
    SetKeyHandler(my_fixed_list_goto_next_item,KEY_DOWN_ARROW,KEY_EVENT_DOWN);
}
  • 群组按键
    为每个数字键加上按键响应(按下某个数字,会跳转到相应的一项)。
    因数字数量多,如果我们为每一个按键都注册一次,代码将会很冗余,所以我们将改用接口SetGroupKeyHandler。其中第一个参数是按键响应函数地址,第二个参数是按键代码列表,第三个参数是注册按键数量,第四个参数是按键操作方式。
void my_fixed_list_goto_item(void)
{
    U16 keycode,keytype;
    S32 index=0;

    gui_lock_double_buffer();
    //获取当前用户操作的按键代码
    GetkeyInfo(&keycode,&keytype);
    //计算出当前按的是哪一个数字
    index=keycode-KEY-1;    
    gui_fixed_list_menu_goto_item(&My_fixed_list_menu,index);
    gui_show_fixed_list_menu(&My_fixed_list_menu);
    gui_unlock_double_buffer();
    gui_BLT_double_buffer(My_fixed_list_menu.x,My_fixed_menu.y,
        My_fixed_list_menu.x+My_fixed_list_menu.width,
        My_fixed_list_menu.y+My_fixed_list_menu.height);
}

void mmi_myapp_entry(void)
{
    U16 shortcut_keys[My_fixed_list_n_items]=
    {
        KEY_1,KEY_2,KEY_3,KEY_4,
        KEY_5,KEY_6,KEY_7,KEY_8
    };
    .....
    //开始显示菜单
    .....
    //显示菜单结束
    SetGroupKeyHandler(my_fixed_list_goto_item,(PU16)shortcut_keys,
        My_fixed_list_n_items,KEY_EVENT_UP);
}

高级控件

  • WGUI Control
    高级控件,即WGUI Control。
    与GUI Control不同,每种高级控件在系统启动的时候即已创建一份实体,我们在用的时候只需要将这份实体重新初始化并显示即可。

  • 初始化菜单框架

//初始化方式与GUI菜单类似
void mmi_myapp_entry(void)
{
    ......
    //开始显示菜单
    //设置位置
    move_fixed_list(20,MMI_content_y+5);
    //设置宽高
    resize_fixed_list(136,MMI_content_height-40);
    //设置显示风格
    MMI_current_menu_type=LIST_MENU;
    //关掉标题条右边的快捷序号显示框(WGUI菜单框默认联合快捷序号显示)
    disable_menu_shorcut_box_display=1;
    //显示菜单结束
    ......
}
  • 初始化菜单项公共属性
//函数create_fixed_icontext_menuitems用来初始化菜单项公共属性
void mmi_myapp_entry(void)
{
    .....
    //开始显示菜单
    .....
    create_fixed_icontext_menuitems();
    //显示菜单结束
    ......
}
  • 初始化菜单项单项数据
void mmi_myapp_entry(void)
{
    ......
    //开始显示菜单
    ......
    for(i=0;i<My_fixed_list_n_items;i++)
    {
        add_fixed_icontext_item(get_string(STR_MYAPP_HELLO+i),(PU8)GetImage
            (IMG_GLOBAL_L1+i));
    }
    //显示菜单结束
    ......
}
  • 联合菜单框架与菜单项
void mmi_myapp_entry(void)
{
    ......
    //开始显示菜单
    ......
    associate_fixed_icontext_list();
    //显示菜单结束
    ......
}
  • 注册按键
void mmi_myapp_entry(void)
{
    ......
    //开始显示菜单
    ......
    //注册高亮接口
    register_fixed_list_highlight_handler(mmi_myapp_highlight)handler);
    //注册方向键
    register_fixed_list_keys();
    //注册数字键
    register_fixed_list_shortcut_handler();
    //显示菜单结束
    ......
}
  • 显示菜单
void mmi_myapp_entry(void)
{
    ......
    //开始显示菜单
    ......
    //先高亮第一项
    fixed_list_goto_item_no_redraw(0);
    //显示菜单
    show_fixed_list();
    //显示菜单结束
    ...
}

  • 其他高级控件
    其他高级控件的使用方式均类似,下面为左右软键的例子:
void mmi_myapp_entry(void)
{
    ......
    //开始显示菜单
    ......
    //显示菜单结束

    //开始显示左右软键

    //设置左软键文本及图标
    change_left_softkey(STR_GLOBAL_OK,IMG_GLOBAL_OK);
    //设置右软键文本及图标
    change_right_softkey(STR)GLOBAL_BACK,IMG_GLOBAL_BACK);
    //显示左软键
    show_softkey(MMI_LEFT_SOFTKEY);
    //显示右软键
    show_softkey(MMI_RIGHT_SOFTKEY);
    //注册右软键响应函数
    SetRightSoftkeyFunction(GoBackHidtory,KEY_EVENT_UP);
    //显示左右软键结束
    //左右软键现实后就不能用SetKeyHandler来注册按键响应了
    //需要改用SetLeftSoftkeyFunction与SetRightSoftkeyFunction
    //SetKeyHandler(GoBackHistory,KEY_RSK,);
}

左右软键现实后就不能用SetKeyHandler来注册按键响应了。需要改用SetLeftSoftkeyFunction与SetRightSoftkeyFunction。
显示结果如下:

屏幕模板

我们系统中的屏幕模板接口都类似于ShowCategoryXXXScreen,这里的XXX是数字。数字没有任何含义,只是个序号而已,因为我们平台早期规划的不是很好,加上屏幕模版很难命名,所以才出现这样命名不太合理的情况。
屏幕模板可以简单分为两大类,一类是通用性模板,这些模版都是可重复使用的。二是非通用性模板,都是某些特殊程序的专用模板,从某种意义上来说这些可以不叫做模板,只是为了方便代码统一管理才放到模板中来的。
* 新模板

//建一个新的模板,命名为ShowCategory888Screen.将我们程序的所有功能都移到模板中来:
void ShowCategory888Screen()
{
    S32 i;

    //初始化屏幕
    EntryNewScreen(SCR_MYAPP_MAIN,mmi_myapp_exit,NULL,NULL);
    gui_lock_double_buffer();
    entry_full_screen();
    clear_screen();

    //初始化菜单框架
    move_fixed_list(20,MMI_content_y+5);
    resize_fixed_list(136,MMI_content_height-40);
    MMI_current_menu_type=LIST_MENU;
    disable_menu_shortcut_box_display=1;

    //初始化菜单公共数据
    create_fixed_icontext_menuitems();

    //联合菜单框架与菜单项
    associate_fixed_icontext_list();

    //初始化菜单项数据
    for(i=0;i<My_fixed_list_n_items;i++)
    {
        add_fixed_icontext(get_string(STR_MYAPP_HELLO+i),(PU8)GetImage(IMG_GLOBAL_L1+i));
    }

    //注册按钮
    register_fixed_list_shortcut_handler();
    register_fixed_list_keys();
    register_fixed_list_highlight_handler(mmi_myapp_highlight_handler);

    //显示菜单
    fixed_list_goto_item_no_redraw(0);
    show_fixed_list();

    //显示左右软键
    change_left_softkey(STR_GLOBAL_OK,IMG_GLOBAL_OK);
    change_right_softkey(STR_GLOBAL_BACK,IMG_GLOBAL_BACK);
    show_softkey(MMI_LEFT_SOFTKEY);
    show_softkey(MMI_RIGHT_SOFTKEY);
    SetRightSoftkeyFunction(GoBackHistory,KEY_EVENT_UP);

    gui_unlock_double_buffer();
    gui_BLT_double_buffer(0,0,UI_device_width-1,device_height-1);
}

void mmi_myapp_entry(void)
{
    showCategory888Screen();
}
//这样的模板别人无法使用,所以需要将经常改动的元素提取出来
  • 可重用模板
    常见的变化元素有:左右软键的文本图标,菜单的内容,菜单项的初始高亮项序号,以及按键的响应函数等。
//将mmi_myapp_highlight_handler改为cat888_highlight_handler
并将mmi_myapp_draw_text中内容加入其中
void cat888_highlight_handler(S32 index)
{
    ......
    gui_measure_string(MMI_fixed_icontext_menuitems[index].item_text,&w,&h);
    gui_print_bordered_text(MMI_fixed_icontext_menuitems[index].item_text);
    gui_layer_unlock_frame_buffer();
    gio_BLT_double_buffer(0,y,UI_device_width-1,y+h);
}

void ShowCategory888Screen(
    U16 left_softkey,UI16 left_softkey_icon, //左软键文本及图标
    UI16 right_softkey,U16 right_softkey_icon, //右软键菜单项列表
    S32 number_of_items, //菜单项项数
    U16 *list_of_items, //菜单项文本列表
    U16 *list_of_icon, //菜单项图标列表
    S32 highlighted)item) //初始菜单高亮项序号
{
    ......

    //初始化菜单项数据
    for(i=0;i<number_of_items;i++)
    {
        add_fixed_icontext_item(get_string(list_of_items[i]),
            (PU8)GetImage(list_of_icons[i]));
    }

    //注册按钮
    register_fixed_list_shortcut_handler();
    register_fixed_list_keys();
    register_fixed_list_highlight_handler(cat888_highlight_handler);

    //显示菜单
    fixed_list_goto_item_no_redraw(highlighted_item);
    show_fixed_list();

    //显示左右软键
    change_left_softkey(left_softkey,left_softkey_icon);
    change_girht_softkey(right_softkey,right_softkey_icon);
    show_softkey(MMI_LEFT_SOFTKEY);
    show_softkey(MMI_RIGHT_SOFTKEY);
    ......
}

void mmi_myapp_entry(void)
{
    S32 i;
    U16 list_of_items[My_fixed_list_n_items];
    U16 list_of_icons[My_fixed_list_n_items];

    EntryNewScreen(SCR_MYAPP_MAIN,mmi_myapp_exit,NULL,NULL);

    for(i=0;i<My_fixed_list_n_items;i++)
    {
        list_of_items[i]=STR_MYAPP_HELLO+i;
        list_of_icons[i]=IMG_GLOBAL_L1+i;
    }
    showCategory888Screen(
        STR_GLOBAL_OK,IMG_GLOBAL_OK,
        STR_GLOBAL_BACK,IMG_GLOBAL_BACK,
        My_fixed_list_n_items,
        list_of_items,
        list_of_icons,
        0);
    SetRightSoftkeyFunction(GoBackHistory,KEY_EVENT_UP);
}
  • 提出绘画部分
    我们通常会将模板中真正的绘画部分提取出来放到一个单独接口中,这样方便在显示的时候临时刷新整个屏幕。(ShowCategory888Screen中就只放模板初始化部分)
void RedrawCategory888Screen(void)
{
    gdi_layer_lock_frame_buffer();

    //显示菜单
    show_fixed_list();

    //显示左右软键
    show_softkey(MMI_LEFT_SOFTKEY);
    show_softkey(MMI_RIGHT_SOFTKEY);

    gdi_layer_unlock_frame_buffer();
    gui_BLT_double_buffer(0,0,UI_device_width-1,UI_device_height-1);
}

void showCategory888Screen(
    U16 left_softkey,U16 left_softkey_icon,
    U16 right_softkey,U16 right_softkey_icon,   
    S32 number_of_items,U16 *list_of_items,
    U16 *list_of_icons,S32 highlighted_item)
{
    .....
    //初始化菜单
    fixed_list_goto_item_no_redraw(hightlighted_item);
    //show_fixed_list()

    //初始化左右软键
    change_left_softkey(left_softkey,left_softkey_icon);
    change_right_softkey(right_softkey,right_softkey_icon);
    //show_softkey(MMI_LEFT_SOFTKEY);
    //show_softkey(MMI_RIGHT_SOFTKEY);

    RedrawCategoryFunction = RedrawCategory888Screen;
    RedrawCategoryFunction();
}
//当需要刷新整个屏幕,调用RedrawCategoryFunction
//不必每次刷新都将屏幕重新初始化一遍
  • 模板历史管理
    在保存屏幕历史的时候,我们通常会将屏幕中相关的一些显示状态也保存下来,比如菜单中当前高亮显示第几项等等,这些状态我们一般都由屏幕模板自己来管理。为方便演示,我们先给程序加上一项功能:当用户按下左软键时,将弹出一个提示框以显示当前所选中项的文本:
void mmi_myapp_popup()
{
    EntryNewScreen(0,NULL,mmi_myapp_popup,NULL);
    ShowCategory165Screen(
        STR_GLOBAL_OK,IMG_GLOBAL_OK,
        STR_GLOBAL_CANCEL,IMG_GLOBAL_BACK,
        get_string(STR_MYAPP_HELLO+MMI_fixed_list_menu.highlighted_item),
        IMG_GLOBAL_ACTIVATED,NULL
        );

    SetLeftSoftkeyFunction(GoBackHistory,KEY_EVENT_UP);
    SetRightSoftkeyFunction(GoBackHistory,KEY_EVENT_UP);
}

void mmi_myapp_entry(void)
{
    ......
    SetLeftSoftkeyFunction(mmi_myapp_popup,KEY_EVENT_UP);
    SetRightSoftkryFunction(GoBackHistory,KEY_EVENT_UP);
}

由上面代码可以了解系统中现有的模板是如何使用的。
运行后,我们选中菜单中某一项并按下左软键,会弹出如下面中间小图所显示提示框,但这时用户返回,会发现菜单高亮为第一项.

//模板历史添加
void mmi_myapp_exit(void)
{
    history curHistory;
    ......
    //添加屏幕模版历史时顺便将模板历史加入其中
    GetCategoryHistory(currHistory.guiBuffer);
    AddHistory(currHistory);
}

U8 *cat888_get_category_history(U8 *history_buffer)
{
    //返回屏幕模版的历史记录
    get_list_menu_category_history(0,history_buffer);
}

S32 cat888_get_category_history_size()
{
    //返回屏幕模版的历史记录大小
    return(sizeof(list_menu_category_history));
}

void ShowCategory888Screen(
    U16 left_softkey,U16 left_softkey_icon,
    U16 right_softkey,U16 right_softkey_icon,   
    S32 number_of_items,U16 *list_of_items,
    U16 *list_of_icons,S32 highlighted_item,
    U8 *history_buffer)
{
    ......
    //初始化菜单
    if(set_list_menu_category_history(0,history_buffer))
    {
        //如果屏幕是GoBack进来的,则历史不为空
        fixed_list_goto_item_no_redraw(MMI_fixed_list_menu.highlighted_item);
    }
    else
    {
        //如果类似为空,则用highlighted_item初始化
        fixed_list_goto_item_no_redraw(highlighted_item);
    }

    ......
    RedrawCategoryFunction=RedrawCategory888Screen;
    GetCategoryHistory=cat888_get_category_history_size;
    RedrawCategoryFunction();
}

void mmi_myapp_entry(void)
{
    .....
    EntryNewScreen(SCR_MYAPP_MAIN,mmi_myapp_exit,NULL,NULL);
    //获取当前屏幕模板历史记录,如果第一次进屏幕则记录为空
    guiBuffer=GetCurrGuiBuffer(SCR_MYAPP_MAIN);
    ShowCategory888Screen(
        STR_GLOBAL_OK,IMG_GLOBAL_OK,
        STR_GLOBAL_BACK,IMG_GLOBAL_BACK,
        My_fixed_list_n_items,
        list_of_items,list_of_icons,
        0,guiBuffer //模板历史记录传给模板
        );
    .....
}
//在屏幕压入历史时,我们都会顺便调用GetCategoryHistory将模板状态一起压入历史
(EntryNewScreen时一般会自动压入),在应用是在将历史取出,交由屏幕模版使用。
  • 退出模板
    如果在屏幕退出时模板需要做某些善后处理,可以将处理函数的地址交由ExitCategoryFunction,屏幕退出时会自动呼叫到ExitCategoryFunction。
void mmi_myapp_exit(void)
{
    .....
    //在reset_fixed_list会自动停止滚动
    //gui_fixed_icontext_menuitem_stop_scroll();
}
void ExitCategory888Screen(void)
{
    //清掉所有高亮响应函数
    ClearHighlightHandler();
    //重置左右软键
    reset_softkeys();
    //重置快捷序号框
    reset_menu_shortcut_handler();
    //重置列表菜单
    reset_fixed_list();
}
void ShowCategory888Screen(
    U16 left_softkey,U16 left_softkey_icon,
    U16 right_softkey,U16 right_softkey_icon,   
    S32 number_of_items,U16 *list_of_items,
    U16 *list_of_icons,S32 highlighted_item)
{
    .....

    ExitCategoryFunction=ExitCategory888Screen;

    RedrawCategoryFunction = RedrawCategory888Screen;
    GetCategoryHistory=cat888_get_category_history;
    GetCategoryHistorySize=cat888_get_category_history_size;
    RedrawCategoryFunction();
}
  • 使用新模板
    现在可以重复使用我们的新模板了
#include "Worldclock.h"
#define My_fixed_list_n_items (30)
void mmi_myapp_entry(void)
{
    S32 i;
    U16 list_of_items[My_fixed_list_n_items];
    U16 list_of_icons[My_fixed_list_n_items];
    U8 *guiBuffer=NULL; 

    EntryNewScreen(SCR_MYAPP_MAIN,mmi_myapp_exit,NULL,NULL);
    guiBuffer=GetCurrGuiBuffer(SCR_MYAPP_MAIN);

    for(i=0;i<My_fixed_list_n_items;i++)
    {
        list_of_items[i]=STR_WCLOCK_CITYI+i;
        list_of_icons[i]=IMG_GLOBAL_L1+i;
    }
    showCategory888Screen(
        STR_GLOBAL_OK,IMG_GLOBAL_OK,
        STR_GLOBAL_BACK,IMG_GLOBAL_BACK,
        My_fixed_list_n_items,
        list_of_items,list_of_icons,
        0,guiBuffer);
    SetLeftSoftkeyFunction(mmi_myapp_popup,KEY_EVENT_UP);
    SetRightSoftkeyFunction(GoBackHistory,KEY_EVENT_UP);
}

显示效果如下:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值