1 #include <Elementary.h>
6 * @defgroup Notify Notify
9 * Display a window in a particular region of the application (top, bottom ...).
10 * A timeout can be set to automatically close the window.
14 typedef struct _Widget_Data Widget_Data;
18 Evas_Object *notify, *content, *parent;
20 Elm_Notify_Orient orient;
21 Eina_Bool repeat_events;
22 Evas_Object *block_events;
28 static const char *widtype = NULL;
29 static void _del_hook(Evas_Object *obj);
30 static void _theme_hook(Evas_Object *obj);
31 static void _sizing_eval(Evas_Object *obj);
32 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
33 static void _sub_del(void *data, Evas_Object *obj, void *event_info);
34 static void _signal_block_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
35 static void _calc(Evas_Object *obj);
36 static void _content_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
37 static void _show(void *data, Evas *e, Evas_Object *obj, void *event_info);
38 static void _hide(void *data, Evas *e, Evas_Object *obj, void *event_info);
39 static void _resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
42 _del_pre_hook(Evas_Object *obj)
44 evas_object_event_callback_del_full(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
45 evas_object_event_callback_del_full(obj, EVAS_CALLBACK_MOVE, _resize, obj);
46 evas_object_event_callback_del_full(obj, EVAS_CALLBACK_SHOW, _show, obj);
47 evas_object_event_callback_del_full(obj, EVAS_CALLBACK_HIDE, _hide, obj);
51 _del_hook(Evas_Object *obj)
53 Widget_Data *wd = elm_widget_data_get(obj);
55 elm_notify_parent_set(obj, NULL);
56 elm_notify_repeat_events_set(obj, EINA_TRUE);
59 ecore_timer_del(wd->timer);
66 _notify_theme_apply(Evas_Object *obj)
68 Widget_Data *wd = elm_widget_data_get(obj);
69 const char *style = elm_widget_style_get(obj);
73 case ELM_NOTIFY_ORIENT_TOP:
74 _elm_theme_object_set(obj, wd->notify, "notify", "top", style);
76 case ELM_NOTIFY_ORIENT_CENTER:
77 _elm_theme_object_set(obj, wd->notify, "notify", "center", style);
79 case ELM_NOTIFY_ORIENT_BOTTOM:
80 _elm_theme_object_set(obj, wd->notify, "notify", "bottom", style);
82 case ELM_NOTIFY_ORIENT_LEFT:
83 _elm_theme_object_set(obj, wd->notify, "notify", "left", style);
85 case ELM_NOTIFY_ORIENT_RIGHT:
86 _elm_theme_object_set(obj, wd->notify, "notify", "right", style);
88 case ELM_NOTIFY_ORIENT_TOP_LEFT:
89 _elm_theme_object_set(obj, wd->notify, "notify", "top_left", style);
91 case ELM_NOTIFY_ORIENT_TOP_RIGHT:
92 _elm_theme_object_set(obj, wd->notify, "notify", "top_right", style);
94 case ELM_NOTIFY_ORIENT_BOTTOM_LEFT:
95 _elm_theme_object_set(obj, wd->notify, "notify", "bottom_left", style);
97 case ELM_NOTIFY_ORIENT_BOTTOM_RIGHT:
98 _elm_theme_object_set(obj, wd->notify, "notify", "bottom_right", style);
100 case ELM_NOTIFY_ORIENT_LAST:
106 _block_events_theme_apply(Evas_Object *obj)
108 Widget_Data *wd = elm_widget_data_get(obj);
109 const char *style = elm_widget_style_get(obj);
110 _elm_theme_object_set(obj, wd->block_events, "notify", "block_events", style);
114 _theme_hook(Evas_Object *obj)
116 Widget_Data *wd = elm_widget_data_get(obj);
118 _notify_theme_apply(obj);
119 if (wd->block_events) _block_events_theme_apply(obj);
120 edje_object_scale_set(wd->notify, elm_widget_scale_get(obj) *
126 _sizing_eval(Evas_Object *obj)
128 Widget_Data *wd = elm_widget_data_get(obj);
131 if (!wd->parent) return;
132 evas_object_geometry_get(wd->parent, &x, &y, &w, &h);
133 evas_object_move(obj, x, y);
134 evas_object_resize(obj, w, h);
138 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
144 _sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
146 Widget_Data *wd = elm_widget_data_get(obj);
147 Evas_Object *sub = event_info;
150 if (sub == wd->content)
152 evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
153 _changed_size_hints, obj);
154 evas_object_event_callback_del_full(sub, EVAS_CALLBACK_RESIZE,
155 _content_resize, obj);
161 _signal_block_clicked(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
163 Widget_Data *wd = elm_widget_data_get(data);
165 evas_object_smart_callback_call(data, "block,clicked", NULL);
169 _resize(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
175 _content_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
181 _calc(Evas_Object *obj)
183 Widget_Data *wd = elm_widget_data_get(obj);
184 Evas_Coord minw = -1, minh = -1;
185 Evas_Coord x, y, w, h;
188 evas_object_geometry_get(obj, &x, &y, &w, &h);
189 edje_object_size_min_get(wd->notify, &minw, &minh);
190 edje_object_size_min_restricted_calc(wd->notify, &minw, &minh, minw, minh);
194 int offx = (w - minw) / 2;
195 int offy = (h - minh) / 2;
199 case ELM_NOTIFY_ORIENT_TOP:
200 evas_object_move(wd->notify, x + offx, y);
202 case ELM_NOTIFY_ORIENT_CENTER:
203 evas_object_move(wd->notify, x + offx, y + offy);
205 case ELM_NOTIFY_ORIENT_BOTTOM:
206 evas_object_move(wd->notify, x + offx, y + h - minh);
208 case ELM_NOTIFY_ORIENT_LEFT:
209 evas_object_move(wd->notify, x, y + offy);
211 case ELM_NOTIFY_ORIENT_RIGHT:
212 evas_object_move(wd->notify, x + w - minw, y + offy);
214 case ELM_NOTIFY_ORIENT_TOP_LEFT:
215 evas_object_move(wd->notify, x, y);
217 case ELM_NOTIFY_ORIENT_TOP_RIGHT:
218 evas_object_move(wd->notify, x + w - minw, y);
220 case ELM_NOTIFY_ORIENT_BOTTOM_LEFT:
221 evas_object_move(wd->notify, x, y + h - minh);
223 case ELM_NOTIFY_ORIENT_BOTTOM_RIGHT:
224 evas_object_move(wd->notify, x + w - minw, y + h - minh);
226 case ELM_NOTIFY_ORIENT_LAST:
229 evas_object_resize(wd->notify, minw, minh);
235 _timer_cb(void *data)
237 Evas_Object *obj = data;
238 Widget_Data *wd = elm_widget_data_get(obj);
239 if (!wd) return ECORE_CALLBACK_CANCEL;
241 evas_object_hide(obj);
242 evas_object_smart_callback_call(obj, "notify,timeout", NULL);
243 return ECORE_CALLBACK_CANCEL;
247 _show(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
249 Widget_Data *wd = elm_widget_data_get(obj);
251 evas_object_show(wd->notify);
252 if (!wd->repeat_events)
253 evas_object_show(wd->block_events);
256 ecore_timer_del(wd->timer);
260 wd->timer = ecore_timer_add(wd->timeout, _timer_cb, obj);
264 _hide(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
266 Widget_Data *wd = elm_widget_data_get(obj);
268 evas_object_hide(wd->notify);
269 if (!wd->repeat_events)
270 evas_object_hide(wd->block_events);
273 ecore_timer_del(wd->timer);
279 _parent_del(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
281 Widget_Data *wd = elm_widget_data_get(obj);
284 evas_object_hide(obj);
288 _parent_hide(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
290 Widget_Data *wd = elm_widget_data_get(obj);
293 evas_object_hide(obj);
297 * Add a new notify to the parent
299 * @param parent The parent object
300 * @return The new object or NULL if it cannot be created
305 elm_notify_add(Evas_Object *parent)
311 wd = ELM_NEW(Widget_Data);
312 e = evas_object_evas_get(parent);
313 obj = elm_widget_add(e);
314 ELM_SET_WIDTYPE(widtype, "notify");
315 elm_widget_type_set(obj, "notify");
316 elm_widget_sub_object_add(parent, obj);
317 elm_widget_data_set(obj, wd);
318 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
319 elm_widget_del_hook_set(obj, _del_hook);
320 elm_widget_theme_hook_set(obj, _theme_hook);
321 elm_widget_can_focus_set(obj, EINA_FALSE);
323 wd->repeat_events = EINA_TRUE;
325 wd->notify = edje_object_add(e);
327 elm_notify_orient_set(obj, ELM_NOTIFY_ORIENT_TOP);
329 elm_notify_parent_set(obj, parent);
331 evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
332 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
333 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _resize, obj);
334 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _show, obj);
335 evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _hide, obj);
342 * Set the content of the notify widget
344 * Once the content object is set, a previously set one will be deleted.
345 * If you want to keep that old content object, use the
346 * elm_notify_content_unset() function.
348 * @param obj The notify object
349 * @param content The content will be filled in this notify object
354 elm_notify_content_set(Evas_Object *obj, Evas_Object *content)
356 ELM_CHECK_WIDTYPE(obj, widtype);
357 Widget_Data *wd = elm_widget_data_get(obj);
359 if (wd->content == content) return;
360 if (wd->content) evas_object_del(wd->content);
361 wd->content = content;
365 elm_widget_sub_object_add(obj, content);
366 evas_object_event_callback_add(content, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
367 _changed_size_hints, obj);
368 evas_object_event_callback_add(content, EVAS_CALLBACK_RESIZE,
369 _content_resize, obj);
370 edje_object_part_swallow(wd->notify, "elm.swallow.content", content);
377 * Unset the content of the notify widget
379 * Unparent and return the content object which was set for this widget
381 * @param obj The notify object
382 * @return The content that was being used
387 elm_notify_content_unset(Evas_Object *obj)
389 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
390 Widget_Data *wd = elm_widget_data_get(obj);
391 Evas_Object *content;
392 if (!wd) return NULL;
393 if (!wd->content) return NULL;
394 content = wd->content;
395 elm_widget_sub_object_del(obj, wd->content);
396 edje_object_part_unswallow(wd->notify, wd->content);
402 * Return the content of the notify widget
404 * @param obj The notify object
405 * @return The content that is being used
410 elm_notify_content_get(const Evas_Object *obj)
412 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
413 Widget_Data *wd = elm_widget_data_get(obj);
415 if ((!wd) || (!wd->content)) return NULL;
420 * Set the notify parent
422 * @param obj The notify object
423 * @param content The new parent
428 elm_notify_parent_set(Evas_Object *obj, Evas_Object *parent)
430 ELM_CHECK_WIDTYPE(obj, widtype);
431 Widget_Data *wd = elm_widget_data_get(obj);
435 evas_object_event_callback_del_full(wd->parent,
436 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
437 _changed_size_hints, obj);
438 evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_RESIZE,
439 _changed_size_hints, obj);
440 evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_MOVE,
441 _changed_size_hints, obj);
442 evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_DEL,
444 evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_HIDE,
452 evas_object_event_callback_add(parent,
453 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
454 _changed_size_hints, obj);
455 evas_object_event_callback_add(parent, EVAS_CALLBACK_RESIZE,
456 _changed_size_hints, obj);
457 evas_object_event_callback_add(parent, EVAS_CALLBACK_MOVE,
458 _changed_size_hints, obj);
459 evas_object_event_callback_add(parent, EVAS_CALLBACK_DEL,
461 evas_object_event_callback_add(parent, EVAS_CALLBACK_HIDE,
463 edje_object_part_swallow(wd->notify, "elm.swallow.parent", parent);
470 * Set the orientation
472 * @param obj The notify object
473 * @param orient The new orientation
478 elm_notify_orient_set(Evas_Object *obj, Elm_Notify_Orient orient)
480 ELM_CHECK_WIDTYPE(obj, widtype);
481 Widget_Data *wd = elm_widget_data_get(obj);
483 if (wd->orient == orient) return;
485 _notify_theme_apply(obj);
486 _resize(obj, NULL, obj, NULL);
490 * Return the orientation
491 * @param obj the notify objects
493 EAPI Elm_Notify_Orient
494 elm_notify_orient_get(const Evas_Object *obj)
496 ELM_CHECK_WIDTYPE(obj, widtype) -1;
497 Widget_Data *wd = elm_widget_data_get(obj);
503 * Set the time before the notify window is hidden. <br>
504 * Set a value < 0 to disable the timer
506 * @param obj The notify object
507 * @param time the new timeout
512 elm_notify_timeout_set(Evas_Object *obj, int timeout)
514 ELM_CHECK_WIDTYPE(obj, widtype);
515 Widget_Data *wd = elm_widget_data_get(obj);
517 wd->timeout = timeout;
518 elm_notify_timer_init(obj);
522 * Return the timeout value (in seconds)
523 * @param obj the notify object
526 elm_notify_timeout_get(const Evas_Object *obj)
528 ELM_CHECK_WIDTYPE(obj, widtype) -1;
529 Widget_Data *wd = elm_widget_data_get(obj);
536 * @param obj The notify object
541 elm_notify_timer_init(Evas_Object *obj)
543 ELM_CHECK_WIDTYPE(obj, widtype);
544 Widget_Data *wd = elm_widget_data_get(obj);
546 if (wd->timer) ecore_timer_del(wd->timer);
549 wd->timer = ecore_timer_add(wd->timeout, _timer_cb, obj);
553 * When true if the user clicks outside the window the events will be
554 * caught by other widgets, else the events are blocked and the signal
555 * block,clicked will be sent when the user click's outside the window.
557 * @note The default value is EINA_TRUE.
559 * @param obj The notify object
560 * @param repeats EINA_TRUE Events are repeated else The events are blocked.
565 elm_notify_repeat_events_set(Evas_Object *obj, Eina_Bool repeat)
567 ELM_CHECK_WIDTYPE(obj, widtype);
568 Widget_Data *wd = elm_widget_data_get(obj);
570 if (repeat == wd->repeat_events) return;
571 wd->repeat_events = repeat;
574 wd->block_events = edje_object_add(evas_object_evas_get(obj));
575 _block_events_theme_apply(obj);
576 elm_widget_resize_object_set(obj, wd->block_events);
577 edje_object_signal_callback_add(wd->block_events, "elm,action,clicked", "elm", _signal_block_clicked, obj);
580 evas_object_del(wd->block_events);
584 * Return true if events are repeat below the notify object
585 * @param obj the notify object
588 elm_notify_repeat_events_get(const Evas_Object *obj)
590 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
591 Widget_Data *wd = elm_widget_data_get(obj);
592 if (!wd) return EINA_FALSE;
593 return wd->repeat_events;