1 #include <Elementary.h>
5 * @defgroup TickerNoti TickerNoti
8 * This is a notification widget which can be used to display some short information.
11 typedef struct _Widget_Data Widget_Data;
16 Evas_Object *edje_obj;
19 Ecore_Event_Handler *rotation_event_handler;
23 Elm_Tickernoti_Mode mode;
24 Elm_Tickernoti_Orient orient;
27 static const char *widtype = NULL;
28 static void _del_hook(Evas_Object *obj);
29 static void _theme_hook(Evas_Object *obj);
30 static void _sizing_eval(Evas_Object *obj);
31 static void _update_geometry_on_rotation(Evas_Object *obj, int angle, int *x, int *y, int *w);
33 static const char SIG_CLICKED[] = "clicked";
34 static const char SIG_HIDDEN[] = "hide";
35 static const Evas_Smart_Cb_Description _signals[] = {
44 evas_object_del(data);
48 _del_hook(Evas_Object *obj)
51 Widget_Data *wd = elm_widget_data_get(obj);
54 parent = elm_widget_parent_get(obj);
55 if (wd->rotation_event_handler)
56 ecore_event_handler_del(wd->rotation_event_handler);
57 if (wd->win) ecore_job_add(_del_job, parent);
58 evas_object_del(wd->edje_obj);
64 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
66 Widget_Data *wd = elm_widget_data_get(obj);
69 edje_object_mirrored_set(wd->edje_obj, rtl);
73 _theme_hook(Evas_Object *obj)
75 char *data_win_height = NULL;
77 Widget_Data *wd = elm_widget_data_get(obj);
80 _elm_widget_mirrored_reload(obj);
81 _mirrored_set(obj, elm_widget_mirrored_get(obj));
83 _elm_theme_object_set(wd->win, wd->edje_obj, "tickernoti",
84 "base", elm_widget_style_get(obj));
86 edje_object_scale_set(wd->edje_obj, elm_widget_scale_get(obj) * _elm_config->scale);
88 /* tickernoti detail height set */
89 data_win_height = (char *)edje_object_data_get(wd->edje_obj, "height");
90 if (data_win_height != NULL && elm_scale_get() > 0.0)
91 wd->noti_height = (int)(elm_scale_get() * atoi(data_win_height));
93 evas_object_geometry_get(wd->win, NULL, NULL, &w, NULL);
94 evas_object_resize(wd->win, w, wd->noti_height);
97 edje_object_part_text_set(wd->edje_obj, "elm.text", wd->label);
99 edje_object_part_swallow(wd->edje_obj, "icon", wd->icon);
101 edje_object_part_swallow(wd->edje_obj, "button", wd->button);
102 edje_object_signal_emit(wd->edje_obj, "effect,show", "elm");
103 edje_object_message_signal_process(wd->edje_obj);
109 _sizing_eval(Evas_Object *obj)
111 Widget_Data *wd = elm_widget_data_get(obj);
112 Evas_Coord minw = -1, minh = -1;
115 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
116 edje_object_size_min_restricted_calc(wd->edje_obj, &minw, &minh, minw, minh);
117 evas_object_size_hint_min_set(obj, minw, minh);
120 #ifdef HAVE_ELEMENTARY_X
122 _update_window_hints(Evas_Object *obj)
125 Ecore_X_Atom _notification_level_atom;
127 // elm_win_xwindow_get() must call after elm_win_alpha_set()
128 xwin = elm_win_xwindow_get(obj);
130 ecore_x_icccm_hints_set(xwin, 0, ECORE_X_WINDOW_STATE_HINT_NONE, 0, 0, 0, 0, 0);
131 ecore_x_netwm_window_type_set(xwin, ECORE_X_WINDOW_TYPE_NOTIFICATION);
132 ecore_x_netwm_opacity_set(xwin, 0);
133 // Create atom for notification level
134 _notification_level_atom = ecore_x_atom_get("_E_ILLUME_NOTIFICATION_LEVEL");
136 // HIGH:150, NORMAL:100, LOW:50
139 // Set notification level of the window
140 ecore_x_window_prop_property_set(xwin, _notification_level_atom, ECORE_X_ATOM_CARDINAL, 32, &level, 1);
144 static void _hide_cb(void *data, Evas_Object *obj __UNUSED__,
145 const char *emission __UNUSED__,
146 const char *source __UNUSED__)
148 Widget_Data *wd = elm_widget_data_get(data);
151 evas_object_hide(wd->win);
152 evas_object_smart_callback_call(data, SIG_HIDDEN, NULL);
155 static void _clicked_cb(void *data, Evas_Object *obj __UNUSED__,
156 const char *emission __UNUSED__,
157 const char *source __UNUSED__)
159 Widget_Data *wd = elm_widget_data_get(data);
162 evas_object_smart_callback_call(data, SIG_CLICKED, NULL);
166 *_create_window(Evas_Object *parent, const char *name)
170 win = elm_win_add(parent, name, ELM_WIN_BASIC);
171 elm_win_title_set(win, name);
172 elm_win_borderless_set(win, EINA_TRUE);
173 elm_win_autodel_set(win, EINA_TRUE);
174 elm_win_alpha_set(win, EINA_TRUE);
175 evas_object_size_hint_weight_set(win, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
176 evas_object_size_hint_align_set(win, EVAS_HINT_FILL, EVAS_HINT_FILL);
178 #ifdef HAVE_ELEMENTARY_X
180 _update_window_hints(win);
186 _win_rotated(Evas_Object *obj)
188 Widget_Data *wd = elm_widget_data_get(obj);
189 int x = 0, y = 0, w = 0, angle = 0;
192 angle = elm_win_rotation_get(wd->win);
193 while (angle < 0) angle += 360;
194 while (angle >= 360) angle -= 360;
195 if (angle%90 != 0) return;
197 _update_geometry_on_rotation(obj, wd->angle, &x, &y, &w);
198 evas_object_move(wd->win, x, y);
199 evas_object_resize(wd->win, w, wd->noti_height);
200 #ifdef HAVE_ELEMENTARY_X
201 _update_window_hints(wd->win);
206 _prop_change(void *data, int type __UNUSED__, void *event)
208 #ifdef HAVE_ELEMENTARY_X
209 Ecore_X_Event_Window_Property *ev;
210 Widget_Data *wd = elm_widget_data_get(data);
212 if (!wd) return ECORE_CALLBACK_PASS_ON;
214 if (ev->atom == ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE)
216 if (ev->win == elm_win_xwindow_get(wd->win))
221 return ECORE_CALLBACK_PASS_ON;
226 _create_tickernoti(Evas_Object *obj)
228 #ifdef HAVE_ELEMENTARY_X
231 Widget_Data *wd = elm_widget_data_get(obj);
232 char *data_win_height = NULL;
237 evas_object_move(wd->win, 0, 0);
238 e = evas_object_evas_get(wd->win);
240 wd->edje_obj = edje_object_add(e);
241 _elm_theme_object_set(wd->win, wd->edje_obj, "tickernoti", "base", "default");
242 elm_win_resize_object_add(wd->win, wd->edje_obj);
244 // tickernoti height setting
245 data_win_height = (char *)edje_object_data_get(wd->edje_obj, "height");
246 if (data_win_height != NULL && elm_scale_get() > 0.0)
247 wd->noti_height = (int)(elm_scale_get() * atoi(data_win_height));
249 #ifdef HAVE_ELEMENTARY_X
250 ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, NULL);
251 evas_object_resize(wd->win, w, wd->noti_height);
252 wd->rotation_event_handler = ecore_event_handler_add(
253 ECORE_X_EVENT_WINDOW_PROPERTY, _prop_change, obj);
256 edje_object_signal_callback_add(wd->edje_obj, "request,hide", "", _hide_cb, obj);
257 edje_object_signal_callback_add(wd->edje_obj, "clicked", "", _clicked_cb, obj);
258 evas_object_show(wd->edje_obj);
262 _disable_hook(Evas_Object *obj)
264 Widget_Data *wd = elm_widget_data_get(obj);
267 //TODO: To stop the event in case of being disabled
271 _show(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
272 void *event_info __UNUSED__)
274 Widget_Data *wd = elm_widget_data_get(obj);
277 #ifdef HAVE_ELEMENTARY_X
278 _update_window_hints(wd->win);
280 evas_object_show(wd->win);
281 edje_object_signal_emit(wd->edje_obj, "effect,show", "elm");
282 edje_object_message_signal_process(wd->edje_obj);
286 _hide(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
287 void *event_info __UNUSED__)
289 Widget_Data *wd = elm_widget_data_get(obj);
292 evas_object_hide(wd->win);
295 static void _tickernoti_hide_cb(void *data, Evas_Object *obj __UNUSED__,
296 void *event_info __UNUSED__)
298 Widget_Data *wd = data;
302 edje_object_signal_emit(wd->edje_obj, "effect,hide", "elm");
303 edje_object_message_signal_process(wd->edje_obj);
307 _update_geometry_on_rotation(Evas_Object *obj, int angle, int *x, int *y, int *w)
309 ELM_CHECK_WIDTYPE(obj, widtype);
310 Widget_Data *wd = elm_widget_data_get(obj);
314 #ifdef HAVE_ELEMENTARY_X
315 Evas_Coord root_w, root_h;
318 * manual calculate win_tickernoti_indi window position & size
319 * - win_indi is not full size window
321 ecore_x_window_size_get(ecore_x_window_root_first_get(), &root_w, &root_h);
327 if (wd->orient == ELM_TICKERNOTI_ORIENT_BOTTOM)
328 *x = root_w-wd->noti_height;
332 if (!(wd->orient == ELM_TICKERNOTI_ORIENT_BOTTOM))
333 *x = root_w-wd->noti_height;
337 if (!wd->orient == ELM_TICKERNOTI_ORIENT_BOTTOM)
338 *y = root_h - wd->noti_height;
343 if (wd->orient == ELM_TICKERNOTI_ORIENT_BOTTOM)
344 *y = root_h - wd->noti_height;
351 _elm_tickernoti_label_set(Evas_Object *obj, const char *part, const char *label)
353 ELM_CHECK_WIDTYPE(obj, widtype);
354 Widget_Data *wd = elm_widget_data_get(obj);
357 if (part && strcmp(part, "default")) return;
358 eina_stringshare_replace(&wd->label, label);
359 edje_object_part_text_set(wd->edje_obj, "elm.text", wd->label);
364 _elm_tickernoti_label_get(const Evas_Object *obj, const char *part)
366 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
367 Widget_Data *wd = elm_widget_data_get(obj);
369 if (part && strcmp(part, "default")) return NULL;
370 if (!wd) return NULL;
375 _elm_tickernoti_icon_set(Evas_Object *obj, Evas_Object *icon)
377 ELM_CHECK_WIDTYPE(obj, widtype);
378 Widget_Data *wd = elm_widget_data_get(obj);
382 edje_object_part_swallow(wd->edje_obj, "icon", icon);
387 _elm_tickernoti_button_set(Evas_Object *obj, Evas_Object *button)
389 ELM_CHECK_WIDTYPE(obj, widtype);
390 Widget_Data *wd = elm_widget_data_get(obj);
393 edje_object_part_swallow(wd->edje_obj, "button", button);
395 evas_object_smart_callback_add(wd->button, "clicked", _tickernoti_hide_cb, wd);
399 _elm_tickernoti_content_part_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
401 ELM_CHECK_WIDTYPE(obj, widtype);
402 Widget_Data *wd = elm_widget_data_get(obj);
404 if (!wd || !part) return;
405 if (!part || !strcmp(part, "icon"))
407 _elm_tickernoti_icon_set(obj, content);
410 else if (!strcmp(part, "button"))
412 _elm_tickernoti_button_set(obj, content);
418 _elm_tickernoti_icon_get(const Evas_Object *obj)
420 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
421 Widget_Data *wd = elm_widget_data_get(obj);
422 if (!wd) return NULL;
427 _elm_tickernoti_button_get(const Evas_Object *obj)
429 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
430 Widget_Data *wd = elm_widget_data_get(obj);
431 if (!wd) return NULL;
436 _elm_tickernoti_content_part_get_hook(Evas_Object *obj, const char *part)
438 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
439 Widget_Data *wd = elm_widget_data_get(obj);
441 if (!wd || !part) return NULL;
442 if (!part || !strcmp(part, "icon"))
443 return _elm_tickernoti_icon_get(obj);
444 else if (!strcmp(part, "button"))
445 return _elm_tickernoti_button_get(obj);
450 * Add a tickernoti object to @p parent
452 * @param parent The parent object
454 * @return The tickernoti object, or NULL upon failure
456 * @ingroup TickerNoti
459 elm_tickernoti_add(Evas_Object *parent)
465 wd = ELM_NEW(Widget_Data);
466 wd->win = _create_window(parent, "noti-window");
468 e = evas_object_evas_get(wd->win);
469 obj = elm_widget_add(e);
470 ELM_SET_WIDTYPE(widtype, "tickernoti");
471 elm_widget_type_set(obj, widtype);
472 elm_widget_sub_object_add(wd->win, obj);
473 elm_widget_data_set(obj, wd);
474 elm_widget_del_hook_set(obj, _del_hook);
475 elm_widget_theme_hook_set(obj, _theme_hook);
476 elm_widget_can_focus_set(obj, 0);
477 elm_widget_disable_hook_set(obj, _disable_hook);
479 wd->orient = ELM_TICKERNOTI_ORIENT_TOP;
481 _create_tickernoti(obj);
482 elm_widget_text_set_hook_set(obj, _elm_tickernoti_label_set);
483 elm_widget_text_get_hook_set(obj, _elm_tickernoti_label_get);
484 elm_widget_content_set_hook_set(obj, _elm_tickernoti_content_part_set_hook);
485 elm_widget_content_get_hook_set(obj, _elm_tickernoti_content_part_get_hook);
487 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _show, NULL);
488 evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _hide, NULL);
489 evas_object_smart_callbacks_descriptions_set(obj, _signals);
494 * Get the rotation of tickernoti object
496 * @param obj The tickernotil object
497 * @return The rotation angle
498 * @ingroup TickerNoti
501 elm_tickernoti_rotation_get(const Evas_Object *obj)
503 ELM_CHECK_WIDTYPE(obj, widtype) -1;
504 Widget_Data *wd = elm_widget_data_get(obj);
510 * Set the rotation angle for the tickernoti object
512 * @param obj The tickernoti object
513 * @param angle The rotation angle(in degree) will be used on the tickernoti object
514 * @ingroup TickerNoti
517 elm_tickernoti_rotation_set(Evas_Object *obj, int angle)
519 ELM_CHECK_WIDTYPE(obj, widtype);
520 Widget_Data *wd = elm_widget_data_get(obj);
523 if (angle%90 != 0) return;
525 while (angle < 0) angle += 360;
526 while (angle >= 360) angle -= 360;
527 elm_win_rotation_with_resize_set (wd->win, angle);
531 * Set the orientation of the tickernoti object
533 * @param obj The tickernoti object
534 * @param orient The orientation of tickernoti object
535 * @ingroup TickerNoti
538 elm_tickernoti_orient_set(Evas_Object *obj, Elm_Tickernoti_Orient orient)
540 ELM_CHECK_WIDTYPE(obj, widtype);
542 #ifdef HAVE_ELEMENTARY_X
543 Evas_Coord root_w, root_h;
545 Widget_Data *wd = elm_widget_data_get(obj);
548 if (orient >= ELM_TICKERNOTI_ORIENT_LAST) return;
550 #ifdef HAVE_ELEMENTARY_X
551 ecore_x_window_size_get(ecore_x_window_root_first_get(), &root_w, &root_h);
555 case ELM_TICKERNOTI_ORIENT_BOTTOM:
556 #ifdef HAVE_ELEMENTARY_X
557 evas_object_move(wd->win, 0, root_h - wd->noti_height);
559 wd->orient = ELM_TICKERNOTI_ORIENT_BOTTOM;
561 case ELM_TICKERNOTI_ORIENT_TOP:
563 #ifdef HAVE_ELEMENTARY_X
564 evas_object_move(wd->win, 0, 0);
566 wd->orient = ELM_TICKERNOTI_ORIENT_TOP;
569 #ifdef HAVE_ELEMENTARY_X
570 _update_window_hints(wd->win);
575 * Get the orientation of the tickernoti object
577 * @param obj The tickernotil object
578 * @return The orientation of tickernotil object
580 * @ingroup TickerNoti
582 EAPI Elm_Tickernoti_Orient
583 elm_tickernoti_orient_get(const Evas_Object *obj)
585 ELM_CHECK_WIDTYPE(obj, widtype) -1;
586 Widget_Data *wd = elm_widget_data_get(obj);
588 if (!wd) return ELM_TICKERNOTI_ORIENT_LAST;
593 * Get the view window(elm_win) on the tickernoti object
595 * @param obj The tickernotil object
596 * @return internal view window(elm_win) object
598 * @ingroup TickerNoti
601 elm_tickernoti_win_get(const Evas_Object *obj)
603 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
604 Widget_Data *wd = elm_widget_data_get(obj);
605 if (!wd) return NULL;
609 // ################### Below APIs are going to be removed. ###########################
611 * Set the detail label on the tickernoti object
613 * @param obj The tickernoti object
614 * @param label The label will be used on the tickernoti object
615 * @deprecated use elm_object_text_set() instead
617 * @ingroup TickerNoti
620 elm_tickernoti_detailview_label_set(Evas_Object *obj, const char *label)
622 _elm_tickernoti_label_set(obj, NULL, label);
626 * Get the detail label used on the tickernoti object
628 * @param obj The tickernotil object
629 * @return The string inside the label
630 * @deprecated use elm_object_text_get() instead
632 * @ingroup TickerNoti
635 elm_tickernoti_detailview_label_get(const Evas_Object *obj)
637 return _elm_tickernoti_label_get(obj, NULL);
641 * Set the button object used on the tickernoti object
643 * @param obj The tickernotil object
644 * @param button The button object will be used on the tickernoti object
645 * @deprecated use elm_object_content_part_set() instead with "icon" as part name
647 * @ingroup TickerNoti
650 elm_tickernoti_detailview_button_set(Evas_Object *obj, Evas_Object *button)
652 _elm_tickernoti_button_set(obj, button);
657 * Get the button object used on the tickernoti object
659 * @param obj The tickernotil object
660 * @return The button object inside the tickernoti
661 * @deprecated use elm_object_content_part_get() instead with "button" as part name
663 * @ingroup TickerNoti
666 elm_tickernoti_detailview_button_get(const Evas_Object *obj)
668 return _elm_tickernoti_button_get(obj);
672 * Set the detail icon object used on the tickernoti object
674 * @param obj The tickernotil object
675 * @param icon The icon object will be used on the tickernoti object
676 * @deprecated use elm_object_content_part_set() instead with "icon" as part name
678 * @ingroup TickerNoti
681 elm_tickernoti_detailview_icon_set(Evas_Object *obj, Evas_Object *icon)
683 _elm_tickernoti_icon_set(obj, icon);
687 * Get the detail icon object used on the tickernoti object
689 * @param obj The tickernotil object
690 * @return The icon object inside the tickernoti
691 * @deprecated use elm_object_content_part_get() instead with "icon" as part name
693 * @ingroup TickerNoti
696 elm_tickernoti_detailview_icon_get(const Evas_Object *obj)
698 return _elm_tickernoti_icon_get(obj);
702 * Get the view mode on the tickernoti object
704 * @param obj The tickernotil object
705 * @return The view mode
706 * @deprecated removed as now styles are used instead
708 * @ingroup TickerNoti
710 EAPI Elm_Tickernoti_Mode
711 elm_tickernoti_mode_get(const Evas_Object *obj)
713 ELM_CHECK_WIDTYPE(obj, widtype) -1;
714 Widget_Data *wd = elm_widget_data_get(obj);
720 * Set the view mode used on the tickernoti object
722 * @param obj The tickernotil object
723 * @param mode The view mode will be used on the tickernoti object
724 * @deprecated removed as now styles are used instead
726 * @ingroup TickerNoti
729 elm_tickernoti_mode_set(Evas_Object *obj, Elm_Tickernoti_Mode mode)
731 ELM_CHECK_WIDTYPE(obj, widtype);
732 Widget_Data *wd = elm_widget_data_get(obj);
736 case ELM_TICKERNOTI_DEFAULT:
737 case ELM_TICKERNOTI_DETAILVIEW:
746 * Get the detail view window(elm_win) on the tickernoti object
748 * @param obj The tickernotil object
749 * @return detail view window(elm_win) object
750 * @ingroup TickerNoti
753 elm_tickernoti_detailview_get(const Evas_Object *obj)
755 return elm_tickernoti_win_get(obj);
759 * Set the orientation of the tickernoti object
761 * @param obj The tickernoti object
762 * @param orient The orientation of tickernoti object
763 * @deprecated use elm_tickernoti_orient_set() instead
765 * @ingroup TickerNoti
768 elm_tickernoti_orientation_set(Evas_Object *obj, Elm_Tickernoti_Orient orient)
770 elm_tickernoti_orient_set(obj, orient);
774 * Get the orientation of the tickernoti object
776 * @param obj The tickernotil object
777 * @return The orientation of tickernotil object
778 * @deprecated use elm_tickernoti_orient_get() instead
780 * @ingroup TickerNoti
782 EAPI Elm_Tickernoti_Orient
783 elm_tickernoti_orientation_get(const Evas_Object *obj)
785 return elm_tickernoti_orient_get(obj);
789 * Set the label on the tickernoti object
791 * @param obj The tickernoti object
792 * @param label The label will be used on the tickernoti object
793 * @deprecated use elm_object_text_get()
795 * @ingroup TickerNoti
798 elm_tickernoti_label_set(Evas_Object *obj, const char *label)
800 _elm_tickernoti_label_set(obj, NULL, label);
804 * Get the label used on the tickernoti object
806 * @param obj The tickernotil object
807 * @return The string inside the label
808 * @deprecated use elm_object_text_get() instead
810 * @ingroup TickerNoti
813 elm_tickernoti_label_get(const Evas_Object *obj)
815 return _elm_tickernoti_label_get(obj, NULL);
819 * Set the action button object used on the tickernoti object
821 * @param obj The tickernotil object
822 * @param button The button object will be used on the tickernoti object
823 * @deprecated use elm_object_content_part_set() instead with "button" as part name
825 * @ingroup TickerNoti
828 elm_tickernoti_button_set(Evas_Object *obj, Evas_Object *button)
830 _elm_tickernoti_button_set(obj, button);
834 * Get the action button object used on the tickernoti object
836 * @param obj The tickernotil object
837 * @return The button object inside the tickernoti
838 * @deprecated use elm_object_content_part_get() instead with "button" as part name
840 * @ingroup TickerNoti
843 elm_tickernoti_button_get(const Evas_Object *obj)
845 return _elm_tickernoti_button_get(obj);
849 * Set the icon object of the tickernoti object
851 * @param obj The tickernotil object
852 * @param icon The icon object will be used on the tickernoti object
853 * @deprecated use elm_object_content_part_set() instead with "icon" as part name
855 * @ingroup TickerNoti
858 elm_tickernoti_icon_set(Evas_Object *obj, Evas_Object *icon)
860 _elm_tickernoti_icon_set(obj, icon);
864 * Get the icon object of the tickernoti object
866 * @param obj The tickernotil object
867 * @return The icon object inside the tickernoti
868 * @deprecated use elm_object_content_part_get() instead with "icon" as part name
870 * @ingroup TickerNoti
873 elm_tickernoti_icon_get(const Evas_Object *obj)
875 return _elm_tickernoti_icon_get(obj);