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