Elementary: Added on-the-fly UI-mirroing support to all of the widgets
[framework/uifw/elementary.git] / src / lib / elc_hoversel.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 /**
5  * @defgroup Hoversel
6  *
7  * A hoversel is a button that pops up a list of items (automatically
8  * choosing the direction to display) that have a lable and/or an icon to
9  * select from. It is a convenience widget to avoid the need to do all the
10  * piecing together yourself. It is intended for a small number of items in
11  * the hoversel menu (no more than 8), though is capable of many more.
12  *
13  * Signals that you can add callbacks for are:
14  *
15  * clicked  - the user clicked the hoversel button and popped up the sel
16  *
17  * selected - an item in the hoversel list is selected. event_info is the item
18  * selected - Elm_Hoversel_Item
19  *
20  * dismissed - the hover is dismissed
21  */
22 typedef struct _Widget_Data Widget_Data;
23
24 struct _Widget_Data
25 {
26    Evas_Object *btn, *hover;
27    Evas_Object *hover_parent;
28    Eina_List *items;
29    Eina_Bool horizontal : 1;
30    Eina_Bool expanded   : 1;
31 };
32
33 struct _Elm_Hoversel_Item
34 {
35    Elm_Widget_Item base;
36    const char *label;
37    const char *icon_file;
38    const char *icon_group;
39    Elm_Icon_Type icon_type;
40    Evas_Smart_Cb func;
41 };
42
43 static const char *widtype = NULL;
44 static void _del_pre_hook(Evas_Object *obj);
45 static void _del_hook(Evas_Object *obj);
46 static void _activate(Evas_Object *obj);
47 static void _activate_hook(Evas_Object *obj);
48 static void _disable_hook(Evas_Object *obj);
49 static void _sizing_eval(Evas_Object *obj);
50 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
51 static void _parent_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
52
53 static void
54 _del_pre_hook(Evas_Object *obj)
55 {
56    Elm_Hoversel_Item *item;
57    Widget_Data *wd = elm_widget_data_get(obj);
58    if (!wd) return;
59    elm_hoversel_hover_end(obj);
60    elm_hoversel_hover_parent_set(obj, NULL);
61    EINA_LIST_FREE(wd->items, item)
62      {
63         elm_widget_item_pre_notify_del(item);
64         eina_stringshare_del(item->label);
65         eina_stringshare_del(item->icon_file);
66         eina_stringshare_del(item->icon_group);
67         elm_widget_item_del(item);
68      }
69 }
70
71 static void
72 _del_hook(Evas_Object *obj)
73 {
74    Widget_Data *wd = elm_widget_data_get(obj);
75    if (!wd) return;
76    free(wd);
77 }
78
79 static void
80 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
81 {
82    Widget_Data *wd = elm_widget_data_get(obj);
83    if (!wd) return;
84    elm_widget_mirrored_set(wd->btn, rtl);
85    elm_widget_mirrored_set(wd->hover, rtl);
86 }
87
88 static void
89 _theme_hook(Evas_Object *obj)
90 {
91    Widget_Data *wd = elm_widget_data_get(obj);
92    char buf[4096];
93    if (!wd) return;
94    _elm_widget_mirrored_reload(obj);
95    elm_hoversel_hover_end(obj);
96    if (wd->horizontal)
97       snprintf(buf, sizeof(buf), "hoversel_horizontal/%s", elm_widget_style_get(obj));
98    else
99       snprintf(buf, sizeof(buf), "hoversel_vertical/%s", elm_widget_style_get(obj));
100    elm_object_style_set(wd->btn, buf);
101    elm_object_disabled_set(wd->btn, elm_widget_disabled_get(obj));
102    _mirrored_set(obj, elm_widget_mirrored_get(obj));
103 }
104
105 static void
106 _disable_hook(Evas_Object *obj)
107 {
108    Widget_Data *wd = elm_widget_data_get(obj);
109    if (!wd) return;
110    elm_object_disabled_set(wd->btn, elm_widget_disabled_get(obj));
111 }
112
113 static void
114 _sizing_eval(Evas_Object *obj)
115 {
116    Widget_Data *wd = elm_widget_data_get(obj);
117    Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
118    if (!wd) return;
119    evas_object_size_hint_min_get(wd->btn, &minw, &minh);
120    evas_object_size_hint_max_get(wd->btn, &maxw, &maxh);
121    evas_object_size_hint_min_set(obj, minw, minh);
122    evas_object_size_hint_max_set(obj, maxw, maxh);
123 }
124
125 static void
126 _on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
127 {
128    Widget_Data *wd = elm_widget_data_get(obj);
129    if (!wd) return;
130    if (elm_widget_focus_get(obj))
131      elm_widget_focus_steal(wd->btn);
132 }
133
134 static void
135 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
136 {
137    _sizing_eval(data);
138 }
139
140 static void
141 _hover_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
142 {
143    elm_hoversel_hover_end(data);
144 }
145
146 static void
147 _item_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
148 {
149    Elm_Hoversel_Item *item = data;
150    Evas_Object *obj2 = item->base.widget;
151
152    elm_hoversel_hover_end(obj2);
153    if (item->func) item->func((void *)item->base.data, obj2, item);
154    evas_object_smart_callback_call(obj2, "selected", item);
155 }
156
157 static void
158 _activate(Evas_Object *obj)
159 {
160    Widget_Data *wd = elm_widget_data_get(obj);
161    Evas_Object *bt, *bx, *ic;
162    const Eina_List *l;
163    const Elm_Hoversel_Item *item;
164    char buf[4096];
165
166    if (!wd) return;
167    if (wd->expanded)
168      {
169         elm_hoversel_hover_end(obj);
170         return;
171      }
172    wd->expanded = EINA_TRUE;
173
174    if (elm_widget_disabled_get(obj)) return;
175    wd->hover = elm_hover_add(obj);
176    if (wd->horizontal)
177      snprintf(buf, sizeof(buf), "hoversel_horizontal/%s", elm_widget_style_get(obj));
178    else
179      snprintf(buf, sizeof(buf), "hoversel_vertical/%s", elm_widget_style_get(obj));
180    elm_object_style_set(wd->hover, buf);
181    evas_object_smart_callback_add(wd->hover, "clicked", _hover_clicked, obj);
182    elm_hover_parent_set(wd->hover, wd->hover_parent);
183    elm_hover_target_set(wd->hover, wd->btn);
184
185    bx = elm_box_add(wd->hover);
186    elm_box_homogenous_set(bx, 1);
187    
188    elm_box_horizontal_set(bx, wd->horizontal);
189    
190    if (wd->horizontal)
191      snprintf(buf, sizeof(buf), "hoversel_horizontal_entry/%s",
192               elm_widget_style_get(obj));
193    else
194      snprintf(buf, sizeof(buf), "hoversel_vertical_entry/%s",
195               elm_widget_style_get(obj));
196    EINA_LIST_FOREACH(wd->items, l, item)
197      {
198         bt = elm_button_add(wd->hover);
199         elm_widget_mirrored_set(bt, elm_widget_mirrored_get(obj));
200         elm_object_style_set(bt, buf);
201         elm_button_label_set(bt, item->label);
202         if (item->icon_file)
203           {
204              ic = elm_icon_add(obj);
205              elm_icon_scale_set(ic, 0, 1);
206              if (item->icon_type == ELM_ICON_FILE)
207                elm_icon_file_set(ic, item->icon_file, item->icon_group);
208              else if (item->icon_type == ELM_ICON_STANDARD)
209                elm_icon_standard_set(ic, item->icon_file);
210              elm_button_icon_set(bt, ic);
211              evas_object_show(ic);
212           }
213         evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
214         evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
215         elm_box_pack_end(bx, bt);
216         evas_object_smart_callback_add(bt, "clicked", _item_clicked, item);
217         evas_object_show(bt);
218      }
219
220    if (wd->horizontal)
221      elm_hover_content_set(wd->hover,
222                            elm_hover_best_content_location_get(wd->hover,
223                                                                ELM_HOVER_AXIS_HORIZONTAL),
224                            bx);
225    else
226      elm_hover_content_set(wd->hover,
227                            elm_hover_best_content_location_get(wd->hover,
228                                                                ELM_HOVER_AXIS_VERTICAL),
229                            bx);
230    evas_object_show(bx);
231
232    evas_object_show(wd->hover);
233    evas_object_smart_callback_call(obj, "clicked", NULL);
234
235 //   if (wd->horizontal) evas_object_hide(wd->btn);
236 }
237
238 static void
239 _activate_hook(Evas_Object *obj)
240 {
241    _activate(obj);
242 }
243
244 static void
245 _button_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
246 {
247    _activate(data);
248 }
249
250 static void
251 _parent_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
252 {
253    Widget_Data *wd = elm_widget_data_get(data);
254    if (!wd) return;
255    wd->hover_parent = NULL;
256 }
257
258 /**
259  * Add a new Hoversel object
260  *
261  * @param parent The parent object
262  * @return The new object or NULL if it cannot be created
263  *
264  * @ingroup Hoversel
265  */
266 EAPI Evas_Object *
267 elm_hoversel_add(Evas_Object *parent)
268 {
269    Evas_Object *obj;
270    Evas *e;
271    Widget_Data *wd;
272
273    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
274
275    wd = ELM_NEW(Widget_Data);
276    e = evas_object_evas_get(parent);
277    if (!e) return NULL;
278    obj = elm_widget_add(e);
279    ELM_SET_WIDTYPE(widtype, "hoversel");
280    elm_widget_type_set(obj, "hoversel");
281    elm_widget_sub_object_add(parent, obj);
282    elm_widget_data_set(obj, wd);
283    elm_widget_del_pre_hook_set(obj, _del_pre_hook);
284    elm_widget_del_hook_set(obj, _del_hook);
285    elm_widget_theme_hook_set(obj, _theme_hook);
286    elm_widget_disable_hook_set(obj, _disable_hook);
287    elm_widget_activate_hook_set(obj, _activate_hook);
288    elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
289    elm_widget_can_focus_set(obj, EINA_TRUE);
290
291    wd->btn = elm_button_add(parent);
292    wd->expanded = EINA_FALSE;
293    elm_widget_resize_object_set(obj, wd->btn);
294    evas_object_event_callback_add(wd->btn, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
295                                   _changed_size_hints, obj);
296    evas_object_smart_callback_add(wd->btn, "clicked", _button_clicked, obj);
297    elm_widget_sub_object_add(obj, wd->btn);
298
299    elm_hoversel_hover_parent_set(obj, parent);
300    _theme_hook(obj);
301    return obj;
302 }
303
304 /**
305  * Set the Hover parent
306  *
307  * Sets the hover parent object. Should probably be the window that the hoversel
308  * is in.  See Hover objects for more information.
309  *
310  * @param obj The hoversel object
311  * @param parent The parent to use
312  *
313  * @ingroup Hoversel
314  */
315 EAPI void
316 elm_hoversel_hover_parent_set(Evas_Object *obj, Evas_Object *parent)
317 {
318    ELM_CHECK_WIDTYPE(obj, widtype);
319    Widget_Data *wd = elm_widget_data_get(obj);
320    if (!wd) return;
321    if (wd->hover_parent)
322      evas_object_event_callback_del_full(wd->hover_parent, EVAS_CALLBACK_DEL,
323                                     _parent_del, obj);
324    wd->hover_parent = parent;
325    if (wd->hover_parent)
326      evas_object_event_callback_add(wd->hover_parent, EVAS_CALLBACK_DEL,
327                                     _parent_del, obj);
328 }
329
330 /**
331  * Get the Hover parent
332  *
333  * Gets the hover parent object. Should probably be the window that the hoversel
334  * is in.  See Hover objects for more information.
335  *
336  * @param obj The hoversel object
337  * @return The used parent
338  *
339  * @ingroup Hoversel
340  */
341 EAPI Evas_Object *
342 elm_hoversel_hover_parent_get(const Evas_Object *obj)
343 {
344    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
345    Widget_Data *wd = elm_widget_data_get(obj);
346    if (!wd) return NULL;
347    return wd->hover_parent;
348 }
349
350 /**
351  * Set the hoversel button label
352  *
353  * This sets the label of the button that is always visible (before it is
354  * clicked and expanded). Also see elm_button_label_set().
355  *
356  * @param obj The hoversel object
357  * @param label The label text.
358  *
359  * @ingroup Hoversel
360  */
361 EAPI void
362 elm_hoversel_label_set(Evas_Object *obj, const char *label)
363 {
364    ELM_CHECK_WIDTYPE(obj, widtype);
365    Widget_Data *wd = elm_widget_data_get(obj);
366    if (!wd) return;
367    elm_button_label_set(wd->btn, label);
368 }
369
370 /**
371  * Get the hoversel button label
372  *
373  * @param obj The hoversel object
374  * @return The label text.
375  *
376  * @ingroup Hoversel
377  */
378 EAPI const char *
379 elm_hoversel_label_get(const Evas_Object *obj)
380 {
381    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
382    Widget_Data *wd = elm_widget_data_get(obj);
383    if ((!wd) || (!wd->btn)) return NULL;
384    return elm_button_label_get(wd->btn);
385 }
386
387 /**
388  * This sets the hoversel to expand horizontally.  The initial button
389  * will display horizontally regardless of this setting.
390  *
391  * @param obj The hoversel object
392  * @param horizontal If true, the hover will expand horizontally to the right.
393  *
394  * @ingroup Hoversel
395  */
396 EAPI void
397 elm_hoversel_horizontal_set(Evas_Object *obj, Eina_Bool horizontal)
398 {
399    ELM_CHECK_WIDTYPE(obj, widtype);
400    Widget_Data *wd = elm_widget_data_get(obj);
401    if (!wd) return;
402    wd->horizontal = !!horizontal;
403 }
404
405
406 /**
407  * This returns whether the hoversel is set to expand horizontally.
408  *
409  * @param obj The hoversel object
410  * @return If true, the hover will expand horizontally to the right.
411  *
412  * @ingroup Hoversel
413  */
414 EAPI Eina_Bool
415 elm_hoversel_horizontal_get(const Evas_Object *obj)
416 {
417    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
418    Widget_Data *wd = elm_widget_data_get(obj);
419    if (!wd) return EINA_FALSE;
420    return wd->horizontal;
421 }
422
423 /**
424  * Set the icon of the hoversel button
425  *
426  * Sets the icon of the button that is always visible (before it is clicked
427  * and expanded). Also see elm_button_icon_set().
428  * Once the icon object is set, a previously set one will be deleted
429  * If you want to keep that old content object, use the
430  * elm_hoversel_icon_unset() function.
431  *
432  * @param obj The hoversel object
433  * @param icon The icon object
434  *
435  * @ingroup Hoversel
436  */
437 EAPI void
438 elm_hoversel_icon_set(Evas_Object *obj, Evas_Object *icon)
439 {
440    ELM_CHECK_WIDTYPE(obj, widtype);
441    Widget_Data *wd = elm_widget_data_get(obj);
442    if (!wd) return;
443    elm_button_icon_set(wd->btn, icon);
444 }
445
446 /**
447  * Get the icon of the hoversel button
448  *
449  * Get the icon of the button that is always visible (before it is clicked
450  * and expanded). Also see elm_button_icon_get().
451  *
452  * @param obj The hoversel object
453  * @return The icon object
454  *
455  * @ingroup Hoversel
456  */
457 EAPI Evas_Object *
458 elm_hoversel_icon_get(const Evas_Object *obj)
459 {
460    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
461    Widget_Data *wd = elm_widget_data_get(obj);
462    if ((!wd) || (!wd->btn)) return NULL;
463    return elm_button_icon_get(wd->btn);
464 }
465
466 /**
467  * Get the icon of the hoversel button
468  *
469  * Unparent and return the icon of the button that is always visible
470  * (before it is clicked and expanded). Also see elm_button_icon_unset().
471  *
472  * @param obj The hoversel object
473  * @return The icon object that was being used
474  *
475  * @ingroup Hoversel
476  */
477 EAPI Evas_Object *
478 elm_hoversel_icon_unset(Evas_Object *obj)
479 {
480    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
481    Widget_Data *wd = elm_widget_data_get(obj);
482    if ((!wd) || (!wd->btn)) return NULL;
483    return elm_button_icon_unset(wd->btn);
484 }
485
486 /**
487  * This triggers the hoversel popup from code, the same as though the
488  * user clicked the button.
489  *
490  * @param obj The hoversel object
491  *
492  * @ingroup Hoversel
493  */
494 EAPI void
495 elm_hoversel_hover_begin(Evas_Object *obj)
496 {
497    ELM_CHECK_WIDTYPE(obj, widtype);
498    Widget_Data *wd = elm_widget_data_get(obj);
499    if (!wd) return;
500    if (wd->hover) return;
501    _activate(obj);
502 }
503
504 /**
505  * This ends the hoversel popup as though the user clicked outside the hover.
506  *
507  * @param obj The hoversel object
508  *
509  * @ingroup Hoversel
510  */
511 EAPI void
512 elm_hoversel_hover_end(Evas_Object *obj)
513 {
514    ELM_CHECK_WIDTYPE(obj, widtype);
515    Widget_Data *wd = elm_widget_data_get(obj);
516    if (!wd) return;
517    if (!wd->hover) return;
518    wd->expanded = EINA_FALSE;
519    evas_object_del(wd->hover);
520    wd->hover = NULL;
521    evas_object_smart_callback_call(obj, "dismissed", NULL);
522 }
523
524 /**
525  * Returns whether the hoversel is expanded.
526  *
527  * @param obj The hoversel object
528  * @return  This will return EINA_TRUE if the hoversel
529  * is expanded or EINA_FALSE if it is not expanded.
530  *
531  * @ingroup Hoversel
532  */
533 EAPI Eina_Bool
534 elm_hoversel_expanded_get(const Evas_Object *obj)
535 {
536    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
537    Widget_Data *wd = elm_widget_data_get(obj);
538    if (!wd) return EINA_FALSE;
539    return (wd->hover) ? EINA_TRUE : EINA_FALSE;
540 }
541   
542 /**
543  * This will remove all the children items from the hoversel. (should not be
544  * called while the hoversel is active; use elm_hoversel_expanded_get()
545  * to check first).
546  *
547  * @param obj The hoversel object
548  *
549  * @ingroup Hoversel
550  */
551 EAPI void
552 elm_hoversel_clear(Evas_Object *obj)
553 {
554    Elm_Hoversel_Item *item;
555    Eina_List *l, *ll;
556    ELM_CHECK_WIDTYPE(obj, widtype);
557    Widget_Data *wd = elm_widget_data_get(obj);
558    if (!wd) return;
559    EINA_LIST_FOREACH_SAFE(wd->items, l, ll, item) elm_hoversel_item_del(item);
560 }
561
562 /**
563  * Get the list of items within the given hoversel.
564  *
565  * @param obj The hoversel object
566  * @return Returns a list of Elm_Hoversel_Item*
567  *
568  * @ingroup Hoversel
569  */
570 EAPI const Eina_List *
571 elm_hoversel_items_get(const Evas_Object *obj)
572 {
573    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
574    Widget_Data *wd = elm_widget_data_get(obj);
575    if (!wd) return NULL;
576    return wd->items;
577 }
578
579 /**
580  * Add an item to the hoversel button
581  *
582  * This adds an item to the hoversel to show when it is clicked. Note: if you
583  * need to use an icon from an edje file then use elm_hoversel_item_icon_set()
584  * right after the this function, and set icon_file to NULL here.
585  *
586  * @param obj The hoversel object
587  * @param label The text label to use for the item (NULL if not desired)
588  * @param icon_file An image file path on disk to use for the icon or standard
589  * icon name (NULL if not desired)
590  * @param icon_type The icon type if relevant
591  * @param func Convenience function to call when this item is selected
592  * @param data Data to pass to item-related functions
593  * @return A handle to the item added.
594  *
595  * @ingroup Hoversel
596  */
597 EAPI Elm_Hoversel_Item *
598 elm_hoversel_item_add(Evas_Object *obj, const char *label, const char *icon_file, Elm_Icon_Type icon_type, Evas_Smart_Cb func, const void *data)
599 {
600    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
601    Widget_Data *wd = elm_widget_data_get(obj);
602    if (!wd) return NULL;
603    Elm_Hoversel_Item *item = elm_widget_item_new(obj, Elm_Hoversel_Item);
604    if (!item) return NULL;
605    wd->items = eina_list_append(wd->items, item);
606    item->label = eina_stringshare_add(label);
607    item->icon_file = eina_stringshare_add(icon_file);
608    item->icon_type = icon_type;
609    item->func = func;
610    item->base.data = data;
611    return item;
612 }
613
614 /**
615  * Delete an item from the hoversel
616  *
617  * This deletes the item from the hoversel (should not be called while the
618  * hoversel is active; use elm_hoversel_expanded_get()
619  * to check first).
620  *
621  * @param item The item to delete
622  *
623  * @ingroup Hoversel
624  */
625 EAPI void
626 elm_hoversel_item_del(Elm_Hoversel_Item *item)
627 {
628    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
629    Widget_Data *wd = elm_widget_data_get(item->base.widget);
630    if (!wd) return;
631    elm_hoversel_hover_end(item->base.widget);
632    wd->items = eina_list_remove(wd->items, item);
633    elm_widget_item_pre_notify_del(item);
634    eina_stringshare_del(item->label);
635    eina_stringshare_del(item->icon_file);
636    eina_stringshare_del(item->icon_group);
637    elm_widget_item_del(item);
638 }
639
640 /**
641  * Set the function called when an item within the hoversel
642  * is freed. That function will receive these parameters:
643  *
644  * void *item_data
645  * Evas_Object *the_item_object
646  * Elm_Hoversel_Item *the_object_struct
647  *
648  * @param item The item to set the callback on
649  * @param func The function called
650  *
651  * @ingroup Hoversel
652  */
653 EAPI void
654 elm_hoversel_item_del_cb_set(Elm_Hoversel_Item *item, Evas_Smart_Cb func)
655 {
656    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
657    elm_widget_item_del_cb_set(item, func);
658 }
659
660 /**
661  * This returns the data pointer supplied with elm_hoversel_item_add() that
662  * will be passed to associated function callbacks.
663  *
664  * @param item The item to get the data from
665  * @return The data pointer set with elm_hoversel_item_add()
666  *
667  * @ingroup Hoversel
668  */
669 EAPI void *
670 elm_hoversel_item_data_get(const Elm_Hoversel_Item *item)
671 {
672    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, NULL);
673    return elm_widget_item_data_get(item);
674 }
675
676 /**
677  * This returns the label text of the given hoversel item.
678  *
679  * @param item The item to get the label
680  * @return The label text of the hoversel item
681  *
682  * @ingroup Hoversel
683  */
684 EAPI const char *
685 elm_hoversel_item_label_get(const Elm_Hoversel_Item *item)
686 {
687    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, NULL);
688    return item->label;
689 }
690
691 /**
692  * This sets the icon for the given hoversel item. The icon can be loaded from
693  * the standard set, from an image file, or from an edje file.
694  *
695  * @param item The item to set the icon
696  * @param icon_file An image file path on disk to use for the icon or standard
697  * icon name
698  * @param icon_group The edje group to use if @p icon_file is an edje file. Set this
699  * to NULL if the icon is not an edje file
700  * @param icon_type The icon type
701  *
702  * @ingroup Hoversel
703  */
704 EAPI void
705 elm_hoversel_item_icon_set(Elm_Hoversel_Item *item, const char *icon_file, const char *icon_group, Elm_Icon_Type icon_type)
706 {
707    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
708    eina_stringshare_replace(&item->icon_file, icon_file);
709    eina_stringshare_replace(&item->icon_group, icon_group);
710    item->icon_type = icon_type;
711 }
712
713 /**
714  * Get the icon object of the hoversel item
715  *
716  * @param item The item to get the icon from
717  * @param icon_file The image file path on disk used for the icon or standard
718  * icon name
719  * @param icon_group The edje group used if @p icon_file is an edje file. NULL
720  * if the icon is not an edje file
721  * @param icon_type The icon type
722  *
723  * @ingroup Hoversel
724  */
725 EAPI void
726 elm_hoversel_item_icon_get(const Elm_Hoversel_Item *item, const char **icon_file, const char **icon_group, Elm_Icon_Type *icon_type)
727 {
728    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
729    if (icon_file) *icon_file = item->icon_file;
730    if (icon_group) *icon_group = item->icon_group;
731    if (icon_type) *icon_type = item->icon_type;
732 }
733