Tizen的SDK,可到这里下载 https://www.tizen.org/
Tizen使用的UI FrameWork是Enlightenment开源项目,简称E,是桌面系统中的一个窗口管理器。Enlightenment的第一个版本发布于1996年10月30日。
除了Enlightenment,还有QT、GTK、KDE等窗口管理器。
Enlightenment的源码,可到这里下载 http://enlightenment.org/
Enlightenment的logo↓
Enlightenment Foundation Library(EFL)是Enlightenment背后的库集:核心基础库。
关于EFL的学习及环境搭建,这里推荐一个CSDN的专栏:http://blog.csdn.net/efl_gui?viewmode=contents
Elementary只是其中一个widget库,如下图
先上一张widget的类继承关系图,这里有助于整体把握
以下是给window设置颜色背景
//ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE); ad->win = elm_win_add(NULL, PACKAGE, ELM_WIN_BASIC); ad->bg = elm_bg_add(ad->win); elm_bg_color_set(ad->bg, 255, 0, 255);//R,G,B elm_win_resize_object_add(ad->win, ad->bg); evas_object_show(ad->bg); evas_object_show(ad->win);
以上代码缺一不可
效果图↓
(1)conformant介绍
conformant的中文意思是顺应、一致,那这到底是什么widget呢?
根据SDK帮助文档的说明
Theaim is to provide a widget that can be used in elementary apps to account forspace taken up by the indicator, virtual keypad & softkey windows when running the illume2 module of E17.
Soconformant content is sized and positioned considering the space required forsuch stuff, and when they popup, as a keyboard shows when an entry is selected,conformant content won't change.
illume备注
Illumeis a module for Enlightenment that modifies the user interface to work cleanlyand nicely on a mobile device. It has support for virtual keyboard
简而言之,conformant是当软键盘、通知栏和softkey这些widget出现时,重新计算它里面content的大小和位置
(2)conformant使用
conformant使用分以下三步:
①设置window为conformant window
elm_win_conformant_set(ad->win, EINA_TRUE);
②添加conformant widget
ad->conformant = elm_conformant_add(ad->win); evas_object_size_hint_weight_set(ad->conformant, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); elm_win_resize_object_add(ad->win, ad->conformant); evas_object_show(ad->conformant);
③添加widget(示例box)作为conformant的内容
elm_object_content_set(ad->conformant, ad->box);
效果图↓
在学习box之前,先看两个常用接口evas_object_size_hint_weight_set和evas_object_size_hint_align_set
我的理解:
hint:暗示、线索的意思,size hint就是说size的暗示、size的预估、size的提示、被推荐的size,这两个接口都包含有size hint的关键字,说明接口设置的属性可作为widget大小位置的参考、依据,但仅仅是参考,因为大小位置不仅仅由这些接口设定,所以这些接口设置了不一定起作用。这里和android自定义view中onMeasure的widthMeasureSpec、heightMeasureSpec有点类似。
x、y分别代表该object在x、y轴上的权重,即在x、y方向上所占的比例,范围都是0~1,缺省值为0,表示不扩展,EVAS_HINT_EXPAND(值为1),表示扩展
x的范围是0~1,0表示左对齐,1表示右对齐;y的范围是0~1,0表示顶端对齐,1表示底端对齐;特殊值EVAS_HINT_FILL(值为-1),表示填满,缺省值为0.5,即居中
总结如下:
(1)weightset里面的x、y表示在相应轴上是否扩展和扩展的比例,0表示不扩展,0.3不表示占30%,如果所在容器只有一个控件,则扩展到整个空间,扩展的意思只是占有空间,并不改变控件的形状大小。
(2)alignset里面的x、y表示对齐方式,特殊值EVAS_HINT_FILL表示填充分配给该控件的所有空间,比如如果该控件在x轴上设置weight为EVAS_HINT_EXPAND,并且在x轴上设置align为EVAS_HINT_FILL,那么,该控件在x轴上就会填满。如果不设置EXPAND,就算设置了FILL,也是不会起作用的,因为EXPAND使控件扩展了空间
(3)特殊情况(感觉是bug):
①在box为垂直排列时,即使x轴的weight设为0(不扩展),如果x轴的align设为FILL,还是会起填充效果的。
②在box为水平排列时,即使y轴的weight设为0(不扩展),如果y轴的align设为FILL,也还是会起填充效果的。
Evas_Object*subobj, //什么obj被pack
int col, //pack到哪一列
int row, //pack到哪一行
int colspan, //跨多少列
int rowspan, //跨多少行
)
注意:colspan是从col开始计算的,如果总的跨度大于col的总数,则会新开一列。rowspan也是如此
②往一个table里面pack一个table1,要想table1生效,也要设置下面两个属性
evas_object_size_hint_weight_set(table1, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(table1, EVAS_HINT_FILL, EVAS_HINT_FILL);
参考代码
#include "table_widget_test.h" typedef struct appdata { } appdata_s; static void win_delete_request_cb(void *data , Evas_Object *obj , void *event_info) { elm_exit(); } static void win_back_cb(void *data, Evas_Object *obj, void *event_info) { /* Let window go to hide state. */ elm_win_lower(data); } static void create_base_gui(appdata_s *ad) { Evas_Object *win, *label, *table, *bg, *table1; /* Window */ win = elm_win_util_standard_add(PACKAGE, PACKAGE); elm_win_autodel_set(win, EINA_TRUE); evas_object_smart_callback_add(win, "delete,request", win_delete_request_cb, NULL); eext_object_event_callback_add(win, EEXT_CALLBACK_BACK, win_back_cb, win); table = elm_table_add(win); elm_win_resize_object_add(win, table); evas_object_show(table); elm_table_padding_set(table, 5, 5); elm_table_homogeneous_set(table, EINA_TRUE); bg = elm_bg_add(win); evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(bg, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_bg_color_set(bg, 255, 0, 255); evas_object_show(bg); elm_table_pack(table, bg, 0, 0, 1, 1); label = elm_label_add(win); elm_object_text_set(label, "label 0"); evas_object_show(label); elm_table_pack(table, label, 0, 0, 1, 1); table1 = elm_table_add(win); evas_object_size_hint_weight_set(table1, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(table1, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_show(table1); elm_table_pack(table, table1, 0, 0, 1, 1); bg = elm_bg_add(win); evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(bg, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_bg_color_set(bg, 125, 125, 125); evas_object_show(bg); elm_table_pack(table1, bg, 0, 0, 1, 1); bg = elm_bg_add(win); evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(bg, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_bg_color_set(bg, 64, 32, 64); evas_object_show(bg); elm_table_pack(table1, bg, 1, 1, 1, 1); bg = elm_bg_add(win); evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(bg, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_bg_color_set(bg, 255, 255, 0); evas_object_show(bg); elm_table_pack(table, bg, 1, 0, 1, 1); label = elm_label_add(win); elm_object_text_set(label, "label 1"); evas_object_show(label); elm_table_pack(table, label, 1, 0, 1, 1); bg = elm_bg_add(win); evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(bg, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_bg_color_set(bg, 0, 255, 255); evas_object_show(bg); elm_table_pack(table, bg, 0, 1, 1, 1); label = elm_label_add(win); elm_object_text_set(label, "label 2"); evas_object_show(label); elm_table_pack(table, label, 0, 1, 1, 1); bg = elm_bg_add(win); evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(bg, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_bg_color_set(bg, 255, 0, 0); evas_object_show(bg); elm_table_pack(table, bg, 1, 1, 2, 1); label = elm_label_add(win); elm_object_text_set(label, "label 3"); evas_object_show(label); elm_table_pack(table, label, 1, 1, 2, 1); /* Show window after base gui is set up */ evas_object_show(win); } static bool app_create(void *data) { /* Hook to take necessary actions before main event loop starts Initialize UI resources and application's data If this function returns true, the main loop of application starts If this function returns false, the application is terminated */ appdata_s *ad = data; create_base_gui(ad); return true; } static void app_language_changed(void *data) { /* Set the current language */ char *locale = NULL; runtime_info_get_value_string(RUNTIME_INFO_KEY_LANGUAGE, &locale); elm_language_set(locale); free(locale); } static void app_control(app_control_h app_control, void *data) { /* Handle the launch request. */ } static void app_pause(void *data) { /* Take necessary actions when application becomes invisible. */ } static void app_resume(void *data) { /* Take necessary actions when application becomes visible. */ } static void app_terminate(void *data) { /* Release all resources. */ } int main(int argc, char *argv[]) { appdata_s ad = {0,}; app_event_callback_s event_callback = {0,}; int ret = 0; event_callback.create = app_create; event_callback.terminate = app_terminate; event_callback.pause = app_pause; event_callback.resume = app_resume; event_callback.app_control = app_control; event_callback.language_changed = app_language_changed; event_callback.low_memory = NULL; event_callback.low_battery = NULL; event_callback.device_orientation = NULL; event_callback.region_format_changed = NULL; ret = app_main(argc, argv, &event_callback, &ad); if (ret != APP_ERROR_NONE) { dlog_print(DLOG_ERROR, LOG_TAG, "app_main() is failed. err = %d", ret); } return ret; }
一些普通接口
①elm_entry_add,默认为multi-line、wordwrap、autosave,默认不滚动
②elm_entry_autocapital_type_set设置自动大写(WORD、SENTENCE、ALLCHARACTER)
③elm_entry_context_menu_item_add添加长按时弹出的menuitem
④elm_entry_editable_set设置是否可以编辑
⑤插入文本
elm_entry_entry_set设置文本,会覆盖原有的
elm_entry_entry_append往最后添加文本
Elm_entry_entry_insert往光标当前位置添加文本
⑥elm_entry_password_set设置为密码状态
⑦elm_entry_select_all选取全部文本
⑧elm_entry_input_panel_enabled_set是否弹出输入盘
⑨elm_entry_input_panel_return_key_type_set设置输入盘中返回键类型
Formatted text
elm_entry_entry_append(entry, “<br>”);插入换行符
elm_entry_entry_append(entry,“<link>underline</link>”);下划线
Special markups
elm_entry_entry_set(entry, “<item size=16x16vsize=fullhref=emoticon/haha></item>”);表情
elm_entry_entry_append(entry, “<ahref=anc-01>”“<link>”“www.eclipse.org”“</link>”“</a>”);//anchortext类似超链接
elm_entry_entry_append(entry, “<font_size=48><color=#0000FF>font_color</color></font_size>”);字体颜色
elm_progressbar_add
elm_progressbar_span_size_set设置progressbar长度
elm_progressbar_pulse_set设置为活动状态
elm_progressbar_pulse表示一种活动状态,表示正在执行任务,但不表示进度
elm_progressbar_value_get
elm_progressbar_value_set
elm_scroller_add
elm_object_part_content_set设置其他obj为scroller的content后便使其他obj具有了滚动的特性
elm_photocam_file_set关联图片
elm_photocam_image_region_show显示图片某个指定区域,无动画
elm_photocam_image_region_bring_in显示图片某个指定区域,如果当前不在该区域,则通过动画方式移动过去
elm_photocam_gesture_enabled_set设置可通过手势缩放
elm_list_add
elm_list_item_append//添加item到list的最后
elm_list_item_prepend添加item到list的最前
elm_list_item_insert_after往某个item后面添加item
elm_list_multi_select_set设置多选
evas_object_smart_callback_add(list, “clicked,double”,list_double_click_cb, NULL);获取list item的双击事件
elm_list_mode_set可以设置以下mode
ELM_LIST_COMPRESS
ELM_LIST_SCROLL当文本长度超出容器大小时可以滚动
ELM_LIST_LIMIT
ELM_LIST_EXPAND
ELM_LIST_LAST
elm_object_item_part_text_get获取item的text文本
elm_list_go在show之前调用,类似刷新一遍
elm_genlist_add
elm_genlist_item_append添加item到list的后面
Elm_Genlist_Item_Class结构
item_style指明item的style,有default、double_label、group_index……
decorate_item_style
decorate_all_item_style
func结构
func.text_get设置item的文本
func.content_get
func.state_get
func.del
parent:如果是第一级item,则parent为NULL
type:
ELM_GENLIST_ITEM_NONE
ELM_GENLIST_ITEM_TREE
ELM_GENLIST_ITEM_GROUP
func:选择该item时的callback
elm_genlist_item_prepend添加item到list的最前面
elm_genlist_item_bring_in(item, type),把某个item显示到界面上,type表示动画效果,有以下
ELM_GENLIST_ITEM_SCROLLTO_NONE
ELM_GENLIST_ITEM_SCROLLTO_IN
ELM_GENLIST_ITEM_SCROLLTO_TOP
ELM_GENLIST_ITEM_SCROLLTO_MIDDLE
elm_colorselector_add
elm_colorselector_color_set
elm_colorselector_color_get
elm_color_selector_mode_set显示模式
elm_colorselector_palette_clear清除调色板
elm_colorselector_palette_color_add添加新颜色到调色板
elm_colorselector_palette_item_color_get得到当前项颜色值
elm_colorselector_palette_name_set设置调色板的名字,不同名字调色板的颜色也不同(“painting”/”default”)
elm_ctxpopup_add
elm_ctxpopup_item_append()
label表示显示的文字,icon表示显示的图标,func表示点击该item的回调
dismissed消息:
当ctxpopup创建后,点击其他地方将会发出dismissed的消息,可在消息处理中删除ctxpopup,如
evas_object_smart_callback_add(ctxpopup,"dismissed",dismissed_cb,NULL);
支持六个域Year, Month, Date, Hour, Minute,AM/PM,不支持秒
%F ----> year-month-day
%D ----> month-day-year
%y ----> year只显示年
%m ----> month只显示month
%b ---->根据系统语言显示月份,如英语显示Jan,中文则显示1月
%d ---->只显示day
更多格式参考libc库的时间格式http://www.gnu.org/s/hello/manual/libc.html#Formatting-Calendar-Time
naviframe全称navigationframe,是一个导航控件,由一个个的view组成,所有的view存放在栈里面,所谓的导航就是通过栈的push和pop操作,在view之间切换
elm_naviframe_item_push(obj,title_label,prev_btn,next_btn, content,item_style)
title_label:当前view的title
prev_btn:
next_btn:
content:可用任何其他控件作为content,比如整个box,box里面有其他控件
item_style:“default”“basic”“overlap”
elm_naviframe_item_pop返回到前一个view
elm_object_item_part_text_set(nf_it,“subtitle”, “this is sub title”);设置subtitle
(1)自定义layout
layout,离不开edc文件,edc的学习请访问http://docs.enlightenment.org/stable/efl/edcref.html
一个layout对应一个edc file里面的一个group,通过elm_layout_file_set(layout_obj,edj_file,group_name)这个接口关联起来,注意第二个参数是edj文件,不是edc文件,edj是edc编译后对应的二进制文件。
①访问edc的data
通过char *title_data =elm_layout_data_get(layout, “Key”);//key值和value一一对应,通过key值可获取到value
②访问edc的TEXT part
通过elm_object_part_text_set来访问edc的textpart,第二个参数指定part name
③访问edc的box part
除了通过elm_layout_box_insert_at接口可以操作boxpart外,还有
elm_layout_box_append
elm_layout_box_prepend
elm_layout_box_insert_before
elm_layout_box_remove
elm_layout_box_remove_all
④访问edc的table part
通过elm_layout_table_pack去设置edc里面的tablepart,第二个参数指定part name
⑤访问edc的swallow part
elm_object_part_content_set这个接口可以访问swallowpart
Tips:
通过elm_object_part_content_set添加到swallow part的widget不需要调用evas_object_show显示出来,这是比较特别的地方,控件的大小、位置、可见性等属性完全由swallow part来控制。
拓展:
swallowpart不代表任何东西,它只在layout中占了一块地方,任何东西都可以往里面丢,比如box、table、button、list,甚至是另一个layout……任何的evas_object,正由于layout中swallowpart的属性,从中也可看出大部分widget都继承layout的端倪了
(2)预定义layout
除了用户定义的edc文件,系统已经预先定义好了一些layout,关联预定义的layout和用户定义的layout有不同的方式,用户定义的是通过elm_layout_file_set,预定义的是通过elm_layout_theme_set
其中elm_layout_theme_set的第三个参数可以是下面这些
这里所说的theme并不是一种widget
在学习layout的时候提过,一个layout对应一个edc文件里面的一个group,其实一个group就是一个theme,比如之前学习label时通过elm_object_style_set设置label的样式为”maker”、”slide_long”、”slide_short”、”slide_bounce”,实际上一个样式就是一个theme,label的这些样式在label.edc文件中都会有相对应的一个group
所以,如果一个widget有多个theme,实际上是对应的edc文件中有多个group
elm_object_style_set可设置obj的theme,这个函数会去搜索theme list
themelist里面有三种theme,default、extension、overlay
Ødefault:系统本身包含的theme,比如上面label的maker、slide_long等等。默认存在于themelist
Øextension:用户自定义的,名字不能和default的相同,在edc文件中实现。通过elm_theme_extension_add把用户定义的extension加入到themelist
Øoverlay:用户自定义的,和default的相同,会覆盖掉default的,在某种特定情况下,不能增加extension,又不能修改default,就用这种overlay的方式。通过elm_theme_overlay_add把overlay加入到themelist。(建议overlay的方式尽量少用)
elm_object_style_set搜索themelist的顺序是:overlay -> default -> extension
elm_notify_add
elm_notify_align_set(obj,double horizontal, double vertical)
elm_object_part_content_set:设置notify的swallowpart为其他content
elm_notify_timeout_set:设置弹出notify的timeout时间,超过时间后notify将消失
elm_notify_allow_events_set:设置是否接收在notify外面的点击事件,如果true,点notify外面将收到“block,clicked”事件,在事件处理中可使notify隐藏起来
popup是个加强版的notify,在项目中会有很多地方用到,比如低电弹框
elm_popup_add
elm_popup_timeout_set设置timeout的时间,超时会收到timeout信号
可通过elm_object_part_text_set、elm_object_part_content_set等接口设置下面这些text part和contentpart
elm_popup_orient_set设置popup的弹出方向
效果图
panel,面板控件,详见截图
elm_panel_add
elm_panel_orient_set设置panel出现的方向
elm_panel_hidden_set设置隐藏状态
elm_panel_toggle触发是否隐藏
elm_object_part_content_set设置panel里面content的内容
panes,两个content之间可拖动bar
elm_panes_add
elm_object_part_content_set可以设置left和right两个contentpart
elm_panes_horizontal_set设置panes的方向
elm_panes_fixed_set如果设置为true,left和rightpart将不可拖动,并且等大
elm_toolbar_add
elm_toolbar_shrink_mode_set设置bar超出parent大小时的显示模式
elm_toolbar_item_append添加子item(图1)
elm_toolbar_item_state_add给item添加状态(图2、图3)
elm_toolbar_item_menu_set设置为menu(图4)
elm_menu_add
elm_menu_item_add,如果第二个参数parent为某一个item,则当前创建的是子item
elm_menu_item_separator_add添加item之间的分隔线
侧边栏的导航,通常按字母表顺序排序,比如用于联系人的快速定位,一般结合list、genlist、gengrid等控件共同使用。
elm_index_add
elm_index_item_append
letter表示对应的字母,func表示当字母选择后的回调,data表示字母选后显示的list item
elm_index_level_go刷新
flip控件,表示一种在front和back两个content之间的动画切换控件,其中front可见,back不可见
有两种方式触发动画
①用户交互手动触发,用户通过滑动/拖动的方式触发
•elm_flip_interaction_direction_enabled_set设置某个方向上是否允许用户触发
•elm_flip_interaction_direction_hitsize_set设置某个方向上要靠近边缘多少的位置触发,比如如下设置
表示在某个方向靠近边缘1/10的范围内拖动才能触发动画切换,值为0.1 ~ 1.0
•elm_flip_interaction_set设置动画切换效果,有如下:
②程序触发动画
elm_flip_go即可触发动画,有以下动画切换模式
elm_fileselector_add
elm_fileselector_expandable_set如果为true,则用户可以选择文件夹,否则只能选择文件
elm_fileselector_path_set设置初始选择的位置
elm_fileselector_folder_only_set列表中只显示文件夹
elm_fileselector_selected_get选择的文件全路径包括文件名
elm_fileselector_path_get选择的文件路径
elm_fileselector_is_save_set是否可以保存文件,true可以输入更改文件名
elm_fileselector_mode_set设置list还是grid模式
elm_fileselector_multi_select_set是否可以多选
elm_spinner_add
elm_spinner_label_format_set(spinner, "%1.1f");设置字符串的格式
elm_spinner_step_set设置步长
elm_spinner_min_max_set(spinner, -50.0, 250.0);设置最大最小值
elm_object_style_set(spinner, “vertical”);设置spinner为垂直
elm_spinner_editable_set设置是否可以编辑
elm_spinner_special_value_add(spinner, 1, “January”);添加特别字样,用January代表1
elm_spinner_interval_set设置长按箭头时每次增减的时间
elm_win_activate激活
elm_win_alpha_set透明度
elm_win_autodel_set如果设置autodel为true,关闭窗口时会自动delete掉所有内容
elm_win_conformant_set
elm_win_fullscreen_set全屏
elm_win_iconified_set最小化
elm_win_indicator_mode_set
elm_win_maximized_set最大化
elm_win_override_set设置为true后,不被windowmanager管理,尽量不用
elm_win_rotation_set旋转
elm_win_title_set