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