[fileselector, hoversel] remove documentation
[framework/uifw/elementary.git] / src / lib / elc_fileselector_button.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 typedef struct _Widget_Data Widget_Data;
5
6 struct _Widget_Data
7 {
8    Evas_Object *self, *btn, *fs, *fsw;
9    const char  *window_title;
10    Evas_Coord   w, h;
11    struct
12    {
13       const char *path;
14       Eina_Bool   expandable : 1;
15       Eina_Bool   folder_only : 1;
16       Eina_Bool   is_save : 1;
17    } fsd;
18    Eina_Bool inwin_mode : 1;
19 };
20
21 #define DEFAULT_WINDOW_TITLE "Select a file"
22
23 static const char *widtype = NULL;
24
25 static void _del_hook(Evas_Object *obj);
26 static void _theme_hook(Evas_Object *obj);
27 static void _disable_hook(Evas_Object *obj);
28 static void _sizing_eval(Evas_Object *obj);
29 static void _changed_size_hints(void        *data,
30                                 Evas        *e,
31                                 Evas_Object *obj,
32                                 void        *event_info);
33 static void _on_focus_hook(void        *data,
34                            Evas_Object *obj);
35 static void _selection_done(void        *data,
36                             Evas_Object *obj,
37                             void        *event_info);
38 static void _activate(Widget_Data *wd);
39
40 static const char SIG_FILE_CHOSEN[] = "file,chosen";
41 static const Evas_Smart_Cb_Description _signals[] = {
42        {SIG_FILE_CHOSEN, "s"},
43        {NULL, NULL}
44 };
45
46 static void
47 _del_hook(Evas_Object *obj)
48 {
49    Evas_Object *win;
50    Widget_Data *wd;
51
52    wd = elm_widget_data_get(obj);
53    if (!wd) return;
54
55    if (wd->window_title) eina_stringshare_del(wd->window_title);
56    if (wd->fsd.path) eina_stringshare_del(wd->fsd.path);
57    if (wd->fs)
58      {
59         win = evas_object_data_del(obj, "win");
60         evas_object_del(win);
61      }
62    free(wd);
63 }
64
65 static void
66 _on_focus_hook(void *data   __UNUSED__,
67                Evas_Object *obj)
68 {
69    Widget_Data *wd = elm_widget_data_get(obj);
70    if (!wd) return;
71    if (elm_widget_focus_get(obj))
72      elm_widget_focus_steal(wd->btn);
73 }
74
75 static void
76 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
77 {
78    Widget_Data *wd = elm_widget_data_get(obj);
79    if (!wd) return;
80    elm_widget_mirrored_set(wd->btn, rtl);
81    elm_widget_mirrored_set(wd->fs, rtl);
82 }
83
84 static void
85 _theme_hook(Evas_Object *obj)
86 {
87    Widget_Data *wd = elm_widget_data_get(obj);
88    char buf[4096];
89    if (!wd) return;
90    _elm_widget_mirrored_reload(obj);
91    _mirrored_set(obj, elm_widget_mirrored_get(obj));
92
93    snprintf(buf, sizeof(buf), "fileselector_button/%s",
94             elm_widget_style_get(obj));
95    elm_object_style_set(wd->btn, buf);
96    _sizing_eval(obj);
97 }
98
99 static void
100 _disable_hook(Evas_Object *obj)
101 {
102    Widget_Data *wd = elm_widget_data_get(obj);
103    if (!wd) return;
104    elm_widget_disabled_set(wd->btn, elm_widget_disabled_get(obj));
105 }
106
107 static void
108 _sizing_eval(Evas_Object *obj)
109 {
110    Widget_Data *wd = elm_widget_data_get(obj);
111    Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
112    if (!wd) return;
113    evas_object_size_hint_min_get(wd->btn, &minw, &minh);
114    evas_object_size_hint_max_get(wd->btn, &maxw, &maxh);
115    evas_object_size_hint_min_set(obj, minw, minh);
116    evas_object_size_hint_max_set(obj, maxw, maxh);
117 }
118
119 static void
120 _changed_size_hints(void            *data,
121                     Evas *e          __UNUSED__,
122                     Evas_Object *obj __UNUSED__,
123                     void *event_info __UNUSED__)
124 {
125    Widget_Data *wd = elm_widget_data_get(data);
126    if (!wd) return;
127    _sizing_eval(data);
128 }
129
130 static void
131 _activate_hook(Evas_Object *obj)
132 {
133    Widget_Data *wd;
134    wd = elm_widget_data_get(obj);
135    if (!wd) return;
136    _activate(wd);
137 }
138
139 static void
140 _button_clicked(void            *data,
141                 Evas_Object *obj __UNUSED__,
142                 void *event_info __UNUSED__)
143 {
144    _activate(data);
145 }
146
147 static Evas_Object *
148 _parent_win_get(Evas_Object *obj)
149 {
150    while ((obj) && (strcmp(elm_widget_type_get(obj), "win")))
151      obj = elm_object_parent_widget_get(obj);
152
153    return obj;
154 }
155
156 static Evas_Object *
157 _new_window_add(Widget_Data *wd)
158 {
159    Evas_Object *win, *bg;
160
161    win = elm_win_add(NULL, "fileselector_button", ELM_WIN_DIALOG_BASIC);
162    elm_win_title_set(win, wd->window_title);
163    elm_win_autodel_set(win, EINA_TRUE);
164
165    bg = elm_bg_add(win);
166    elm_win_resize_object_add(win, bg);
167    evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
168    evas_object_show(bg);
169
170    evas_object_resize(win, wd->w, wd->h);
171    return win;
172 }
173
174 static void
175 _activate(Widget_Data *wd)
176 {
177    Eina_Bool is_inwin = EINA_FALSE;
178
179    if (wd->fs) return;
180
181    if (wd->inwin_mode)
182      {
183         wd->fsw = _parent_win_get(wd->self);
184
185         if (!wd->fsw)
186           wd->fsw = _new_window_add(wd);
187         else
188           {
189              wd->fsw = elm_win_inwin_add(wd->fsw);
190              is_inwin = EINA_TRUE;
191           }
192      }
193    else
194      wd->fsw = _new_window_add(wd);
195
196    wd->fs = elm_fileselector_add(wd->fsw);
197    elm_widget_mirrored_set(wd->fs, elm_widget_mirrored_get(wd->self));
198    elm_widget_mirrored_automatic_set(wd->fs, EINA_FALSE);
199    elm_fileselector_expandable_set(wd->fs, wd->fsd.expandable);
200    elm_fileselector_folder_only_set(wd->fs, wd->fsd.folder_only);
201    elm_fileselector_is_save_set(wd->fs, wd->fsd.is_save);
202    elm_fileselector_selected_set(wd->fs, wd->fsd.path);
203    evas_object_size_hint_weight_set(wd->fs, EVAS_HINT_EXPAND,
204                                     EVAS_HINT_EXPAND);
205    evas_object_size_hint_align_set(wd->fs, EVAS_HINT_FILL, EVAS_HINT_FILL);
206    evas_object_smart_callback_add(wd->fs, "done", _selection_done, wd);
207    evas_object_show(wd->fs);
208
209    if (is_inwin)
210      {
211         elm_win_inwin_content_set(wd->fsw, wd->fs);
212         elm_win_inwin_activate(wd->fsw);
213      }
214    else
215      {
216         elm_win_resize_object_add(wd->fsw, wd->fs);
217         evas_object_show(wd->fsw);
218      }
219 }
220
221 static void
222 _selection_done(void            *data,
223                 Evas_Object *obj __UNUSED__,
224                 void            *event_info)
225 {
226    const char *file = event_info;
227    Widget_Data *wd = data;
228    Evas_Object *del;
229    if (!wd) return;
230
231    if (file) eina_stringshare_replace(&wd->fsd.path, file);
232
233    del = wd->fsw;
234    wd->fs = NULL;
235    wd->fsw = NULL;
236    evas_object_del(del);
237
238    evas_object_smart_callback_call(wd->self, SIG_FILE_CHOSEN,
239                                    (void *)wd->fsd.path);
240 }
241
242 static void
243 _elm_fileselector_button_label_set(Evas_Object *obj, const char *item,
244                                   const char  *label)
245 {
246    ELM_CHECK_WIDTYPE(obj, widtype);
247    if (item && strcmp(item, "default")) return;
248    Widget_Data *wd = elm_widget_data_get(obj);
249    if (!wd) return;
250    elm_object_text_set(wd->btn, label);
251 }
252
253 static const char *
254 _elm_fileselector_button_label_get(const Evas_Object *obj, const char *item)
255 {
256    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
257    Widget_Data *wd = elm_widget_data_get(obj);
258    if (item && strcmp(item, "default")) return NULL;
259    if (!wd) return NULL;
260    return elm_object_text_get(wd->btn);
261 }
262
263 EAPI Evas_Object *
264 elm_fileselector_button_add(Evas_Object *parent)
265 {
266    Evas_Object *obj;
267    Evas *e;
268    Widget_Data *wd;
269
270    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
271
272    ELM_SET_WIDTYPE(widtype, "fileselector_button");
273    elm_widget_type_set(obj, "fileselector_button");
274    elm_widget_sub_object_add(parent, obj);
275    elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
276    elm_widget_data_set(obj, wd);
277    elm_widget_del_hook_set(obj, _del_hook);
278    elm_widget_theme_hook_set(obj, _theme_hook);
279    elm_widget_disable_hook_set(obj, _disable_hook);
280    elm_widget_can_focus_set(obj, EINA_TRUE);
281    elm_widget_activate_hook_set(obj, _activate_hook);
282    elm_widget_text_set_hook_set(obj, _elm_fileselector_button_label_set);
283    elm_widget_text_get_hook_set(obj, _elm_fileselector_button_label_get);
284
285    wd->self = obj;
286    wd->window_title = eina_stringshare_add(DEFAULT_WINDOW_TITLE);
287    if (getenv("HOME")) wd->fsd.path = eina_stringshare_add(getenv("HOME"));
288    else wd->fsd.path = eina_stringshare_add("/");
289    wd->fsd.expandable = _elm_config->fileselector_expand_enable;
290    wd->inwin_mode = _elm_config->inwin_dialogs_enable;
291    wd->w = 400;
292    wd->h = 400;
293
294    wd->btn = elm_button_add(parent);
295    elm_widget_mirrored_automatic_set(wd->btn, EINA_FALSE);
296    elm_widget_resize_object_set(obj, wd->btn);
297    evas_object_event_callback_add(wd->btn, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
298                                   _changed_size_hints, obj);
299    evas_object_smart_callback_add(wd->btn, "clicked", _button_clicked, wd);
300    elm_widget_sub_object_add(obj, wd->btn);
301
302    _theme_hook(obj);
303    evas_object_smart_callbacks_descriptions_set(obj, _signals);
304    return obj;
305 }
306
307 EAPI void
308 elm_fileselector_button_label_set(Evas_Object *obj,
309                                   const char  *label)
310 {
311    _elm_fileselector_button_label_set(obj, NULL, label);
312 }
313
314 EAPI const char *
315 elm_fileselector_button_label_get(const Evas_Object *obj)
316 {
317    return _elm_fileselector_button_label_get(obj, NULL);
318 }
319
320 EAPI void
321 elm_fileselector_button_window_title_set(Evas_Object *obj,
322                                          const char  *title)
323 {
324    ELM_CHECK_WIDTYPE(obj, widtype);
325    Widget_Data *wd = elm_widget_data_get(obj);
326
327    if (!wd) return;
328    eina_stringshare_replace(&wd->window_title, title);
329
330    if (wd->fsw)
331      elm_win_title_set(wd->fsw, wd->window_title);
332 }
333
334 EAPI const char *
335 elm_fileselector_button_window_title_get(const Evas_Object *obj)
336 {
337    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
338    Widget_Data *wd = elm_widget_data_get(obj);
339
340    if (!wd) return NULL;
341    return wd->window_title;
342 }
343
344 EAPI void
345 elm_fileselector_button_window_size_set(Evas_Object *obj,
346                                         Evas_Coord   width,
347                                         Evas_Coord   height)
348 {
349    ELM_CHECK_WIDTYPE(obj, widtype);
350    Widget_Data *wd = elm_widget_data_get(obj);
351
352    if (!wd) return;
353    wd->w = width;
354    wd->h = height;
355
356    if (wd->fsw)
357      evas_object_resize(wd->fsw, wd->w, wd->h);
358 }
359
360 EAPI void
361 elm_fileselector_button_window_size_get(const Evas_Object *obj,
362                                         Evas_Coord        *width,
363                                         Evas_Coord        *height)
364 {
365    ELM_CHECK_WIDTYPE(obj, widtype);
366    Widget_Data *wd = elm_widget_data_get(obj);
367
368    if (!wd) return;
369    if (width) *width = wd->w;
370    if (height) *height = wd->h;
371 }
372
373 EAPI void
374 elm_fileselector_button_path_set(Evas_Object *obj,
375                                  const char  *path)
376 {
377    ELM_CHECK_WIDTYPE(obj, widtype);
378    Widget_Data *wd = elm_widget_data_get(obj);
379
380    if (!wd) return;
381    eina_stringshare_replace(&wd->fsd.path, path);
382
383    if (wd->fs)
384      elm_fileselector_selected_set(wd->fs, wd->fsd.path);
385 }
386
387 EAPI const char *
388 elm_fileselector_button_path_get(const Evas_Object *obj)
389 {
390    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
391    Widget_Data *wd = elm_widget_data_get(obj);
392    if (!wd) return NULL;
393    return wd->fsd.path;
394 }
395
396 EAPI void
397 elm_fileselector_button_expandable_set(Evas_Object *obj,
398                                        Eina_Bool    value)
399 {
400    ELM_CHECK_WIDTYPE(obj, widtype);
401    Widget_Data *wd = elm_widget_data_get(obj);
402
403    if (!wd) return;
404    wd->fsd.expandable = value;
405
406    if (wd->fs)
407      elm_fileselector_expandable_set(wd->fs, wd->fsd.expandable);
408 }
409
410 EAPI Eina_Bool
411 elm_fileselector_button_expandable_get(const Evas_Object *obj)
412 {
413    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
414    Widget_Data *wd = elm_widget_data_get(obj);
415
416    if (!wd) return EINA_FALSE;
417    return wd->fsd.expandable;
418 }
419
420 EAPI void
421 elm_fileselector_button_folder_only_set(Evas_Object *obj,
422                                         Eina_Bool    value)
423 {
424    ELM_CHECK_WIDTYPE(obj, widtype);
425    Widget_Data *wd = elm_widget_data_get(obj);
426
427    if (!wd) return;
428    wd->fsd.folder_only = value;
429
430    if (wd->fs)
431      elm_fileselector_folder_only_set(wd->fs, wd->fsd.folder_only);
432 }
433
434 EAPI Eina_Bool
435 elm_fileselector_button_folder_only_get(const Evas_Object *obj)
436 {
437    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
438    Widget_Data *wd = elm_widget_data_get(obj);
439
440    if (!wd) return EINA_FALSE;
441    return wd->fsd.folder_only;
442 }
443
444 EAPI void
445 elm_fileselector_button_is_save_set(Evas_Object *obj,
446                                     Eina_Bool    value)
447 {
448    ELM_CHECK_WIDTYPE(obj, widtype);
449    Widget_Data *wd = elm_widget_data_get(obj);
450
451    if (!wd) return;
452    wd->fsd.is_save = value;
453
454    if (wd->fs)
455      elm_fileselector_is_save_set(wd->fs, wd->fsd.is_save);
456 }
457
458 EAPI Eina_Bool
459 elm_fileselector_button_is_save_get(const Evas_Object *obj)
460 {
461    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
462    Widget_Data *wd = elm_widget_data_get(obj);
463
464    if (!wd) return EINA_FALSE;
465    return wd->fsd.is_save;
466 }
467
468 EAPI void
469 elm_fileselector_button_inwin_mode_set(Evas_Object *obj,
470                                        Eina_Bool    value)
471 {
472    ELM_CHECK_WIDTYPE(obj, widtype);
473    Widget_Data *wd = elm_widget_data_get(obj);
474
475    if (!wd) return;
476    wd->inwin_mode = value;
477 }
478
479 EAPI Eina_Bool
480 elm_fileselector_button_inwin_mode_get(const Evas_Object *obj)
481 {
482    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
483    Widget_Data *wd = elm_widget_data_get(obj);
484
485    if (!wd) return EINA_FALSE;
486    return wd->inwin_mode;
487 }
488
489 EAPI void
490 elm_fileselector_button_icon_set(Evas_Object *obj,
491                                  Evas_Object *icon)
492 {
493    ELM_CHECK_WIDTYPE(obj, widtype);
494    Widget_Data *wd = elm_widget_data_get(obj);
495    if (!wd)
496      {
497         evas_object_del(icon);
498         return;
499      }
500    elm_button_icon_set(wd->btn, icon);
501 }
502
503 EAPI Evas_Object *
504 elm_fileselector_button_icon_get(const Evas_Object *obj)
505 {
506    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
507    Widget_Data *wd = elm_widget_data_get(obj);
508    if (!wd) return NULL;
509    return elm_button_icon_get(wd->btn);
510 }
511
512 EAPI Evas_Object *
513 elm_fileselector_button_icon_unset(Evas_Object *obj)
514 {
515    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
516    Widget_Data *wd = elm_widget_data_get(obj);
517    if (!wd) return NULL;
518    return elm_button_icon_unset(wd->btn);
519 }
520