9588cb14272e9756ea228e5a1341685d7bda5a94
[framework/uifw/elementary.git] / src / lib / elm_toolbar.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 /**
5  * @defgroup Toolbar Toolbar
6  *
7  * A toolbar is a widget that displays a list of buttons inside
8  * a box.  It is scrollable, and only one item can be selected at a time.
9  *
10  * Signals that you can add callbacks for are:
11  *
12  * "clicked" - when the user clicks on a toolbar item and becomes selected
13  *
14  */
15
16 typedef struct _Widget_Data Widget_Data;
17
18 struct _Widget_Data
19 {
20    Evas_Object *scr, *bx;
21    Evas_Object *menu_parent;
22    Eina_Inlist *items;
23    Elm_Toolbar_Item *more_item, *selected_item;
24    Elm_Toolbar_Shrink_Mode shrink_mode;
25    Elm_Icon_Lookup_Order lookup_order;
26    int icon_size;
27    double align;
28    Eina_Bool homogeneous : 1;
29    Eina_Bool no_select : 1;
30    Ecore_Job *resize_job;
31 };
32
33 struct _Elm_Toolbar_Item
34 {
35    Elm_Widget_Item base;
36    EINA_INLIST;
37    const char *label;
38    const char *icon_str;
39    Evas_Object *icon;
40    Evas_Object *o_menu;
41    Evas_Smart_Cb func;
42    struct {
43       int priority;
44       Eina_Bool visible : 1;
45    } prio;
46    Eina_Bool selected : 1;
47    Eina_Bool disabled : 1;
48    Eina_Bool separator : 1;
49    Eina_Bool menu : 1;
50    Eina_List *states;
51    Eina_List *current_state;
52 };
53
54 #define ELM_TOOLBAR_ITEM_FROM_INLIST(item)      \
55   ((item) ? EINA_INLIST_CONTAINER_GET(item, Elm_Toolbar_Item) : NULL)
56
57 struct _Elm_Toolbar_Item_State
58 {
59    const char *label;
60    const char *icon_str;
61    Evas_Object *icon;
62    Evas_Smart_Cb func;
63    const void *data;
64 };
65
66 static const char *widtype = NULL;
67 static void _item_show(Elm_Toolbar_Item *it);
68 static void _item_select(Elm_Toolbar_Item *it);
69 static void _item_unselect(Elm_Toolbar_Item *it);
70 static void _item_disable(Elm_Toolbar_Item *it, Eina_Bool disabled);
71 static void _del_pre_hook(Evas_Object *obj);
72 static void _del_hook(Evas_Object *obj);
73 static void _mirrored_set(Evas_Object *obj, Eina_Bool mirrored);
74 static void _mirrored_set_item(Evas_Object *obj, Elm_Toolbar_Item *it, Eina_Bool mirrored);
75 static void _theme_hook(Evas_Object *obj);
76 static void _sizing_eval(Evas_Object *obj);
77 static void _resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
78 static void _menu_move_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
79 static void _menu_hide(void *data, Evas *e, Evas_Object *obj, void *event_info);
80 static void _layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data);
81 static void _elm_toolbar_item_icon_obj_set(Evas_Object *obj, Elm_Toolbar_Item *item, Evas_Object *icon_obj, const char *icon_str, double icon_size, const char *signal);
82 static void _item_label_set(Elm_Toolbar_Item *item, const char *label, const char *signal);
83
84 static Eina_Bool
85 _item_icon_set(Evas_Object *icon_obj, const char *type, const char *icon)
86 {
87    char icon_str[512];
88
89    if ((!type) || (!*type)) goto end;
90    if ((!icon) || (!*icon)) return EINA_FALSE;
91    if ((snprintf(icon_str, sizeof(icon_str), "%s%s", type, icon) > 0)
92        && (elm_icon_standard_set(icon_obj, icon_str)))
93      return EINA_TRUE;
94 end:
95    if (elm_icon_standard_set(icon_obj, icon))
96      return EINA_TRUE;
97    WRN("couldn't find icon definition for '%s'", icon);
98    return EINA_FALSE;
99 }
100
101 static int
102 _elm_toolbar_icon_size_get(Widget_Data *wd)
103 {
104    const char *icon_size = edje_object_data_get(
105       elm_smart_scroller_edje_object_get(wd->scr), "icon_size");
106    if (icon_size)
107      return atoi(icon_size);
108    return _elm_config->icon_size;
109 }
110
111 static void
112 _item_show(Elm_Toolbar_Item *it)
113 {
114    Widget_Data *wd = elm_widget_data_get(it->base.widget);
115    Evas_Coord x, y, w, h, bx, by;
116
117    if (!wd) return;
118    evas_object_geometry_get(wd->bx, &bx, &by, NULL, NULL);
119    evas_object_geometry_get(it->base.view, &x, &y, &w, &h);
120    elm_smart_scroller_child_region_show(wd->scr, x - bx, y - by, w, h);
121 }
122
123 static void
124 _item_unselect(Elm_Toolbar_Item *item)
125 {
126    Widget_Data *wd;
127    if ((!item) || (!item->selected)) return;
128    wd = elm_widget_data_get(item->base.widget);
129    if (!wd) return;
130    item->selected = EINA_FALSE;
131    wd->selected_item = NULL;
132    edje_object_signal_emit(item->base.view, "elm,state,unselected", "elm");
133    elm_widget_signal_emit(item->icon, "elm,state,unselected", "elm");
134 }
135
136 static void
137 _item_select(Elm_Toolbar_Item *it)
138 {
139    Elm_Toolbar_Item *it2;
140    Widget_Data *wd = elm_widget_data_get(it->base.widget);
141    Evas_Object *obj2;
142
143    if (!wd) return;
144    if ((it->selected) || (it->disabled) || (it->separator)) return;
145
146    if (!wd->no_select)
147      {
148         it2 = elm_toolbar_selected_item_get(it->base.widget);
149         _item_unselect(it2);
150
151         it->selected = EINA_TRUE;
152         wd->selected_item = it;
153         edje_object_signal_emit(it->base.view, "elm,state,selected", "elm");
154         elm_widget_signal_emit(it->icon, "elm,state,selected", "elm");
155         _item_show(it);
156      }
157    obj2 = it->base.widget;
158    if (it->menu)
159      {
160         evas_object_show(it->o_menu);
161         evas_object_event_callback_add(it->base.view, EVAS_CALLBACK_RESIZE,
162                                        _menu_move_resize, it);
163         evas_object_event_callback_add(it->base.view, EVAS_CALLBACK_MOVE,
164                                        _menu_move_resize, it);
165
166         _menu_move_resize(it, NULL, NULL, NULL);
167      }
168    if (it->func) it->func((void *)(it->base.data), it->base.widget, it);
169    evas_object_smart_callback_call(obj2, "clicked", it);
170 }
171
172 static void
173 _menu_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
174 {
175    Elm_Toolbar_Item *selected;
176    Elm_Toolbar_Item *it = data;
177    selected = elm_toolbar_selected_item_get(it->base.widget);
178    _item_unselect(selected);
179 }
180
181 static void
182 _menu_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
183 {
184    // avoid hide being emitted during object deletion
185    evas_object_event_callback_del_full
186       (obj, EVAS_CALLBACK_HIDE, _menu_hide, data);
187 }
188
189 static void
190 _menu_move_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
191 {
192    Elm_Toolbar_Item *it = data;
193    Evas_Coord x,y,w,h;
194    Widget_Data *wd = elm_widget_data_get(it->base.widget);
195
196    if ((!wd) || (!wd->menu_parent)) return;
197    evas_object_geometry_get(it->base.view, &x, &y, &w, &h);
198    elm_menu_move(it->o_menu, x, y+h);
199 }
200
201 static void
202 _item_disable(Elm_Toolbar_Item *it, Eina_Bool disabled)
203 {
204    Widget_Data *wd = elm_widget_data_get(it->base.widget);
205
206    if (!wd) return;
207    if (it->disabled == disabled) return;
208    it->disabled = disabled;
209    if (it->disabled)
210      {
211         edje_object_signal_emit(it->base.view, "elm,state,disabled", "elm");
212         elm_widget_signal_emit(it->icon, "elm,state,disabled", "elm");
213      }
214    else
215      {
216         edje_object_signal_emit(it->base.view, "elm,state,enabled", "elm");
217         elm_widget_signal_emit(it->icon, "elm,state,enabled", "elm");
218      }
219 }
220
221 static void
222 _item_del(Elm_Toolbar_Item *it)
223 {
224    Elm_Toolbar_Item_State *it_state;
225    _item_unselect(it);
226    elm_widget_item_pre_notify_del(it);
227    EINA_LIST_FREE(it->states, it_state)
228      {
229         if (it->icon == it_state->icon)
230           it->icon = NULL;
231         eina_stringshare_del(it_state->label);
232         eina_stringshare_del(it_state->icon_str);
233         if (it_state->icon) evas_object_del(it_state->icon);
234         free(it_state);
235      }
236    eina_stringshare_del(it->label);
237    eina_stringshare_del(it->icon_str);
238    if (it->icon) evas_object_del(it->icon);
239    //TODO: See if checking for wd->menu_parent is necessary before deleting menu
240    if (it->o_menu) evas_object_del(it->o_menu);
241    elm_widget_item_del(it);
242 }
243
244 static void
245 _del_pre_hook(Evas_Object *obj)
246 {
247    Widget_Data *wd = elm_widget_data_get(obj);
248    Elm_Toolbar_Item *it, *next;
249
250    if (!wd) return;
251    it = ELM_TOOLBAR_ITEM_FROM_INLIST(wd->items);
252    while(it)
253      {
254         next = ELM_TOOLBAR_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
255         _item_del(it);
256         it = next;
257      }
258    if (wd->more_item)
259      _item_del(wd->more_item);
260 }
261
262 static void
263 _del_hook(Evas_Object *obj)
264 {
265    Widget_Data *wd = elm_widget_data_get(obj);
266
267    if (!wd) return;
268    free(wd);
269 }
270
271
272 static void
273 _mirrored_set_item(Evas_Object *obj __UNUSED__, Elm_Toolbar_Item *it, Eina_Bool mirrored)
274 {
275    edje_object_mirrored_set(it->base.view, mirrored);
276    elm_widget_mirrored_set(it->o_menu, mirrored);
277 }
278
279 static void
280 _theme_hook_item(Evas_Object *obj, Elm_Toolbar_Item *it, double scale, int icon_size)
281 {
282    Evas_Object *view = it->base.view;
283    Evas_Coord mw, mh;
284    const char *style = elm_widget_style_get(obj);
285
286    _mirrored_set_item(obj, it, elm_widget_mirrored_get(obj));
287    edje_object_scale_set(view, scale);
288    if (!it->separator)
289      {
290         _elm_theme_object_set(obj, view, "toolbar", "item", style);
291         if (it->selected)
292           {
293              edje_object_signal_emit(view, "elm,state,selected", "elm");
294              elm_widget_signal_emit(it->icon, "elm,state,selected", "elm");
295           }
296         if (it->disabled)
297           {
298              edje_object_signal_emit(view, "elm,state,disabled", "elm");
299              elm_widget_signal_emit(it->icon, "elm,state,disabled", "elm");
300           }
301         if (it->icon)
302           {
303              int ms = 0;
304
305              ms = ((double)icon_size * scale);
306              evas_object_size_hint_min_set(it->icon, ms, ms);
307              evas_object_size_hint_max_set(it->icon, ms, ms);
308              edje_object_part_swallow(view, "elm.swallow.icon",
309                                       it->icon);
310           }
311         edje_object_part_text_set(view, "elm.text", it->label);
312      }
313    else
314      _elm_theme_object_set(obj, view, "toolbar", "separator", style);
315
316    mw = mh = -1;
317    if (!it->separator)
318      elm_coords_finger_size_adjust(1, &mw, 1, &mh);
319    edje_object_size_min_restricted_calc(view, &mw, &mh, mw, mh);
320    if (!it->separator)
321      elm_coords_finger_size_adjust(1, &mw, 1, &mh);
322    evas_object_size_hint_min_set(view, mw, mh);
323 }
324
325 static void
326 _mirrored_set(Evas_Object *obj, Eina_Bool mirrored)
327 {
328    Widget_Data *wd = elm_widget_data_get(obj);
329    Elm_Toolbar_Item *it;
330
331    EINA_INLIST_FOREACH(wd->items, it)
332       _mirrored_set_item(obj, it, mirrored);
333    if (wd->more_item)
334      _mirrored_set_item(obj, wd->more_item, mirrored);
335 }
336
337 static void
338 _theme_hook(Evas_Object *obj)
339 {
340    Widget_Data *wd = elm_widget_data_get(obj);
341    Elm_Toolbar_Item *it;
342    double scale = 0;
343
344    if (!wd) return;
345    _elm_widget_mirrored_reload(obj);
346    elm_smart_scroller_object_theme_set(obj, wd->scr, "toolbar", "base", elm_widget_style_get(obj));
347    _mirrored_set(obj, elm_widget_mirrored_get(obj));
348    scale = (elm_widget_scale_get(obj) * _elm_config->scale);
349    edje_object_scale_set(wd->scr, scale);
350    wd->icon_size = _elm_toolbar_icon_size_get(wd);
351    EINA_INLIST_FOREACH(wd->items, it)
352       _theme_hook_item(obj, it, scale, wd->icon_size);
353    if (wd->more_item)
354      _theme_hook_item(obj, wd->more_item, scale, wd->icon_size);
355    _sizing_eval(obj);
356 }
357
358 static void
359 _sizing_eval(Evas_Object *obj)
360 {
361    Widget_Data *wd = elm_widget_data_get(obj);
362    Evas_Coord minw = -1, minh = -1, minw_bx;
363    Evas_Coord vw = 0, vh = 0;
364    Evas_Coord w, h;
365
366    if (!wd) return;
367    evas_object_smart_calculate(wd->bx);
368    edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
369                              &minw, &minh);
370    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
371    if (w < minw) w = minw;
372    if (h < minh) h = minh;
373
374    evas_object_resize(wd->scr, w, h);
375
376    evas_object_size_hint_min_get(wd->bx, &minw, &minh);
377    minw_bx = minw;
378    if (w > minw) minw = w;
379    evas_object_resize(wd->bx, minw, minh);
380    elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
381    switch (wd->shrink_mode)
382      {
383       case ELM_TOOLBAR_SHRINK_MENU: /* fallthrough */
384       case ELM_TOOLBAR_SHRINK_HIDE: /* fallthrough */
385       case ELM_TOOLBAR_SHRINK_SCROLL: minw = w - vw; break;
386       case ELM_TOOLBAR_SHRINK_NONE: minw = minw_bx + (w - vw); break;
387      }
388    minh = minh + (h - vh);
389    evas_object_size_hint_min_set(obj, minw, minh);
390    evas_object_size_hint_max_set(obj, -1, -1);
391 }
392
393 static void
394 _item_menu_create(Widget_Data *wd, Elm_Toolbar_Item *item)
395 {
396    item->o_menu = elm_menu_add(item->base.view);
397    if (wd->menu_parent)
398      elm_menu_parent_set(item->o_menu, wd->menu_parent);
399    evas_object_event_callback_add(item->o_menu, EVAS_CALLBACK_HIDE,
400                                   _menu_hide, item);
401    evas_object_event_callback_add(item->o_menu, EVAS_CALLBACK_DEL,
402                                   _menu_del, item);
403 }
404
405 static void
406 _item_menu_destroy(Elm_Toolbar_Item *item)
407 {
408    if (item->o_menu)
409      {
410         evas_object_del(item->o_menu);
411         item->o_menu = NULL;
412      }
413 }
414
415 static int
416 _toolbar_item_prio_compare_cb(const void *i1, const void *i2)
417 {
418    const Elm_Toolbar_Item *eti1 = i1;
419    const Elm_Toolbar_Item *eti2 = i2;
420
421    if (!eti2) return 1;
422    if (!eti1) return -1;
423
424    return eti2->prio.priority - eti1->prio.priority;
425 }
426
427 static void
428 _fix_items_visibility(Widget_Data *wd, Evas_Coord *iw, Evas_Coord vw)
429 {
430    Elm_Toolbar_Item *it;
431    Eina_List *sorted = NULL;
432    Evas_Coord ciw;
433
434    EINA_INLIST_FOREACH(wd->items, it)
435      {
436         sorted = eina_list_sorted_insert(sorted,
437                                          _toolbar_item_prio_compare_cb, it);
438      }
439
440    if (wd->more_item)
441      {
442         evas_object_geometry_get(wd->more_item->base.view, NULL, NULL, &ciw, NULL);
443         *iw += ciw;
444      }
445    EINA_LIST_FREE(sorted, it)
446      {
447         evas_object_geometry_get(it->base.view, NULL, NULL, &ciw, NULL);
448         *iw += ciw;
449         it->prio.visible = (*iw <= vw);
450      }
451 }
452
453 static void
454 _elm_toolbar_item_menu_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
455 {
456    Elm_Toolbar_Item *it = data;
457    if (it->func) it->func((void *)(it->base.data), it->base.widget, it);
458 }
459
460 static void
461 _resize_job(void *data)
462 {
463    Widget_Data *wd = elm_widget_data_get(data);
464    Evas_Coord mw, mh, vw, vh, w, h;
465    Elm_Toolbar_Item *it;
466    Evas_Object *obj = (Evas_Object *) data;
467
468    if (!wd) return;
469    wd->resize_job = NULL;
470    elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
471    evas_object_size_hint_min_get(wd->bx, &mw, &mh);
472    evas_object_geometry_get(wd->bx, NULL, NULL, &w, &h);
473    if (wd->shrink_mode == ELM_TOOLBAR_SHRINK_MENU)
474      {
475         Evas_Coord iw = 0, more_w;
476
477         evas_object_resize(wd->bx, vw, h);
478         _fix_items_visibility(wd, &iw, vw);
479         evas_object_geometry_get(wd->more_item->base.view, NULL, NULL, &more_w, NULL);
480         if (iw - more_w <= vw)
481           iw -= more_w;
482
483         /* All items are removed from the box object, since removing individual
484          * items won't trigger a resize. Items are be readded below. */
485         evas_object_box_remove_all(wd->bx, EINA_FALSE);
486         if (iw > vw)
487           {
488              Evas_Object *menu;
489
490              _item_menu_destroy(wd->more_item);
491              _item_menu_create(wd, wd->more_item);
492              menu = elm_toolbar_item_menu_get(wd->more_item);
493
494              EINA_INLIST_FOREACH(wd->items, it)
495                {
496                   if (!it->prio.visible)
497                     {
498                        if (it->separator)
499                          elm_menu_item_separator_add(menu, NULL);
500                        else
501                          {
502                             Elm_Menu_Item *item;
503                             item = elm_menu_item_add(menu, NULL, it->icon_str, it->label,
504                                                      _elm_toolbar_item_menu_cb, it);
505                             elm_menu_item_disabled_set(item, it->disabled);
506                             if (it->o_menu) elm_menu_clone(it->o_menu, menu, item);
507                          }
508                        evas_object_hide(it->base.view);
509                     }
510                   else
511                     {
512                        evas_object_box_append(wd->bx, it->base.view);
513                        evas_object_show(it->base.view);
514                     }
515                }
516
517              evas_object_box_append(wd->bx, wd->more_item->base.view);
518              evas_object_show(wd->more_item->base.view);
519           }
520         else
521           {
522              /* All items are visible, show them all (except for the "More"
523               * button, of course). */
524              EINA_INLIST_FOREACH(wd->items, it)
525                {
526                   evas_object_show(it->base.view);
527                   evas_object_box_append(wd->bx, it->base.view);
528                }
529              evas_object_hide(wd->more_item->base.view);
530           }
531      }
532    else if (wd->shrink_mode == ELM_TOOLBAR_SHRINK_HIDE)
533      {
534         Evas_Coord iw = 0;
535
536         evas_object_resize(wd->bx, vw, h);
537         _fix_items_visibility(wd, &iw, vw);
538         evas_object_box_remove_all(wd->bx, EINA_FALSE);
539         if (iw > vw)
540           {
541              EINA_INLIST_FOREACH(wd->items, it)
542                {
543                   if (!it->prio.visible)
544                     evas_object_hide(it->base.view);
545                   else
546                     {
547                        evas_object_box_append(wd->bx, it->base.view);
548                        evas_object_show(it->base.view);
549                     }
550                }
551           }
552         else
553           {
554              /* All items are visible, show them all */
555              EINA_INLIST_FOREACH(wd->items, it)
556                {
557                   evas_object_show(it->base.view);
558                   evas_object_box_append(wd->bx, it->base.view);
559                }
560           }
561      }
562    else
563      {
564         if ((vw >= mw) && (w != vw)) evas_object_resize(wd->bx, vw, h);
565         EINA_INLIST_FOREACH(wd->items, it)
566           {
567              if (it->selected)
568                {
569                   _item_show(it);
570                   break;
571                }
572           }
573      }
574
575    _mirrored_set(obj, elm_widget_mirrored_get(obj));
576 }
577
578 static void
579 _resize_item(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
580 {
581    _sizing_eval(data);
582    _resize(data, NULL, NULL, NULL);
583 }
584
585 static void
586 _resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
587 {
588    Widget_Data *wd = elm_widget_data_get(data);
589    if (!wd->resize_job)
590      wd->resize_job = ecore_job_add(_resize_job, data);
591 }
592
593 static void
594 _select(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
595 {
596    _item_select(data);
597 }
598
599 static void
600 _mouse_in(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
601 {
602    Elm_Toolbar_Item *it = data;
603    edje_object_signal_emit(it->base.view, "elm,state,highlighted", "elm");
604    elm_widget_signal_emit(it->icon, "elm,state,highlighted", "elm");
605 }
606
607 static void
608 _mouse_out(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
609 {
610    Elm_Toolbar_Item *it = data;
611    edje_object_signal_emit(it->base.view, "elm,state,unhighlighted", "elm");
612    elm_widget_signal_emit(it->icon, "elm,state,unhighlighted", "elm");
613 }
614
615 static void
616 _layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data)
617 {
618    Evas_Object *obj = (Evas_Object *) data;
619    Widget_Data *wd = elm_widget_data_get(obj);
620    if (!wd) return;
621    _els_box_layout(o, priv, 1, wd->homogeneous, elm_widget_mirrored_get(obj));
622 }
623
624 static Elm_Toolbar_Item *
625 _item_new(Evas_Object *obj, const char *icon, const char *label, Evas_Smart_Cb func, const void *data)
626 {
627    Widget_Data *wd = elm_widget_data_get(obj);
628    Evas_Object *icon_obj;
629    Evas_Coord mw, mh;
630    Elm_Toolbar_Item *it;
631
632    icon_obj = elm_icon_add(obj);
633    elm_icon_order_lookup_set(icon_obj, wd->lookup_order);
634    if (!icon_obj) return NULL;
635    it = elm_widget_item_new(obj, Elm_Toolbar_Item);
636    if (!it)
637      {
638         evas_object_del(icon_obj);
639         return NULL;
640      }
641    it->label = eina_stringshare_add(label);
642    it->prio.visible = 1;
643    it->prio.priority = 0;
644    it->func = func;
645    it->separator = EINA_FALSE;
646    it->base.data = data;
647    it->base.view = edje_object_add(evas_object_evas_get(obj));
648    if (_item_icon_set(icon_obj, "toolbar/", icon))
649      {
650         it->icon = icon_obj;
651         it->icon_str = eina_stringshare_add(icon);
652      }
653    else
654      {
655         it->icon = NULL;
656         it->icon_str = NULL;
657         evas_object_del(icon_obj);
658      }
659
660    _elm_theme_object_set(obj, it->base.view, "toolbar", "item",
661                          elm_widget_style_get(obj));
662    edje_object_signal_callback_add(it->base.view, "elm,action,click", "elm",
663                                    _select, it);
664    edje_object_signal_callback_add(it->base.view, "elm,mouse,in", "elm",
665                                    _mouse_in, it);
666    edje_object_signal_callback_add(it->base.view, "elm,mouse,out", "elm",
667                                    _mouse_out, it);
668    elm_widget_sub_object_add(obj, it->base.view);
669    if (it->icon)
670      {
671         int ms = 0;
672
673         ms = ((double)wd->icon_size * _elm_config->scale);
674         evas_object_size_hint_min_set(it->icon, ms, ms);
675         evas_object_size_hint_max_set(it->icon, ms, ms);
676         edje_object_part_swallow(it->base.view, "elm.swallow.icon", it->icon);
677         evas_object_show(it->icon);
678         elm_widget_sub_object_add(obj, it->icon);
679      }
680    edje_object_part_text_set(it->base.view, "elm.text", it->label);
681    mw = mh = -1;
682    elm_coords_finger_size_adjust(1, &mw, 1, &mh);
683    edje_object_size_min_restricted_calc(it->base.view, &mw, &mh, mw, mh);
684    elm_coords_finger_size_adjust(1, &mw, 1, &mh);
685    evas_object_size_hint_weight_set(it->base.view, -1.0, EVAS_HINT_EXPAND);
686    evas_object_size_hint_align_set(it->base.view, 0.5, EVAS_HINT_FILL);
687    evas_object_size_hint_min_set(it->base.view, mw, mh);
688    evas_object_event_callback_add(it->base.view, EVAS_CALLBACK_RESIZE,
689                                   _resize_item, obj);
690    return it;
691 }
692
693 /**
694  * Add a toolbar object to @p parent.
695  *
696  * @param parent The parent object
697  *
698  * @return The created object, or NULL on failure
699  *
700  * @ingroup Toolbar
701  */
702 EAPI Evas_Object *
703 elm_toolbar_add(Evas_Object *parent)
704 {
705    Evas_Object *obj;
706    Evas *e;
707    Widget_Data *wd;
708
709    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
710
711    ELM_SET_WIDTYPE(widtype, "toolbar");
712    elm_widget_type_set(obj, "toolbar");
713    elm_widget_sub_object_add(parent, obj);
714    elm_widget_data_set(obj, wd);
715    elm_widget_del_pre_hook_set(obj, _del_pre_hook);
716    elm_widget_del_hook_set(obj, _del_hook);
717    elm_widget_theme_hook_set(obj, _theme_hook);
718    elm_widget_can_focus_set(obj, EINA_FALSE);
719
720    wd->more_item = NULL;
721    wd->selected_item = NULL;
722    wd->scr = elm_smart_scroller_add(e);
723    elm_smart_scroller_widget_set(wd->scr, obj);
724    elm_smart_scroller_object_theme_set(obj, wd->scr, "toolbar", "base", "default");
725    elm_smart_scroller_bounce_allow_set(wd->scr,
726                                        _elm_config->thumbscroll_bounce_enable,
727                                        EINA_FALSE);
728    elm_widget_resize_object_set(obj, wd->scr);
729    elm_smart_scroller_policy_set(wd->scr,
730                                  ELM_SMART_SCROLLER_POLICY_AUTO,
731                                  ELM_SMART_SCROLLER_POLICY_OFF);
732
733
734    wd->icon_size = _elm_toolbar_icon_size_get(wd);
735
736
737    wd->homogeneous = EINA_TRUE;
738    wd->align = 0.5;
739
740    wd->bx = evas_object_box_add(e);
741    evas_object_size_hint_align_set(wd->bx, wd->align, 0.5);
742    evas_object_box_layout_set(wd->bx, _layout, obj, NULL);
743    elm_widget_sub_object_add(obj, wd->bx);
744    elm_smart_scroller_child_set(wd->scr, wd->bx);
745    evas_object_show(wd->bx);
746
747    elm_toolbar_mode_shrink_set(obj, _elm_config->toolbar_shrink_mode);
748    evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_RESIZE, _resize, obj);
749    evas_object_event_callback_add(wd->bx, EVAS_CALLBACK_RESIZE, _resize, obj);
750    elm_toolbar_icon_order_lookup_set(obj, ELM_ICON_LOOKUP_THEME_FDO);
751
752    _sizing_eval(obj);
753    return obj;
754 }
755
756 /**
757  * Set the icon size (in pixels) for the toolbar.
758  *
759  * @param obj The toolbar object
760  * @param icon_size The icon size in pixels
761  *
762  * @ingroup Toolbar
763  */
764 EAPI void
765 elm_toolbar_icon_size_set(Evas_Object *obj, int icon_size)
766 {
767    ELM_CHECK_WIDTYPE(obj, widtype);
768    Widget_Data *wd = elm_widget_data_get(obj);
769    if (!wd) return;
770    if (wd->icon_size == icon_size) return;
771    wd->icon_size = icon_size;
772    _theme_hook(obj);
773 }
774
775 /**
776  * Get the icon size (in pixels) for the toolbar.
777  *
778  * @param obj The toolbar object
779  * @return The icon size in pixels
780  *
781  * @ingroup Toolbar
782  */
783 EAPI int
784 elm_toolbar_icon_size_get(const Evas_Object *obj)
785 {
786    ELM_CHECK_WIDTYPE(obj, widtype) 0;
787    Widget_Data *wd = elm_widget_data_get(obj);
788    if (!wd) return 0;
789    return wd->icon_size;
790 }
791
792 /**
793  * Append item to the toolbar
794  *
795  * @param obj The toolbar object
796  * @param icon A string with icon name or the absolute path of an image file.
797  * @param label The label of the item
798  * @param func The function to call when the item is clicked
799  * @param data The data to associate with the item
800  * @return The toolbar item, or NULL upon failure
801  *
802  * @see elm_toolbar_item_icon_set
803  *
804  * @ingroup Toolbar
805  */
806 EAPI Elm_Toolbar_Item *
807 elm_toolbar_item_append(Evas_Object *obj, const char *icon, const char *label, Evas_Smart_Cb func, const void *data)
808 {
809    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
810    Widget_Data *wd = elm_widget_data_get(obj);
811    if (!wd) return NULL;
812
813    Elm_Toolbar_Item *it = _item_new(obj, icon, label, func, data);
814    if (!it) return NULL;
815
816    wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
817    evas_object_box_append(wd->bx, it->base.view);
818    evas_object_show(it->base.view);
819    _sizing_eval(obj);
820
821    return it;
822 }
823
824 static void
825 _elm_toolbar_item_state_cb(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
826 {
827    Elm_Toolbar_Item *it = event_info;
828    Elm_Toolbar_Item_State *it_state;
829
830    it_state = eina_list_data_get(it->current_state);
831    if (it_state->func)
832      it_state->func((void *)it_state->data, obj, event_info);
833 }
834
835 /**
836  * Sets the next @p item state as the current state.
837  *
838  * @param item The item.
839  *
840  * @ingroup Toolbar
841  */
842 EAPI Elm_Toolbar_Item_State *
843 elm_toolbar_item_state_next(Elm_Toolbar_Item *item)
844 {
845    Widget_Data *wd;
846    Evas_Object *obj;
847    Eina_List *next_state;
848    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, NULL);
849
850    obj = item->base.widget;
851    wd = elm_widget_data_get(obj);
852    if (!wd) return NULL;
853    if (!item->states) return NULL;
854
855    next_state = eina_list_next(item->current_state);
856    if (!next_state)
857      next_state = eina_list_next(item->states);
858    return eina_list_data_get(next_state);
859 }
860
861 /**
862  * Sets the previous @p item state as the current state.
863  *
864  * @param item The item.
865  *
866  * @ingroup Toolbar
867  */
868 EAPI Elm_Toolbar_Item_State *
869 elm_toolbar_item_state_prev(Elm_Toolbar_Item *item)
870 {
871    Widget_Data *wd;
872    Evas_Object *obj;
873    Eina_List *prev_state;
874    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, NULL);
875
876    obj = item->base.widget;
877    wd = elm_widget_data_get(obj);
878    if (!wd) return NULL;
879    if (!item->states) return NULL;
880
881    prev_state = eina_list_prev(item->current_state);
882    if ((!prev_state) || (prev_state == item->states))
883      prev_state = eina_list_last(item->states);
884    return eina_list_data_get(prev_state);
885 }
886
887 /**
888  * Unset the state of @p it
889  * The default icon and label from this item will be displayed.
890  *
891  * @param it The item.
892  *
893  * @ingroup Toolbar
894  */
895 EAPI void
896 elm_toolbar_item_state_unset(Elm_Toolbar_Item *it)
897 {
898    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it);
899    elm_toolbar_item_state_set(it, NULL);
900 }
901
902 /**
903  * Sets @p state as the current state of @p it.
904  * If @p state is NULL, it won't select any state and the default icon and
905  * label will be used.
906  *
907  * @param it The item.
908  * @param state The state to use.
909  *
910  * @return True if the state was correctly set.
911  *
912  * @ingroup Toolbar
913  */
914 EAPI Eina_Bool
915 elm_toolbar_item_state_set(Elm_Toolbar_Item *it, Elm_Toolbar_Item_State *state)
916 {
917    Widget_Data *wd;
918    Eina_List *next_state;
919    Elm_Toolbar_Item_State *it_state;
920    Evas_Object *obj;
921    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, EINA_FALSE);
922
923    obj = it->base.widget;
924    wd = elm_widget_data_get(obj);
925    if (!wd) return EINA_FALSE;
926    if (!it->states) return EINA_FALSE;
927
928    if (state)
929      {
930         next_state = eina_list_data_find_list(it->states, state);
931         if (!next_state) return EINA_FALSE;
932      }
933    else
934      next_state = it->states;
935
936    if (next_state == it->current_state) return EINA_TRUE;
937
938    it_state = eina_list_data_get(next_state);
939    if (eina_list_data_find(it->current_state, state))
940      {
941         _item_label_set(it, it_state->label, "elm,state,label_set,forward");
942         _elm_toolbar_item_icon_obj_set(obj, it, it_state->icon, it_state->icon_str,
943                                        wd->icon_size, "elm,state,icon_set,forward");
944      }
945    else
946      {
947         _item_label_set(it, it_state->label, "elm,state,label_set,backward");
948         _elm_toolbar_item_icon_obj_set(obj, it, it_state->icon, it_state->icon_str,
949                                        wd->icon_size, "elm,state,icon_set,backward");
950      }
951    if (it->disabled)
952      elm_widget_signal_emit(it->icon, "elm,state,disabled", "elm");
953    else
954      elm_widget_signal_emit(it->icon, "elm,state,enabled", "elm");
955
956    it->current_state = next_state;
957    return EINA_TRUE;
958 }
959
960 /**
961  * Get the current state of @p item.
962  * If no state is selected, returns NULL.
963  *
964  * @param item The item.
965  *
966  * @return The state.
967  *
968  * @ingroup Toolbar
969  */
970 EAPI Elm_Toolbar_Item_State *
971 elm_toolbar_item_state_get(const Elm_Toolbar_Item *it)
972 {
973    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, NULL);
974    if ((!it->states) || (!it->current_state)) return NULL;
975    if (it->current_state == it->states) return NULL;
976
977    return eina_list_data_get(it->current_state);
978 }
979
980 static Elm_Toolbar_Item_State *
981 _item_state_new(const char *label, const char *icon_str, Evas_Object *icon, Evas_Smart_Cb func, const void *data)
982 {
983    Elm_Toolbar_Item_State *it_state;
984    it_state = ELM_NEW(Elm_Toolbar_Item_State);
985    it_state->label = eina_stringshare_add(label);
986    it_state->icon_str = eina_stringshare_add(icon_str);
987    it_state->icon = icon;
988    it_state->func = func;
989    it_state->data = data;
990    return it_state;
991 }
992
993 /**
994  * Add a new state to @p item
995  *
996  * @param item The item.
997  * @param icon The icon string
998  * @param label The label of the new state
999  * @param func The function to call when the item is clicked when this state is
1000  * selected.
1001  * @param data The data to associate with the state
1002  * @return The toolbar item state, or NULL upon failure
1003  *
1004  * @ingroup Toolbar
1005  */
1006 EAPI Elm_Toolbar_Item_State *
1007 elm_toolbar_item_state_add(Elm_Toolbar_Item *item, const char *icon, const char *label, Evas_Smart_Cb func, const void *data)
1008 {
1009    Elm_Toolbar_Item_State *it_state;
1010    Evas_Object *icon_obj;
1011    Evas_Object *obj;
1012    Widget_Data *wd;
1013    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, NULL);
1014    obj = item->base.widget;
1015    wd = elm_widget_data_get(item->base.widget);
1016    if (!wd) return NULL;
1017
1018    if (!item->states)
1019      {
1020         it_state = _item_state_new(item->label, item->icon_str, item->icon,
1021                                    item->func, item->base.data);
1022         item->states = eina_list_append(item->states, it_state);
1023         item->current_state = item->states;
1024      }
1025
1026    icon_obj = elm_icon_add(obj);
1027    elm_icon_order_lookup_set(icon_obj, wd->lookup_order);
1028    if (!icon_obj) goto error_state_add;
1029
1030    if (!_item_icon_set(icon_obj, "toolbar/", icon))
1031      {
1032         evas_object_del(icon_obj);
1033         icon_obj = NULL;
1034         icon = NULL;
1035      }
1036
1037    it_state = _item_state_new(label, icon, icon_obj, func, data);
1038    item->states = eina_list_append(item->states, it_state);
1039    item->func = _elm_toolbar_item_state_cb;
1040    item->base.data = NULL;
1041
1042    return it_state;
1043
1044 error_state_add:
1045    if (item->states && !eina_list_next(item->states))
1046      {
1047         eina_stringshare_del(item->label);
1048         eina_stringshare_del(item->icon_str);
1049         free(eina_list_data_get(item->states));
1050         eina_list_free(item->states);
1051         item->states = NULL;
1052      }
1053    return NULL;
1054 }
1055
1056 EAPI Eina_Bool
1057 elm_toolbar_item_state_del(Elm_Toolbar_Item *item, Elm_Toolbar_Item_State *state)
1058 {
1059    Eina_List *del_state;
1060    Elm_Toolbar_Item_State *it_state;
1061    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, EINA_FALSE);
1062
1063    if (!state) return EINA_FALSE;
1064    if (!item->states) return EINA_FALSE;
1065
1066    del_state = eina_list_data_find_list(item->states, state);
1067    if (del_state == item->states) return EINA_FALSE;
1068    if (del_state == item->current_state)
1069      elm_toolbar_item_state_unset(item);
1070
1071    eina_stringshare_del(state->label);
1072    eina_stringshare_del(state->icon_str);
1073    if (state->icon) evas_object_del(state->icon);
1074    free(state);
1075    item->states = eina_list_remove_list(item->states, del_state);
1076    if (item->states && !eina_list_next(item->states))
1077      {
1078         it_state = eina_list_data_get(item->states);
1079         item->base.data = it_state->data;
1080         item->func = it_state->func;
1081         eina_stringshare_del(it_state->label);
1082         eina_stringshare_del(it_state->icon_str);
1083         free(eina_list_data_get(item->states));
1084         eina_list_free(item->states);
1085         item->states = NULL;
1086      }
1087    return EINA_TRUE;
1088 }
1089
1090
1091 /**
1092  * Prepend item to the toolbar
1093  *
1094  * @param obj The toolbar object
1095  * @param icon A string with icon name or the absolute path of an image file.
1096  * @param label The label of the item
1097  * @param func The function to call when the item is clicked
1098  * @param data The data to associate with the item
1099  * @return The toolbar item, or NULL upon failure
1100  *
1101  * @see elm_toolbar_item_icon_set
1102  *
1103  * @ingroup Toolbar
1104  */
1105 EAPI Elm_Toolbar_Item *
1106 elm_toolbar_item_prepend(Evas_Object *obj, const char *icon, const char *label, Evas_Smart_Cb func, const void *data)
1107 {
1108    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1109    Widget_Data *wd = elm_widget_data_get(obj);
1110    if (!wd) return NULL;
1111
1112    Elm_Toolbar_Item *it = _item_new(obj, icon, label, func, data);
1113    if (!it) return NULL;
1114
1115    wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
1116    evas_object_box_prepend(wd->bx, it->base.view);
1117    evas_object_show(it->base.view);
1118    _sizing_eval(obj);
1119
1120    return it;
1121 }
1122
1123 /**
1124  * Insert item before another in the toolbar
1125  *
1126  * @param obj The toolbar object
1127  * @param before The item to insert before
1128  * @param icon A string with icon name or the absolute path of an image file.
1129  * @param label The label of the item
1130  * @param func The function to call when the item is clicked
1131  * @param data The data to associate with the item
1132  * @return The toolbar item, or NULL upon failure
1133  *
1134  * @see elm_toolbar_item_icon_set
1135  *
1136  * @ingroup Toolbar
1137  */
1138 EAPI Elm_Toolbar_Item *
1139 elm_toolbar_item_insert_before(Evas_Object *obj, Elm_Toolbar_Item *before, const char *icon, const char *label, Evas_Smart_Cb func, const void *data)
1140 {
1141    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1142    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(before, NULL);
1143    Widget_Data *wd = elm_widget_data_get(obj);
1144    if (!wd) return NULL;
1145
1146    Elm_Toolbar_Item *it = _item_new(obj, icon, label, func, data);
1147    if (!it) return NULL;
1148
1149    wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
1150                                             EINA_INLIST_GET(before));
1151    evas_object_box_insert_before(wd->bx, it->base.view, before->base.view);
1152    evas_object_show(it->base.view);
1153    _sizing_eval(obj);
1154
1155    return it;
1156 }
1157
1158 /**
1159  * Insert item after another in the toolbar
1160  *
1161  * @param obj The toolbar object
1162  * @param after The item to insert after
1163  * @param icon A string with icon name or the absolute path of an image file.
1164  * @param label The label of the item
1165  * @param func The function to call when the item is clicked
1166  * @param data The data to associate with the item
1167  * @return The toolbar item, or NULL upon failure
1168  *
1169  * @see elm_toolbar_item_icon_set
1170  *
1171  * @ingroup Toolbar
1172  */
1173 EAPI Elm_Toolbar_Item *
1174 elm_toolbar_item_insert_after(Evas_Object *obj, Elm_Toolbar_Item *after, const char *icon, const char *label, Evas_Smart_Cb func, const void *data)
1175 {
1176    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1177    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(after, NULL);
1178    Widget_Data *wd = elm_widget_data_get(obj);
1179    if (!wd) return NULL;
1180
1181    Elm_Toolbar_Item *it = _item_new(obj, icon, label, func, data);
1182    if (!it) return NULL;
1183
1184    wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
1185                                            EINA_INLIST_GET(after));
1186    evas_object_box_insert_after(wd->bx, it->base.view, after->base.view);
1187    evas_object_show(it->base.view);
1188    _sizing_eval(obj);
1189
1190    return it;
1191 }
1192
1193 /**
1194  * Get the first item in the toolbar
1195  *
1196  * @param obj The toolbar object
1197  * @return The first item, or NULL if none
1198  *
1199  * @ingroup Toolbar
1200  */
1201 EAPI Elm_Toolbar_Item *
1202 elm_toolbar_first_item_get(const Evas_Object *obj)
1203 {
1204    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1205    Widget_Data *wd = elm_widget_data_get(obj);
1206    if (!wd || !wd->items) return NULL;
1207    Elm_Toolbar_Item *it = ELM_TOOLBAR_ITEM_FROM_INLIST(wd->items);
1208    return it;
1209 }
1210
1211 /**
1212  * Get the last item in the toolbar
1213  *
1214  * @return The last item, or NULL if none
1215  *
1216  * @ingroup Toolbar
1217  */
1218 EAPI Elm_Toolbar_Item *
1219 elm_toolbar_last_item_get(const Evas_Object *obj)
1220 {
1221    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1222    Widget_Data *wd = elm_widget_data_get(obj);
1223    if (!wd || !wd->items) return NULL;
1224    Elm_Toolbar_Item *it = ELM_TOOLBAR_ITEM_FROM_INLIST(wd->items->last);
1225    return it;
1226 }
1227
1228 /**
1229  * Get the next item in the toolbar
1230  *
1231  * This returns the item after the item @p it.
1232  *
1233  * @param item The item
1234  * @return The item after @p it, or NULL if none
1235  *
1236  * @ingroup Toolbar
1237  */
1238 EAPI Elm_Toolbar_Item *
1239 elm_toolbar_item_next_get(const Elm_Toolbar_Item *item)
1240 {
1241    Elm_Toolbar_Item *next;
1242    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, NULL);
1243    next = ELM_TOOLBAR_ITEM_FROM_INLIST(EINA_INLIST_GET(item)->next);
1244    return next;
1245 }
1246
1247 /**
1248  * Get the previous item in the toolbar
1249  *
1250  * This returns the item before the item @p it.
1251  *
1252  * @param item The item
1253  * @return The item before @p it, or NULL if none
1254  *
1255  * @ingroup Toolbar
1256  */
1257 EAPI Elm_Toolbar_Item *
1258 elm_toolbar_item_prev_get(const Elm_Toolbar_Item *item)
1259 {
1260    Elm_Toolbar_Item *prev;
1261    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, NULL);
1262    prev = ELM_TOOLBAR_ITEM_FROM_INLIST(EINA_INLIST_GET(item)->prev);
1263    return prev;
1264 }
1265
1266 /**
1267  * Get the toolbar object from an item
1268  *
1269  * This returns the toolbar object itself that an item belongs to.
1270  *
1271  * @param item The item
1272  * @return The toolbar object
1273  *
1274  * @ingroup Toolbar
1275  */
1276 EAPI Evas_Object *
1277 elm_toolbar_item_toolbar_get(const Elm_Toolbar_Item *item)
1278 {
1279    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, NULL);
1280    return item->base.widget;
1281 }
1282
1283 /**
1284  * Sets the priority of a toolbar item. This is used only when the toolbar
1285  * shrink mode is set to ELM_TOOLBAR_SHRINK_MENU or ELM_TOOLBAR_SHRINK_HIDE:
1286  * when space is at a premium, items with low priority will be removed from
1287  * the toolbar and added to a dynamically-created menu, while items with
1288  * higher priority will remain on the toolbar, with the same order they were
1289  * added.
1290  *
1291  * @param item The toolbar item.
1292  * @param priority The item priority. The default is zero.
1293  *
1294  * @ingroup Toolbar
1295  */
1296 EAPI void
1297 elm_toolbar_item_priority_set(Elm_Toolbar_Item *item, int priority)
1298 {
1299    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
1300    if (item->prio.priority == priority) return;
1301    item->prio.priority = priority;
1302    _resize(item->base.widget, NULL, NULL, NULL);
1303 }
1304
1305 /**
1306  * Gets the priority of a toolbar item.
1307  *
1308  * @param item The toolbar item.
1309  * @return The item priority, or 0 if an error occurred.
1310  *
1311  * @ingroup Toolbar
1312  */
1313 EAPI int
1314 elm_toolbar_item_priority_get(const Elm_Toolbar_Item *item)
1315 {
1316    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, 0);
1317    return item->prio.priority;
1318 }
1319
1320 /**
1321  * Get the string used to set the icon of @p item.
1322  *
1323  * @param item The toolbar item
1324  * @return The string associated with the icon object.
1325  *
1326  * @see elm_toolbar_item_icon_set()
1327  *
1328  * @ingroup Toolbar
1329  */
1330 EAPI const char *
1331 elm_toolbar_item_icon_get(const Elm_Toolbar_Item *item)
1332 {
1333    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, NULL);
1334    return item->icon_str;
1335 }
1336
1337 /**
1338  * Get the label associated with @p item.
1339  *
1340  * @param item The toolbar item
1341  * @return The label
1342  *
1343  * @ingroup Toolbar
1344  */
1345 EAPI const char *
1346 elm_toolbar_item_label_get(const Elm_Toolbar_Item *item)
1347 {
1348    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, NULL);
1349    return item->label;
1350 }
1351
1352 static void
1353 _elm_toolbar_item_label_update(Elm_Toolbar_Item *item)
1354 {
1355    Evas_Coord mw = -1, mh = -1;
1356    edje_object_part_text_set(item->base.view, "elm.text", item->label);
1357
1358    elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1359    edje_object_size_min_restricted_calc(item->base.view, &mw, &mh, mw, mh);
1360    elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1361    evas_object_size_hint_weight_set(item->base.view, -1.0, EVAS_HINT_EXPAND);
1362    evas_object_size_hint_align_set(item->base.view, 0.5, EVAS_HINT_FILL);
1363    evas_object_size_hint_min_set(item->base.view, mw, mh);
1364 }
1365
1366 static void
1367 _elm_toolbar_item_label_set_cb (void *data, Evas_Object *obj, const char *emission, const char *source)
1368 {
1369    Elm_Toolbar_Item *item = data;
1370    _elm_toolbar_item_label_update(item);
1371    edje_object_signal_callback_del(obj, emission, source,
1372                                    _elm_toolbar_item_label_set_cb);
1373    edje_object_signal_emit (item->base.view, "elm,state,label,reset", "elm");
1374 }
1375
1376 static void
1377 _item_label_set(Elm_Toolbar_Item *item, const char *label, const char *signal)
1378 {
1379    const char *s;
1380
1381    if ((label) && (item->label) && (!strcmp(label, item->label))) return;
1382
1383    eina_stringshare_replace(&item->label, label);
1384    s = edje_object_data_get(item->base.view, "transition_animation_on");
1385    if ((s) && (atoi(s)))
1386      {
1387         edje_object_part_text_set(item->base.view, "elm.text_new", item->label);
1388         edje_object_signal_emit (item->base.view, signal, "elm");
1389         edje_object_signal_callback_add(item->base.view,
1390                                         "elm,state,label_set,done", "elm",
1391                                         _elm_toolbar_item_label_set_cb, item);
1392      }
1393    else
1394      _elm_toolbar_item_label_update(item);
1395    _resize(item->base.widget, NULL, NULL, NULL);
1396 }
1397
1398 /**
1399  * Set the label associated with @p item.
1400  *
1401  * @param item The toolbar item
1402  * @param label The label of @p item
1403  *
1404  * @ingroup Toolbar
1405  */
1406 EAPI void
1407 elm_toolbar_item_label_set(Elm_Toolbar_Item *item, const char *label)
1408 {
1409    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
1410    _item_label_set(item, label, "elm,state,label_set");
1411 }
1412
1413 static void
1414 _elm_toolbar_item_icon_update(Elm_Toolbar_Item *item)
1415 {
1416    Elm_Toolbar_Item_State *it_state;
1417    Eina_List *l;
1418    Evas_Coord mw = -1, mh = -1;
1419    Evas_Object *old_icon = edje_object_part_swallow_get(item->base.view,
1420                                                         "elm.swallow.icon");
1421    elm_widget_sub_object_del(item->base.view, old_icon);
1422    evas_object_hide(old_icon);
1423    edje_object_part_swallow(item->base.view, "elm.swallow.icon", item->icon);
1424    elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1425    edje_object_size_min_restricted_calc(item->base.view, &mw, &mh, mw, mh);
1426    elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1427    evas_object_size_hint_weight_set(item->base.view, -1.0, EVAS_HINT_EXPAND);
1428    evas_object_size_hint_align_set(item->base.view, 0.5, EVAS_HINT_FILL);
1429    evas_object_size_hint_min_set(item->base.view, mw, mh);
1430
1431    EINA_LIST_FOREACH(item->states, l, it_state)
1432       if (it_state->icon == old_icon)
1433         return;
1434    evas_object_del(old_icon);
1435 }
1436
1437 /**
1438  * Get the selected state of @p item.
1439  *
1440  * @param item The toolbar item
1441  * @return If true, the item is selected
1442  *
1443  * @ingroup Toolbar
1444  */
1445 EAPI Eina_Bool
1446 elm_toolbar_item_selected_get(const Elm_Toolbar_Item *item)
1447 {
1448    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, EINA_FALSE);
1449    return item->selected;
1450 }
1451
1452 /**
1453  * Set the selected state of an item
1454  *
1455  * This sets the selected state (1 selected, 0 not selected) of the given
1456  * item @p it. If a new item is selected the previosly selected will be
1457  * unselected.
1458  *
1459  * @param item The item
1460  * @param selected The selected state
1461  *
1462  * @ingroup Toolbar
1463  */
1464 EAPI void
1465 elm_toolbar_item_selected_set(Elm_Toolbar_Item *item, Eina_Bool selected)
1466 {
1467    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
1468    Widget_Data *wd = elm_widget_data_get(item->base.widget);
1469    if (!wd) return;
1470
1471    if (item->selected == selected) return;
1472
1473    if (selected)
1474      _item_select(item);
1475    else
1476      _item_unselect(item);
1477 }
1478
1479 /**
1480  * Get the selectd item in the toolbar
1481  *
1482  * If no item is selected, NULL is returned.
1483  *
1484  * @param obj The toolbar object
1485  * @return The selected item, or NULL if none.
1486  *
1487  * @ingroup Toolbar
1488  */
1489 EAPI Elm_Toolbar_Item *
1490 elm_toolbar_selected_item_get(const Evas_Object *obj)
1491 {
1492    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1493    Widget_Data *wd = elm_widget_data_get(obj);
1494    if (!wd) return NULL;
1495    return wd->selected_item;
1496 }
1497
1498 static void
1499 _elm_toolbar_item_icon_set_cb (void *data, Evas_Object *obj, const char *emission, const char *source)
1500 {
1501    Elm_Toolbar_Item *item = data;
1502    edje_object_part_unswallow(item->base.view, item->icon);
1503    _elm_toolbar_item_icon_update(item);
1504    edje_object_signal_callback_del(obj, emission, source,
1505                                    _elm_toolbar_item_icon_set_cb);
1506    edje_object_signal_emit (item->base.view, "elm,state,icon,reset", "elm");
1507 }
1508
1509 static void
1510 _elm_toolbar_item_icon_obj_set(Evas_Object *obj, Elm_Toolbar_Item *item, Evas_Object *icon_obj, const char *icon_str, double icon_size, const char *signal)
1511 {
1512    Evas_Object *old_icon;
1513    int ms = 0;
1514    const char *s;
1515
1516    if (icon_str)
1517      eina_stringshare_replace(&item->icon_str, icon_str);
1518    else
1519      {
1520         eina_stringshare_del(item->icon_str);
1521         item->icon_str = NULL;
1522      }
1523    item->icon = icon_obj;
1524    if (icon_obj)
1525      {
1526         ms = (icon_size * _elm_config->scale);
1527         evas_object_size_hint_min_set(item->icon, ms, ms);
1528         evas_object_size_hint_max_set(item->icon, ms, ms);
1529         evas_object_show(item->icon);
1530         elm_widget_sub_object_add(obj, item->icon);
1531      }
1532    s = edje_object_data_get(item->base.view, "transition_animation_on");
1533    if ((s) && (atoi(s)))
1534      {
1535         old_icon = edje_object_part_swallow_get(item->base.view,
1536                                                 "elm.swallow.icon_new");
1537         if (old_icon)
1538           {
1539              elm_widget_sub_object_del(item->base.view, old_icon);
1540              evas_object_hide(old_icon);
1541           }
1542         edje_object_part_swallow(item->base.view, "elm.swallow.icon_new",
1543                                  item->icon);
1544         edje_object_signal_emit (item->base.view, signal, "elm");
1545         edje_object_signal_callback_add(item->base.view,
1546                                         "elm,state,icon_set,done", "elm",
1547                                         _elm_toolbar_item_icon_set_cb, item);
1548      }
1549    else
1550      _elm_toolbar_item_icon_update(item);
1551    _resize(obj, NULL, NULL, NULL);
1552 }
1553
1554 /**
1555  * Set the icon associated with @p item.
1556  *
1557  * Toolbar will load icon image from fdo or current theme.
1558  * This behavior can be set by elm_toolbar_icon_order_lookup_set() function.
1559  * If an absolute path is provided it will load it direct from a file.
1560  *
1561  * @param obj The parent of this item
1562  * @param item The toolbar item
1563  * @param icon A string with icon name or the absolute path of an image file.
1564  *
1565  * @see elm_toolbar_icon_order_lookup_set(), elm_toolbar_icon_order_lookup_get()
1566  *
1567  * @ingroup Toolbar
1568  */
1569 EAPI void
1570 elm_toolbar_item_icon_set(Elm_Toolbar_Item *item, const char *icon)
1571 {
1572    Evas_Object *icon_obj;
1573    Widget_Data *wd;
1574    Evas_Object *obj = item->base.widget;
1575
1576    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
1577    wd = elm_widget_data_get(obj);
1578    if (!wd) return;
1579    if ((icon) && (item->icon_str) && (!strcmp(icon, item->icon_str))) return;
1580
1581    icon_obj = elm_icon_add(obj);
1582    if (!icon_obj) return;
1583    if (_item_icon_set(icon_obj, "toolbar/", icon))
1584      _elm_toolbar_item_icon_obj_set(obj, item, icon_obj, icon, wd->icon_size,
1585                                     "elm,state,icon_set");
1586    else
1587      {
1588         _elm_toolbar_item_icon_obj_set(obj, item, NULL, NULL, 0,
1589                                        "elm,state,icon_set");
1590         evas_object_del(icon_obj);
1591      }
1592 }
1593
1594 /**
1595  * Delete a toolbar item.
1596  *
1597  * @param item The toolbar item
1598  *
1599  * @ingroup Toolbar
1600  */
1601 EAPI void
1602 elm_toolbar_item_del(Elm_Toolbar_Item *item)
1603 {
1604    Widget_Data *wd;
1605    Evas_Object *obj2;
1606
1607    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
1608    wd = elm_widget_data_get(item->base.widget);
1609    if (!wd) return;
1610    obj2 = item->base.widget;
1611    wd->items = eina_inlist_remove(wd->items, EINA_INLIST_GET(item));
1612    _item_del(item);
1613    _theme_hook(obj2);
1614 }
1615
1616 /**
1617  * Set the function called when a toolbar item is freed.
1618  *
1619  * @param item The item to set the callback on
1620  * @param func The function called
1621  *
1622  * @ingroup Toolbar
1623  */
1624 EAPI void
1625 elm_toolbar_item_del_cb_set(Elm_Toolbar_Item *item, Evas_Smart_Cb func)
1626 {
1627    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
1628    elm_widget_item_del_cb_set(item, func);
1629 }
1630
1631 /**
1632  * Get the disabled state of @p item.
1633  *
1634  * @param item The toolbar item
1635  * @return If true, the item is disabled
1636  *
1637  * @ingroup Toolbar
1638  */
1639 EAPI Eina_Bool
1640 elm_toolbar_item_disabled_get(const Elm_Toolbar_Item *item)
1641 {
1642    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, EINA_FALSE);
1643    return item->disabled;
1644 }
1645
1646 /**
1647  * Set the disabled state of @p item.
1648  *
1649  * @param item The toolbar item
1650  * @param disabled If true, the item is disabled
1651  *
1652  * @ingroup Toolbar
1653  */
1654 EAPI void
1655 elm_toolbar_item_disabled_set(Elm_Toolbar_Item *item, Eina_Bool disabled)
1656 {
1657    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
1658    _item_disable(item, disabled);
1659    _resize(item->base.widget, NULL, NULL, NULL);
1660 }
1661
1662 /**
1663  * Get the separator state of @p item.
1664  *
1665  * @param item The toolbar item
1666  * @param separator If true, the item is a separator
1667  *
1668  * @ingroup Toolbar
1669  */
1670 EAPI void
1671 elm_toolbar_item_separator_set(Elm_Toolbar_Item *item, Eina_Bool separator)
1672 {
1673    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
1674    if (item->separator == separator) return;
1675    item->separator = separator;
1676    _theme_hook(item->base.view);
1677 }
1678
1679 /**
1680  * Set the separator state of @p item.
1681  *
1682  * @param item The toolbar item
1683  * @return If true, the item is a separator
1684  *
1685  * @ingroup Toolbar
1686  */
1687 EAPI Eina_Bool
1688 elm_toolbar_item_separator_get(const Elm_Toolbar_Item *item)
1689 {
1690    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, EINA_FALSE);
1691    return item->separator;
1692 }
1693
1694 /**
1695  * Set the shrink state of toolbar @p obj.
1696  *
1697  * @param obj The toolbar object
1698  * @param shrink_mode The toolbar won't scroll if ELM_TOOLBAR_SHRINK_NONE,
1699  * but will enforce a minimun size so all the items will fit, won't scroll
1700  * and won't show the items that don't fit if ELM_TOOLBAR_SHRINK_HIDE,
1701  * will scroll if ELM_TOOLBAR_SHRINK_SCROLL, and will create a button to
1702  * pop up excess elements with ELM_TOOLBAR_SHRINK_MENU.
1703  *
1704  * @ingroup Toolbar
1705  */
1706 EAPI void
1707 elm_toolbar_mode_shrink_set(Evas_Object *obj, Elm_Toolbar_Shrink_Mode shrink_mode)
1708 {
1709    ELM_CHECK_WIDTYPE(obj, widtype);
1710    Widget_Data *wd = elm_widget_data_get(obj);
1711    Eina_Bool bounce;
1712
1713    if (!wd) return;
1714    wd->shrink_mode = shrink_mode;
1715    bounce = (_elm_config->thumbscroll_bounce_enable) &&
1716       (shrink_mode == ELM_TOOLBAR_SHRINK_SCROLL);
1717    elm_smart_scroller_bounce_allow_set(wd->scr, bounce, EINA_FALSE);
1718
1719    if (wd->more_item)
1720      {
1721         _item_del(wd->more_item);
1722         wd->more_item = NULL;
1723      }
1724
1725    if (shrink_mode == ELM_TOOLBAR_SHRINK_MENU)
1726      {
1727         elm_smart_scroller_policy_set(wd->scr, ELM_SMART_SCROLLER_POLICY_OFF, ELM_SMART_SCROLLER_POLICY_OFF);
1728
1729         wd->more_item = _item_new(obj, "more_menu", "More",
1730                                   NULL, NULL);
1731      }
1732    else if (shrink_mode == ELM_TOOLBAR_SHRINK_HIDE)
1733      elm_smart_scroller_policy_set(wd->scr, ELM_SMART_SCROLLER_POLICY_OFF,
1734                                    ELM_SMART_SCROLLER_POLICY_OFF);
1735    else
1736      elm_smart_scroller_policy_set(wd->scr, ELM_SMART_SCROLLER_POLICY_AUTO,
1737                                    ELM_SMART_SCROLLER_POLICY_OFF);
1738    _sizing_eval(obj);
1739 }
1740
1741 /**
1742  * Get the shrink mode of toolbar @p obj.
1743  *
1744  * @param obj The toolbar object
1745  * @return See elm_toolbar_mode_shrink_set.
1746  *
1747  * @ingroup Toolbar
1748  */
1749 EAPI Elm_Toolbar_Shrink_Mode
1750 elm_toolbar_mode_shrink_get(const Evas_Object *obj)
1751 {
1752    ELM_CHECK_WIDTYPE(obj, widtype) ELM_TOOLBAR_SHRINK_NONE;
1753    Widget_Data *wd = elm_widget_data_get(obj);
1754
1755    if (!wd) return ELM_TOOLBAR_SHRINK_NONE;
1756    return wd->shrink_mode;
1757 }
1758
1759 /**
1760  * Set the homogenous mode of toolbar @p obj.
1761  *
1762  * @param obj The toolbar object
1763  * @param homogenous If true, the toolbar items will be uniform in size
1764  *
1765  * @ingroup Toolbar
1766  */
1767 EAPI void
1768 elm_toolbar_homogenous_set(Evas_Object *obj, Eina_Bool homogenous)
1769 {
1770    ELM_CHECK_WIDTYPE(obj, widtype);
1771    Widget_Data *wd = elm_widget_data_get(obj);
1772
1773    if (!wd) return;
1774    wd->homogeneous = !!homogenous;
1775    evas_object_smart_calculate(wd->bx);
1776 }
1777
1778 /**
1779  * Get the homogenous mode of toolbar @p obj.
1780  *
1781  * @param obj The toolbar object
1782  * @return If true, the toolbar items are uniform in size
1783  *
1784  * @ingroup Toolbar
1785  */
1786 EAPI Eina_Bool
1787 elm_toolbar_homogenous_get(const Evas_Object *obj)
1788 {
1789    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1790    Widget_Data *wd = elm_widget_data_get(obj);
1791
1792    if (!wd) return EINA_FALSE;
1793    return wd->homogeneous;
1794 }
1795
1796 /**
1797  * Set the parent object of the toolbar menu
1798  *
1799  * @param obj The toolbar object
1800  * @param parent The parent of the menu object
1801  *
1802  * @ingroup Toolbar
1803  */
1804 EAPI void
1805 elm_toolbar_menu_parent_set(Evas_Object *obj, Evas_Object *parent)
1806 {
1807    Elm_Toolbar_Item *it;
1808    ELM_CHECK_WIDTYPE(obj, widtype);
1809    Widget_Data *wd = elm_widget_data_get(obj);
1810
1811    if (!wd) return;
1812    EINA_SAFETY_ON_NULL_RETURN(parent);
1813    wd->menu_parent = parent;
1814    EINA_INLIST_FOREACH(wd->items, it)
1815      {
1816         if (it->o_menu)
1817           elm_menu_parent_set(it->o_menu, wd->menu_parent);
1818      }
1819    if ((wd->more_item) && (wd->more_item->o_menu))
1820      elm_menu_parent_set(wd->more_item->o_menu, wd->menu_parent);
1821 }
1822
1823 /**
1824  * Get the parent object of the toolbar menu
1825  *
1826  * @param obj The toolbar object
1827  * @return The parent of the menu object
1828  *
1829  * @ingroup Toolbar
1830  */
1831 EAPI Evas_Object *
1832 elm_toolbar_menu_parent_get(const Evas_Object *obj)
1833 {
1834    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1835    Widget_Data *wd = elm_widget_data_get(obj);
1836
1837    if (!wd) return NULL;
1838    return wd->menu_parent;
1839 }
1840
1841 /**
1842  * Set the alignment of the items.
1843  *
1844  * @param obj The toolbar object
1845  * @param align The new alignment. (left) 0.0 ... 1.0 (right)
1846  *
1847  * @ingroup Toolbar
1848  */
1849 EAPI void
1850 elm_toolbar_align_set(Evas_Object *obj, double align)
1851 {
1852    ELM_CHECK_WIDTYPE(obj, widtype);
1853    Widget_Data *wd = elm_widget_data_get(obj);
1854
1855    if (!wd) return;
1856    if (wd->align != align)
1857      evas_object_size_hint_align_set(wd->bx, align, 0.5);
1858    wd->align = align;
1859 }
1860
1861 /**
1862  * Get the alignment of the items.
1863  *
1864  * @param obj The toolbar object
1865  * @return The alignment. (left) 0.0 ... 1.0 (right)
1866  *
1867  * @ingroup Toolbar
1868  */
1869 EAPI double
1870 elm_toolbar_align_get(const Evas_Object *obj)
1871 {
1872    ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
1873    Widget_Data *wd = elm_widget_data_get(obj);
1874
1875    if (!wd) return 0.0;
1876    return wd->align;
1877 }
1878
1879 /**
1880  * Set whether the toolbar item opens a menu.
1881  *
1882  * @param item The toolbar item
1883  * @param menu If true, @p item will open a menu when selected
1884  *
1885  * @ingroup Toolbar
1886  */
1887 EAPI void
1888 elm_toolbar_item_menu_set(Elm_Toolbar_Item *item, Eina_Bool menu)
1889 {
1890    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
1891    Widget_Data *wd = elm_widget_data_get(item->base.widget);
1892    if (!wd) return;
1893
1894    if (item->menu == menu) return;
1895    item->menu = menu;
1896    if (menu) _item_menu_create(wd, item);
1897    else _item_menu_destroy(item);
1898 }
1899
1900 /**
1901  * Set the text to be shown in the toolbar item.
1902  *
1903  * @param item Target item
1904  * @param text The text to set in the content
1905  *
1906  * Setup the text as tooltip to object. The item can have only one tooltip,
1907  * so any previous tooltip data is removed.
1908  *
1909  * @ingroup Toolbar
1910  */
1911 EAPI void
1912 elm_toolbar_item_tooltip_text_set(Elm_Toolbar_Item *item, const char *text)
1913 {
1914    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
1915    elm_widget_item_tooltip_text_set(item, text);
1916 }
1917
1918 /**
1919  * Set the content to be shown in the tooltip item
1920  *
1921  * Setup the tooltip to item. The item can have only one tooltip,
1922  * so any previous tooltip data is removed. @p func(with @p data) will
1923  * be called every time that need show the tooltip and it should
1924  * return a valid Evas_Object. This object is then managed fully by
1925  * tooltip system and is deleted when the tooltip is gone.
1926  *
1927  * @param item the toolbar item being attached a tooltip.
1928  * @param func the function used to create the tooltip contents.
1929  * @param data what to provide to @a func as callback data/context.
1930  * @param del_cb called when data is not needed anymore, either when
1931  *        another callback replaces @func, the tooltip is unset with
1932  *        elm_toolbar_item_tooltip_unset() or the owner @a item
1933  *        dies. This callback receives as the first parameter the
1934  *        given @a data, and @c event_info is the item.
1935  *
1936  * @ingroup Toolbar
1937  */
1938 EAPI void
1939 elm_toolbar_item_tooltip_content_cb_set(Elm_Toolbar_Item *item, Elm_Tooltip_Item_Content_Cb func, const void *data, Evas_Smart_Cb del_cb)
1940 {
1941    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
1942    elm_widget_item_tooltip_content_cb_set(item, func, data, del_cb);
1943 }
1944
1945 /**
1946  * Unset tooltip from item
1947  *
1948  * @param item toolbar item to remove previously set tooltip.
1949  *
1950  * Remove tooltip from item. The callback provided as del_cb to
1951  * elm_toolbar_item_tooltip_content_cb_set() will be called to notify
1952  * it is not used anymore.
1953  *
1954  * @see elm_toolbar_item_tooltip_content_cb_set()
1955  *
1956  * @ingroup Toolbar
1957  */
1958 EAPI void
1959 elm_toolbar_item_tooltip_unset(Elm_Toolbar_Item *item)
1960 {
1961    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
1962    elm_widget_item_tooltip_unset(item);
1963 }
1964
1965 /**
1966  * Sets a different style for this item tooltip.
1967  *
1968  * @note before you set a style you should define a tooltip with
1969  *       elm_toolbar_item_tooltip_content_cb_set() or
1970  *       elm_toolbar_item_tooltip_text_set()
1971  *
1972  * @param item toolbar item with tooltip already set.
1973  * @param style the theme style to use (default, transparent, ...)
1974  *
1975  * @ingroup Toolbar
1976  */
1977 EAPI void
1978 elm_toolbar_item_tooltip_style_set(Elm_Toolbar_Item *item, const char *style)
1979 {
1980    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
1981    elm_widget_item_tooltip_style_set(item, style);
1982 }
1983
1984 /**
1985  * Get the style for this item tooltip.
1986  *
1987  * @param item toolbar item with tooltip already set.
1988  * @return style the theme style in use, defaults to "default". If the
1989  *         object does not have a tooltip set, then NULL is returned.
1990  *
1991  * @ingroup Toolbar
1992  */
1993 EAPI const char *
1994 elm_toolbar_item_tooltip_style_get(const Elm_Toolbar_Item *item)
1995 {
1996    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, NULL);
1997    return elm_widget_item_tooltip_style_get(item);
1998 }
1999
2000 /**
2001  * Set the cursor to be shown when mouse is over the toolbar item
2002  *
2003  * @param item Target item
2004  * @param cursor the cursor name to be used.
2005  *
2006  * @see elm_object_cursor_set()
2007  * @ingroup Toolbar
2008  */
2009 EAPI void
2010 elm_toolbar_item_cursor_set(Elm_Toolbar_Item *item, const char *cursor)
2011 {
2012    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
2013    elm_widget_item_cursor_set(item, cursor);
2014 }
2015
2016 /**
2017  * Get the cursor to be shown when mouse is over the toolbar item
2018  *
2019  * @param item toolbar item with cursor already set.
2020  * @return the cursor name.
2021  *
2022  * @ingroup Toolbar
2023  */
2024 EAPI const char *
2025 elm_toolbar_item_cursor_get(const Elm_Toolbar_Item *item)
2026 {
2027    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, NULL);
2028    return elm_widget_item_cursor_get(item);
2029 }
2030
2031 /**
2032  * Unset the cursor to be shown when mouse is over the toolbar item
2033  *
2034  * @param item Target item
2035  *
2036  * @see elm_object_cursor_unset()
2037  * @ingroup Toolbar
2038  */
2039 EAPI void
2040 elm_toolbar_item_cursor_unset(Elm_Toolbar_Item *item)
2041 {
2042    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
2043    elm_widget_item_cursor_unset(item);
2044 }
2045
2046 /**
2047  * Sets a different style for this item cursor.
2048  *
2049  * @note before you set a style you should define a cursor with
2050  *       elm_toolbar_item_cursor_set()
2051  *
2052  * @param item toolbar item with cursor already set.
2053  * @param style the theme style to use (default, transparent, ...)
2054  *
2055  * @ingroup Toolbar
2056  */
2057 EAPI void
2058 elm_toolbar_item_cursor_style_set(Elm_Toolbar_Item *item, const char *style)
2059 {
2060    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
2061    elm_widget_item_cursor_style_set(item, style);
2062 }
2063
2064 /**
2065  * Get the style for this item cursor.
2066  *
2067  * @param item toolbar item with cursor already set.
2068  * @return style the theme style in use, defaults to "default". If the
2069  *         object does not have a cursor set, then NULL is returned.
2070  *
2071  * @ingroup Toolbar
2072  */
2073 EAPI const char *
2074 elm_toolbar_item_cursor_style_get(const Elm_Toolbar_Item *item)
2075 {
2076    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, NULL);
2077    return elm_widget_item_cursor_style_get(item);
2078 }
2079
2080 /**
2081  * Set if the cursor set should be searched on the theme or should use
2082  * the provided by the engine, only.
2083  *
2084  * @note before you set if should look on theme you should define a cursor
2085  * with elm_object_cursor_set(). By default it will only look for cursors
2086  * provided by the engine.
2087  *
2088  * @param item widget item with cursor already set.
2089  * @param engine_only boolean to define it cursors should be looked only
2090  * between the provided by the engine or searched on widget's theme as well.
2091  *
2092  * @ingroup Toolbar
2093  */
2094 EAPI void
2095 elm_toolbar_item_cursor_engine_only_set(Elm_Toolbar_Item *item, Eina_Bool engine_only)
2096 {
2097    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
2098    elm_widget_item_cursor_engine_only_set(item, engine_only);
2099 }
2100
2101 /**
2102  * Get the cursor engine only usage for this item cursor.
2103  *
2104  * @param item widget item with cursor already set.
2105  * @return engine_only boolean to define it cursors should be looked only
2106  * between the provided by the engine or searched on widget's theme as well. If
2107  *         the object does not have a cursor set, then EINA_FALSE is returned.
2108  *
2109  * @ingroup Toolbar
2110  */
2111 EAPI Eina_Bool
2112 elm_toolbar_item_cursor_engine_only_get(const Elm_Toolbar_Item *item)
2113 {
2114    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, EINA_FALSE);
2115    return elm_widget_item_cursor_engine_only_get(item);
2116 }
2117
2118 /**
2119  * Get whether the toolbar item opens a menu.
2120  *
2121  * @param item The toolbar item
2122  * @return If true, @p item opens a menu when selected
2123  *
2124  * @ingroup Toolbar
2125  */
2126 EAPI Evas_Object *
2127 elm_toolbar_item_menu_get(Elm_Toolbar_Item *item)
2128 {
2129    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, NULL);
2130    Widget_Data *wd = elm_widget_data_get(item->base.widget);
2131    if (!wd) return NULL;
2132    /* FIXME: It's not ok. This function needs to be reviewed. And should
2133     * receive a const item */
2134    elm_toolbar_item_menu_set(item, 1);
2135    return item->o_menu;
2136 }
2137
2138 /**
2139  * Returns a pointer to a toolbar item by its label
2140  *
2141  * @param obj The toolbar object
2142  * @param label The label of the item to find
2143  *
2144  * @return The pointer to the toolbar item matching @p label
2145  * Returns NULL on failure.
2146  *
2147  * @ingroup Toolbar
2148  */
2149 EAPI Elm_Toolbar_Item *
2150 elm_toolbar_item_find_by_label(const Evas_Object *obj, const char *label)
2151 {
2152    Elm_Toolbar_Item *it;
2153    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2154    Widget_Data *wd = elm_widget_data_get(obj);
2155
2156    if (!wd) return NULL;
2157    EINA_INLIST_FOREACH(wd->items, it)
2158      {
2159         if (!strcmp(it->label, label)) return it;
2160      }
2161
2162    return NULL;
2163 }
2164
2165 /**
2166  * Set the data item from the toolbar item
2167  *
2168  * This set the data value passed on the elm_toolbar_item_append() and
2169  * related item addition calls.
2170  *
2171  * @param item The item
2172  * @param data The new data pointer to set
2173  *
2174  * @ingroup Toolbar
2175  */
2176 EAPI void
2177 elm_toolbar_item_data_set(Elm_Toolbar_Item *item, const void *data)
2178 {
2179    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
2180    elm_widget_item_data_set(item, data);
2181 }
2182
2183 /**
2184  * Get the data item from the toolbar item
2185  *
2186  * This returns the data value passed on the elm_toolbar_item_append() and
2187  * related item addition calls.
2188  *
2189  * @param item The item
2190  * @return The data pointer provided when created
2191  *
2192  * @ingroup Toolbar
2193  */
2194 EAPI void *
2195 elm_toolbar_item_data_get(const Elm_Toolbar_Item *item)
2196 {
2197    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, NULL);
2198    return elm_widget_item_data_get(item);
2199 }
2200
2201 /**
2202  * Set no select mode.
2203  *
2204  * This will turn off the ability to select items entirely and they will
2205  * neither appear selected nor emit selected signals. The clicked
2206  * callback function will still be called.
2207  *
2208  * @param obj The Toolbar object
2209  * @param no_select The no select mode (EINA_TRUE = on, EINA_FALSE = off)
2210  *
2211  * @ingroup Toolbar
2212  */
2213 EAPI void
2214 elm_toolbar_no_select_mode_set(Evas_Object *obj, Eina_Bool no_select)
2215 {
2216    ELM_CHECK_WIDTYPE(obj, widtype);
2217    Widget_Data *wd = elm_widget_data_get(obj);
2218    if (!wd) return;
2219    wd->no_select = no_select;
2220 }
2221
2222 /**
2223  * Gets no select mode.
2224  *
2225  * @param obj The Toolbar object
2226  * @return The no select mode (EINA_TRUE = on, EINA_FALSE = off)
2227  *
2228  * @ingroup Toolbar
2229  */
2230 EAPI Eina_Bool
2231 elm_toolbar_no_select_mode_get(const Evas_Object *obj)
2232 {
2233    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2234    Widget_Data *wd = elm_widget_data_get(obj);
2235    if (!wd) return EINA_FALSE;
2236    return wd->no_select;
2237 }
2238
2239 /**
2240  * Sets icon lookup order, for icons used in this toolbar.
2241  * Icons added before calling this function will not be affected.
2242  * The default lookup order is ELM_ICON_LOOKUP_THEME_FDO.
2243  *
2244  * @param obj The toolbar object
2245  * @param order The icon lookup order
2246  *
2247  * @ingroup Toolbar
2248  */
2249 EAPI void
2250 elm_toolbar_icon_order_lookup_set(Evas_Object *obj, Elm_Icon_Lookup_Order order)
2251 {
2252    ELM_CHECK_WIDTYPE(obj, widtype);
2253    Elm_Toolbar_Item *it;
2254    Widget_Data *wd = elm_widget_data_get(obj);
2255    if (!wd) return;
2256
2257    wd->lookup_order = order;
2258    EINA_INLIST_FOREACH(wd->items, it)
2259       elm_icon_order_lookup_set(it->icon, order);
2260    if (wd->more_item)
2261      elm_icon_order_lookup_set(wd->more_item->icon, order);
2262 }
2263
2264 /**
2265  * Gets the icon lookup order.
2266  *
2267  * @param obj The Toolbar object
2268  * @return The icon lookup order
2269  *
2270  * @ingroup Toolbar
2271  */
2272 EAPI Elm_Icon_Lookup_Order
2273 elm_toolbar_icon_order_lookup_get(const Evas_Object *obj)
2274 {
2275    ELM_CHECK_WIDTYPE(obj, widtype) ELM_ICON_LOOKUP_THEME_FDO;
2276    Widget_Data *wd = elm_widget_data_get(obj);
2277    if (!wd) return ELM_ICON_LOOKUP_THEME_FDO;
2278    return wd->lookup_order;
2279 }