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