elementary/notify - too much copy and pastes. fixed a logic error.
[framework/uifw/elementary.git] / src / lib / elm_notify.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 /**
5  * @defgroup Notify Notify
6  *
7  * Display a window in a particular region of the application (top,
8  * bottom, etc.  A timeout can be set to automatically close the
9  * window. This is so that, after an evas_object_show() on a notify
10  * object, if a timeout was set on it, it will <b>automatically</b>
11  * get hidden after that time.
12  *
13  * Signals that you can add callbacks for are:
14  *
15  * "timeout" - when timeout happens on notify and it's hidden
16  * "block,clicked" - when it's hidden by a click outside of the notify's view
17  */
18
19 typedef struct _Widget_Data Widget_Data;
20
21 struct _Widget_Data
22 {
23    Evas_Object *notify, *content, *parent;
24
25    Elm_Notify_Orient orient;
26    Eina_Bool repeat_events;
27    Evas_Object *block_events;
28
29    double timeout;
30    Ecore_Timer *timer;
31 };
32
33 static const char *widtype = NULL;
34 static void _del_hook(Evas_Object *obj);
35 static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
36 static void _theme_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_block_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
41 static void _calc(Evas_Object *obj);
42 static void _content_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
43 static void _show(void *data, Evas *e, Evas_Object *obj, void *event_info);
44 static void _hide(void *data, Evas *e, Evas_Object *obj, void *event_info);
45 static void _resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
46
47 static const char SIG_BLOCK_CLICKED[] = "block,clicked";
48 static const char SIG_TIMEOUT[] = "timeout";
49 static const Evas_Smart_Cb_Description _signals[] = {
50        {SIG_BLOCK_CLICKED, ""},
51        {SIG_TIMEOUT, ""},
52        {NULL, NULL}
53 };
54
55 static void
56 _del_pre_hook(Evas_Object *obj)
57 {
58    evas_object_event_callback_del_full(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
59    evas_object_event_callback_del_full(obj, EVAS_CALLBACK_MOVE, _resize, obj);
60    evas_object_event_callback_del_full(obj, EVAS_CALLBACK_SHOW, _show, obj);
61    evas_object_event_callback_del_full(obj, EVAS_CALLBACK_HIDE, _hide, obj);
62 }
63
64 static void
65 _del_hook(Evas_Object *obj)
66 {
67    Widget_Data *wd = elm_widget_data_get(obj);
68    if (!wd) return;
69    elm_notify_parent_set(obj, NULL);
70    elm_notify_repeat_events_set(obj, EINA_TRUE);
71    if (wd->timer)
72      {
73         ecore_timer_del(wd->timer);
74         wd->timer = NULL;
75      }
76    free(wd);
77 }
78
79 /**
80  * Return Notification orientation with RTL
81  *
82  * This function switches-sides of notification area when in RTL mode.
83  *
84  * @param obj notification object.
85  *
86  * @param orient Original notification orientation.
87  *
88  * @return notification orientation with respect to the object RTL mode.
89  *
90  * @internal
91  **/
92 static Elm_Notify_Orient
93 _notify_orientation_with_rtl(Evas_Object *obj, Elm_Notify_Orient orient)
94 {
95    if (elm_widget_mirrored_get(obj))
96      {
97         switch (orient)
98           {
99            case ELM_NOTIFY_ORIENT_LEFT:
100               orient = ELM_NOTIFY_ORIENT_RIGHT;
101               break;
102            case ELM_NOTIFY_ORIENT_RIGHT:
103               orient = ELM_NOTIFY_ORIENT_LEFT;
104               break;
105            case ELM_NOTIFY_ORIENT_TOP_LEFT:
106               orient = ELM_NOTIFY_ORIENT_TOP_RIGHT;
107               break;
108            case ELM_NOTIFY_ORIENT_TOP_RIGHT:
109               orient = ELM_NOTIFY_ORIENT_TOP_LEFT;
110               break;
111            case ELM_NOTIFY_ORIENT_BOTTOM_LEFT:
112               orient = ELM_NOTIFY_ORIENT_BOTTOM_RIGHT;
113               break;
114            case ELM_NOTIFY_ORIENT_BOTTOM_RIGHT:
115               orient = ELM_NOTIFY_ORIENT_BOTTOM_LEFT;
116               break;
117            default:
118               break;
119           }
120      }
121
122    return orient;
123 }
124
125 static void
126 _notify_theme_apply(Evas_Object *obj)
127 {
128    Widget_Data *wd = elm_widget_data_get(obj);
129    const char *style = elm_widget_style_get(obj);
130
131    switch (wd->orient)
132      {
133       case ELM_NOTIFY_ORIENT_TOP:
134          _elm_theme_object_set(obj, wd->notify, "notify", "top", style);
135          break;
136       case ELM_NOTIFY_ORIENT_CENTER:
137          _elm_theme_object_set(obj, wd->notify, "notify", "center", style);
138          break;
139       case ELM_NOTIFY_ORIENT_BOTTOM:
140          _elm_theme_object_set(obj, wd->notify, "notify", "bottom", style);
141          break;
142       case ELM_NOTIFY_ORIENT_LEFT:
143          _elm_theme_object_set(obj, wd->notify, "notify", "left", style);
144          break;
145       case ELM_NOTIFY_ORIENT_RIGHT:
146          _elm_theme_object_set(obj, wd->notify, "notify", "right", style);
147          break;
148       case ELM_NOTIFY_ORIENT_TOP_LEFT:
149          _elm_theme_object_set(obj, wd->notify, "notify", "top_left", style);
150          break;
151       case ELM_NOTIFY_ORIENT_TOP_RIGHT:
152          _elm_theme_object_set(obj, wd->notify, "notify", "top_right", style);
153          break;
154       case ELM_NOTIFY_ORIENT_BOTTOM_LEFT:
155          _elm_theme_object_set(obj, wd->notify, "notify", "bottom_left", style);
156          break;
157       case ELM_NOTIFY_ORIENT_BOTTOM_RIGHT:
158          _elm_theme_object_set(obj, wd->notify, "notify", "bottom_right", style);
159          break;
160       case ELM_NOTIFY_ORIENT_LAST:
161          break;
162      }
163 }
164
165 /**
166  * Moves notification to orientation.
167  *
168  * This fucntion moves notification to orientation
169  * according to object RTL orientation.
170  *
171  * @param obj notification object.
172  *
173  * @param orient notification orientation.
174  *
175  * @internal
176  **/
177 static void
178 _notify_move_to_orientation(Evas_Object *obj)
179 {
180    Widget_Data *wd = elm_widget_data_get(obj);
181    int offx;
182    int offy;
183    Evas_Coord minw = -1, minh = -1;
184    Evas_Coord x, y, w, h;
185
186    if (!wd) return;
187    evas_object_geometry_get(obj, &x, &y, &w, &h);
188    edje_object_size_min_get(wd->notify, &minw, &minh);
189    edje_object_size_min_restricted_calc(wd->notify, &minw, &minh, minw, minh);
190    offx = (w - minw) / 2;
191    offy = (h - minh) / 2;
192
193    switch (_notify_orientation_with_rtl(obj, wd->orient))
194      {
195       case ELM_NOTIFY_ORIENT_TOP:
196          evas_object_move(wd->notify, x + offx, y);
197          break;
198       case ELM_NOTIFY_ORIENT_CENTER:
199          evas_object_move(wd->notify, x + offx, y + offy);
200          break;
201       case ELM_NOTIFY_ORIENT_BOTTOM:
202          evas_object_move(wd->notify, x + offx, y + h - minh);
203          break;
204       case ELM_NOTIFY_ORIENT_LEFT:
205          evas_object_move(wd->notify, x, y + offy);
206          break;
207       case ELM_NOTIFY_ORIENT_RIGHT:
208          evas_object_move(wd->notify, x + w - minw, y + offy);
209          break;
210       case ELM_NOTIFY_ORIENT_TOP_LEFT:
211          evas_object_move(wd->notify, x, y);
212          break;
213       case ELM_NOTIFY_ORIENT_TOP_RIGHT:
214          evas_object_move(wd->notify, x + w - minw, y);
215          break;
216       case ELM_NOTIFY_ORIENT_BOTTOM_LEFT:
217          evas_object_move(wd->notify, x, y + h - minh);
218          break;
219       case ELM_NOTIFY_ORIENT_BOTTOM_RIGHT:
220          evas_object_move(wd->notify, x + w - minw, y + h - minh);
221          break;
222       case ELM_NOTIFY_ORIENT_LAST:
223          break;
224      }
225 }
226
227 static void
228 _block_events_theme_apply(Evas_Object *obj)
229 {
230    Widget_Data *wd = elm_widget_data_get(obj);
231    const char *style = elm_widget_style_get(obj);
232    _elm_theme_object_set(obj, wd->block_events, "notify", "block_events", style);
233 }
234
235 static void
236 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
237 {
238    Widget_Data *wd = elm_widget_data_get(obj);
239    if (!wd) return;
240    edje_object_mirrored_set(wd->notify, rtl);
241    _notify_move_to_orientation(obj);
242 }
243
244 static void
245 _theme_hook(Evas_Object *obj)
246 {
247    Widget_Data *wd = elm_widget_data_get(obj);
248    if (!wd) return;
249    _elm_widget_mirrored_reload(obj);
250    _mirrored_set(obj, elm_widget_mirrored_get(obj));
251    _notify_theme_apply(obj);
252    if (wd->block_events) _block_events_theme_apply(obj);
253    edje_object_scale_set(wd->notify, elm_widget_scale_get(obj) *
254                          _elm_config->scale);
255    _sizing_eval(obj);
256 }
257
258 static void
259 _sizing_eval(Evas_Object *obj)
260 {
261    Widget_Data *wd = elm_widget_data_get(obj);
262    Evas_Coord x,y,w,h;
263    if (!wd) return;
264    if (!wd->parent) return;
265    evas_object_geometry_get(wd->parent, &x, &y, &w, &h);
266    evas_object_move(obj, x, y);
267    evas_object_resize(obj, w, h);
268 }
269
270 static void
271 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
272 {
273    _calc(data);
274 }
275
276 static void
277 _sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
278 {
279    Widget_Data *wd = elm_widget_data_get(obj);
280    Evas_Object *sub = event_info;
281    if (!wd) return;
282
283    if (sub == wd->content)
284      {
285         evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
286                                             _changed_size_hints, obj);
287         evas_object_event_callback_del_full(sub, EVAS_CALLBACK_RESIZE,
288                                             _content_resize, obj);
289         wd->content = NULL;
290      }
291 }
292
293 static void
294 _signal_block_clicked(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
295 {
296    Widget_Data *wd = elm_widget_data_get(data);
297    if (!wd) return;
298    evas_object_smart_callback_call(data, SIG_BLOCK_CLICKED, NULL);
299 }
300
301 static void
302 _resize(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
303 {
304    _calc(obj);
305 }
306
307 static void
308 _content_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
309 {
310    _calc(data);
311 }
312
313 static void
314 _calc(Evas_Object *obj)
315 {
316    Widget_Data *wd = elm_widget_data_get(obj);
317    Evas_Coord minw = -1, minh = -1;
318    Evas_Coord x, y, w, h;
319
320    if (!wd) return;
321    evas_object_geometry_get(obj, &x, &y, &w, &h);
322    edje_object_size_min_get(wd->notify, &minw, &minh);
323    edje_object_size_min_restricted_calc(wd->notify, &minw, &minh, minw, minh);
324
325    if (wd->content)
326      {
327         _notify_move_to_orientation(obj);
328         evas_object_resize(wd->notify, minw, minh);
329      }
330    _sizing_eval(obj);
331 }
332
333 static Eina_Bool
334 _timer_cb(void *data)
335 {
336    Evas_Object *obj = data;
337    Widget_Data *wd = elm_widget_data_get(obj);
338    if (!wd) return ECORE_CALLBACK_CANCEL;
339    wd->timer = NULL;
340    evas_object_hide(obj);
341    evas_object_smart_callback_call(obj, SIG_TIMEOUT, NULL);
342    return ECORE_CALLBACK_CANCEL;
343 }
344
345 static void
346 _timer_init(Evas_Object *obj, Widget_Data *wd)
347 {
348    if (wd->timer)
349      {
350         ecore_timer_del(wd->timer);
351         wd->timer = NULL;
352      }
353    if ((evas_object_visible_get(obj)) && (wd->timeout > 0.0))
354      wd->timer = ecore_timer_add(wd->timeout, _timer_cb, obj);
355 }
356
357 static void
358 _show(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
359 {
360    Widget_Data *wd = elm_widget_data_get(obj);
361    if (!wd) return;
362    evas_object_show(wd->notify);
363    if (!wd->repeat_events)
364      evas_object_show(wd->block_events);
365    _timer_init(obj, wd);
366    elm_object_focus(obj);
367 }
368
369 static void
370 _hide(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
371 {
372    Widget_Data *wd = elm_widget_data_get(obj);
373    if (!wd) return;
374    evas_object_hide(wd->notify);
375    if (!wd->repeat_events)
376      evas_object_hide(wd->block_events);
377    if (wd->timer)
378      {
379         ecore_timer_del(wd->timer);
380         wd->timer = NULL;
381      }
382 }
383
384 static void
385 _parent_del(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
386 {
387    Widget_Data *wd = elm_widget_data_get(obj);
388    if (!wd) return;
389    wd->parent = NULL;
390    evas_object_hide(obj);
391 }
392
393 static void
394 _parent_hide(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
395 {
396    Widget_Data *wd = elm_widget_data_get(obj);
397    if (!wd) return;
398    evas_object_hide(obj);
399 }
400
401 static Eina_Bool
402 _elm_notify_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
403 {
404    Widget_Data *wd = elm_widget_data_get(obj);
405    Evas_Object *cur;
406
407    if ((!wd) || (!wd->content))
408      return EINA_FALSE;
409
410    cur = wd->content;
411
412    /* Try Focus cycle in subitem */
413    return elm_widget_focus_next_get(cur, dir, next);
414 }
415
416 /**
417  * Add a new notify to the parent
418  *
419  * @param parent The parent object
420  * @return The new object or NULL if it cannot be created
421  *
422  * @ingroup Notify
423  */
424 EAPI Evas_Object *
425 elm_notify_add(Evas_Object *parent)
426 {
427    Evas_Object *obj;
428    Evas *e;
429    Widget_Data *wd;
430
431    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
432
433    ELM_SET_WIDTYPE(widtype, "notify");
434    elm_widget_type_set(obj, "notify");
435    elm_widget_sub_object_add(parent, obj);
436    elm_widget_data_set(obj, wd);
437    elm_widget_del_pre_hook_set(obj, _del_pre_hook);
438    elm_widget_del_hook_set(obj, _del_hook);
439    elm_widget_theme_hook_set(obj, _theme_hook);
440    elm_widget_can_focus_set(obj, EINA_FALSE);
441    elm_widget_focus_next_hook_set(obj, _elm_notify_focus_next_hook);
442
443    wd->repeat_events = EINA_TRUE;
444
445    wd->notify = edje_object_add(e);
446    wd->orient = -1;
447    elm_notify_orient_set(obj, ELM_NOTIFY_ORIENT_TOP);
448
449    elm_notify_parent_set(obj, parent);
450
451    evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
452    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
453    evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _resize, obj);
454    evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _show, obj);
455    evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _hide, obj);
456
457    _mirrored_set(obj, elm_widget_mirrored_get(obj));
458    _sizing_eval(obj);
459
460    evas_object_smart_callbacks_descriptions_set(obj, _signals);
461    return obj;
462 }
463
464 /**
465  * Set the content of the notify widget
466  *
467  * Once the content object is set, a previously set one will be deleted.
468  * If you want to keep that old content object, use the
469  * elm_notify_content_unset() function.
470  *
471  * @param obj The notify object
472  * @param content The content will be filled in this notify object
473  *
474  * @ingroup Notify
475  */
476 EAPI void
477 elm_notify_content_set(Evas_Object *obj, Evas_Object *content)
478 {
479    ELM_CHECK_WIDTYPE(obj, widtype);
480    Widget_Data *wd = elm_widget_data_get(obj);
481    if (!wd) return;
482    if (wd->content == content) return;
483    if (wd->content) evas_object_del(wd->content);
484    wd->content = content;
485
486    if (content)
487      {
488         elm_widget_sub_object_add(obj, content);
489         evas_object_event_callback_add(content, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
490                                        _changed_size_hints, obj);
491         evas_object_event_callback_add(content, EVAS_CALLBACK_RESIZE,
492                                        _content_resize, obj);
493         edje_object_part_swallow(wd->notify, "elm.swallow.content", content);
494      }
495    _sizing_eval(obj);
496    _calc(obj);
497 }
498
499 /**
500  * Unset the content of the notify widget
501  *
502  * Unparent and return the content object which was set for this widget
503  *
504  * @param obj The notify object
505  * @return The content that was being used
506  *
507  * @ingroup Notify
508  */
509 EAPI Evas_Object *
510 elm_notify_content_unset(Evas_Object *obj)
511 {
512    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
513    Widget_Data *wd = elm_widget_data_get(obj);
514    Evas_Object *content;
515    if (!wd) return NULL;
516    if (!wd->content) return NULL;
517    content = wd->content;
518    elm_widget_sub_object_del(obj, wd->content);
519    edje_object_part_unswallow(wd->notify, wd->content);
520    wd->content = NULL;
521    return content;
522 }
523
524 /**
525  * Return the content of the notify widget
526  *
527  * @param obj The notify object
528  * @return The content that is being used
529  *
530  * @ingroup Notify
531  */
532 EAPI Evas_Object *
533 elm_notify_content_get(const Evas_Object *obj)
534 {
535    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
536    Widget_Data *wd = elm_widget_data_get(obj);
537
538    if (!wd) return NULL;
539    return wd->content;
540 }
541
542 /**
543  * Set the notify parent
544  *
545  * Once the parent object is set, a previously set one will be disconnected
546  * and replaced.
547  *
548  * @param obj The notify object
549  * @param content The new parent
550  *
551  * @ingroup Notify
552  */
553 EAPI void
554 elm_notify_parent_set(Evas_Object *obj, Evas_Object *parent)
555 {
556    ELM_CHECK_WIDTYPE(obj, widtype);
557    Widget_Data *wd = elm_widget_data_get(obj);
558    if (!wd) return;
559    if (wd->parent)
560      {
561         evas_object_event_callback_del_full(wd->parent,
562                                             EVAS_CALLBACK_CHANGED_SIZE_HINTS,
563                                             _changed_size_hints, obj);
564         evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_RESIZE,
565                                             _changed_size_hints, obj);
566         evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_MOVE,
567                                             _changed_size_hints, obj);
568         evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_DEL,
569                                             _parent_del, obj);
570         evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_HIDE,
571                                             _parent_hide, obj);
572         wd->parent = NULL;
573      }
574
575    if (parent)
576      {
577         wd->parent = parent;
578         evas_object_event_callback_add(parent,
579                                        EVAS_CALLBACK_CHANGED_SIZE_HINTS,
580                                        _changed_size_hints, obj);
581         evas_object_event_callback_add(parent, EVAS_CALLBACK_RESIZE,
582                                        _changed_size_hints, obj);
583         evas_object_event_callback_add(parent, EVAS_CALLBACK_MOVE,
584                                        _changed_size_hints, obj);
585         evas_object_event_callback_add(parent, EVAS_CALLBACK_DEL,
586                                        _parent_del, obj);
587         evas_object_event_callback_add(parent, EVAS_CALLBACK_HIDE,
588                                        _parent_hide, obj);
589         edje_object_part_swallow(wd->notify, "elm.swallow.parent", parent);
590         _sizing_eval(obj);
591      }
592    _calc(obj);
593 }
594
595 /**
596  * Get the notify parent
597  *
598  * @param obj The notify object
599  * @return The parent
600  *
601  * @ingroup Notify
602  */
603 EAPI Evas_Object *
604 elm_notify_parent_get(const Evas_Object *obj)
605 {
606    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
607    Widget_Data *wd = elm_widget_data_get(obj);
608    if (!wd) return NULL;
609    return wd->parent;
610 }
611
612 /**
613  * Set the orientation
614  *
615  * @param obj The notify object
616  * @param orient The new orientation
617  *
618  * @ingroup Notify
619  */
620 EAPI void
621 elm_notify_orient_set(Evas_Object *obj, Elm_Notify_Orient orient)
622 {
623    ELM_CHECK_WIDTYPE(obj, widtype);
624    Widget_Data *wd = elm_widget_data_get(obj);
625    if (!wd) return;
626    if (wd->orient == orient) return;
627    wd->orient = orient;
628    _notify_theme_apply(obj);
629    _resize(obj, NULL, obj, NULL);
630 }
631
632 /**
633  * Return the orientation
634  * @param obj the notify objects
635  */
636 EAPI Elm_Notify_Orient
637 elm_notify_orient_get(const Evas_Object *obj)
638 {
639    ELM_CHECK_WIDTYPE(obj, widtype) -1;
640    Widget_Data *wd = elm_widget_data_get(obj);
641    if (!wd) return -1;
642    return wd->orient;
643 }
644
645 /**
646  * Set the time interval after which the notify window is going to be
647  * hidden.
648  *
649  * @param obj The notify object
650  * @param time The new timeout
651  *
652  * As said previously, an evas_object_show() on a notify object which
653  * had a timeout set by this function will trigger a timer to
654  * automatically hide it again. So, any order one calls
655  * elm_notify_timeout_set() and evas_object_show() on the same object
656  * (at hidden state) will behave the same.
657  *
658  * @note Set a value <= 0.0 to disable a running timer.
659  *
660  * @note If the value > 0.0 and the notify is previously visible, the
661  * timer will be started with this value, canceling any running timer.
662  *
663  */
664 EAPI void
665 elm_notify_timeout_set(Evas_Object *obj, double timeout)
666 {
667    ELM_CHECK_WIDTYPE(obj, widtype);
668    Widget_Data *wd = elm_widget_data_get(obj);
669    if (!wd) return;
670    wd->timeout = timeout;
671    _timer_init(obj, wd);
672 }
673
674 /**
675  * Return the timeout value (in seconds)
676  * @param obj the notify object
677  */
678 EAPI double
679 elm_notify_timeout_get(const Evas_Object *obj)
680 {
681    ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
682    Widget_Data *wd = elm_widget_data_get(obj);
683    if (!wd) return 0.0;
684    return wd->timeout;
685 }
686
687 /**
688  * When true if the user clicks outside the window the events will be
689  * catch by the others widgets, else the events are block and the signal
690  * dismiss will be sent when the user click outside the window.
691  *
692  * @note The default value is EINA_TRUE.
693  *
694  * @param obj The notify object
695  * @param repeats EINA_TRUE Events are repeats, else no
696  */
697 EAPI void
698 elm_notify_repeat_events_set(Evas_Object *obj, Eina_Bool repeat)
699 {
700    ELM_CHECK_WIDTYPE(obj, widtype);
701    Widget_Data *wd = elm_widget_data_get(obj);
702    if (!wd) return;
703    if (repeat == wd->repeat_events) return;
704    wd->repeat_events = repeat;
705    if (!repeat)
706      {
707         wd->block_events = edje_object_add(evas_object_evas_get(obj));
708         _block_events_theme_apply(obj);
709         elm_widget_resize_object_set(obj, wd->block_events);
710         edje_object_signal_callback_add(wd->block_events, "elm,action,clicked",
711                                         "elm", _signal_block_clicked, obj);
712      }
713    else
714      evas_object_del(wd->block_events);
715 }
716
717 /**
718  * Return true if events are repeat below the notify object
719  * @param obj the notify object
720  */
721 EAPI Eina_Bool
722 elm_notify_repeat_events_get(const Evas_Object *obj)
723 {
724    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
725    Widget_Data *wd = elm_widget_data_get(obj);
726    if (!wd) return EINA_FALSE;
727    return wd->repeat_events;
728 }