-#include <Elementary.h>\r
-#include "elm_priv.h"\r
-\r
-/**\r
- * @defgroup Multibuttonentry Multibuttonentry\r
- * @ingroup Elementary\r
- *\r
- * This is a Multibuttonentry.\r
- */\r
-\r
-#define MAX_STR 256\r
-#define MAX_W_BTN 200\r
-#define MIN_W_ENTRY 20\r
-\r
-typedef enum _Multibuttonentry_Pos\r
-{\r
- MULTIBUTONENTRY_POS_START,\r
- MULTIBUTONENTRY_POS_END,\r
- MULTIBUTONENTRY_POS_BEFORE,\r
- MULTIBUTONENTRY_POS_AFTER,\r
- MULTIBUTONENTRY_POS_NUM\r
-} Multibuttonentry_Pos;\r
-\r
-typedef enum _Multibuttonentry_Button_State\r
-{\r
- MULTIBUTONENTRY_BUTTON_STATE_DEFAULT,\r
- MULTIBUTONENTRY_BUTTON_STATE_SELECTED,\r
- MULTIBUTONENTRY_BUTTON_STATE_NUM\r
-} Multibuttonentry_Button_State;\r
-\r
-typedef enum _MultiButtonEntry_Closed_Button_Type {\r
- MULTIBUTTONENTRY_CLOSED_IMAGE,\r
- MULTIBUTTONENTRY_CLOSED_LABEL\r
-} MultiButtonEntry_Closed_Button_Type;\r
-\r
-struct _Multibuttonentry_Item {\r
- Evas_Object *multibuttonentry;\r
- Evas_Object *button;\r
- Evas_Object *label;\r
- void *data;\r
- Evas_Coord vw, rw; // vw: visual width, real width\r
- Eina_Bool visible: 1;\r
-};\r
-\r
-typedef struct _Widget_Data Widget_Data;\r
-struct _Widget_Data {\r
- Evas_Object *base;\r
- Evas_Object *box;\r
- Evas_Object *entry;\r
- Evas_Object *label;\r
- Evas_Object *guidetext;\r
- Evas_Object *end; // used to represent the total number of invisible buttons\r
-\r
- Evas_Object *rectForEnd;\r
- MultiButtonEntry_Closed_Button_Type end_type;\r
-\r
- Eina_List *items;\r
- Eina_List *current;\r
- int n_str;\r
-\r
- Evas_Coord w_box, h_box;\r
- int contracted;\r
- Eina_Bool focused: 1;\r
-};\r
-\r
-static const char *widtype = NULL;\r
-static void _del_hook(Evas_Object *obj);\r
-static void _theme_hook(Evas_Object *obj);\r
-static void _on_focus_hook(void *data __UNUSED__, Evas_Object *obj);\r
-static void _sizing_eval(Evas_Object *obj);\r
-static void _changed_size_hint_cb(void *data, Evas *evas, Evas_Object *obj, void *event);\r
-static void _resize_cb(void *data, Evas *evas, Evas_Object *obj, void *event);\r
-static void _event_init(Evas_Object *obj);\r
-static void _contracted_state_set(Evas_Object *obj, int contracted);\r
-static void _view_update(Evas_Object *obj);\r
-static void _set_label(Evas_Object *obj, const char* str);\r
-static void _change_current_button_state(Evas_Object *obj, Multibuttonentry_Button_State state);\r
-static void _change_current_button(Evas_Object *obj, Evas_Object *btn);\r
-static void _button_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);\r
-static void _del_button_obj(Evas_Object *obj, Evas_Object *btn);\r
-static void _del_button_item(Elm_Multibuttonentry_Item *item);\r
-static void _del_button(Evas_Object *obj);\r
-static Elm_Multibuttonentry_Item* _add_button_item(Evas_Object *obj, const char *str, Multibuttonentry_Pos pos, const Elm_Multibuttonentry_Item *reference, void *data);\r
-static void _add_button(Evas_Object *obj, char *str);\r
-static void _evas_key_up_cb(void *data, Evas *e , Evas_Object *obj , void *event_info );\r
-static void _view_init(Evas_Object *obj);\r
-static void _set_vis_guidetext(Evas_Object *obj);\r
-\r
-static void\r
-_del_hook(Evas_Object *obj)\r
-{\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (!wd) return;\r
-\r
- if (wd->items)\r
- {\r
- Elm_Multibuttonentry_Item *item;\r
- EINA_LIST_FREE(wd->items, item)\r
- {\r
- _del_button_obj(obj, item->button);\r
- free(item);\r
- }\r
- wd->items = NULL;\r
- }\r
- wd->current = NULL;\r
-\r
- if (wd->entry) evas_object_del (wd->entry);\r
- if (wd->label) evas_object_del (wd->label);\r
- if (wd->guidetext) evas_object_del (wd->guidetext);\r
- if (wd->end) evas_object_del (wd->end);\r
- if (wd->rectForEnd) evas_object_del(wd->rectForEnd);\r
-}\r
-\r
-static void\r
-_theme_hook(Evas_Object *obj)\r
-{\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- Eina_List *l;\r
- Elm_Multibuttonentry_Item *item;\r
- if (!wd) return;\r
-\r
- _elm_theme_object_set(obj, wd->base, "multibuttonentry", "base", elm_widget_style_get(obj));\r
- if (wd->box) edje_object_part_swallow (wd->base, "box.swallow", wd->box);\r
- edje_object_scale_set(wd->base, elm_widget_scale_get(obj) * _elm_config->scale);\r
-\r
- EINA_LIST_FOREACH(wd->items, l, item)\r
- {\r
- if (item->button)\r
- _elm_theme_object_set (obj, item->button, "multibuttonentry", "btn", elm_widget_style_get (obj));\r
- if (item->label)\r
- edje_object_part_swallow (item->button, "elm.label", item->label);\r
- edje_object_scale_set(item->button, elm_widget_scale_get(obj) * _elm_config->scale);\r
- }\r
-\r
- _sizing_eval(obj);\r
-}\r
-\r
-static void\r
-_on_focus_hook(void *data __UNUSED__, Evas_Object *obj)\r
-{\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (!wd) return;\r
-\r
- if (!elm_widget_focus_get(obj) && !(elm_widget_disabled_get(obj)))\r
- {\r
- wd->focused = EINA_FALSE;\r
- _view_update(obj);\r
- evas_object_smart_callback_call(obj, "unfocused", NULL);\r
- }\r
-}\r
-\r
-static void\r
-_signal_emit_hook(Evas_Object *obj, const char *emission, const char *source)\r
-{\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (!wd) return;\r
- edje_object_signal_emit(wd->base, emission, source);\r
-}\r
-\r
-static void\r
-_sizing_eval(Evas_Object *obj)\r
-{\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- Evas_Coord minw = -1, minh = -1;\r
- Evas_Coord left, right, top, bottom;\r
- if (!wd) return;\r
-\r
- evas_object_size_hint_min_get(wd->box, &minw, &minh);\r
- edje_object_part_geometry_get(wd->base, "top.left.pad", NULL, NULL, &left, &top);\r
- edje_object_part_geometry_get(wd->base, "bottom.right.pad", NULL, NULL, &right, &bottom);\r
-\r
- minw += (left + right);\r
- minh += (top + bottom);\r
-\r
- evas_object_size_hint_min_set(obj, minw, minh);\r
-}\r
-\r
-static void\r
-_signal_mouse_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)\r
-{\r
- Widget_Data *wd = elm_widget_data_get(data);\r
- if(!wd || !wd->base) return;\r
-\r
- wd->focused = EINA_TRUE;\r
- _view_update(data);\r
- evas_object_smart_callback_call(data, "clicked", NULL);\r
-}\r
-\r
-static void\r
-_changed_size_hint_cb(void *data, Evas *evas, Evas_Object *obj, void *event)\r
-{\r
- Evas_Object *eo = (Evas_Object *)data;\r
- Widget_Data *wd = elm_widget_data_get(data);\r
- if (!wd) return;\r
- _sizing_eval(eo);\r
-}\r
-\r
-static void\r
-_resize_cb(void *data, Evas *evas, Evas_Object *obj, void *event)\r
-{\r
- Widget_Data *wd = elm_widget_data_get(data);\r
- Evas_Coord w, h;\r
- if (!wd) return;\r
-\r
- evas_object_geometry_get(wd->box, NULL, NULL, &w, &h);\r
-\r
- if (wd->h_box < h) evas_object_smart_callback_call (data, "expanded", NULL);\r
- else if (wd->h_box > h) evas_object_smart_callback_call (data, "contracted", NULL);\r
- else ;\r
-\r
- wd->w_box = w;\r
- wd->h_box = h;\r
-\r
- _view_update(data);\r
-}\r
-\r
-static void\r
-_event_init(Evas_Object *obj)\r
-{\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (!wd || !wd->base) return;\r
-\r
- if (wd->base)\r
- {\r
- edje_object_signal_callback_add(wd->base, "mouse,clicked,1", "*", _signal_mouse_clicked, obj);\r
- edje_object_signal_callback_add(wd->base, "clicked", "*", _signal_mouse_clicked, obj);\r
- }\r
-\r
- if (wd->box)\r
- {\r
- evas_object_event_callback_add(wd->box, EVAS_CALLBACK_RESIZE, _resize_cb, obj);\r
- evas_object_event_callback_add(wd->box, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hint_cb, obj);\r
- }\r
-}\r
-\r
-static void\r
-_set_vis_guidetext(Evas_Object *obj)\r
-{\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (wd && !eina_list_count(wd->items) && wd->guidetext\r
- && !elm_widget_focus_get(obj) && !wd->focused)\r
- {\r
- elm_box_unpack(wd->box, wd->guidetext);\r
- elm_box_unpack(wd->box, wd->entry);\r
- evas_object_hide(wd->entry);\r
- elm_box_pack_end(wd->box, wd->guidetext);\r
- evas_object_show(wd->guidetext);\r
- if (wd->n_str)\r
- {\r
- elm_scrolled_entry_entry_set(wd->entry, "");\r
- wd->n_str = 0;\r
- }\r
- }\r
- else\r
- {\r
- elm_box_unpack(wd->box, wd->entry);\r
- elm_box_unpack(wd->box, wd->guidetext);\r
- evas_object_hide(wd->guidetext);\r
- if (!wd->contracted)\r
- {\r
- elm_box_pack_end(wd->box, wd->entry);\r
- evas_object_show(wd->entry);\r
- if (elm_widget_focus_get(obj) || wd->focused)\r
- elm_object_focus(wd->entry);\r
- }\r
- }\r
- return;\r
-}\r
-\r
-static void\r
-_contracted_state_set(Evas_Object *obj, int contracted)\r
-{\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- Eina_List *l;\r
- Elm_Multibuttonentry_Item *item;\r
- if (!wd || !wd->box) return;\r
-\r
- if (wd->contracted == contracted) return;\r
-\r
- if (!eina_list_count(wd->items))\r
- {\r
- _set_vis_guidetext(obj);\r
- wd->contracted = 0;\r
- return;\r
- }\r
-\r
- elm_scrolled_entry_entry_set(wd->entry, "");\r
-\r
- if (contracted == 1)\r
- {\r
- Evas_Coord w=0, w_tmp=0;\r
- Evas_Coord box_inner_item_width_padding = 0;\r
-\r
- elm_box_padding_get(wd->box, &box_inner_item_width_padding, NULL);\r
- // unpack all items and entry\r
- elm_box_unpack_all(wd->box);\r
- EINA_LIST_FOREACH(wd->items, l, item)\r
- {\r
- if (item)\r
- {\r
- evas_object_hide(item->button);\r
- item->visible = EINA_FALSE;\r
- }\r
- }\r
- evas_object_hide(wd->entry);\r
-\r
-\r
- // pack buttons only 1line\r
- w = wd->w_box;\r
-\r
- if (wd->label)\r
- {\r
- elm_box_pack_end(wd->box, wd->label);\r
- evas_object_size_hint_min_get(wd->label, &w_tmp, NULL);\r
- w -= w_tmp;\r
- w -= box_inner_item_width_padding;\r
- }\r
-\r
- Eina_Bool on_contracted = EINA_FALSE;\r
- item = NULL;\r
- int count = eina_list_count(wd->items);\r
- Evas_Coord button_min_width = 0;\r
- /* Evas_Coord button_min_height = 0; */\r
- if (wd->end_type == MULTIBUTTONENTRY_CLOSED_IMAGE)\r
- {\r
- const char *size_str;\r
- size_str = edje_object_data_get(wd->end, "closed_button_width");\r
- if(size_str) button_min_width = (Evas_Coord)atoi(size_str);\r
- /* it use for later\r
- size_str = edje_object_data_get(wd->end, "closed_button_height");\r
- if(size_str) button_min_width = (Evas_Coord)atoi(size_str);\r
- */\r
- }\r
-\r
- EINA_LIST_FOREACH(wd->items, l, item)\r
- {\r
- if (item)\r
- {\r
- int w_label_count = 0;\r
- char buf[MAX_STR] = {0,};\r
-\r
- elm_box_pack_end(wd->box, item->button);\r
- evas_object_show(item->button);\r
- item->visible = EINA_TRUE;\r
-\r
- w -= item->vw;\r
- w -= box_inner_item_width_padding;\r
- count--;\r
-\r
- if (wd->end_type == MULTIBUTTONENTRY_CLOSED_LABEL)\r
- {\r
- if (count > 0)\r
- {\r
- snprintf(buf, sizeof(buf), "... + %d", count);\r
- elm_label_label_set(wd->end, buf);\r
- evas_object_size_hint_min_get(wd->end, &w_label_count, NULL);\r
- }\r
-\r
- if (w < 0 || w < w_label_count)\r
- {\r
- elm_box_unpack(wd->box, item->button);\r
- evas_object_hide(item->button);\r
- item->visible = EINA_FALSE;\r
-\r
- count++;\r
- snprintf(buf, sizeof(buf), "... + %d", count);\r
- elm_label_label_set(wd->end, buf);\r
- evas_object_size_hint_min_get(wd->end, &w_label_count, NULL);\r
-\r
- elm_box_pack_end(wd->box, wd->end);\r
- evas_object_show(wd->end);\r
-\r
- on_contracted = EINA_TRUE;\r
- wd->contracted = contracted;\r
- evas_object_smart_callback_call(obj, "contracted,state,changed", (void *)wd->contracted);\r
- break;\r
- }\r
- }\r
- else if (wd->end_type == MULTIBUTTONENTRY_CLOSED_IMAGE)\r
- {\r
- if (w < button_min_width)\r
- {\r
- Evas_Coord rectSize;\r
- Evas_Coord closed_height = 0;\r
- const char *height_str = edje_object_data_get(wd->base, "closed_height");\r
- if(height_str) closed_height = (Evas_Coord)atoi(height_str);\r
- elm_box_unpack(wd->box, item->button);\r
- evas_object_hide(item->button);\r
- item->visible = EINA_FALSE;\r
-\r
- w += item->vw;\r
- rectSize = w - button_min_width;\r
- if (!wd->rectForEnd)\r
- {\r
- Evas *e = evas_object_evas_get(obj);\r
- wd->rectForEnd = evas_object_rectangle_add(e);\r
- evas_object_color_set(wd->rectForEnd, 0, 0, 0, 0);\r
- }\r
- evas_object_size_hint_min_set(wd->rectForEnd, rectSize, closed_height);\r
- elm_box_pack_end(wd->box, wd->rectForEnd);\r
- evas_object_show(wd->rectForEnd);\r
-\r
- elm_box_pack_end(wd->box, wd->end);\r
- evas_object_show(wd->end);\r
-\r
- on_contracted = EINA_TRUE;\r
- wd->contracted = contracted;\r
- evas_object_smart_callback_call(obj, "contracted,state,changed", (void *)wd->contracted);\r
- break;\r
- }\r
- }\r
- }\r
- }\r
- if(on_contracted == EINA_FALSE) // unset contracted mode\r
- {\r
- // pack entry\r
- elm_box_pack_end(wd->box, wd->entry);\r
- evas_object_show(wd->entry);\r
- if(elm_widget_focus_get(obj))\r
- elm_object_focus(wd->entry);\r
- wd->contracted = 0;\r
- }\r
- }\r
- else\r
- {\r
- // unpack all items and entry\r
- elm_box_unpack_all(wd->box);\r
- EINA_LIST_FOREACH(wd->items, l, item)\r
- {\r
- if (item)\r
- {\r
- evas_object_hide(item->button);\r
- item->visible = EINA_FALSE;\r
- }\r
- }\r
- evas_object_hide(wd->end);\r
-\r
- if (wd->rectForEnd) evas_object_hide(wd->rectForEnd);\r
-\r
- // pack buttons only 1line\r
-\r
- if (wd->label) elm_box_pack_end(wd->box, wd->label);\r
-\r
- // pack remain btns\r
- item = NULL;\r
- EINA_LIST_FOREACH(wd->items, l, item)\r
- {\r
- if (item && !item->visible)\r
- {\r
- elm_box_pack_end(wd->box, item->button);\r
- evas_object_show(item->button);\r
- }\r
- }\r
-\r
- // pack entry\r
- elm_box_pack_end(wd->box, wd->entry);\r
- evas_object_show(wd->entry);\r
- if(elm_widget_focus_get(obj))\r
- elm_object_focus(wd->entry);\r
-\r
- wd->contracted = contracted;\r
- evas_object_smart_callback_call(obj, "contracted,state,changed", (void *)wd->contracted);\r
- }\r
-}\r
-\r
-static void\r
-_view_update(Evas_Object *obj)\r
-{\r
- Evas_Coord width = 1, height = 1;\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (!wd || !wd->box || !wd->entry || !(wd->w_box > 0)) return;\r
-\r
- // update label\r
- if (wd->label)\r
- {\r
- elm_box_unpack(wd->box, wd->label);\r
- elm_box_pack_start(wd->box, wd->label);\r
- evas_object_size_hint_min_get(wd->label, &width, &height);\r
- }\r
-\r
- if (wd->guidetext)\r
- {\r
- Evas_Coord guide_text_width = wd->w_box - width;\r
- evas_object_size_hint_min_set(wd->guidetext, guide_text_width, height);\r
- }\r
-\r
- // update buttons in contracted mode\r
- if (wd->contracted == 1)\r
- {\r
- _contracted_state_set(obj, 0);\r
- _contracted_state_set(obj, 1);\r
- }\r
-\r
- // update guidetext\r
- _set_vis_guidetext(obj);\r
-}\r
-\r
-static void\r
-_set_label(Evas_Object *obj, const char* str)\r
-{\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (!wd || !str) return;\r
-\r
- if (wd->label)\r
- {\r
- Evas_Coord width, height, sum_width = 0;\r
- evas_object_size_hint_min_set(wd->label, 0, 0);\r
- evas_object_resize(wd->label, 0, 0);\r
- edje_object_part_text_set(wd->label, "mbe.label", str);\r
-\r
- if (!strcmp(str, ""))\r
- {\r
- /* FIXME: not work yet */\r
- edje_object_signal_emit(wd->label, "elm,mbe,clear_text", "");\r
- edje_object_part_geometry_get(wd->label, "mbe.label", NULL, NULL, &width, &height);\r
- sum_width += width;\r
- }\r
- else\r
- {\r
- edje_object_signal_emit(wd->label, "elm,mbe,set_text", "");\r
- edje_object_part_geometry_get(wd->label, "mbe.label", NULL, NULL, &width, &height);\r
- sum_width += width;\r
-\r
- edje_object_part_geometry_get(wd->label, "mbe.label.left.padding", NULL, NULL, &width, NULL);\r
- sum_width += width;\r
-\r
- edje_object_part_geometry_get(wd->label, "mbe.label.right.padding", NULL, NULL, &width, NULL);\r
- sum_width += width;\r
- }\r
- evas_object_size_hint_min_set(wd->label, sum_width, height);\r
- }\r
- evas_object_show(wd->label);\r
- _view_update(obj);\r
-}\r
-\r
-static void\r
-_set_guidetext(Evas_Object *obj, const char* str)\r
-{\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (!wd || !str) return;\r
-\r
- if (!wd->guidetext)\r
- {\r
- if (! (wd->guidetext = edje_object_add (evas_object_evas_get (obj)))) return;\r
- _elm_theme_object_set(obj, wd->guidetext, "multibuttonentry", "guidetext", elm_widget_style_get(obj));\r
- evas_object_size_hint_weight_set(wd->guidetext, 0.0, EVAS_HINT_EXPAND);\r
- evas_object_size_hint_align_set(wd->guidetext, EVAS_HINT_FILL, EVAS_HINT_FILL);\r
- }\r
-\r
- if (wd->guidetext) edje_object_part_text_set (wd->guidetext, "elm.text", str);\r
- _view_update(obj);\r
-}\r
-\r
-static void\r
-_change_current_button_state(Evas_Object *obj, Multibuttonentry_Button_State state)\r
-{\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- Elm_Multibuttonentry_Item *item = NULL;\r
- if (!wd) return;\r
-\r
- if (wd->current)\r
- item = eina_list_data_get(wd->current);\r
-\r
- if (item && item->button)\r
- {\r
- switch(state)\r
- {\r
- case MULTIBUTONENTRY_BUTTON_STATE_DEFAULT:\r
- edje_object_signal_emit(item->button, "default", "");\r
- wd->current = NULL;\r
- break;\r
- case MULTIBUTONENTRY_BUTTON_STATE_SELECTED:\r
- edje_object_signal_emit(item->button, "focused", "");\r
- evas_object_smart_callback_call(obj, "item,selected", item);\r
- break;\r
- default:\r
- edje_object_signal_emit(item->button, "default", "");\r
- wd->current = NULL;\r
- break;\r
- }\r
- }\r
-}\r
-\r
-static void\r
-_change_current_button(Evas_Object *obj, Evas_Object *btn)\r
-{\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- Eina_List *l;\r
- Elm_Multibuttonentry_Item *item;\r
- if (!wd) return;\r
-\r
- // change the state of previous button to "default"\r
- _change_current_button_state(obj, MULTIBUTONENTRY_BUTTON_STATE_DEFAULT);\r
-\r
- // change the current\r
- EINA_LIST_FOREACH(wd->items, l, item)\r
- {\r
- if (item->button == btn)\r
- {\r
- wd->current = l;\r
- break;\r
- }\r
- }\r
-\r
- // chagne the state of current button to "focused"\r
- _change_current_button_state(obj, MULTIBUTONENTRY_BUTTON_STATE_SELECTED);\r
-\r
-}\r
-\r
-static void\r
-_button_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)\r
-{\r
- Widget_Data *wd = elm_widget_data_get(data);\r
- static char str[MAX_STR];\r
- Elm_Multibuttonentry_Item *item = NULL;\r
- if (!wd || wd->contracted) return;\r
-\r
- strncpy(str, elm_scrolled_entry_entry_get(wd->entry), MAX_STR);\r
- str[MAX_STR - 1]= 0;\r
-\r
- if (strlen (str))\r
- _add_button(data, str);\r
-\r
- _change_current_button(data, obj);\r
-\r
- if (wd->current)\r
- if((item = eina_list_data_get(wd->current)) != NULL)\r
- evas_object_smart_callback_call(data, "item,clicked", item);\r
-}\r
-\r
-static void\r
-_del_button_obj(Evas_Object *obj, Evas_Object *btn)\r
-{\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- Evas_Object *label;\r
- if (!wd || !btn) return;\r
-\r
- if (btn)\r
- {\r
- // del label\r
- label = edje_object_part_swallow_get(btn, "elm.label");\r
- edje_object_part_unswallow(btn, label);\r
- evas_object_del(label);\r
-\r
- // del button\r
- evas_object_del(btn);\r
- }\r
-}\r
-\r
-static void\r
-_del_button_item(Elm_Multibuttonentry_Item *item)\r
-{\r
- Eina_List *l;\r
- Elm_Multibuttonentry_Item *_item;\r
- if (!item) return;\r
- Widget_Data *wd;\r
-\r
- Evas_Object *obj = item->multibuttonentry;\r
- wd = elm_widget_data_get(obj);\r
- if (!wd) return;\r
-\r
- EINA_LIST_FOREACH(wd->items, l, _item)\r
- {\r
- if (_item == item)\r
- {\r
- wd->items = eina_list_remove(wd->items, _item);\r
- elm_box_unpack(wd->box, _item->button);\r
- evas_object_smart_callback_call(obj, "item,deleted", _item);\r
- _del_button_obj(obj, _item->button);\r
- free(_item);\r
- if (wd->current == l)\r
- wd->current = NULL;\r
- break;\r
- }\r
- }\r
- _view_update(obj);\r
-}\r
-\r
-static void\r
-_del_button(Evas_Object *obj)\r
-{\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- Elm_Multibuttonentry_Item *item;\r
- if (!wd || !wd->items) return;\r
-\r
- if (!wd->current)\r
- {\r
- // let the last button focus\r
- item = eina_list_data_get(eina_list_last(wd->items));\r
- if (item->button) _change_current_button (obj, item->button);\r
- }\r
- else\r
- {\r
- item = eina_list_data_get(wd->current);\r
- if (item)\r
- {\r
- _del_button_item(item);\r
- }\r
- }\r
-}\r
-\r
-static void\r
-_resize_button(Evas_Object *btn, Evas_Object *label, Evas_Coord *realw, Evas_Coord *vieww)\r
-{\r
- Evas_Coord rw, vw;\r
- Evas_Coord w_label, h_label, w_btn, h_btn, padding_outer, padding_inner;\r
-\r
- // decide the size of button\r
- evas_object_size_hint_min_get(label, &w_label, &h_label);\r
- edje_object_part_geometry_get(btn, "elm.base", NULL, NULL, NULL, &h_btn);\r
- edje_object_part_geometry_get(btn, "left.padding", NULL, NULL, &padding_outer, NULL);\r
- edje_object_part_geometry_get(btn, "left.inner.padding", NULL, NULL, &padding_inner, NULL);\r
- w_btn = w_label + 2*padding_outer + 2*padding_inner;\r
-\r
- rw = w_btn;\r
- vw =(MAX_W_BTN < w_btn) ? MAX_W_BTN : w_btn;\r
-\r
- //resize btn and label\r
- evas_object_resize(btn, vw, h_btn);\r
- evas_object_size_hint_min_set(btn, vw, h_btn);\r
- if ( (rw != vw) && (vw - 2*padding_outer - 2*padding_inner >=0))\r
- {\r
- evas_object_resize(label, vw - 2*padding_outer - 2*padding_inner, h_label);\r
- elm_label_wrap_width_set(label, vw - 2*padding_outer - 2*padding_inner );\r
- }\r
-\r
- if(realw) *realw = rw;\r
- if(vieww) *vieww = vw;\r
-}\r
-\r
-static Elm_Multibuttonentry_Item*\r
-_add_button_item(Evas_Object *obj, const char *str, Multibuttonentry_Pos pos, const Elm_Multibuttonentry_Item *reference, void *data)\r
-{\r
- Elm_Multibuttonentry_Item *item;\r
- Evas_Object *btn;\r
- Evas_Object *label;\r
- //Evas_Coord w_label, h_label, w_btn, h_btn, padding_outer, padding_inner;\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (!wd || !wd->box || !wd->entry) return NULL;\r
-\r
- //if (wd->contracted == 1) return NULL;\r
-\r
- // add button\r
- btn = edje_object_add(evas_object_evas_get(obj));\r
-\r
- const char *btn_style = edje_object_data_get(wd->base,"button");\r
-\r
- if (!btn_style || !strcmp(btn_style,"rect"))\r
- _elm_theme_object_set(obj,btn,"multibuttonentry","rect_btn",elm_widget_style_get(obj));\r
- else\r
- _elm_theme_object_set(obj, btn, "multibuttonentry", "btn", elm_widget_style_get(obj));\r
- edje_object_signal_callback_add(btn, "mouse,clicked,1", "*", _button_clicked, obj);\r
- evas_object_size_hint_weight_set(btn, 0.0, 0.0);\r
- evas_object_show(btn);\r
-\r
- // add label\r
- label = elm_label_add(obj);\r
- elm_object_style_set(label, "extended/multibuttonentry_button");\r
- elm_label_label_set(label, str);\r
- elm_label_ellipsis_set(label, EINA_TRUE);\r
- edje_object_part_swallow(btn, "elm.label", label);\r
-\r
- // append item list\r
- item = ELM_NEW(Elm_Multibuttonentry_Item);\r
- if (item)\r
- {\r
- Evas_Coord rw, vw;\r
- _resize_button(btn, label, &rw, &vw);\r
-\r
- item->multibuttonentry = obj;\r
- item->button = btn;\r
- item->label = label;\r
- item->data = data;\r
- item->rw = rw;\r
- item->vw = vw;\r
- item->visible = EINA_TRUE;\r
-\r
- switch(pos)\r
- {\r
- case MULTIBUTONENTRY_POS_START:\r
- wd->items = eina_list_prepend(wd->items, item);\r
- if(wd->label) elm_box_pack_after(wd->box, btn, wd->label);\r
- else elm_box_pack_start(wd->box, btn);\r
- _view_update(obj);\r
- break;\r
- case MULTIBUTONENTRY_POS_END:\r
- wd->items = eina_list_append(wd->items, item);\r
- _view_update(obj);\r
- elm_box_pack_before(wd->box, btn, wd->entry);\r
- break;\r
- case MULTIBUTONENTRY_POS_BEFORE:\r
- if (reference)\r
- {\r
- wd->items = eina_list_prepend_relative(wd->items, item, reference);\r
- elm_box_pack_before(wd->box, btn, reference->button);\r
- _view_update(obj);\r
- }\r
- else\r
- {\r
- wd->items = eina_list_append(wd->items, item);\r
- _view_update(obj);\r
- elm_box_pack_before(wd->box, btn, wd->entry);\r
- }\r
- break;\r
- case MULTIBUTONENTRY_POS_AFTER:\r
- if (reference)\r
- {\r
- wd->items = eina_list_append_relative(wd->items, item, reference);\r
- elm_box_pack_after(wd->box, btn, reference->button);\r
- _view_update(obj);\r
- }\r
- else\r
- {\r
- wd->items = eina_list_append(wd->items, item);\r
- _view_update(obj);\r
- elm_box_pack_before(wd->box, btn, wd->entry);\r
- }\r
- break;\r
- default:\r
- break;\r
- }\r
- }\r
-\r
- evas_object_smart_callback_call(obj, "item,added", item);\r
-\r
- return item;\r
-}\r
-\r
-static void\r
-_add_button(Evas_Object *obj, char *str)\r
-{\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (!wd) return;\r
-\r
- //remove entry text\r
- elm_scrolled_entry_entry_set(wd->entry, "");\r
-\r
- // add button\r
- _add_button_item(obj, str, MULTIBUTONENTRY_POS_END, NULL, NULL);\r
-}\r
-\r
-static void\r
-_evas_key_up_cb(void *data, Evas *e , Evas_Object *obj , void *event_info )\r
-{\r
- Widget_Data *wd = elm_widget_data_get(data);\r
- Evas_Event_Key_Up *ev = (Evas_Event_Key_Up *) event_info;\r
- static char str[MAX_STR];\r
- if (!wd || !wd->base || !wd->box) return;\r
-\r
- strncpy(str, elm_scrolled_entry_entry_get(wd->entry), MAX_STR);\r
- str[MAX_STR - 1]= 0;\r
-\r
- if ( (wd->n_str == 0) && (strcmp (str, "") == 0) && ( (strcmp (ev->keyname, "BackSpace") == 0)|| (strcmp (ev->keyname, "BackSpace (") == 0)))\r
- {\r
- _del_button(data);\r
- }\r
- else if ( (strcmp (str, "") != 0) && (strcmp (ev->keyname, "KP_Enter") == 0 ||strcmp (ev->keyname, "Return") == 0 ))\r
- {\r
- _add_button(data, str);\r
- wd->n_str = 0;\r
- return;\r
- }\r
- else\r
- {\r
- //\r
- }\r
-\r
- wd->n_str = strlen(str);\r
-}\r
-\r
-static void\r
-_view_init(Evas_Object *obj)\r
-{\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (!wd) return;\r
-\r
- if (!wd->box)\r
- {\r
- if (! (wd->box = elm_box_add (obj))) return;\r
- elm_widget_sub_object_add(obj, wd->box);\r
- elm_box_extended_mode_set(wd->box, EINA_TRUE);\r
- elm_box_homogenous_set(wd->box, EINA_FALSE);\r
- edje_object_part_swallow(wd->base, "box.swallow", wd->box);\r
- }\r
-\r
- if (!wd->label)\r
- {\r
- if (!(wd->label = edje_object_add(evas_object_evas_get(obj)))) return;\r
- _elm_theme_object_set(obj, wd->label, "multibuttonentry", "label", elm_widget_style_get(obj));\r
- _set_label(obj, "");\r
- }\r
-\r
- if (!wd->entry)\r
- {\r
- if (! (wd->entry = elm_scrolled_entry_add (obj))) return;\r
- elm_scrolled_entry_single_line_set(wd->entry, EINA_TRUE);\r
- elm_scrolled_entry_entry_set(wd->entry, "");\r
- elm_scrolled_entry_cursor_end_set(wd->entry);\r
- evas_object_size_hint_min_set(wd->entry, MIN_W_ENTRY, 0);\r
- evas_object_event_callback_add(wd->entry, EVAS_CALLBACK_KEY_UP, _evas_key_up_cb, obj);\r
- evas_object_size_hint_weight_set(wd->entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);\r
- evas_object_size_hint_align_set(wd->entry, EVAS_HINT_FILL, EVAS_HINT_FILL);\r
- if (wd->box) elm_box_pack_end (wd->box, wd->entry);\r
- evas_object_show(wd->entry);\r
- }\r
-\r
- if (!wd->end)\r
- {\r
- const char *end_type = edje_object_data_get(wd->base, "closed_button_type");\r
- if (!end_type || !strcmp(end_type, "label"))\r
- {\r
- if (! (wd->end = elm_label_add (obj))) return;\r
- elm_object_style_set(wd->end, "extended/multibuttonentry_default");\r
- wd->end_type = MULTIBUTTONENTRY_CLOSED_LABEL;\r
- }\r
- else\r
- {\r
- const char *size_str;\r
- if (!(wd->end = edje_object_add(evas_object_evas_get(obj)))) return;\r
- _elm_theme_object_set(obj, wd->end, "multibuttonentry", "closedbutton", elm_widget_style_get(obj));\r
- Evas_Coord button_min_width = 0;\r
- Evas_Coord button_min_height = 0;\r
-\r
- size_str = edje_object_data_get(wd->end, "closed_button_width");\r
- if(size_str) button_min_width = (Evas_Coord)atoi(size_str);\r
- size_str = edje_object_data_get(wd->end, "closed_button_height");\r
- if(size_str) button_min_height = (Evas_Coord)atoi(size_str);\r
-\r
- wd->end_type = MULTIBUTTONENTRY_CLOSED_IMAGE;\r
- evas_object_size_hint_min_set(wd->end, button_min_width, button_min_height);\r
- elm_widget_sub_object_add(obj, wd->end);\r
- }\r
- }\r
-}\r
-\r
-/**\r
- * Add a new multibuttonentry to the parent\r
- *\r
- * @param parent The parent object\r
- * @return The new object or NULL if it cannot be created\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI Evas_Object *\r
-elm_multibuttonentry_add(Evas_Object *parent)\r
-{\r
- Evas_Object *obj;\r
- Evas *e;\r
- Widget_Data *wd;\r
- if (!parent) return NULL;\r
-\r
- wd = ELM_NEW(Widget_Data);\r
- e = evas_object_evas_get(parent);\r
- if (!e) return NULL;\r
- obj = elm_widget_add(e);\r
- ELM_SET_WIDTYPE(widtype, "multibuttonentry");\r
- elm_widget_type_set(obj, "multibuttonentry");\r
- elm_widget_sub_object_add(parent, obj);\r
- elm_widget_data_set(obj, wd);\r
-\r
- elm_widget_del_hook_set(obj, _del_hook);\r
- elm_widget_theme_hook_set(obj, _theme_hook);\r
- elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);\r
- elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);\r
-\r
- wd->base = edje_object_add(e);\r
- _elm_theme_object_set(obj, wd->base, "multibuttonentry", "base", "default");\r
- elm_widget_resize_object_set(obj, wd->base);\r
-\r
- wd->contracted = 0;\r
- wd->focused = EINA_FALSE;\r
- wd->n_str = 0;\r
- wd->rectForEnd = NULL;\r
-\r
- _view_init(obj);\r
- _event_init(obj);\r
-\r
- return obj;\r
-}\r
-\r
-/**\r
- * Get the entry of the multibuttonentry object\r
- *\r
- * @param obj The multibuttonentry object\r
- * @return The entry object, or NULL if none\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI Evas_Object *\r
-elm_multibuttonentry_entry_get(Evas_Object *obj)\r
-{\r
- ELM_CHECK_WIDTYPE(obj, widtype) NULL;\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (!wd) return NULL;\r
-\r
- return wd->entry;\r
-}\r
-\r
-/**\r
- * Get the label\r
- *\r
- * @param obj The multibuttonentry object\r
- * @return The label, or NULL if none\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI const char *\r
-elm_multibuttonentry_label_get(Evas_Object *obj)\r
-{\r
- ELM_CHECK_WIDTYPE(obj, widtype) NULL;\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (!wd) return NULL;\r
- if (wd->label) return edje_object_part_text_get(wd->guidetext, "elm.text");\r
- return NULL;\r
-}\r
-\r
-/**\r
- * Set the label\r
- *\r
- * @param obj The multibuttonentry object\r
- * @param label The text label string\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI void\r
-elm_multibuttonentry_label_set(Evas_Object *obj, const char *label)\r
-{\r
- ELM_CHECK_WIDTYPE(obj, widtype);\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (!wd || !label) return;\r
- _set_label(obj, label);\r
-}\r
-\r
-/**\r
- * Get the guide text\r
- *\r
- * @param obj The multibuttonentry object\r
- * @return The guide text, or NULL if none\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI const char *\r
-elm_multibuttonentry_guide_text_get(Evas_Object *obj)\r
-{\r
- ELM_CHECK_WIDTYPE(obj, widtype) NULL;\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (!wd) return NULL;\r
- if (wd->guidetext) return edje_object_part_text_get(wd->guidetext, "elm.text");\r
- return NULL;\r
-}\r
-\r
-/**\r
- * Set the guide text\r
- *\r
- * @param obj The multibuttonentry object\r
- * @param label The guide text string\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI void\r
-elm_multibuttonentry_guide_text_set(Evas_Object *obj, const char *guidetext)\r
-{\r
- ELM_CHECK_WIDTYPE(obj, widtype);\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (!wd || !guidetext) return;\r
- _set_guidetext(obj, guidetext);\r
-}\r
-\r
-/**\r
- * Get the value of contracted state.\r
- *\r
- * @param obj The multibuttonentry object\r
- * @param the value of contracted state.\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI int\r
-elm_multibuttonentry_contracted_state_get(Evas_Object *obj)\r
-{\r
- ELM_CHECK_WIDTYPE(obj, widtype) -1;\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (!wd) return -1;\r
- return wd->contracted;\r
-}\r
-\r
-/**\r
- * Set/Unset the multibuttonentry to contracted state of single line\r
- *\r
- * @param obj The multibuttonentry object\r
- * @param the value of contracted state. set this to 1 to set the multibuttonentry to contracted state of single line. set this to 0 to unset the contracted state.\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI void\r
-elm_multibuttonentry_contracted_state_set(Evas_Object *obj, int contracted)\r
-{\r
- ELM_CHECK_WIDTYPE(obj, widtype);\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (!wd || !wd->box || (wd->contracted == contracted)) return;\r
- _contracted_state_set(obj, contracted);\r
-}\r
-\r
-/**\r
- * Prepend a new item to the multibuttonentry\r
- *\r
- * @param obj The multibuttonentry object\r
- * @param label The label of new item\r
- * @param data The ponter to the data to be attached\r
- * @return A handle to the item added or NULL if not possible\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI Elm_Multibuttonentry_Item *\r
-elm_multibuttonentry_item_add_start(Evas_Object *obj, const char *label, void *data)\r
-{\r
- ELM_CHECK_WIDTYPE(obj, widtype) NULL;\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- Elm_Multibuttonentry_Item *item;\r
- if (!wd || !label) return NULL;\r
- item = _add_button_item(obj, label, MULTIBUTONENTRY_POS_START, NULL, data);\r
- return item;\r
-}\r
-\r
-/**\r
- * Append a new item to the multibuttonentry\r
- *\r
- * @param obj The multibuttonentry object\r
- * @param label The label of new item\r
- * @param data The ponter to the data to be attached\r
- * @return A handle to the item added or NULL if not possible\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI Elm_Multibuttonentry_Item *\r
-elm_multibuttonentry_item_add_end(Evas_Object *obj, const char *label, void *data)\r
-{\r
- ELM_CHECK_WIDTYPE(obj, widtype) NULL;\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- Elm_Multibuttonentry_Item *item;\r
- if (!wd || !label) return NULL;\r
- item = _add_button_item(obj, label, MULTIBUTONENTRY_POS_END, NULL, data);\r
- return item;\r
-}\r
-\r
-/**\r
- * Add a new item to the multibuttonentry before the indicated object\r
- *\r
- * reference.\r
- * @param obj The multibuttonentry object\r
- * @param label The label of new item\r
- * @param before The item before which to add it\r
- * @param data The ponter to the data to be attached\r
- * @return A handle to the item added or NULL if not possible\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI Elm_Multibuttonentry_Item *\r
-elm_multibuttonentry_item_add_before(Evas_Object *obj, const char *label, Elm_Multibuttonentry_Item *before, void *data)\r
-{\r
- ELM_CHECK_WIDTYPE(obj, widtype) NULL;\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- Elm_Multibuttonentry_Item *item;\r
- if (!wd || !label) return NULL;\r
- item = _add_button_item(obj, label, MULTIBUTONENTRY_POS_BEFORE, before, data);\r
- return item;\r
-}\r
-\r
-/**\r
- * Add a new item to the multibuttonentry after the indicated object\r
- *\r
- * @param obj The multibuttonentry object\r
- * @param label The label of new item\r
- * @param after The item after which to add it\r
- * @param data The ponter to the data to be attached\r
- * @return A handle to the item added or NULL if not possible\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI Elm_Multibuttonentry_Item *\r
-elm_multibuttonentry_item_add_after(Evas_Object *obj, const char *label, Elm_Multibuttonentry_Item *after, void *data)\r
-{\r
- ELM_CHECK_WIDTYPE(obj, widtype) NULL;\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- Elm_Multibuttonentry_Item *item;\r
- if (!wd || !label) return NULL;\r
- item = _add_button_item(obj, label, MULTIBUTONENTRY_POS_AFTER, after, data);\r
- return item;\r
-}\r
-\r
-/**\r
- * Get a list of items in the multibuttonentry\r
- *\r
- * @param obj The multibuttonentry object\r
- * @return The list of items, or NULL if none\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI const Eina_List *\r
-elm_multibuttonentry_items_get(Evas_Object *obj)\r
-{\r
- ELM_CHECK_WIDTYPE(obj, widtype) NULL;\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (!wd) return NULL;\r
- return wd->items;\r
-}\r
-\r
-/**\r
- * Get the first item in the multibuttonentry\r
- *\r
- * @param obj The multibuttonentry object\r
- * @return The first item, or NULL if none\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI Elm_Multibuttonentry_Item *\r
-elm_multibuttonentry_item_first_get(Evas_Object *obj)\r
-{\r
- ELM_CHECK_WIDTYPE(obj, widtype) NULL;\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (!wd || !wd->items) return NULL;\r
- return eina_list_data_get(wd->items);\r
-}\r
-\r
-/**\r
- * Get the last item in the multibuttonentry\r
- *\r
- * @param obj The multibuttonentry object\r
- * @return The last item, or NULL if none\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI Elm_Multibuttonentry_Item *\r
-elm_multibuttonentry_item_last_get(Evas_Object *obj)\r
-{\r
- ELM_CHECK_WIDTYPE(obj, widtype) NULL;\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (!wd || !wd->items) return NULL;\r
- return eina_list_data_get(eina_list_last(wd->items));\r
-}\r
-\r
-/**\r
- * Get the selected item in the multibuttonentry\r
- *\r
- * @param obj The multibuttonentry object\r
- * @return The selected item, or NULL if none\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI Elm_Multibuttonentry_Item *\r
-elm_multibuttonentry_item_selected_get(Evas_Object *obj)\r
-{\r
- ELM_CHECK_WIDTYPE(obj, widtype) NULL;\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (!wd || !wd->current) return NULL;\r
- return eina_list_data_get(wd->current);\r
-}\r
-\r
-/**\r
- * Set the selected state of an item\r
- *\r
- * @param item The item\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI void\r
-elm_multibuttonentry_item_selected_set(Elm_Multibuttonentry_Item *item)\r
-{\r
- Widget_Data *wd;\r
- Eina_List *l;\r
- Elm_Multibuttonentry_Item *_item;\r
- if (!item) return;\r
- ELM_CHECK_WIDTYPE(item->multibuttonentry, widtype);\r
- wd = elm_widget_data_get(item->multibuttonentry);\r
- if (!wd) return;\r
-\r
- EINA_LIST_FOREACH(wd->items, l, _item)\r
- {\r
- if (_item == item)\r
- {\r
- _change_current_button(item->multibuttonentry, item->button);\r
- }\r
- }\r
-}\r
-\r
-/**\r
- * unselect all of items.\r
- *\r
- * @param obj The multibuttonentry object\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI void\r
-elm_multibuttonentry_item_unselect_all(Evas_Object *obj)\r
-{\r
- ELM_CHECK_WIDTYPE(obj, widtype);\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (!wd) return;\r
- _change_current_button_state(obj, MULTIBUTONENTRY_BUTTON_STATE_DEFAULT);\r
-}\r
-\r
-/**\r
- * Remove all items in the multibuttonentry.\r
- *\r
- * @param obj The multibuttonentry object\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI void\r
-elm_multibuttonentry_items_del(Evas_Object *obj)\r
-{\r
- ELM_CHECK_WIDTYPE(obj, widtype);\r
- Widget_Data *wd = elm_widget_data_get(obj);\r
- if (!wd) return;\r
-\r
- if (wd->contracted == 1)\r
- _contracted_state_set(obj, 0);\r
-\r
- if (wd->items)\r
- {\r
- Elm_Multibuttonentry_Item *item;\r
- EINA_LIST_FREE(wd->items, item)\r
- {\r
- elm_box_unpack(wd->box, item->button);\r
- _del_button_obj(obj, item->button);\r
- free(item);\r
- }\r
- wd->items = NULL;\r
- }\r
- wd->current = NULL;\r
- _view_update(obj);\r
-}\r
-\r
-/**\r
- * Delete a given item\r
- *\r
- * @param item The item\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI void\r
-elm_multibuttonentry_item_del(Elm_Multibuttonentry_Item *item)\r
-{\r
- if (!item) return;\r
- _del_button_item(item);\r
-}\r
-\r
-/**\r
- * Get the label of a given item\r
- *\r
- * @param item The item\r
- * @return The label of a given item, or NULL if none\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI const char *\r
-elm_multibuttonentry_item_label_get(Elm_Multibuttonentry_Item *item)\r
-{\r
- Widget_Data *wd;\r
- Eina_List *l;\r
- Elm_Multibuttonentry_Item *_item;\r
- if (!item) return NULL;\r
- ELM_CHECK_WIDTYPE(item->multibuttonentry, widtype) NULL;\r
- wd = elm_widget_data_get(item->multibuttonentry);\r
- if (!wd || !wd->items) return NULL;\r
-\r
- EINA_LIST_FOREACH(wd->items, l, _item)\r
- if (_item == item)\r
- {\r
- Evas_Object *label = edje_object_part_swallow_get(_item->button, "elm.label");\r
- if (label) return elm_label_label_get (label);\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-/**\r
- * Set the label of a given item\r
- *\r
- * @param item The item\r
- * @param label The text label string\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI void\r
-elm_multibuttonentry_item_label_set(Elm_Multibuttonentry_Item *item, const char *str)\r
-{\r
- Widget_Data *wd;\r
- Eina_List *l;\r
- Elm_Multibuttonentry_Item *_item;\r
- if (!item || !str) return;\r
- ELM_CHECK_WIDTYPE(item->multibuttonentry, widtype);\r
- wd = elm_widget_data_get(item->multibuttonentry);\r
- if (!wd || !wd->items) return;\r
-\r
- EINA_LIST_FOREACH(wd->items, l, _item)\r
- if (_item == item)\r
- {\r
- Evas_Object *label = edje_object_part_swallow_get(_item->button, "elm.label");\r
- if (label) elm_label_label_set (label, str);\r
- _resize_button(_item->button, label, &_item->rw, &_item->vw);\r
- break;\r
- }\r
-}\r
-\r
-/**\r
- * Get the previous item in the multibuttonentry\r
- *\r
- * @param item The item\r
- * @return The item before the item @p item\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI Elm_Multibuttonentry_Item *\r
-elm_multibuttonentry_item_prev(Elm_Multibuttonentry_Item *item)\r
-{\r
- Widget_Data *wd;\r
- Eina_List *l;\r
- Elm_Multibuttonentry_Item *_item;\r
- if (!item) return NULL;\r
- ELM_CHECK_WIDTYPE(item->multibuttonentry, widtype) NULL;\r
- wd = elm_widget_data_get(item->multibuttonentry);\r
- if (!wd || !wd->items) return NULL;\r
-\r
- EINA_LIST_FOREACH(wd->items, l, _item)\r
- if (_item == item)\r
- {\r
- l = eina_list_prev(l);\r
- if (!l) return NULL;\r
- return eina_list_data_get(l);\r
- }\r
- return NULL;\r
-}\r
-\r
-/**\r
- * Get the next item in the multibuttonentry\r
- *\r
- * @param item The item\r
- * @return The item after the item @p item\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI Elm_Multibuttonentry_Item *\r
-elm_multibuttonentry_item_next(Elm_Multibuttonentry_Item *item)\r
-{\r
- Widget_Data *wd;\r
- Eina_List *l;\r
- Elm_Multibuttonentry_Item *_item;\r
- if (!item) return NULL;\r
- ELM_CHECK_WIDTYPE(item->multibuttonentry, widtype) NULL;\r
- wd = elm_widget_data_get(item->multibuttonentry);\r
- if (!wd || !wd->items) return NULL;\r
-\r
- EINA_LIST_FOREACH(wd->items, l, _item)\r
- if (_item == item)\r
- {\r
- l = eina_list_next(l);\r
- if (!l) return NULL;\r
- return eina_list_data_get(l);\r
- }\r
- return NULL;\r
-}\r
-\r
-/**\r
- * Get private data of item\r
- *\r
- * @param item The item\r
- * @return The data pointer stored, or NULL if none was stored\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI void *\r
-elm_multibuttonentry_item_data_get(Elm_Multibuttonentry_Item *item)\r
-{\r
- if (!item) return NULL;\r
- return item->data;\r
-}\r
-\r
-/**\r
- * Set private data of item\r
- *\r
- * @param item The item\r
- * @param data The ponter to the data to be attached\r
- *\r
- * @ingroup Multibuttonentry\r
- */\r
-EAPI void\r
-elm_multibuttonentry_item_data_set(Elm_Multibuttonentry_Item *item, void *data)\r
-{\r
- if (!item) return;\r
- item->data = data;\r
-}\r
-\r
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Multibuttonentry Multibuttonentry
+ * @ingroup Elementary
+ *
+ * This is a Multibuttonentry.
+ */
+
+#define MAX_STR 256
+#define MAX_W_BTN 200
+#define MIN_W_ENTRY 20
+
+typedef enum _Multibuttonentry_Pos
+{
+ MULTIBUTONENTRY_POS_START,
+ MULTIBUTONENTRY_POS_END,
+ MULTIBUTONENTRY_POS_BEFORE,
+ MULTIBUTONENTRY_POS_AFTER,
+ MULTIBUTONENTRY_POS_NUM
+} Multibuttonentry_Pos;
+
+typedef enum _Multibuttonentry_Button_State
+{
+ MULTIBUTONENTRY_BUTTON_STATE_DEFAULT,
+ MULTIBUTONENTRY_BUTTON_STATE_SELECTED,
+ MULTIBUTONENTRY_BUTTON_STATE_NUM
+} Multibuttonentry_Button_State;
+
+typedef enum _MultiButtonEntry_Closed_Button_Type {
+ MULTIBUTTONENTRY_CLOSED_IMAGE,
+ MULTIBUTTONENTRY_CLOSED_LABEL
+} MultiButtonEntry_Closed_Button_Type;
+
+struct _Multibuttonentry_Item {
+ Evas_Object *multibuttonentry;
+ Evas_Object *button;
+ Evas_Object *label;
+ void *data;
+ Evas_Coord vw, rw; // vw: visual width, real width
+ Eina_Bool visible: 1;
+};
+
+typedef struct _Widget_Data Widget_Data;
+struct _Widget_Data {
+ Evas_Object *base;
+ Evas_Object *box;
+ Evas_Object *entry;
+ Evas_Object *label;
+ Evas_Object *guidetext;
+ Evas_Object *end; // used to represent the total number of invisible buttons
+
+ Evas_Object *rectForEnd;
+ MultiButtonEntry_Closed_Button_Type end_type;
+
+ Eina_List *items;
+ Eina_List *current;
+ int n_str;
+
+ Evas_Coord w_box, h_box;
+ int contracted;
+ Eina_Bool focused: 1;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _on_focus_hook(void *data __UNUSED__, Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _changed_size_hint_cb(void *data, Evas *evas, Evas_Object *obj, void *event);
+static void _resize_cb(void *data, Evas *evas, Evas_Object *obj, void *event);
+static void _event_init(Evas_Object *obj);
+static void _contracted_state_set(Evas_Object *obj, int contracted);
+static void _view_update(Evas_Object *obj);
+static void _set_label(Evas_Object *obj, const char* str);
+static void _change_current_button_state(Evas_Object *obj, Multibuttonentry_Button_State state);
+static void _change_current_button(Evas_Object *obj, Evas_Object *btn);
+static void _button_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _del_button_obj(Evas_Object *obj, Evas_Object *btn);
+static void _del_button_item(Elm_Multibuttonentry_Item *item);
+static void _del_button(Evas_Object *obj);
+static Elm_Multibuttonentry_Item* _add_button_item(Evas_Object *obj, const char *str, Multibuttonentry_Pos pos, const Elm_Multibuttonentry_Item *reference, void *data);
+static void _add_button(Evas_Object *obj, char *str);
+static void _evas_key_up_cb(void *data, Evas *e , Evas_Object *obj , void *event_info );
+static void _view_init(Evas_Object *obj);
+static void _set_vis_guidetext(Evas_Object *obj);
+
+static void
+_del_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ if (wd->items)
+ {
+ Elm_Multibuttonentry_Item *item;
+ EINA_LIST_FREE(wd->items, item)
+ {
+ _del_button_obj(obj, item->button);
+ free(item);
+ }
+ wd->items = NULL;
+ }
+ wd->current = NULL;
+
+ if (wd->entry) evas_object_del (wd->entry);
+ if (wd->label) evas_object_del (wd->label);
+ if (wd->guidetext) evas_object_del (wd->guidetext);
+ if (wd->end) evas_object_del (wd->end);
+ if (wd->rectForEnd) evas_object_del(wd->rectForEnd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Eina_List *l;
+ Elm_Multibuttonentry_Item *item;
+ if (!wd) return;
+
+ _elm_theme_object_set(obj, wd->base, "multibuttonentry", "base", elm_widget_style_get(obj));
+ if (wd->box) edje_object_part_swallow (wd->base, "box.swallow", wd->box);
+ edje_object_scale_set(wd->base, elm_widget_scale_get(obj) * _elm_config->scale);
+
+ EINA_LIST_FOREACH(wd->items, l, item)
+ {
+ if (item->button)
+ _elm_theme_object_set (obj, item->button, "multibuttonentry", "btn", elm_widget_style_get (obj));
+ if (item->label)
+ edje_object_part_swallow (item->button, "elm.label", item->label);
+ edje_object_scale_set(item->button, elm_widget_scale_get(obj) * _elm_config->scale);
+ }
+
+ _sizing_eval(obj);
+}
+
+static void
+_on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ if (!elm_widget_focus_get(obj) && !(elm_widget_disabled_get(obj)))
+ {
+ wd->focused = EINA_FALSE;
+ _view_update(obj);
+ evas_object_smart_callback_call(obj, "unfocused", NULL);
+ }
+}
+
+static void
+_signal_emit_hook(Evas_Object *obj, const char *emission, const char *source)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ edje_object_signal_emit(wd->base, emission, source);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Evas_Coord minw = -1, minh = -1;
+ Evas_Coord left, right, top, bottom;
+ if (!wd) return;
+
+ evas_object_size_hint_min_get(wd->box, &minw, &minh);
+ edje_object_part_geometry_get(wd->base, "top.left.pad", NULL, NULL, &left, &top);
+ edje_object_part_geometry_get(wd->base, "bottom.right.pad", NULL, NULL, &right, &bottom);
+
+ minw += (left + right);
+ minh += (top + bottom);
+
+ evas_object_size_hint_min_set(obj, minw, minh);
+}
+
+static void
+_signal_mouse_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+ Widget_Data *wd = elm_widget_data_get(data);
+ if(!wd || !wd->base) return;
+
+ wd->focused = EINA_TRUE;
+ _view_update(data);
+ evas_object_smart_callback_call(data, "clicked", NULL);
+}
+
+static void
+_changed_size_hint_cb(void *data, Evas *evas, Evas_Object *obj, void *event)
+{
+ Evas_Object *eo = (Evas_Object *)data;
+ Widget_Data *wd = elm_widget_data_get(data);
+ if (!wd) return;
+ _sizing_eval(eo);
+}
+
+static void
+_resize_cb(void *data, Evas *evas, Evas_Object *obj, void *event)
+{
+ Widget_Data *wd = elm_widget_data_get(data);
+ Evas_Coord w, h;
+ if (!wd) return;
+
+ evas_object_geometry_get(wd->box, NULL, NULL, &w, &h);
+
+ if (wd->h_box < h) evas_object_smart_callback_call (data, "expanded", NULL);
+ else if (wd->h_box > h) evas_object_smart_callback_call (data, "contracted", NULL);
+ else ;
+
+ wd->w_box = w;
+ wd->h_box = h;
+
+ _view_update(data);
+}
+
+static void
+_event_init(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd || !wd->base) return;
+
+ if (wd->base)
+ {
+ edje_object_signal_callback_add(wd->base, "mouse,clicked,1", "*", _signal_mouse_clicked, obj);
+ edje_object_signal_callback_add(wd->base, "clicked", "*", _signal_mouse_clicked, obj);
+ }
+
+ if (wd->box)
+ {
+ evas_object_event_callback_add(wd->box, EVAS_CALLBACK_RESIZE, _resize_cb, obj);
+ evas_object_event_callback_add(wd->box, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hint_cb, obj);
+ }
+}
+
+static void
+_set_vis_guidetext(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (wd && !eina_list_count(wd->items) && wd->guidetext
+ && !elm_widget_focus_get(obj) && !wd->focused)
+ {
+ elm_box_unpack(wd->box, wd->guidetext);
+ elm_box_unpack(wd->box, wd->entry);
+ evas_object_hide(wd->entry);
+ elm_box_pack_end(wd->box, wd->guidetext);
+ evas_object_show(wd->guidetext);
+ if (wd->n_str)
+ {
+ elm_scrolled_entry_entry_set(wd->entry, "");
+ wd->n_str = 0;
+ }
+ }
+ else
+ {
+ elm_box_unpack(wd->box, wd->entry);
+ elm_box_unpack(wd->box, wd->guidetext);
+ evas_object_hide(wd->guidetext);
+ if (!wd->contracted)
+ {
+ elm_box_pack_end(wd->box, wd->entry);
+ evas_object_show(wd->entry);
+ if (elm_widget_focus_get(obj) || wd->focused)
+ elm_object_focus(wd->entry);
+ }
+ }
+ return;
+}
+
+static void
+_contracted_state_set(Evas_Object *obj, int contracted)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Eina_List *l;
+ Elm_Multibuttonentry_Item *item;
+ if (!wd || !wd->box) return;
+
+ if (wd->contracted == contracted) return;
+
+ if (!eina_list_count(wd->items))
+ {
+ _set_vis_guidetext(obj);
+ wd->contracted = 0;
+ return;
+ }
+
+ elm_scrolled_entry_entry_set(wd->entry, "");
+
+ if (contracted == 1)
+ {
+ Evas_Coord w=0, w_tmp=0;
+ Evas_Coord box_inner_item_width_padding = 0;
+
+ elm_box_padding_get(wd->box, &box_inner_item_width_padding, NULL);
+ // unpack all items and entry
+ elm_box_unpack_all(wd->box);
+ EINA_LIST_FOREACH(wd->items, l, item)
+ {
+ if (item)
+ {
+ evas_object_hide(item->button);
+ item->visible = EINA_FALSE;
+ }
+ }
+ evas_object_hide(wd->entry);
+
+
+ // pack buttons only 1line
+ w = wd->w_box;
+
+ if (wd->label)
+ {
+ elm_box_pack_end(wd->box, wd->label);
+ evas_object_size_hint_min_get(wd->label, &w_tmp, NULL);
+ w -= w_tmp;
+ w -= box_inner_item_width_padding;
+ }
+
+ Eina_Bool on_contracted = EINA_FALSE;
+ item = NULL;
+ int count = eina_list_count(wd->items);
+ Evas_Coord button_min_width = 0;
+ /* Evas_Coord button_min_height = 0; */
+ if (wd->end_type == MULTIBUTTONENTRY_CLOSED_IMAGE)
+ {
+ const char *size_str;
+ size_str = edje_object_data_get(wd->end, "closed_button_width");
+ if(size_str) button_min_width = (Evas_Coord)atoi(size_str);
+ /* it use for later
+ size_str = edje_object_data_get(wd->end, "closed_button_height");
+ if(size_str) button_min_width = (Evas_Coord)atoi(size_str);
+ */
+ }
+
+ EINA_LIST_FOREACH(wd->items, l, item)
+ {
+ if (item)
+ {
+ int w_label_count = 0;
+ char buf[MAX_STR] = {0,};
+
+ elm_box_pack_end(wd->box, item->button);
+ evas_object_show(item->button);
+ item->visible = EINA_TRUE;
+
+ w -= item->vw;
+ w -= box_inner_item_width_padding;
+ count--;
+
+ if (wd->end_type == MULTIBUTTONENTRY_CLOSED_LABEL)
+ {
+ if (count > 0)
+ {
+ snprintf(buf, sizeof(buf), "... + %d", count);
+ elm_label_label_set(wd->end, buf);
+ evas_object_size_hint_min_get(wd->end, &w_label_count, NULL);
+ }
+
+ if (w < 0 || w < w_label_count)
+ {
+ elm_box_unpack(wd->box, item->button);
+ evas_object_hide(item->button);
+ item->visible = EINA_FALSE;
+
+ count++;
+ snprintf(buf, sizeof(buf), "... + %d", count);
+ elm_label_label_set(wd->end, buf);
+ evas_object_size_hint_min_get(wd->end, &w_label_count, NULL);
+
+ elm_box_pack_end(wd->box, wd->end);
+ evas_object_show(wd->end);
+
+ on_contracted = EINA_TRUE;
+ wd->contracted = contracted;
+ evas_object_smart_callback_call(obj, "contracted,state,changed", (void *)wd->contracted);
+ break;
+ }
+ }
+ else if (wd->end_type == MULTIBUTTONENTRY_CLOSED_IMAGE)
+ {
+ if (w < button_min_width)
+ {
+ Evas_Coord rectSize;
+ Evas_Coord closed_height = 0;
+ const char *height_str = edje_object_data_get(wd->base, "closed_height");
+ if(height_str) closed_height = (Evas_Coord)atoi(height_str);
+ elm_box_unpack(wd->box, item->button);
+ evas_object_hide(item->button);
+ item->visible = EINA_FALSE;
+
+ w += item->vw;
+ rectSize = w - button_min_width;
+ if (!wd->rectForEnd)
+ {
+ Evas *e = evas_object_evas_get(obj);
+ wd->rectForEnd = evas_object_rectangle_add(e);
+ evas_object_color_set(wd->rectForEnd, 0, 0, 0, 0);
+ }
+ evas_object_size_hint_min_set(wd->rectForEnd, rectSize, closed_height);
+ elm_box_pack_end(wd->box, wd->rectForEnd);
+ evas_object_show(wd->rectForEnd);
+
+ elm_box_pack_end(wd->box, wd->end);
+ evas_object_show(wd->end);
+
+ on_contracted = EINA_TRUE;
+ wd->contracted = contracted;
+ evas_object_smart_callback_call(obj, "contracted,state,changed", (void *)wd->contracted);
+ break;
+ }
+ }
+ }
+ }
+ if(on_contracted == EINA_FALSE) // unset contracted mode
+ {
+ // pack entry
+ elm_box_pack_end(wd->box, wd->entry);
+ evas_object_show(wd->entry);
+ if(elm_widget_focus_get(obj))
+ elm_object_focus(wd->entry);
+ wd->contracted = 0;
+ }
+ }
+ else
+ {
+ // unpack all items and entry
+ elm_box_unpack_all(wd->box);
+ EINA_LIST_FOREACH(wd->items, l, item)
+ {
+ if (item)
+ {
+ evas_object_hide(item->button);
+ item->visible = EINA_FALSE;
+ }
+ }
+ evas_object_hide(wd->end);
+
+ if (wd->rectForEnd) evas_object_hide(wd->rectForEnd);
+
+ // pack buttons only 1line
+
+ if (wd->label) elm_box_pack_end(wd->box, wd->label);
+
+ // pack remain btns
+ item = NULL;
+ EINA_LIST_FOREACH(wd->items, l, item)
+ {
+ if (item && !item->visible)
+ {
+ elm_box_pack_end(wd->box, item->button);
+ evas_object_show(item->button);
+ }
+ }
+
+ // pack entry
+ elm_box_pack_end(wd->box, wd->entry);
+ evas_object_show(wd->entry);
+ if(elm_widget_focus_get(obj))
+ elm_object_focus(wd->entry);
+
+ wd->contracted = contracted;
+ evas_object_smart_callback_call(obj, "contracted,state,changed", (void *)wd->contracted);
+ }
+}
+
+static void
+_view_update(Evas_Object *obj)
+{
+ Evas_Coord width = 1, height = 1;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd || !wd->box || !wd->entry || !(wd->w_box > 0)) return;
+
+ // update label
+ if (wd->label)
+ {
+ elm_box_unpack(wd->box, wd->label);
+ elm_box_pack_start(wd->box, wd->label);
+ evas_object_size_hint_min_get(wd->label, &width, &height);
+ }
+
+ if (wd->guidetext)
+ {
+ Evas_Coord guide_text_width = wd->w_box - width;
+ evas_object_size_hint_min_set(wd->guidetext, guide_text_width, height);
+ }
+
+ // update buttons in contracted mode
+ if (wd->contracted == 1)
+ {
+ _contracted_state_set(obj, 0);
+ _contracted_state_set(obj, 1);
+ }
+
+ // update guidetext
+ _set_vis_guidetext(obj);
+}
+
+static void
+_set_label(Evas_Object *obj, const char* str)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd || !str) return;
+
+ if (wd->label)
+ {
+ Evas_Coord width, height, sum_width = 0;
+ evas_object_size_hint_min_set(wd->label, 0, 0);
+ evas_object_resize(wd->label, 0, 0);
+ edje_object_part_text_set(wd->label, "mbe.label", str);
+
+ if (!strcmp(str, ""))
+ {
+ /* FIXME: not work yet */
+ edje_object_signal_emit(wd->label, "elm,mbe,clear_text", "");
+ edje_object_part_geometry_get(wd->label, "mbe.label", NULL, NULL, &width, &height);
+ sum_width += width;
+ }
+ else
+ {
+ edje_object_signal_emit(wd->label, "elm,mbe,set_text", "");
+ edje_object_part_geometry_get(wd->label, "mbe.label", NULL, NULL, &width, &height);
+ sum_width += width;
+
+ edje_object_part_geometry_get(wd->label, "mbe.label.left.padding", NULL, NULL, &width, NULL);
+ sum_width += width;
+
+ edje_object_part_geometry_get(wd->label, "mbe.label.right.padding", NULL, NULL, &width, NULL);
+ sum_width += width;
+ }
+ evas_object_size_hint_min_set(wd->label, sum_width, height);
+ }
+ evas_object_show(wd->label);
+ _view_update(obj);
+}
+
+static void
+_set_guidetext(Evas_Object *obj, const char* str)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd || !str) return;
+
+ if (!wd->guidetext)
+ {
+ if (! (wd->guidetext = edje_object_add (evas_object_evas_get (obj)))) return;
+ _elm_theme_object_set(obj, wd->guidetext, "multibuttonentry", "guidetext", elm_widget_style_get(obj));
+ evas_object_size_hint_weight_set(wd->guidetext, 0.0, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(wd->guidetext, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ }
+
+ if (wd->guidetext) edje_object_part_text_set (wd->guidetext, "elm.text", str);
+ _view_update(obj);
+}
+
+static void
+_change_current_button_state(Evas_Object *obj, Multibuttonentry_Button_State state)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Elm_Multibuttonentry_Item *item = NULL;
+ if (!wd) return;
+
+ if (wd->current)
+ item = eina_list_data_get(wd->current);
+
+ if (item && item->button)
+ {
+ switch(state)
+ {
+ case MULTIBUTONENTRY_BUTTON_STATE_DEFAULT:
+ edje_object_signal_emit(item->button, "default", "");
+ wd->current = NULL;
+ break;
+ case MULTIBUTONENTRY_BUTTON_STATE_SELECTED:
+ edje_object_signal_emit(item->button, "focused", "");
+ evas_object_smart_callback_call(obj, "item,selected", item);
+ break;
+ default:
+ edje_object_signal_emit(item->button, "default", "");
+ wd->current = NULL;
+ break;
+ }
+ }
+}
+
+static void
+_change_current_button(Evas_Object *obj, Evas_Object *btn)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Eina_List *l;
+ Elm_Multibuttonentry_Item *item;
+ if (!wd) return;
+
+ // change the state of previous button to "default"
+ _change_current_button_state(obj, MULTIBUTONENTRY_BUTTON_STATE_DEFAULT);
+
+ // change the current
+ EINA_LIST_FOREACH(wd->items, l, item)
+ {
+ if (item->button == btn)
+ {
+ wd->current = l;
+ break;
+ }
+ }
+
+ // chagne the state of current button to "focused"
+ _change_current_button_state(obj, MULTIBUTONENTRY_BUTTON_STATE_SELECTED);
+
+}
+
+static void
+_button_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+ Widget_Data *wd = elm_widget_data_get(data);
+ static char str[MAX_STR];
+ Elm_Multibuttonentry_Item *item = NULL;
+ if (!wd || wd->contracted) return;
+
+ strncpy(str, elm_scrolled_entry_entry_get(wd->entry), MAX_STR);
+ str[MAX_STR - 1]= 0;
+
+ if (strlen (str))
+ _add_button(data, str);
+
+ _change_current_button(data, obj);
+
+ if (wd->current)
+ if((item = eina_list_data_get(wd->current)) != NULL)
+ evas_object_smart_callback_call(data, "item,clicked", item);
+}
+
+static void
+_del_button_obj(Evas_Object *obj, Evas_Object *btn)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Evas_Object *label;
+ if (!wd || !btn) return;
+
+ if (btn)
+ {
+ // del label
+ label = edje_object_part_swallow_get(btn, "elm.label");
+ edje_object_part_unswallow(btn, label);
+ evas_object_del(label);
+
+ // del button
+ evas_object_del(btn);
+ }
+}
+
+static void
+_del_button_item(Elm_Multibuttonentry_Item *item)
+{
+ Eina_List *l;
+ Elm_Multibuttonentry_Item *_item;
+ if (!item) return;
+ Widget_Data *wd;
+
+ Evas_Object *obj = item->multibuttonentry;
+ wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ EINA_LIST_FOREACH(wd->items, l, _item)
+ {
+ if (_item == item)
+ {
+ wd->items = eina_list_remove(wd->items, _item);
+ elm_box_unpack(wd->box, _item->button);
+ evas_object_smart_callback_call(obj, "item,deleted", _item);
+ _del_button_obj(obj, _item->button);
+ free(_item);
+ if (wd->current == l)
+ wd->current = NULL;
+ break;
+ }
+ }
+ _view_update(obj);
+}
+
+static void
+_del_button(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Elm_Multibuttonentry_Item *item;
+ if (!wd || !wd->items) return;
+
+ if (!wd->current)
+ {
+ // let the last button focus
+ item = eina_list_data_get(eina_list_last(wd->items));
+ if (item->button) _change_current_button (obj, item->button);
+ }
+ else
+ {
+ item = eina_list_data_get(wd->current);
+ if (item)
+ {
+ _del_button_item(item);
+ }
+ }
+}
+
+static void
+_resize_button(Evas_Object *btn, Evas_Object *label, Evas_Coord *realw, Evas_Coord *vieww)
+{
+ Evas_Coord rw, vw;
+ Evas_Coord w_label, h_label, w_btn, h_btn, padding_outer, padding_inner;
+
+ // decide the size of button
+ evas_object_size_hint_min_get(label, &w_label, &h_label);
+ edje_object_part_geometry_get(btn, "elm.base", NULL, NULL, NULL, &h_btn);
+ edje_object_part_geometry_get(btn, "left.padding", NULL, NULL, &padding_outer, NULL);
+ edje_object_part_geometry_get(btn, "left.inner.padding", NULL, NULL, &padding_inner, NULL);
+ w_btn = w_label + 2*padding_outer + 2*padding_inner;
+
+ rw = w_btn;
+ vw =(MAX_W_BTN < w_btn) ? MAX_W_BTN : w_btn;
+
+ //resize btn and label
+ evas_object_resize(btn, vw, h_btn);
+ evas_object_size_hint_min_set(btn, vw, h_btn);
+ if ( (rw != vw) && (vw - 2*padding_outer - 2*padding_inner >=0))
+ {
+ evas_object_resize(label, vw - 2*padding_outer - 2*padding_inner, h_label);
+ elm_label_wrap_width_set(label, vw - 2*padding_outer - 2*padding_inner );
+ }
+
+ if(realw) *realw = rw;
+ if(vieww) *vieww = vw;
+}
+
+static Elm_Multibuttonentry_Item*
+_add_button_item(Evas_Object *obj, const char *str, Multibuttonentry_Pos pos, const Elm_Multibuttonentry_Item *reference, void *data)
+{
+ Elm_Multibuttonentry_Item *item;
+ Evas_Object *btn;
+ Evas_Object *label;
+ //Evas_Coord w_label, h_label, w_btn, h_btn, padding_outer, padding_inner;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd || !wd->box || !wd->entry) return NULL;
+
+ //if (wd->contracted == 1) return NULL;
+
+ // add button
+ btn = edje_object_add(evas_object_evas_get(obj));
+
+ const char *btn_style = edje_object_data_get(wd->base,"button");
+
+ if (!btn_style || !strcmp(btn_style,"rect"))
+ _elm_theme_object_set(obj,btn,"multibuttonentry","rect_btn",elm_widget_style_get(obj));
+ else
+ _elm_theme_object_set(obj, btn, "multibuttonentry", "btn", elm_widget_style_get(obj));
+ edje_object_signal_callback_add(btn, "mouse,clicked,1", "*", _button_clicked, obj);
+ evas_object_size_hint_weight_set(btn, 0.0, 0.0);
+ evas_object_show(btn);
+
+ // add label
+ label = elm_label_add(obj);
+ elm_object_style_set(label, "extended/multibuttonentry_button");
+ elm_label_label_set(label, str);
+ elm_label_ellipsis_set(label, EINA_TRUE);
+ edje_object_part_swallow(btn, "elm.label", label);
+
+ // append item list
+ item = ELM_NEW(Elm_Multibuttonentry_Item);
+ if (item)
+ {
+ Evas_Coord rw, vw;
+ _resize_button(btn, label, &rw, &vw);
+
+ item->multibuttonentry = obj;
+ item->button = btn;
+ item->label = label;
+ item->data = data;
+ item->rw = rw;
+ item->vw = vw;
+ item->visible = EINA_TRUE;
+
+ switch(pos)
+ {
+ case MULTIBUTONENTRY_POS_START:
+ wd->items = eina_list_prepend(wd->items, item);
+ if(wd->label) elm_box_pack_after(wd->box, btn, wd->label);
+ else elm_box_pack_start(wd->box, btn);
+ _view_update(obj);
+ break;
+ case MULTIBUTONENTRY_POS_END:
+ wd->items = eina_list_append(wd->items, item);
+ _view_update(obj);
+ elm_box_pack_before(wd->box, btn, wd->entry);
+ break;
+ case MULTIBUTONENTRY_POS_BEFORE:
+ if (reference)
+ {
+ wd->items = eina_list_prepend_relative(wd->items, item, reference);
+ elm_box_pack_before(wd->box, btn, reference->button);
+ _view_update(obj);
+ }
+ else
+ {
+ wd->items = eina_list_append(wd->items, item);
+ _view_update(obj);
+ elm_box_pack_before(wd->box, btn, wd->entry);
+ }
+ break;
+ case MULTIBUTONENTRY_POS_AFTER:
+ if (reference)
+ {
+ wd->items = eina_list_append_relative(wd->items, item, reference);
+ elm_box_pack_after(wd->box, btn, reference->button);
+ _view_update(obj);
+ }
+ else
+ {
+ wd->items = eina_list_append(wd->items, item);
+ _view_update(obj);
+ elm_box_pack_before(wd->box, btn, wd->entry);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ evas_object_smart_callback_call(obj, "item,added", item);
+
+ return item;
+}
+
+static void
+_add_button(Evas_Object *obj, char *str)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ //remove entry text
+ elm_scrolled_entry_entry_set(wd->entry, "");
+
+ // add button
+ _add_button_item(obj, str, MULTIBUTONENTRY_POS_END, NULL, NULL);
+}
+
+static void
+_evas_key_up_cb(void *data, Evas *e , Evas_Object *obj , void *event_info )
+{
+ Widget_Data *wd = elm_widget_data_get(data);
+ Evas_Event_Key_Up *ev = (Evas_Event_Key_Up *) event_info;
+ static char str[MAX_STR];
+ if (!wd || !wd->base || !wd->box) return;
+
+ strncpy(str, elm_scrolled_entry_entry_get(wd->entry), MAX_STR);
+ str[MAX_STR - 1]= 0;
+
+ if ( (wd->n_str == 0) && (strcmp (str, "") == 0) && ( (strcmp (ev->keyname, "BackSpace") == 0)|| (strcmp (ev->keyname, "BackSpace (") == 0)))
+ {
+ _del_button(data);
+ }
+ else if ( (strcmp (str, "") != 0) && (strcmp (ev->keyname, "KP_Enter") == 0 ||strcmp (ev->keyname, "Return") == 0 ))
+ {
+ _add_button(data, str);
+ wd->n_str = 0;
+ return;
+ }
+ else
+ {
+ //
+ }
+
+ wd->n_str = strlen(str);
+}
+
+static void
+_view_init(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ if (!wd->box)
+ {
+ if (! (wd->box = elm_box_add (obj))) return;
+ elm_widget_sub_object_add(obj, wd->box);
+ elm_box_extended_mode_set(wd->box, EINA_TRUE);
+ elm_box_homogenous_set(wd->box, EINA_FALSE);
+ edje_object_part_swallow(wd->base, "box.swallow", wd->box);
+ }
+
+ if (!wd->label)
+ {
+ if (!(wd->label = edje_object_add(evas_object_evas_get(obj)))) return;
+ _elm_theme_object_set(obj, wd->label, "multibuttonentry", "label", elm_widget_style_get(obj));
+ _set_label(obj, "");
+ }
+
+ if (!wd->entry)
+ {
+ if (! (wd->entry = elm_scrolled_entry_add (obj))) return;
+ elm_scrolled_entry_single_line_set(wd->entry, EINA_TRUE);
+ elm_scrolled_entry_entry_set(wd->entry, "");
+ elm_scrolled_entry_cursor_end_set(wd->entry);
+ evas_object_size_hint_min_set(wd->entry, MIN_W_ENTRY, 0);
+ evas_object_event_callback_add(wd->entry, EVAS_CALLBACK_KEY_UP, _evas_key_up_cb, obj);
+ evas_object_size_hint_weight_set(wd->entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(wd->entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ if (wd->box) elm_box_pack_end (wd->box, wd->entry);
+ evas_object_show(wd->entry);
+ }
+
+ if (!wd->end)
+ {
+ const char *end_type = edje_object_data_get(wd->base, "closed_button_type");
+ if (!end_type || !strcmp(end_type, "label"))
+ {
+ if (! (wd->end = elm_label_add (obj))) return;
+ elm_object_style_set(wd->end, "extended/multibuttonentry_default");
+ wd->end_type = MULTIBUTTONENTRY_CLOSED_LABEL;
+ }
+ else
+ {
+ const char *size_str;
+ if (!(wd->end = edje_object_add(evas_object_evas_get(obj)))) return;
+ _elm_theme_object_set(obj, wd->end, "multibuttonentry", "closedbutton", elm_widget_style_get(obj));
+ Evas_Coord button_min_width = 0;
+ Evas_Coord button_min_height = 0;
+
+ size_str = edje_object_data_get(wd->end, "closed_button_width");
+ if(size_str) button_min_width = (Evas_Coord)atoi(size_str);
+ size_str = edje_object_data_get(wd->end, "closed_button_height");
+ if(size_str) button_min_height = (Evas_Coord)atoi(size_str);
+
+ wd->end_type = MULTIBUTTONENTRY_CLOSED_IMAGE;
+ evas_object_size_hint_min_set(wd->end, button_min_width, button_min_height);
+ elm_widget_sub_object_add(obj, wd->end);
+ }
+ }
+}
+
+/**
+ * Add a new multibuttonentry to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI Evas_Object *
+elm_multibuttonentry_add(Evas_Object *parent)
+{
+ Evas_Object *obj;
+ Evas *e;
+ Widget_Data *wd;
+ if (!parent) return NULL;
+
+ wd = ELM_NEW(Widget_Data);
+ e = evas_object_evas_get(parent);
+ if (!e) return NULL;
+ obj = elm_widget_add(e);
+ ELM_SET_WIDTYPE(widtype, "multibuttonentry");
+ elm_widget_type_set(obj, "multibuttonentry");
+ elm_widget_sub_object_add(parent, obj);
+ elm_widget_data_set(obj, wd);
+
+ elm_widget_del_hook_set(obj, _del_hook);
+ elm_widget_theme_hook_set(obj, _theme_hook);
+ elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
+ elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
+
+ wd->base = edje_object_add(e);
+ _elm_theme_object_set(obj, wd->base, "multibuttonentry", "base", "default");
+ elm_widget_resize_object_set(obj, wd->base);
+
+ wd->contracted = 0;
+ wd->focused = EINA_FALSE;
+ wd->n_str = 0;
+ wd->rectForEnd = NULL;
+
+ _view_init(obj);
+ _event_init(obj);
+
+ return obj;
+}
+
+/**
+ * Get the entry of the multibuttonentry object
+ *
+ * @param obj The multibuttonentry object
+ * @return The entry object, or NULL if none
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI Evas_Object *
+elm_multibuttonentry_entry_get(Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return NULL;
+
+ return wd->entry;
+}
+
+/**
+ * Get the label
+ *
+ * @param obj The multibuttonentry object
+ * @return The label, or NULL if none
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI const char *
+elm_multibuttonentry_label_get(Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return NULL;
+ if (wd->label) return edje_object_part_text_get(wd->guidetext, "elm.text");
+ return NULL;
+}
+
+/**
+ * Set the label
+ *
+ * @param obj The multibuttonentry object
+ * @param label The text label string
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI void
+elm_multibuttonentry_label_set(Evas_Object *obj, const char *label)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd || !label) return;
+ _set_label(obj, label);
+}
+
+/**
+ * Get the guide text
+ *
+ * @param obj The multibuttonentry object
+ * @return The guide text, or NULL if none
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI const char *
+elm_multibuttonentry_guide_text_get(Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return NULL;
+ if (wd->guidetext) return edje_object_part_text_get(wd->guidetext, "elm.text");
+ return NULL;
+}
+
+/**
+ * Set the guide text
+ *
+ * @param obj The multibuttonentry object
+ * @param label The guide text string
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI void
+elm_multibuttonentry_guide_text_set(Evas_Object *obj, const char *guidetext)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd || !guidetext) return;
+ _set_guidetext(obj, guidetext);
+}
+
+/**
+ * Get the value of contracted state.
+ *
+ * @param obj The multibuttonentry object
+ * @param the value of contracted state.
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI int
+elm_multibuttonentry_contracted_state_get(Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) -1;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return -1;
+ return wd->contracted;
+}
+
+/**
+ * Set/Unset the multibuttonentry to contracted state of single line
+ *
+ * @param obj The multibuttonentry object
+ * @param the value of contracted state. set this to 1 to set the multibuttonentry to contracted state of single line. set this to 0 to unset the contracted state.
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI void
+elm_multibuttonentry_contracted_state_set(Evas_Object *obj, int contracted)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd || !wd->box || (wd->contracted == contracted)) return;
+ _contracted_state_set(obj, contracted);
+}
+
+/**
+ * Prepend a new item to the multibuttonentry
+ *
+ * @param obj The multibuttonentry object
+ * @param label The label of new item
+ * @param data The ponter to the data to be attached
+ * @return A handle to the item added or NULL if not possible
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI Elm_Multibuttonentry_Item *
+elm_multibuttonentry_item_add_start(Evas_Object *obj, const char *label, void *data)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Elm_Multibuttonentry_Item *item;
+ if (!wd || !label) return NULL;
+ item = _add_button_item(obj, label, MULTIBUTONENTRY_POS_START, NULL, data);
+ return item;
+}
+
+/**
+ * Append a new item to the multibuttonentry
+ *
+ * @param obj The multibuttonentry object
+ * @param label The label of new item
+ * @param data The ponter to the data to be attached
+ * @return A handle to the item added or NULL if not possible
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI Elm_Multibuttonentry_Item *
+elm_multibuttonentry_item_add_end(Evas_Object *obj, const char *label, void *data)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Elm_Multibuttonentry_Item *item;
+ if (!wd || !label) return NULL;
+ item = _add_button_item(obj, label, MULTIBUTONENTRY_POS_END, NULL, data);
+ return item;
+}
+
+/**
+ * Add a new item to the multibuttonentry before the indicated object
+ *
+ * reference.
+ * @param obj The multibuttonentry object
+ * @param label The label of new item
+ * @param before The item before which to add it
+ * @param data The ponter to the data to be attached
+ * @return A handle to the item added or NULL if not possible
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI Elm_Multibuttonentry_Item *
+elm_multibuttonentry_item_add_before(Evas_Object *obj, const char *label, Elm_Multibuttonentry_Item *before, void *data)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Elm_Multibuttonentry_Item *item;
+ if (!wd || !label) return NULL;
+ item = _add_button_item(obj, label, MULTIBUTONENTRY_POS_BEFORE, before, data);
+ return item;
+}
+
+/**
+ * Add a new item to the multibuttonentry after the indicated object
+ *
+ * @param obj The multibuttonentry object
+ * @param label The label of new item
+ * @param after The item after which to add it
+ * @param data The ponter to the data to be attached
+ * @return A handle to the item added or NULL if not possible
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI Elm_Multibuttonentry_Item *
+elm_multibuttonentry_item_add_after(Evas_Object *obj, const char *label, Elm_Multibuttonentry_Item *after, void *data)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Elm_Multibuttonentry_Item *item;
+ if (!wd || !label) return NULL;
+ item = _add_button_item(obj, label, MULTIBUTONENTRY_POS_AFTER, after, data);
+ return item;
+}
+
+/**
+ * Get a list of items in the multibuttonentry
+ *
+ * @param obj The multibuttonentry object
+ * @return The list of items, or NULL if none
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI const Eina_List *
+elm_multibuttonentry_items_get(Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return NULL;
+ return wd->items;
+}
+
+/**
+ * Get the first item in the multibuttonentry
+ *
+ * @param obj The multibuttonentry object
+ * @return The first item, or NULL if none
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI Elm_Multibuttonentry_Item *
+elm_multibuttonentry_item_first_get(Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd || !wd->items) return NULL;
+ return eina_list_data_get(wd->items);
+}
+
+/**
+ * Get the last item in the multibuttonentry
+ *
+ * @param obj The multibuttonentry object
+ * @return The last item, or NULL if none
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI Elm_Multibuttonentry_Item *
+elm_multibuttonentry_item_last_get(Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd || !wd->items) return NULL;
+ return eina_list_data_get(eina_list_last(wd->items));
+}
+
+/**
+ * Get the selected item in the multibuttonentry
+ *
+ * @param obj The multibuttonentry object
+ * @return The selected item, or NULL if none
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI Elm_Multibuttonentry_Item *
+elm_multibuttonentry_item_selected_get(Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd || !wd->current) return NULL;
+ return eina_list_data_get(wd->current);
+}
+
+/**
+ * Set the selected state of an item
+ *
+ * @param item The item
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI void
+elm_multibuttonentry_item_selected_set(Elm_Multibuttonentry_Item *item)
+{
+ Widget_Data *wd;
+ Eina_List *l;
+ Elm_Multibuttonentry_Item *_item;
+ if (!item) return;
+ ELM_CHECK_WIDTYPE(item->multibuttonentry, widtype);
+ wd = elm_widget_data_get(item->multibuttonentry);
+ if (!wd) return;
+
+ EINA_LIST_FOREACH(wd->items, l, _item)
+ {
+ if (_item == item)
+ {
+ _change_current_button(item->multibuttonentry, item->button);
+ }
+ }
+}
+
+/**
+ * unselect all of items.
+ *
+ * @param obj The multibuttonentry object
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI void
+elm_multibuttonentry_item_unselect_all(Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ _change_current_button_state(obj, MULTIBUTONENTRY_BUTTON_STATE_DEFAULT);
+}
+
+/**
+ * Remove all items in the multibuttonentry.
+ *
+ * @param obj The multibuttonentry object
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI void
+elm_multibuttonentry_items_del(Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ if (wd->contracted == 1)
+ _contracted_state_set(obj, 0);
+
+ if (wd->items)
+ {
+ Elm_Multibuttonentry_Item *item;
+ EINA_LIST_FREE(wd->items, item)
+ {
+ elm_box_unpack(wd->box, item->button);
+ _del_button_obj(obj, item->button);
+ free(item);
+ }
+ wd->items = NULL;
+ }
+ wd->current = NULL;
+ _view_update(obj);
+}
+
+/**
+ * Delete a given item
+ *
+ * @param item The item
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI void
+elm_multibuttonentry_item_del(Elm_Multibuttonentry_Item *item)
+{
+ if (!item) return;
+ _del_button_item(item);
+}
+
+/**
+ * Get the label of a given item
+ *
+ * @param item The item
+ * @return The label of a given item, or NULL if none
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI const char *
+elm_multibuttonentry_item_label_get(Elm_Multibuttonentry_Item *item)
+{
+ Widget_Data *wd;
+ Eina_List *l;
+ Elm_Multibuttonentry_Item *_item;
+ if (!item) return NULL;
+ ELM_CHECK_WIDTYPE(item->multibuttonentry, widtype) NULL;
+ wd = elm_widget_data_get(item->multibuttonentry);
+ if (!wd || !wd->items) return NULL;
+
+ EINA_LIST_FOREACH(wd->items, l, _item)
+ if (_item == item)
+ {
+ Evas_Object *label = edje_object_part_swallow_get(_item->button, "elm.label");
+ if (label) return elm_label_label_get (label);
+ }
+
+ return NULL;
+}
+
+/**
+ * Set the label of a given item
+ *
+ * @param item The item
+ * @param label The text label string
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI void
+elm_multibuttonentry_item_label_set(Elm_Multibuttonentry_Item *item, const char *str)
+{
+ Widget_Data *wd;
+ Eina_List *l;
+ Elm_Multibuttonentry_Item *_item;
+ if (!item || !str) return;
+ ELM_CHECK_WIDTYPE(item->multibuttonentry, widtype);
+ wd = elm_widget_data_get(item->multibuttonentry);
+ if (!wd || !wd->items) return;
+
+ EINA_LIST_FOREACH(wd->items, l, _item)
+ if (_item == item)
+ {
+ Evas_Object *label = edje_object_part_swallow_get(_item->button, "elm.label");
+ if (label) elm_label_label_set (label, str);
+ _resize_button(_item->button, label, &_item->rw, &_item->vw);
+ break;
+ }
+}
+
+/**
+ * Get the previous item in the multibuttonentry
+ *
+ * @param item The item
+ * @return The item before the item @p item
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI Elm_Multibuttonentry_Item *
+elm_multibuttonentry_item_prev(Elm_Multibuttonentry_Item *item)
+{
+ Widget_Data *wd;
+ Eina_List *l;
+ Elm_Multibuttonentry_Item *_item;
+ if (!item) return NULL;
+ ELM_CHECK_WIDTYPE(item->multibuttonentry, widtype) NULL;
+ wd = elm_widget_data_get(item->multibuttonentry);
+ if (!wd || !wd->items) return NULL;
+
+ EINA_LIST_FOREACH(wd->items, l, _item)
+ if (_item == item)
+ {
+ l = eina_list_prev(l);
+ if (!l) return NULL;
+ return eina_list_data_get(l);
+ }
+ return NULL;
+}
+
+/**
+ * Get the next item in the multibuttonentry
+ *
+ * @param item The item
+ * @return The item after the item @p item
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI Elm_Multibuttonentry_Item *
+elm_multibuttonentry_item_next(Elm_Multibuttonentry_Item *item)
+{
+ Widget_Data *wd;
+ Eina_List *l;
+ Elm_Multibuttonentry_Item *_item;
+ if (!item) return NULL;
+ ELM_CHECK_WIDTYPE(item->multibuttonentry, widtype) NULL;
+ wd = elm_widget_data_get(item->multibuttonentry);
+ if (!wd || !wd->items) return NULL;
+
+ EINA_LIST_FOREACH(wd->items, l, _item)
+ if (_item == item)
+ {
+ l = eina_list_next(l);
+ if (!l) return NULL;
+ return eina_list_data_get(l);
+ }
+ return NULL;
+}
+
+/**
+ * Get private data of item
+ *
+ * @param item The item
+ * @return The data pointer stored, or NULL if none was stored
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI void *
+elm_multibuttonentry_item_data_get(Elm_Multibuttonentry_Item *item)
+{
+ if (!item) return NULL;
+ return item->data;
+}
+
+/**
+ * Set private data of item
+ *
+ * @param item The item
+ * @param data The ponter to the data to be attached
+ *
+ * @ingroup Multibuttonentry
+ */
+EAPI void
+elm_multibuttonentry_item_data_set(Elm_Multibuttonentry_Item *item, void *data)
+{
+ if (!item) return;
+ item->data = data;
+}
+