1 #include <Elementary.h>
4 typedef struct _Widget_Data Widget_Data;
12 Ecore_Event_Handler *rotation_event_handler;
16 Elm_Tickernoti_Mode mode;
17 Elm_Tickernoti_Orient orient;
20 static const char *widtype = NULL;
21 static void _del_hook(Evas_Object *obj);
22 static void _theme_hook(Evas_Object *obj);
23 static void _sizing_eval(Evas_Object *obj);
24 static void _update_geometry_on_rotation(Evas_Object *obj, int angle, int *x, int *y, int *w);
26 static const char SIG_CLICKED[] = "clicked";
27 static const char SIG_HIDDEN[] = "hide";
28 static const Evas_Smart_Cb_Description _signals[] = {
37 evas_object_del(data);
41 _del_hook(Evas_Object *obj)
44 Widget_Data *wd = elm_widget_data_get(obj);
47 parent = elm_widget_parent_get(obj);
48 if (wd->rotation_event_handler)
49 ecore_event_handler_del(wd->rotation_event_handler);
50 if (wd->win) ecore_job_add(_del_job, parent);
51 evas_object_del(wd->edje_obj);
57 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
59 Widget_Data *wd = elm_widget_data_get(obj);
62 edje_object_mirrored_set(wd->edje_obj, rtl);
66 _theme_hook(Evas_Object *obj)
68 char *data_win_height = NULL;
70 Widget_Data *wd = elm_widget_data_get(obj);
73 _elm_widget_mirrored_reload(obj);
74 _mirrored_set(obj, elm_widget_mirrored_get(obj));
76 _elm_theme_object_set(wd->win, wd->edje_obj, "tickernoti",
77 "base", elm_widget_style_get(obj));
79 edje_object_scale_set(wd->edje_obj, elm_widget_scale_get(obj) * _elm_config->scale);
81 /* tickernoti detail height set */
82 data_win_height = (char *)edje_object_data_get(wd->edje_obj, "height");
83 if (data_win_height != NULL && elm_scale_get() > 0.0)
84 wd->noti_height = (int)(elm_scale_get() * atoi(data_win_height));
86 evas_object_geometry_get(wd->win, NULL, NULL, &w, NULL);
87 evas_object_resize(wd->win, w, wd->noti_height);
90 edje_object_part_text_set(wd->edje_obj, "elm.text", wd->label);
92 edje_object_part_swallow(wd->edje_obj, "icon", wd->icon);
94 edje_object_part_swallow(wd->edje_obj, "button", wd->button);
95 edje_object_signal_emit(wd->edje_obj, "effect,show", "elm");
96 edje_object_message_signal_process(wd->edje_obj);
102 _sizing_eval(Evas_Object *obj)
104 Widget_Data *wd = elm_widget_data_get(obj);
105 Evas_Coord minw = -1, minh = -1;
108 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
109 edje_object_size_min_restricted_calc(wd->edje_obj, &minw, &minh, minw, minh);
110 evas_object_size_hint_min_set(obj, minw, minh);
113 #ifdef HAVE_ELEMENTARY_X
115 _update_window_hints(Evas_Object *obj)
118 Ecore_X_Atom _notification_level_atom;
120 // elm_win_xwindow_get() must call after elm_win_alpha_set()
121 xwin = elm_win_xwindow_get(obj);
123 ecore_x_icccm_hints_set(xwin, 0, ECORE_X_WINDOW_STATE_HINT_NONE, 0, 0, 0, 0, 0);
124 ecore_x_netwm_window_type_set(xwin, ECORE_X_WINDOW_TYPE_NOTIFICATION);
125 ecore_x_netwm_opacity_set(xwin, 0);
126 // Create atom for notification level
127 _notification_level_atom = ecore_x_atom_get("_E_ILLUME_NOTIFICATION_LEVEL");
129 // HIGH:150, NORMAL:100, LOW:50
132 // Set notification level of the window
133 ecore_x_window_prop_property_set(xwin, _notification_level_atom, ECORE_X_ATOM_CARDINAL, 32, &level, 1);
137 static void _hide_cb(void *data, Evas_Object *obj __UNUSED__,
138 const char *emission __UNUSED__,
139 const char *source __UNUSED__)
141 Widget_Data *wd = elm_widget_data_get(data);
144 evas_object_hide(wd->win);
145 evas_object_smart_callback_call(data, SIG_HIDDEN, NULL);
148 static void _clicked_cb(void *data, Evas_Object *obj __UNUSED__,
149 const char *emission __UNUSED__,
150 const char *source __UNUSED__)
152 Widget_Data *wd = elm_widget_data_get(data);
155 evas_object_smart_callback_call(data, SIG_CLICKED, NULL);
159 *_create_window(Evas_Object *parent, const char *name)
163 win = elm_win_add(parent, name, ELM_WIN_BASIC);
164 elm_win_title_set(win, name);
165 elm_win_borderless_set(win, EINA_TRUE);
166 elm_win_autodel_set(win, EINA_TRUE);
167 elm_win_alpha_set(win, EINA_TRUE);
168 evas_object_size_hint_weight_set(win, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
169 evas_object_size_hint_align_set(win, EVAS_HINT_FILL, EVAS_HINT_FILL);
171 #ifdef HAVE_ELEMENTARY_X
173 _update_window_hints(win);
179 _win_rotated(Evas_Object *obj)
181 Widget_Data *wd = elm_widget_data_get(obj);
182 int x = 0, y = 0, w = 0, angle = 0;
185 angle = elm_win_rotation_get(wd->win);
186 if (angle % 90) return;
188 if (angle < 0) angle += 360;
190 _update_geometry_on_rotation(obj, wd->angle, &x, &y, &w);
191 evas_object_move(wd->win, x, y);
192 evas_object_resize(wd->win, w, wd->noti_height);
193 #ifdef HAVE_ELEMENTARY_X
194 _update_window_hints(wd->win);
199 _prop_change(void *data, int type __UNUSED__, void *event)
201 #ifdef HAVE_ELEMENTARY_X
202 Ecore_X_Event_Window_Property *ev;
203 Widget_Data *wd = elm_widget_data_get(data);
205 if (!wd) return ECORE_CALLBACK_PASS_ON;
207 if (ev->atom == ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE)
209 if (ev->win == elm_win_xwindow_get(wd->win))
214 return ECORE_CALLBACK_PASS_ON;
219 _create_tickernoti(Evas_Object *obj)
221 #ifdef HAVE_ELEMENTARY_X
224 Widget_Data *wd = elm_widget_data_get(obj);
225 char *data_win_height = NULL;
230 evas_object_move(wd->win, 0, 0);
231 e = evas_object_evas_get(wd->win);
233 wd->edje_obj = edje_object_add(e);
234 _elm_theme_object_set(wd->win, wd->edje_obj, "tickernoti", "base", "default");
235 elm_win_resize_object_add(wd->win, wd->edje_obj);
237 // tickernoti height setting
238 data_win_height = (char *)edje_object_data_get(wd->edje_obj, "height");
239 if (data_win_height != NULL && elm_scale_get() > 0.0)
240 wd->noti_height = (int)(elm_scale_get() * atoi(data_win_height));
242 #ifdef HAVE_ELEMENTARY_X
243 ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, NULL);
244 evas_object_resize(wd->win, w, wd->noti_height);
245 wd->rotation_event_handler = ecore_event_handler_add(
246 ECORE_X_EVENT_WINDOW_PROPERTY, _prop_change, obj);
249 edje_object_signal_callback_add(wd->edje_obj, "request,hide", "", _hide_cb, obj);
250 edje_object_signal_callback_add(wd->edje_obj, "clicked", "", _clicked_cb, obj);
251 evas_object_show(wd->edje_obj);
255 _disable_hook(Evas_Object *obj)
257 Widget_Data *wd = elm_widget_data_get(obj);
260 //TODO: To stop the event in case of being disabled
264 _show(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
265 void *event_info __UNUSED__)
267 Widget_Data *wd = elm_widget_data_get(obj);
270 #ifdef HAVE_ELEMENTARY_X
271 _update_window_hints(wd->win);
273 evas_object_show(wd->win);
274 edje_object_signal_emit(wd->edje_obj, "effect,show", "elm");
275 edje_object_message_signal_process(wd->edje_obj);
279 _hide(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
280 void *event_info __UNUSED__)
282 Widget_Data *wd = elm_widget_data_get(obj);
285 evas_object_hide(wd->win);
288 static void _tickernoti_hide_cb(void *data, Evas_Object *obj __UNUSED__,
289 void *event_info __UNUSED__)
291 Widget_Data *wd = data;
295 edje_object_signal_emit(wd->edje_obj, "effect,hide", "elm");
296 edje_object_message_signal_process(wd->edje_obj);
300 _update_geometry_on_rotation(Evas_Object *obj, int angle, int *x, int *y, int *w)
302 ELM_CHECK_WIDTYPE(obj, widtype);
303 Widget_Data *wd = elm_widget_data_get(obj);
307 #ifdef HAVE_ELEMENTARY_X
308 Evas_Coord root_w, root_h;
311 * manually calculate win_tickernoti_indi window position & size
312 * - win_indi is not full size window
314 ecore_x_window_size_get(ecore_x_window_root_first_get(), &root_w, &root_h);
320 if (wd->orient == ELM_TICKERNOTI_ORIENT_BOTTOM)
321 *x = root_w - wd->noti_height;
325 if (!(wd->orient == ELM_TICKERNOTI_ORIENT_BOTTOM))
326 *x = root_w - wd->noti_height;
330 if (!wd->orient == ELM_TICKERNOTI_ORIENT_BOTTOM)
331 *y = root_h - wd->noti_height;
336 if (wd->orient == ELM_TICKERNOTI_ORIENT_BOTTOM)
337 *y = root_h - wd->noti_height;
344 _sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
346 Widget_Data *wd = elm_widget_data_get(obj);
347 Evas_Object *sub = event_info;
351 if (sub == wd->button)
356 _elm_tickernoti_label_set(Evas_Object *obj, const char *part, const char *label)
358 ELM_CHECK_WIDTYPE(obj, widtype);
359 Widget_Data *wd = elm_widget_data_get(obj);
362 if (part && strcmp(part, "default")) return;
363 eina_stringshare_replace(&wd->label, label);
364 edje_object_part_text_set(wd->edje_obj, "elm.text", wd->label);
369 _elm_tickernoti_label_get(const Evas_Object *obj, const char *part)
371 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
372 Widget_Data *wd = elm_widget_data_get(obj);
374 if (part && strcmp(part, "default")) return NULL;
375 if (!wd) return NULL;
380 _elm_tickernoti_icon_set(Evas_Object *obj, Evas_Object *icon)
382 ELM_CHECK_WIDTYPE(obj, widtype);
383 Widget_Data *wd = elm_widget_data_get(obj);
386 if (wd->icon == icon) return;
387 if (wd->icon) evas_object_del(wd->icon);
391 elm_widget_sub_object_add(obj, icon);
392 edje_object_part_swallow(wd->edje_obj, "icon", icon);
397 _elm_tickernoti_button_set(Evas_Object *obj, Evas_Object *button)
399 ELM_CHECK_WIDTYPE(obj, widtype);
400 Widget_Data *wd = elm_widget_data_get(obj);
403 if (wd->button == button) return;
404 if (wd->button) evas_object_del(wd->button);
408 elm_widget_sub_object_add(obj, button);
409 edje_object_part_swallow(wd->edje_obj, "button", button);
410 evas_object_smart_callback_add(wd->button, "clicked", _tickernoti_hide_cb, wd);
415 _elm_tickernoti_content_part_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
417 ELM_CHECK_WIDTYPE(obj, widtype);
418 Widget_Data *wd = elm_widget_data_get(obj);
420 if (!wd || !part) return;
421 if (!part || !strcmp(part, "icon"))
423 _elm_tickernoti_icon_set(obj, content);
426 else if (!strcmp(part, "button"))
428 _elm_tickernoti_button_set(obj, content);
434 _elm_tickernoti_icon_get(const Evas_Object *obj)
436 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
437 Widget_Data *wd = elm_widget_data_get(obj);
438 if (!wd) return NULL;
443 _elm_tickernoti_button_get(const Evas_Object *obj)
445 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
446 Widget_Data *wd = elm_widget_data_get(obj);
447 if (!wd) return NULL;
452 _elm_tickernoti_content_part_get_hook(Evas_Object *obj, const char *part)
454 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
455 Widget_Data *wd = elm_widget_data_get(obj);
457 if (!wd || !part) return NULL;
458 if (!part || !strcmp(part, "icon"))
459 return _elm_tickernoti_icon_get(obj);
460 else if (!strcmp(part, "button"))
461 return _elm_tickernoti_button_get(obj);
466 _elm_tickernoti_icon_unset(Evas_Object *obj)
468 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
470 Widget_Data *wd = elm_widget_data_get(obj);
472 if (!wd || !wd->icon) return NULL;
474 elm_widget_sub_object_del(obj, wd->icon);
475 edje_object_part_unswallow(wd->edje_obj, icon);
481 _elm_tickernoti_button_unset(Evas_Object *obj)
483 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
485 Widget_Data *wd = elm_widget_data_get(obj);
487 if (!wd || !wd->button) return NULL;
489 elm_widget_sub_object_del(obj, wd->button);
490 edje_object_part_unswallow(wd->edje_obj, button);
496 _elm_tickernoti_content_part_unset_hook(Evas_Object *obj, const char *part)
498 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
499 Widget_Data *wd = elm_widget_data_get(obj);
501 if (!wd || !part) return NULL;
502 if (!strcmp(part, "icon"))
503 return _elm_tickernoti_icon_unset(obj);
504 else if (!strcmp(part, "button"))
505 return _elm_tickernoti_button_unset(obj);
510 elm_tickernoti_add(Evas_Object *parent)
516 wd = ELM_NEW(Widget_Data);
517 wd->win = _create_window(parent, "noti-window");
519 e = evas_object_evas_get(wd->win);
520 obj = elm_widget_add(e);
521 ELM_SET_WIDTYPE(widtype, "tickernoti");
522 elm_widget_type_set(obj, widtype);
523 elm_widget_sub_object_add(wd->win, obj);
524 elm_widget_data_set(obj, wd);
525 elm_widget_del_hook_set(obj, _del_hook);
526 elm_widget_theme_hook_set(obj, _theme_hook);
527 elm_widget_can_focus_set(obj, 0);
528 elm_widget_disable_hook_set(obj, _disable_hook);
530 wd->orient = ELM_TICKERNOTI_ORIENT_TOP;
532 _create_tickernoti(obj);
533 elm_widget_text_set_hook_set(obj, _elm_tickernoti_label_set);
534 elm_widget_text_get_hook_set(obj, _elm_tickernoti_label_get);
535 elm_widget_content_set_hook_set(obj, _elm_tickernoti_content_part_set_hook);
536 elm_widget_content_get_hook_set(obj, _elm_tickernoti_content_part_get_hook);
537 elm_widget_content_unset_hook_set(obj, _elm_tickernoti_content_part_unset_hook);
538 evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, NULL);
540 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _show, NULL);
541 evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _hide, NULL);
542 evas_object_smart_callbacks_descriptions_set(obj, _signals);
547 elm_tickernoti_rotation_get(const Evas_Object *obj)
549 ELM_CHECK_WIDTYPE(obj, widtype) -1;
550 Widget_Data *wd = elm_widget_data_get(obj);
556 elm_tickernoti_rotation_set(Evas_Object *obj, int angle)
558 ELM_CHECK_WIDTYPE(obj, widtype);
559 Widget_Data *wd = elm_widget_data_get(obj);
562 if (angle % 90) return;
564 if (angle < 0) angle += 360;
566 elm_win_rotation_with_resize_set (wd->win, angle);
570 elm_tickernoti_orient_set(Evas_Object *obj, Elm_Tickernoti_Orient orient)
572 ELM_CHECK_WIDTYPE(obj, widtype);
574 #ifdef HAVE_ELEMENTARY_X
575 Evas_Coord root_w, root_h;
577 Widget_Data *wd = elm_widget_data_get(obj);
580 if (orient >= ELM_TICKERNOTI_ORIENT_LAST) return;
582 #ifdef HAVE_ELEMENTARY_X
583 ecore_x_window_size_get(ecore_x_window_root_first_get(), &root_w, &root_h);
587 case ELM_TICKERNOTI_ORIENT_BOTTOM:
588 #ifdef HAVE_ELEMENTARY_X
589 evas_object_move(wd->win, 0, root_h - wd->noti_height);
591 wd->orient = ELM_TICKERNOTI_ORIENT_BOTTOM;
593 case ELM_TICKERNOTI_ORIENT_TOP:
595 #ifdef HAVE_ELEMENTARY_X
596 evas_object_move(wd->win, 0, 0);
598 wd->orient = ELM_TICKERNOTI_ORIENT_TOP;
601 #ifdef HAVE_ELEMENTARY_X
602 _update_window_hints(wd->win);
606 EAPI Elm_Tickernoti_Orient
607 elm_tickernoti_orient_get(const Evas_Object *obj)
609 ELM_CHECK_WIDTYPE(obj, widtype) -1;
610 Widget_Data *wd = elm_widget_data_get(obj);
612 if (!wd) return ELM_TICKERNOTI_ORIENT_LAST;
617 elm_tickernoti_win_get(const Evas_Object *obj)
619 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
620 Widget_Data *wd = elm_widget_data_get(obj);
621 if (!wd) return NULL;
626 elm_tickernoti_detailview_label_set(Evas_Object *obj, const char *label)
628 _elm_tickernoti_label_set(obj, NULL, label);
632 elm_tickernoti_detailview_label_get(const Evas_Object *obj)
634 return _elm_tickernoti_label_get(obj, NULL);
638 elm_tickernoti_detailview_button_set(Evas_Object *obj, Evas_Object *button)
640 _elm_tickernoti_button_set(obj, button);
644 elm_tickernoti_detailview_button_get(const Evas_Object *obj)
646 return _elm_tickernoti_button_get(obj);
650 elm_tickernoti_detailview_icon_set(Evas_Object *obj, Evas_Object *icon)
652 _elm_tickernoti_icon_set(obj, icon);
656 elm_tickernoti_detailview_icon_get(const Evas_Object *obj)
658 return _elm_tickernoti_icon_get(obj);
661 EAPI Elm_Tickernoti_Mode
662 elm_tickernoti_mode_get(const Evas_Object *obj)
664 ELM_CHECK_WIDTYPE(obj, widtype) -1;
665 Widget_Data *wd = elm_widget_data_get(obj);
671 elm_tickernoti_mode_set(Evas_Object *obj, Elm_Tickernoti_Mode mode)
673 ELM_CHECK_WIDTYPE(obj, widtype);
674 Widget_Data *wd = elm_widget_data_get(obj);
678 case ELM_TICKERNOTI_DEFAULT:
679 case ELM_TICKERNOTI_DETAILVIEW:
688 elm_tickernoti_detailview_get(const Evas_Object *obj)
690 return elm_tickernoti_win_get(obj);
694 elm_tickernoti_orientation_set(Evas_Object *obj, Elm_Tickernoti_Orient orient)
696 elm_tickernoti_orient_set(obj, orient);
699 EAPI Elm_Tickernoti_Orient
700 elm_tickernoti_orientation_get(const Evas_Object *obj)
702 return elm_tickernoti_orient_get(obj);
706 elm_tickernoti_label_set(Evas_Object *obj, const char *label)
708 _elm_tickernoti_label_set(obj, NULL, label);
712 elm_tickernoti_label_get(const Evas_Object *obj)
714 return _elm_tickernoti_label_get(obj, NULL);
718 elm_tickernoti_button_set(Evas_Object *obj, Evas_Object *button)
720 _elm_tickernoti_button_set(obj, button);
724 elm_tickernoti_button_get(const Evas_Object *obj)
726 return _elm_tickernoti_button_get(obj);
730 elm_tickernoti_icon_set(Evas_Object *obj, Evas_Object *icon)
732 _elm_tickernoti_icon_set(obj, icon);
736 elm_tickernoti_icon_get(const Evas_Object *obj)
738 return _elm_tickernoti_icon_get(obj);