02cc27979fb1d806cbf18671d38ad4508528fa9c
[framework/uifw/elementary.git] / src / lib / elc_fileselector_button.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4  /**
5  * @defgroup File_Selector_Button File Selector Button
6  * @ingroup Elementary
7  *
8  * A button that, when clicked, creates an Elementary window (or inner
9  * window) with an Elementary File Selector within. When a file is
10  * chosen, the (inner) window is closed and the selected file is
11  * exposed as an evas_object_smart_callback_call() of the button.
12  */
13
14 typedef struct _Widget_Data Widget_Data;
15
16 struct _Widget_Data
17 {
18    Evas_Object *btn, *icon, *fs;
19    const char *window_title;
20    const char *btn_label;
21    Evas_Coord w, h;
22    struct {
23       const char *path;
24       Eina_Bool expandable:1;
25       Eina_Bool folder_only:1;
26       Eina_Bool is_save:1;
27    } fsd;
28    Eina_Bool inwin_mode:1;
29 };
30
31 static const char DEFAULT_WINDOW_TITLE[] = "Select a file";
32
33 static const char *widtype = NULL;
34 static void _del_hook(Evas_Object *obj);
35 static void _theme_hook(Evas_Object *obj);
36 static void _disable_hook(Evas_Object *obj);
37 static void _sizing_eval(Evas_Object *obj);
38 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
39 static void _sub_del(void *data, Evas_Object *obj, void *event_info);
40 static void _signal_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
41 static void _signal_pressed(void *data, Evas_Object *obj, const char *emission, const char *source);
42 static void _signal_unpressed(void *data, Evas_Object *obj, const char *emission, const char *source);
43 static void _on_focus_hook(void *data, Evas_Object *obj);
44 static void _selection_done(void *data, Evas_Object *obj, void *event_info);
45
46 static const char SIG_CLICKED[] = "clicked";
47 static const char SIG_UNPRESSED[] = "unpressed";
48 static const char SIG_FILE_CHOSEN[] = "file,chosen";
49 static const Evas_Smart_Cb_Description _signals[] = 
50 {
51    {SIG_CLICKED, ""},
52    {SIG_UNPRESSED, ""},
53    {SIG_FILE_CHOSEN, "s"},
54    {NULL, NULL}
55 };
56
57 static void
58 _del_hook(Evas_Object *obj)
59 {
60    Evas_Object *win;
61    Widget_Data *wd;
62
63    wd = elm_widget_data_get(obj);
64    if (!wd) return;
65
66    if (wd->btn_label) eina_stringshare_del(wd->btn_label);
67    if (wd->window_title) eina_stringshare_del(wd->window_title);
68    if (wd->fsd.path) eina_stringshare_del(wd->fsd.path);
69    if (wd->fs)
70      {
71         win = evas_object_data_del(obj, "win");
72         evas_object_del(win);
73      }
74    free(wd);
75 }
76
77 static void
78 _on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
79 {
80    Widget_Data *wd = elm_widget_data_get(obj);
81    if (!wd) return;
82    if (elm_widget_focus_get(obj))
83      {
84         edje_object_signal_emit(wd->btn, "elm,action,focus", "elm");
85         evas_object_focus_set(wd->btn, 1);
86      }
87    else
88      {
89         edje_object_signal_emit(wd->btn, "elm,action,unfocus", "elm");
90         evas_object_focus_set(wd->btn, 0);
91      }
92 }
93
94 static void
95 _theme_hook(Evas_Object *obj)
96 {
97    Widget_Data *wd = elm_widget_data_get(obj);
98    if (!wd) return;
99    _elm_theme_object_set(obj, wd->btn, "button", "base", elm_widget_style_get(obj));
100    if (wd->icon)
101      edje_object_part_swallow(wd->btn, "elm.swallow.content", wd->icon);
102    if (wd->btn_label)
103      edje_object_signal_emit(wd->btn, "elm,state,text,visible", "elm");
104    else
105      edje_object_signal_emit(wd->btn, "elm,state,text,hidden", "elm");
106    if (wd->icon)
107      edje_object_signal_emit(wd->btn, "elm,state,icon,visible", "elm");
108    else
109      edje_object_signal_emit(wd->btn, "elm,state,icon,hidden", "elm");
110    edje_object_part_text_set(wd->btn, "elm.text", wd->btn_label);
111    edje_object_message_signal_process(wd->btn);
112    edje_object_scale_set(wd->btn, 
113                          elm_widget_scale_get(obj) * _elm_config->scale);
114    _sizing_eval(obj);
115 }
116
117 static void
118 _disable_hook(Evas_Object *obj)
119 {
120    Widget_Data *wd = elm_widget_data_get(obj);
121    if (!wd) return;
122    if (elm_widget_disabled_get(obj))
123      edje_object_signal_emit(wd->btn, "elm,state,disabled", "elm");
124    else
125      edje_object_signal_emit(wd->btn, "elm,state,enabled", "elm");
126 }
127
128 static void
129 _sizing_eval(Evas_Object *obj)
130 {
131    Widget_Data *wd = elm_widget_data_get(obj);
132    Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
133
134    if (!wd) return;
135    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
136    edje_object_size_min_restricted_calc(wd->btn, &minw, &minh, minw, minh);
137    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
138    evas_object_size_hint_min_set(obj, minw, minh);
139    evas_object_size_hint_max_set(obj, maxw, maxh);
140 }
141
142 static void
143 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
144 {
145    Widget_Data *wd = elm_widget_data_get(data);
146    if (!wd) return;
147    if (obj != wd->icon) return;
148    _sizing_eval(data);
149 }
150
151 static void
152 _sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
153 {
154    Widget_Data *wd = elm_widget_data_get(obj);
155    Evas_Object *sub = event_info;
156    if (!wd) return;
157    if (sub == wd->icon)
158      {
159         edje_object_signal_emit(wd->btn, "elm,state,icon,hidden", "elm");
160         evas_object_event_callback_del_full(sub,
161                                             EVAS_CALLBACK_CHANGED_SIZE_HINTS,
162                                             _changed_size_hints, obj);
163         wd->icon = NULL;
164         edje_object_message_signal_process(wd->btn);
165         _sizing_eval(obj);
166      }
167 }
168
169 static void
170 _signal_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
171 {
172    Widget_Data *wd = elm_widget_data_get(data);
173    if (!wd) return;
174
175    evas_object_smart_callback_call(data, SIG_CLICKED, NULL);
176
177    /* safe guard when the theme does not emit the 'unpress' signal */
178    _signal_unpressed(data, obj, emission, source);
179 }
180
181 static Evas_Object *
182 _parent_win_get(Evas_Object *obj)
183 {
184    Evas_Object *ret;
185
186    ret = elm_object_parent_widget_get(obj);
187    if (!ret) return NULL;
188
189    if (strcmp(elm_widget_type_get(ret), "win") != 0)
190      {
191         DBG("Widget type (%s) is not \"win\", going up\n",
192             elm_widget_type_get(ret));
193         return _parent_win_get(ret);
194      }
195
196    return ret;
197 }
198
199 static Evas_Object *
200 _new_window_add(Widget_Data *wd)
201 {
202    Evas_Object *win, *bg;
203
204    win = elm_win_add(NULL, "fileselector_button", ELM_WIN_DIALOG_BASIC);
205    elm_win_title_set(win, wd->window_title);
206    elm_win_autodel_set(win, EINA_TRUE);
207
208    bg = elm_bg_add(win);
209    elm_win_resize_object_add(win, bg);
210    evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
211    evas_object_show(bg);
212
213    evas_object_resize(win, wd->w, wd->h);
214    return win;
215 }
216
217 static void
218 _fs_launch(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
219 {
220    Evas_Object *fs_btn, *win = NULL, *iw = NULL;
221    Eina_Bool win_fallback;
222    Widget_Data *wd;
223
224    fs_btn = data;
225    wd = elm_widget_data_get(fs_btn);
226
227    if (!wd) return;
228    if (wd->fs) return;
229
230    win_fallback = EINA_FALSE;
231    if (wd->inwin_mode)
232      {
233         win = _parent_win_get(fs_btn);
234
235         if (!win)
236           {
237              ERR("No elementary window found as parent of the file selector "
238                  "button! Launching the file selector inside a new elementary"
239                  " window, then.");
240              win_fallback = EINA_TRUE;
241           }
242         else
243           {
244              iw = elm_win_inwin_add(win);
245              evas_object_data_set(fs_btn, "win", iw);
246           }
247      }
248
249    if ((!wd->inwin_mode) || (win_fallback))
250      {
251         win = _new_window_add(wd);
252         evas_object_data_set(fs_btn, "win", win);
253      }
254
255    wd->fs = elm_fileselector_add(win);
256    elm_fileselector_expandable_set(wd->fs, wd->fsd.expandable);
257    elm_fileselector_folder_only_set(wd->fs, wd->fsd.folder_only);
258    elm_fileselector_is_save_set(wd->fs, wd->fsd.is_save);
259    elm_fileselector_selected_set(wd->fs, wd->fsd.path);
260    evas_object_size_hint_weight_set(wd->fs, EVAS_HINT_EXPAND,
261                                     EVAS_HINT_EXPAND);
262    evas_object_size_hint_align_set(wd->fs, EVAS_HINT_FILL, EVAS_HINT_FILL);
263    evas_object_smart_callback_add(wd->fs, "done", _selection_done, fs_btn);
264    evas_object_show(wd->fs);
265
266    if ((wd->inwin_mode) && (!win_fallback))
267      {
268         elm_win_inwin_content_set(iw, wd->fs);
269         elm_win_inwin_activate(iw);
270      }
271    else
272      {
273         elm_win_resize_object_add(win, wd->fs);
274         evas_object_show(win);
275      }
276 }
277
278 static void
279 _selection_done(void *data, Evas_Object *obj __UNUSED__, void *event_info)
280 {
281    Evas_Object *fs_btn, *win;
282    const char *file;
283    Widget_Data *wd;
284
285    file = event_info;
286    fs_btn = data;
287
288    wd = elm_widget_data_get(fs_btn);
289    if (!wd) return;
290
291    win = evas_object_data_del(fs_btn, "win");
292
293    evas_object_smart_callback_call(fs_btn, SIG_FILE_CHOSEN, event_info);
294    if (file) eina_stringshare_replace(&wd->fsd.path, file);
295
296    wd->fs = NULL;
297    evas_object_del(win);
298 }
299
300 static void
301 _signal_pressed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
302 {
303    Widget_Data *wd = elm_widget_data_get(data);
304    if (!wd) return;
305 }
306
307 static void
308 _signal_unpressed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
309 {
310    Widget_Data *wd = elm_widget_data_get(data);
311    if (!wd) return;
312    evas_object_smart_callback_call(data, SIG_UNPRESSED, NULL);
313 }
314
315 /**
316  * Add a new file selector button into the parent object.
317  *
318  * @param parent The parent object
319  * @return The new object or NULL if it cannot be created
320  *
321  * @ingroup File_Selector_Button
322  */
323 EAPI Evas_Object *
324 elm_fileselector_button_add(Evas_Object *parent)
325 {
326    Evas_Object *obj;
327    Evas *e;
328    Widget_Data *wd;
329
330    wd = ELM_NEW(Widget_Data);
331    wd->window_title = eina_stringshare_add(DEFAULT_WINDOW_TITLE);
332    wd->fsd.path = eina_stringshare_add(getenv("HOME"));
333    wd->w = 400;
334    wd->h = 400;
335
336    e = evas_object_evas_get(parent);
337    obj = elm_widget_add(e);
338    ELM_SET_WIDTYPE(widtype, "fileselector_button");
339    elm_widget_type_set(obj, "fileselector_button");
340    elm_widget_sub_object_add(parent, obj);
341    elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
342    elm_widget_data_set(obj, wd);
343    elm_widget_del_hook_set(obj, _del_hook);
344    elm_widget_theme_hook_set(obj, _theme_hook);
345    elm_widget_disable_hook_set(obj, _disable_hook);
346    elm_widget_can_focus_set(obj, 1);
347
348    wd->btn = edje_object_add(e);
349    _elm_theme_object_set(obj, wd->btn, "button", "base", "default");
350    edje_object_signal_callback_add(wd->btn, "elm,action,click", "",
351                                    _signal_clicked, obj);
352    edje_object_signal_callback_add(wd->btn, "elm,action,click", "",
353                                    _fs_launch, obj);
354    edje_object_signal_callback_add(wd->btn, "elm,action,press", "",
355                                    _signal_pressed, obj);
356    edje_object_signal_callback_add(wd->btn, "elm,action,unpress", "",
357                                    _signal_unpressed, obj);
358    elm_widget_resize_object_set(obj, wd->btn);
359
360    evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
361
362    _sizing_eval(obj);
363
364    // TODO: convert Elementary to subclassing of Evas_Smart_Class
365    // TODO: and save some bytes, making descriptions per-class and not instance!
366    evas_object_smart_callbacks_descriptions_set(obj, _signals);
367    return obj;
368 }
369
370 /**
371  * Set the label used in the file selector button.
372  *
373  * @param obj The button object
374  * @param label The text label text to be displayed on the button
375  *
376  * @ingroup File_Selector_Button
377  */
378 EAPI void
379 elm_fileselector_button_label_set(Evas_Object *obj, const char *label)
380 {
381    ELM_CHECK_WIDTYPE(obj, widtype);
382    Widget_Data *wd = elm_widget_data_get(obj);
383    if (!wd) return;
384    eina_stringshare_replace(&wd->btn_label, label);
385    if (label)
386      edje_object_signal_emit(wd->btn, "elm,state,text,visible", "elm");
387    else
388      edje_object_signal_emit(wd->btn, "elm,state,text,hidden", "elm");
389    edje_object_message_signal_process(wd->btn);
390    edje_object_part_text_set(wd->btn, "elm.text", label);
391    _sizing_eval(obj);
392 }
393
394 EAPI const char *
395 elm_fileselector_button_label_get(const Evas_Object *obj)
396 {
397    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
398    Widget_Data *wd = elm_widget_data_get(obj);
399    if (!wd) return NULL;
400    return wd->btn_label;
401 }
402
403 /**
404  * Set the path to start the button's file selector with, when clicked.
405  *
406  * @param obj The button object
407  * @param path Path to a file/directory
408  *
409  * Default path is "HOME" environment variable's value.
410  *
411  * @ingroup File_Selector_Button
412  */
413 EAPI void
414 elm_fileselector_button_selected_set(Evas_Object *obj, const char *path)
415 {
416    ELM_CHECK_WIDTYPE(obj, widtype);
417    Widget_Data *wd = elm_widget_data_get(obj);
418    if (!wd) return;
419    eina_stringshare_replace(&wd->fsd.path, path);
420 }
421
422 /**
423  * Get the <b>last</b> path which the button's file selector was set to.
424  *
425  * @param obj The button object
426  * @param path Path to a file/directory
427  *
428  * Default path is "HOME" environment variable's value.
429  *
430  * @ingroup File_Selector_Button
431  */
432 EAPI const char *
433 elm_fileselector_button_selected_get(const Evas_Object *obj)
434 {
435    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
436    Widget_Data *wd = elm_widget_data_get(obj);
437    if (!wd) return NULL;
438    return wd->fsd.path;
439 }
440
441 /**
442  * Set the title of the file selector button's window.
443  *
444  * @param obj The button object
445  * @param title The title string
446  *
447  * Note that it will only take any effect if the fileselector button
448  * not at "inwin mode".
449  *
450  * @ingroup File_Selector_Button
451  */
452 EAPI void
453 elm_fileselector_button_window_title_set(Evas_Object *obj, const char *title)
454 {
455    ELM_CHECK_WIDTYPE(obj, widtype);
456    Widget_Data *wd = elm_widget_data_get(obj);
457    if (!wd) return;
458    eina_stringshare_replace(&wd->window_title, title);
459 }
460
461 /**
462  * Get the title of the file selector button's window.
463  *
464  * @param obj The button object
465  *
466  * @ingroup File_Selector_Button
467  */
468 EAPI const char *
469 elm_fileselector_button_window_title_get(const Evas_Object *obj)
470 {
471    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
472    Widget_Data *wd = elm_widget_data_get(obj);
473    if (!wd) return NULL;
474    return wd->window_title;
475 }
476
477 /**
478  * Set the size of the file selector button's window.
479  *
480  * @param obj The button object
481  * @param width The width
482  * @param height The height
483  *
484  * Note that it will only take any effect if the fileselector button not at
485  * "inwin mode". Default size for the window (when applicable) is 400x400.
486  *
487  * @ingroup File_Selector_Button
488  */
489 EAPI void
490 elm_fileselector_button_window_size_set(Evas_Object *obj, Evas_Coord width, Evas_Coord height)
491 {
492    ELM_CHECK_WIDTYPE(obj, widtype);
493    Widget_Data *wd = elm_widget_data_get(obj);
494    if (!wd) return;
495    wd->w = width;
496    wd->h = height;
497 }
498
499 /**
500  * Get the size of the file selector button's window.
501  *
502  * @param obj The button object
503  * @param width Pointer into which to store the width value
504  * @param height Pointer into which to store the height value
505  *
506  * @ingroup File_Selector_Button
507  */
508 EAPI void
509 elm_fileselector_button_window_size_get(const Evas_Object *obj, Evas_Coord *width, Evas_Coord *height)
510 {
511    ELM_CHECK_WIDTYPE(obj, widtype);
512    Widget_Data *wd = elm_widget_data_get(obj);
513    if (!wd) return;
514    if (width) *width = wd->w;
515    if (height) *height = wd->h;
516 }
517
518 /**
519  * Set the starting path of the file selector button's window.
520  *
521  * @param obj The button object
522  * @param path The path string
523  *
524  * It must be a <b>directory</b> path.
525  *
526  * @ingroup File_Selector_Button
527  */
528 EAPI void
529 elm_fileselector_button_path_set(Evas_Object *obj, const char *path)
530 {
531    ELM_CHECK_WIDTYPE(obj, widtype);
532    Widget_Data *wd = elm_widget_data_get(obj);
533    if (!wd) return;
534    eina_stringshare_replace(&wd->fsd.path, path);
535 }
536
537 /**
538  * Get the <b>last</b> path of the file selector button's window.
539  *
540  * @param obj The button object
541  *
542  * @ingroup File_Selector_Button
543  */
544 EAPI const char *
545 elm_fileselector_button_path_get(const Evas_Object *obj)
546 {
547    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
548    Widget_Data *wd = elm_widget_data_get(obj);
549    if (!wd) return NULL;
550    return wd->fsd.path;
551 }
552
553 /**
554  * Set whether the button's file selector is to present itself as an
555  * Elementary Generic List (which will expand its entries for nested
556  * directories) or as canonical list, which will be rendered again
557  * with the contents of each selected directory.
558  *
559  * @param obj The button object
560  * @param value The expandable flag
561  *
562  * @ingroup File_Selector_Button
563  */
564 EAPI void
565 elm_fileselector_button_expandable_set(Evas_Object *obj, Eina_Bool value)
566 {
567    ELM_CHECK_WIDTYPE(obj, widtype);
568    Widget_Data *wd = elm_widget_data_get(obj);
569    if (!wd) return;
570    wd->fsd.expandable = value;
571 }
572
573 /**
574  * Get the button's file selector expandable flag.
575  *
576  * @param obj The button object
577  * @return value The expandable flag
578  *
579  * @ingroup File_Selector_Button
580  */
581 EAPI Eina_Bool
582 elm_fileselector_button_expandable_get(const Evas_Object *obj)
583 {
584    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
585    Widget_Data *wd = elm_widget_data_get(obj);
586    if (!wd) return EINA_FALSE;
587    return wd->fsd.expandable;
588 }
589
590 /**
591  * Set whether the button's file selector list is to display folders
592  * only or the directory contents, as well.
593  *
594  * @param obj The button object
595  * @param value The "folder only" flag
596  *
597  * @ingroup File_Selector_Button
598  */
599 EAPI void
600 elm_fileselector_button_folder_only_set(Evas_Object *obj, Eina_Bool value)
601 {
602    ELM_CHECK_WIDTYPE(obj, widtype);
603    Widget_Data *wd = elm_widget_data_get(obj);
604    if (!wd) return;
605    wd->fsd.folder_only = value;
606 }
607
608 /**
609  * Get the button's file selector "folder only" flag.
610  *
611  * @param obj The button object
612  * @return value The "folder only" flag
613  *
614  * @ingroup File_Selector_Button
615  */
616 EAPI Eina_Bool
617 elm_fileselector_button_folder_only_get(const Evas_Object *obj)
618 {
619    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
620    Widget_Data *wd = elm_widget_data_get(obj);
621    if (!wd) return EINA_FALSE;
622    return wd->fsd.folder_only;
623 }
624
625 /**
626  * Set whether the button's file selector has an editable text entry
627  * which will hold its current selection.
628  *
629  * @param obj The button object
630  * @param value The "is save" flag
631  *
632  * @ingroup File_Selector_Button
633  */
634 EAPI void
635 elm_fileselector_button_is_save_set(Evas_Object *obj, Eina_Bool value)
636 {
637    ELM_CHECK_WIDTYPE(obj, widtype);
638    Widget_Data *wd = elm_widget_data_get(obj);
639    if (!wd) return;
640    wd->fsd.is_save = value;
641 }
642
643 /**
644  * Get the button's file selector "is save" flag.
645  *
646  * @param obj The button object
647  * @return value The "is save" flag
648  *
649  * @ingroup File_Selector_Button
650  */
651 EAPI Eina_Bool
652 elm_fileselector_button_is_save_get(const Evas_Object *obj)
653 {
654    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
655    Widget_Data *wd = elm_widget_data_get(obj);
656    if (!wd) return EINA_FALSE;
657    return wd->fsd.is_save;
658 }
659
660 /**
661  * Set whether the button's file selector will raise an Elementary
662  * Inner Window, instead of a dedicated Elementary Window. By default,
663  * it won't.
664  *
665  * @param obj The button object
666  * @param value The "inwin mode" flag
667  *
668  * @ingroup File_Selector_Button
669  */
670 EAPI void
671 elm_fileselector_button_inwin_mode_set(Evas_Object *obj, Eina_Bool value)
672 {
673    ELM_CHECK_WIDTYPE(obj, widtype);
674    Widget_Data *wd = elm_widget_data_get(obj);
675    if (!wd) return;
676    wd->inwin_mode = value;
677 }
678
679 /**
680  * Get the button's file selector "inwin mode" flag.
681  *
682  * @param obj The button object
683  * @return value The "inwin mode" flag
684  *
685  * @ingroup File_Selector_Button
686  */
687 EAPI Eina_Bool
688 elm_fileselector_button_inwin_mode_get(const Evas_Object *obj)
689 {
690    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
691    Widget_Data *wd = elm_widget_data_get(obj);
692    if (!wd) return EINA_FALSE;
693    return wd->inwin_mode;
694 }
695
696 /**
697  * Set the icon used for the button
698  *
699  * Once the icon object is set, a previously set one will be deleted.
700  *
701  * @param obj The button object
702  * @param icon  The image for the button
703  *
704  * @ingroup File_Selector_Button
705  */
706 EAPI void
707 elm_fileselector_button_icon_set(Evas_Object *obj, Evas_Object *icon)
708 {
709    ELM_CHECK_WIDTYPE(obj, widtype);
710    Widget_Data *wd = elm_widget_data_get(obj);
711    if (!wd) return;
712    if (wd->icon == icon) return;
713    if (wd->icon) evas_object_del(wd->icon);
714    wd->icon = icon;
715    if (icon)
716      {
717         elm_widget_sub_object_add(obj, icon);
718         evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
719                                        _changed_size_hints, obj);
720         edje_object_part_swallow(wd->btn, "elm.swallow.content", icon);
721         edje_object_signal_emit(wd->btn, "elm,state,icon,visible", "elm");
722         edje_object_message_signal_process(wd->btn);
723      }
724    _sizing_eval(obj);
725 }
726
727 /**
728  * Get the icon used for the button
729  *
730  * @param obj The button object
731  * @return The image for the button
732  *
733  * @ingroup File_Selector_Button
734  */
735 EAPI Evas_Object *
736 elm_fileselector_button_icon_get(const Evas_Object *obj)
737 {
738    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
739    Widget_Data *wd = elm_widget_data_get(obj);
740    if (!wd) return NULL;
741    return wd->icon;
742 }