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