Merge branch 'master' into svn_merge
[framework/uifw/elementary.git] / src / lib / elm_tickernoti.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 /**
5  * @defgroup TickerNoti TickerNoti
6  * @ingroup Elementary
7  *
8  */
9
10 typedef struct _Widget_Data Widget_Data;
11
12 struct _Widget_Data
13 {
14    Evas_Object *win_indi;
15    Evas_Object *win_detail;
16    Evas_Object *edje_indi;
17    Evas_Object *edje_detail;
18    Evas_Object *icon_indi;
19    Evas_Object *icon_detail;
20    Evas_Object *button_detail;
21
22    const char *label_indi;
23    const char *label_detail;
24
25    int indicator_height;
26    int detail_view_height;
27    int angle;
28
29    Elm_Tickernoti_Mode mode;
30 };
31
32 static const char *widtype = NULL;
33 static void _del_hook(Evas_Object *obj);
34 static void _theme_hook(Evas_Object *obj);
35 static void _sizing_eval(Evas_Object *obj);
36
37 static void
38 _del_job(void *data)
39 {
40    Evas_Object *obj = data;
41    evas_object_del(obj);
42 }
43
44 static void
45 _del_hook(Evas_Object *obj)
46 {
47    Widget_Data *wd = elm_widget_data_get(obj);
48    if (!wd) return;
49
50    Evas_Object *p = elm_widget_parent_get(obj);
51    if (p == wd->win_indi) ecore_job_add (_del_job, p);
52    
53    evas_object_del (wd->edje_indi);
54    wd->edje_indi = NULL;
55    evas_object_del (wd->edje_detail);
56    wd->edje_detail = NULL;
57    evas_object_del (wd->win_detail);
58    wd->win_detail = NULL;
59
60    free(wd);
61 }
62
63 static void
64 _theme_hook(Evas_Object *obj)
65 {
66    Widget_Data *wd = elm_widget_data_get(obj);
67    char *data_win_height = NULL;
68
69    if (!wd) return;
70
71    _elm_theme_object_set (wd->win_indi, wd->edje_indi, "tickernoti", "base", elm_widget_style_get(obj));
72    _elm_theme_object_set (wd->edje_detail, wd->edje_detail, "tickernoti", "2line", elm_widget_style_get(obj));
73
74    edje_object_scale_set (wd->edje_indi, elm_widget_scale_get(obj) * _elm_config->scale);
75    edje_object_scale_set (wd->edje_detail, elm_widget_scale_get(obj) * _elm_config->scale);
76
77    /* tickernoti indicator height set */
78    data_win_height = (char *)edje_object_data_get (wd->edje_indi, "height");
79    if (data_win_height != NULL && elm_scale_get() > 0.0)
80      wd->indicator_height = (int)(elm_scale_get() * atoi(data_win_height));
81
82    /* tickernoti detail height set */
83    data_win_height = (char *)edje_object_data_get (wd->edje_detail, "height");
84    if (data_win_height != NULL && elm_scale_get() > 0.0)
85      wd->detail_view_height = (int)(elm_scale_get() * atoi(data_win_height));
86
87 #ifdef HAVE_ELEMENTARY_X
88    Evas_Coord w;
89
90    ecore_x_window_size_get (ecore_x_window_root_first_get(), &w, NULL);
91    evas_object_resize (wd->win_indi, w, wd->indicator_height);
92    evas_object_resize (wd->win_detail, w, wd->detail_view_height);
93 #endif
94
95    _sizing_eval(obj);
96 }
97
98 static void
99 _sizing_eval(Evas_Object *obj)
100 {
101    Widget_Data *wd = elm_widget_data_get(obj);
102 //   Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
103    if (!wd) return;
104
105 /*
106    edje_object_size_min_calc(wd->win_detail, &minw, &minh);
107    evas_object_size_hint_min_set(obj, minw, minh);
108    evas_object_size_hint_max_set(obj, maxw, maxh);
109    evas_object_size_hint_align_set(obj, maxw, maxh);
110 */
111 }
112 #ifdef HAVE_ELEMENTARY_X
113 static void
114 _make_notification_window (Evas_Object *obj)
115 {
116    Widget_Data *wd = elm_widget_data_get(obj);
117    if (!wd) return;
118
119    Ecore_X_Window xwin;
120    Ecore_X_Atom _notification_level_atom;
121    int level;
122 /* elm_win_xwindow_get() must call after elm_win_alpha_set() */
123    xwin = elm_win_xwindow_get (obj);
124    ecore_x_netwm_window_type_set (xwin, ECORE_X_WINDOW_TYPE_NOTIFICATION);
125    ecore_x_icccm_hints_set(xwin, 0, ECORE_X_WINDOW_STATE_HINT_NONE, 0, 0, 0, 0, 0);
126
127    /* Create atom for notification level */
128    _notification_level_atom = ecore_x_atom_get ("_E_ILLUME_NOTIFICATION_LEVEL");
129
130    /* HIGH:150, NORMAL:100, LOW:50 */
131    level = 100;
132
133    /* Set notification level of the window */
134    ecore_x_window_prop_property_set (xwin, _notification_level_atom, ECORE_X_ATOM_CARDINAL, 32, &level, 1);
135 }
136 #endif
137
138 static void _detail_show_cb (void *data, Evas_Object *obj __UNUSED__,
139                              const char *emission __UNUSED__,
140                              const char *source __UNUSED__)
141 {
142    evas_object_smart_callback_call ((Evas_Object *)data, "detail,show", NULL);
143 }
144
145 static void _detail_hide_cb (void *data, Evas_Object *obj __UNUSED__,
146                              const char *emission __UNUSED__,
147                              const char *source __UNUSED__)
148 {
149    evas_object_smart_callback_call ((Evas_Object *)data, "detail,hide", NULL);
150 }
151
152 static Evas_Object 
153 *_create_window (Evas_Object *parent, const char *name)
154 {
155    Evas_Object *win;
156
157    win = elm_win_add (parent, name, ELM_WIN_BASIC);
158 /* Property */
159    elm_win_title_set (win, name);
160    elm_win_borderless_set (win, EINA_TRUE);
161    elm_win_autodel_set (win, EINA_TRUE);
162    elm_win_alpha_set (win, EINA_TRUE);
163
164 #ifdef HAVE_ELEMENTARY_X
165 /* set top window */
166    _make_notification_window (win);
167 #endif
168    return win;
169 }
170
171 static void 
172 _create_tickernoti_indi (Evas_Object *obj)
173 {
174    Widget_Data *wd = elm_widget_data_get(obj);
175    if (!wd) return;
176
177    Evas *e;
178 #ifdef HAVE_ELEMENTARY_X
179    Evas_Coord w;
180 #endif
181
182    char *data_win_height = NULL; 
183    evas_object_move (wd->win_indi, 0, 0);
184
185    e = evas_object_evas_get (wd->win_indi);
186
187    wd->edje_indi = edje_object_add (e);
188    _elm_theme_object_set (wd->win_indi, wd->edje_indi, "tickernoti", "base", "default");
189    elm_win_resize_object_add (wd->win_indi, wd->edje_indi);
190
191    /* tickernoti indicator height set */
192    data_win_height = (char *)edje_object_data_get (wd->edje_indi, "height");
193    if (data_win_height != NULL && elm_scale_get() > 0.0) 
194      wd->indicator_height = (int)(elm_scale_get() * atoi(data_win_height));
195
196 #ifdef HAVE_ELEMENTARY_X
197    ecore_x_window_size_get (ecore_x_window_root_first_get(), &w, NULL);
198    evas_object_resize (wd->win_indi, w, wd->indicator_height);
199 #endif
200         
201    edje_object_signal_callback_add (wd->edje_indi, "request,detail,show", "", _detail_show_cb, obj);
202    evas_object_show (wd->edje_indi);
203 }
204
205 static void 
206 _create_tickernoti_detail (Evas_Object *obj)
207 {
208    Widget_Data *wd = elm_widget_data_get(obj);
209    char *data_win_height = NULL;
210
211    if (!wd) return;
212
213    Evas *e;
214
215    evas_object_move (wd->win_detail, 0, 0);
216    e = evas_object_evas_get (wd->win_detail);
217
218    wd->edje_detail = edje_object_add (e);
219    _elm_theme_object_set (wd->win_detail, wd->edje_detail, "tickernoti", "2line", "default");
220    elm_win_resize_object_add (wd->win_detail, wd->edje_detail);
221
222    /* tickernoti detail height set */
223    data_win_height = (char *)edje_object_data_get (wd->edje_detail, "height");
224    if (data_win_height != NULL && elm_scale_get() > 0.0)
225      wd->detail_view_height = (int)(elm_scale_get() * atoi(data_win_height));
226
227 #ifdef HAVE_ELEMENTARY_X
228    Evas_Coord w;
229
230    ecore_x_window_size_get (ecore_x_window_root_first_get(), &w, NULL);
231    evas_object_resize (wd->win_detail, w, wd->detail_view_height);
232 #endif
233
234    edje_object_signal_callback_add(wd->edje_detail, "request,detail,hide", "", _detail_hide_cb, obj);
235    evas_object_show (wd->edje_detail);
236 }
237
238 static void
239 _show(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
240       void *event_info __UNUSED__)
241 {
242    Widget_Data *wd = elm_widget_data_get(obj);
243    if (!wd) return;
244
245    if (wd->mode == ELM_TICKERNOTI_DEFAULT) 
246      {
247         evas_object_hide (wd->win_detail);
248 #ifdef HAVE_ELEMENTARY_X
249         _make_notification_window (wd->win_indi);
250 #endif
251         evas_object_show (wd->win_indi);
252         edje_object_signal_emit (wd->edje_indi, "effect,show", "bg_1line");
253      }
254    else if (wd->mode == ELM_TICKERNOTI_DETAILVIEW) 
255      {
256         evas_object_hide (wd->win_indi);
257 #ifdef HAVE_ELEMENTARY_X
258         _make_notification_window (wd->win_detail);
259 #endif
260         evas_object_show (wd->win_detail);
261         edje_object_signal_emit (wd->edje_detail, "effect,show", "bg_2line");
262      }
263 }
264
265 static void
266 _hide(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
267       void *event_info __UNUSED__)
268 {
269    Widget_Data *wd = elm_widget_data_get(obj);
270
271    if (!wd) return;
272    evas_object_hide (obj); 
273    evas_object_hide (wd->win_indi);
274    evas_object_hide (wd->win_detail);
275 }
276
277 /**
278  * Add a tickernoti object to @p parent
279  *
280  * @param parent The parent object
281  *
282  * @return The tickernoti object, or NULL upon failure
283  *
284  * @ingroup TickerNoti
285  */
286 EAPI Evas_Object *
287 elm_tickernoti_add(Evas_Object *parent)
288 {
289    Evas_Object *obj;
290    Evas *e;
291    Widget_Data *wd;
292
293    wd = ELM_NEW(Widget_Data);
294    wd->win_indi = _create_window (parent, "indi");
295    wd->win_detail = _create_window (parent, "detail");
296
297    if (!parent) parent = wd->win_indi;
298
299    e = evas_object_evas_get(parent);
300    obj = elm_widget_add(e);
301    ELM_SET_WIDTYPE(widtype, "tickernoti");
302    elm_widget_type_set(obj, "tickernoti");
303    elm_widget_sub_object_add(parent, obj);
304    elm_widget_data_set(obj, wd);
305    elm_widget_del_hook_set(obj, _del_hook);
306    elm_widget_theme_hook_set(obj, _theme_hook);
307    elm_widget_can_focus_set(obj, 0);
308
309    wd->edje_indi = NULL;
310    wd->edje_detail = NULL;
311    wd->icon_indi = NULL;
312    wd->icon_detail = NULL;
313    wd->button_detail = NULL;
314
315    wd->label_indi = NULL;
316    wd->label_detail = NULL;
317
318    wd->indicator_height = 0;
319    wd->angle = 0;
320
321    wd->mode = ELM_TICKERNOTI_DEFAULT;
322
323    _create_tickernoti_indi (obj);
324    _create_tickernoti_detail (obj);
325
326    evas_object_event_callback_add (obj, EVAS_CALLBACK_SHOW, _show, NULL);
327    evas_object_event_callback_add (obj, EVAS_CALLBACK_HIDE, _hide, NULL);
328
329    return obj;
330 }
331
332
333 /**
334  * Set the icon object used on the tickernoti object
335  *
336  * @param obj The tickernotil object
337  * @param icon The icon object will be used on the tickernoti object
338  * @ingroup TickerNoti
339  */
340 EAPI void 
341 elm_tickernoti_icon_set (const Evas_Object *obj, Evas_Object *icon)
342 {
343    ELM_CHECK_WIDTYPE(obj, widtype);
344    Widget_Data *wd = elm_widget_data_get(obj);
345    if (!wd) return;
346    if (!icon) return;
347    edje_object_part_swallow (wd->edje_indi, "icon", icon);
348    wd->icon_indi = icon;
349 }
350
351 /**
352  * Get the icon object used on the tickernoti object
353  *
354  * @param obj The tickernotil object
355  * @return The icon object inside the tickernoti
356  * @ingroup TickerNoti
357  */
358 EAPI Evas_Object *
359 elm_tickernoti_icon_get (const Evas_Object *obj)
360 {
361    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
362    Widget_Data *wd = elm_widget_data_get(obj);
363    if (!wd) return NULL;
364    return wd->icon_indi;
365 }
366
367 /**
368  * Set the label on the tickernoti object
369  *
370  * @param obj The tickernoti object
371  * @param label The label will be used on the tickernoti object
372  *
373  * @ingroup TickerNoti
374  */
375 EAPI void
376 elm_tickernoti_label_set (Evas_Object *obj, const char *label)
377 {
378    ELM_CHECK_WIDTYPE(obj, widtype);
379    Widget_Data *wd = elm_widget_data_get(obj);
380    if (!wd) return;
381    if (!label) label = "";
382    eina_stringshare_replace(&wd->label_indi, label);
383    edje_object_part_text_set(wd->edje_indi, "text", label);
384    _sizing_eval(obj);
385 }
386
387 /**
388  * Get the label used on the tickernoti object
389  *
390  * @param obj The tickernotil object
391  * @return The string inside the label
392  * @ingroup TickerNoti
393  */
394 EAPI const char *
395 elm_tickernoti_label_get (const Evas_Object *obj)
396 {
397    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
398    Widget_Data *wd = elm_widget_data_get(obj);
399    if (!wd) return NULL;
400    return wd->label_indi;
401 }
402
403 /**
404  * Set the detail label on the tickernoti object
405  *
406  * @param obj The tickernoti object
407  * @param label The label will be used on the tickernoti object
408  *
409  * @ingroup TickerNoti
410  */
411 EAPI void
412 elm_tickernoti_detailview_label_set (Evas_Object *obj, const char *label)
413 {
414    ELM_CHECK_WIDTYPE(obj, widtype);
415    Widget_Data *wd = elm_widget_data_get(obj);
416    if (!wd) return;
417    if (!label) label = "";
418    eina_stringshare_replace(&wd->label_detail, label);
419    edje_object_part_text_set(wd->edje_detail, "text", label);
420    _sizing_eval(obj);
421 }
422
423 /**
424  * Get the detail label used on the tickernoti object
425  *
426  * @param obj The tickernotil object
427  * @return The string inside the label
428  * @ingroup TickerNoti
429  */
430 EAPI const char *
431 elm_tickernoti_detailview_label_get (const Evas_Object *obj)
432 {
433    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
434    Widget_Data *wd = elm_widget_data_get(obj);
435    if (!wd) return NULL;
436    return wd->label_detail;
437 }
438
439 /**
440  * Set the button object used on the tickernoti object
441  *
442  * @param obj The tickernotil object
443  * @param button The button object will be used on the tickernoti object
444  * @ingroup TickerNoti
445  */
446 EAPI void 
447 elm_tickernoti_detailview_button_set (const Evas_Object *obj, Evas_Object *button)
448 {
449    ELM_CHECK_WIDTYPE(obj, widtype);
450    Widget_Data *wd = elm_widget_data_get(obj);
451    if (!wd) return;
452    if (!button) return;
453    edje_object_part_swallow (wd->edje_detail, "button", button);
454    wd->button_detail = button;
455 }
456
457 /**
458  * Get the button object used on the tickernoti object
459  *
460  * @param obj The tickernotil object
461  * @return The button object inside the tickernoti
462  * @ingroup TickerNoti
463  */
464 EAPI Evas_Object *
465 elm_tickernoti_detailview_button_get (const Evas_Object *obj)
466 {
467    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
468    Widget_Data *wd = elm_widget_data_get(obj);
469    if (!wd) return NULL;
470    return wd->button_detail;
471 }
472
473 /**
474  * Set the detail icon object used on the tickernoti object
475  *
476  * @param obj The tickernotil object
477  * @param icon The icon object will be used on the tickernoti object
478  * @ingroup TickerNoti
479  */
480 EAPI void 
481 elm_tickernoti_detailview_icon_set (const Evas_Object *obj, Evas_Object *icon)
482 {
483    ELM_CHECK_WIDTYPE(obj, widtype);
484    Widget_Data *wd = elm_widget_data_get(obj);
485    if (!wd) return;
486    if (!icon) return;
487    edje_object_part_swallow (wd->edje_detail, "icon", icon);
488    wd->icon_detail = icon;
489 }
490
491 /**
492  * Get the detail icon object used on the tickernoti object
493  *
494  * @param obj The tickernotil object
495  * @return The icon object inside the tickernoti
496  * @ingroup TickerNoti
497  */
498 EAPI Evas_Object *
499 elm_tickernoti_detailview_icon_get (const Evas_Object *obj)
500 {
501    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
502    Widget_Data *wd = elm_widget_data_get(obj);
503    if (!wd) return NULL;
504    return wd->icon_detail;
505 }
506
507 /**
508  * Get the rotation used on the tickernoti object
509  *
510  * @param obj The tickernotil object
511  * @return The rotation angle 
512  * @ingroup TickerNoti
513  */
514 EAPI int
515 elm_tickernoti_rotation_get (const Evas_Object *obj)
516 {
517    ELM_CHECK_WIDTYPE(obj, widtype) -1;
518    Widget_Data *wd = elm_widget_data_get(obj);
519    if (!wd) return -1;
520    return wd->angle;
521 }
522
523 /**
524  * Set the rotation used on the tickernoti object
525  *
526  * @param obj The tickernotil object
527  * @param angle The rotation angle(in degree) will be used on the tickernoti object
528  * @ingroup TickerNoti
529  */
530 EAPI void
531 elm_tickernoti_rotation_set (const Evas_Object *obj, int angle)
532 {
533    ELM_CHECK_WIDTYPE(obj, widtype);
534    Widget_Data *wd = elm_widget_data_get(obj);
535    Evas_Coord x, y, w, h;
536
537    if (!wd) return;
538    if (angle%90 != 0) return;
539
540    if (angle >= 0)
541      angle = angle%360;
542    else
543      angle = angle - (angle/360 - 1)*360;
544
545    wd->angle = angle;
546 #ifdef HAVE_ELEMENTARY_X
547    Evas_Coord root_w, root_h;
548    /* 
549    * manual calculate win_tickernoti_indi window position & size 
550    *  - win_indi is not full size window (480 x 27)
551    */
552    ecore_x_window_size_get (ecore_x_window_root_first_get(), &root_w, &root_h);
553 #endif
554    evas_object_geometry_get (wd->win_indi, &x, &y, &w, &h);
555
556    if (evas_object_visible_get (wd->win_detail))
557      evas_object_geometry_get (wd->win_detail, &x, &y, &w, &h);
558
559    /* rotate win */
560    switch (angle) 
561      {
562       case 90:
563 #ifdef HAVE_ELEMENTARY_X
564          w = root_h;
565 #endif
566          x = 0;
567          y = 0;
568          break;
569       case 270:
570 #ifdef HAVE_ELEMENTARY_X
571          w = root_h;
572 #endif
573 #ifdef HAVE_ELEMENTARY_X
574          x = root_w-h;
575 #endif
576          y = 0;
577          break;
578       case 180:
579 #ifdef HAVE_ELEMENTARY_X
580          w = root_w;
581 #endif
582          x = 0;
583 #ifdef HAVE_ELEMENTARY_X
584          y = root_h-h;
585 #endif
586          break;
587       default:
588       case 0:
589 #ifdef HAVE_ELEMENTARY_X
590          w = root_w;
591 #endif
592          x = 0;
593          y = 0;
594          break;
595      }
596
597 /* indicator */
598    elm_win_rotation_with_resize_set (wd->win_indi, angle);
599    evas_object_move (wd->win_indi, x, y);
600    evas_object_resize (wd->win_indi, w, wd->indicator_height);
601    if (evas_object_visible_get (wd->win_indi)) 
602      {
603 #ifdef HAVE_ELEMENTARY_X
604         _make_notification_window (wd->win_indi);
605 #endif
606      }
607 /* detail */
608    elm_win_rotation_with_resize_set (wd->win_detail, angle);
609    evas_object_move (wd->win_detail, x, y);
610    evas_object_resize (wd->win_detail, w, wd->detail_view_height);
611    if (evas_object_visible_get (wd->win_detail))  
612      {
613 #ifdef HAVE_ELEMENTARY_X
614         _make_notification_window (wd->win_detail);
615 #endif
616      }
617 }
618
619 /**
620  * Get the view mode on the tickernoti object
621  *
622  * @param obj The tickernotil object
623  * @return The view mode
624  * @ingroup TickerNoti
625  */
626 EAPI Elm_Tickernoti_Mode
627 elm_tickernoti_mode_get (const Evas_Object *obj)
628 {
629    ELM_CHECK_WIDTYPE(obj, widtype) -1;
630    Widget_Data *wd = elm_widget_data_get(obj);
631    if (!wd) return -1;
632    return wd->mode;
633 }
634
635 /**
636  * Set the view mode used on the tickernoti object
637  *
638  * @param obj The tickernotil object
639  * @param mode The view mode will be used on the tickernoti object
640  * @ingroup TickerNoti
641  */
642 EAPI void
643 elm_tickernoti_mode_set (const Evas_Object *obj, Elm_Tickernoti_Mode mode)
644 {
645    ELM_CHECK_WIDTYPE(obj, widtype);
646    Widget_Data *wd = elm_widget_data_get(obj);
647    if (!wd) return;
648
649    switch(mode){
650       case ELM_TICKERNOTI_DEFAULT:
651       case ELM_TICKERNOTI_DETAILVIEW:
652          wd->mode = mode;
653          break;
654       default:
655          break;
656    }
657    printf("wd->mode : %d\n", wd->mode);
658 }
659
660 /**
661  * Get the detail view window(elm_win) on the tickernoti object
662  *
663  * @param obj The tickernotil object
664  * @return detail view window(elm_win) object
665  * @ingroup TickerNoti
666  */
667 EAPI Evas_Object *
668 elm_tickernoti_detailview_get (const Evas_Object *obj)
669 {
670    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
671    Widget_Data *wd = elm_widget_data_get(obj);
672    if (!wd) return NULL;
673    return wd->win_detail;
674 }
675