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