[TickerNoti] CQ:H0100126265 fixed. Detail:Any value of angle input is
[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, const char *emission, const char *source)
139 {
140    evas_object_smart_callback_call ((Evas_Object *)data, "detail,show", NULL);
141 }
142
143 static void _detail_hide_cb (void *data, Evas_Object *obj, const char *emission, const char *source)
144 {
145    evas_object_smart_callback_call ((Evas_Object *)data, "detail,hide", NULL);
146 }
147
148 static Evas_Object 
149 *_create_window (Evas_Object *parent, const char *name)
150 {
151    Evas_Object *win;
152
153    win = elm_win_add (parent, name, ELM_WIN_BASIC);
154 /* Property */
155    elm_win_title_set (win, name);
156    elm_win_borderless_set (win, EINA_TRUE);
157    elm_win_autodel_set (win, EINA_TRUE);
158    elm_win_alpha_set (win, EINA_TRUE);
159
160 /* set top window */
161    _make_notification_window (win);
162    
163    return win;
164 }
165
166 static void 
167 _create_tickernoti_indi (Evas_Object *obj)
168 {
169    Widget_Data *wd = elm_widget_data_get(obj);
170    if (!wd) return;
171
172    Evas *e;
173 #ifdef HAVE_ELEMENTARY_X
174    Evas_Coord w;
175 #endif
176
177    char *data_win_height = NULL; 
178    evas_object_move (wd->win_indi, 0, 0);
179
180    e = evas_object_evas_get (wd->win_indi);
181
182    wd->edje_indi = edje_object_add (e);
183    _elm_theme_object_set (wd->win_indi, wd->edje_indi, "tickernoti", "base", "default");
184    elm_win_resize_object_add (wd->win_indi, wd->edje_indi);
185
186    /* tickernoti indicator height set */
187    data_win_height = (char *)edje_object_data_get (wd->edje_indi, "height");
188    if (data_win_height != NULL && elm_scale_get() > 0.0) 
189      wd->indicator_height = (int)(elm_scale_get() * atoi(data_win_height));
190
191 #ifdef HAVE_ELEMENTARY_X
192    ecore_x_window_size_get (ecore_x_window_root_first_get(), &w, NULL);
193    evas_object_resize (wd->win_indi, w, wd->indicator_height);
194 #endif
195         
196    edje_object_signal_callback_add (wd->edje_indi, "request,detail,show", "", _detail_show_cb, obj);
197    evas_object_show (wd->edje_indi);
198 }
199
200 static void 
201 _create_tickernoti_detail (Evas_Object *obj)
202 {
203    Widget_Data *wd = elm_widget_data_get(obj);
204    char *data_win_height = NULL;
205
206    if (!wd) return;
207
208    Evas *e;
209
210    evas_object_move (wd->win_detail, 0, 0);
211    e = evas_object_evas_get (wd->win_detail);
212
213    wd->edje_detail = edje_object_add (e);
214    _elm_theme_object_set (wd->win_detail, wd->edje_detail, "tickernoti", "2line", "default");
215    elm_win_resize_object_add (wd->win_detail, wd->edje_detail);
216
217    /* tickernoti detail height set */
218    data_win_height = (char *)edje_object_data_get (wd->edje_detail, "height");
219    if (data_win_height != NULL && elm_scale_get() > 0.0)
220      wd->detail_view_height = (int)(elm_scale_get() * atoi(data_win_height));
221
222 #ifdef HAVE_ELEMENTARY_X
223    Evas_Coord w;
224
225    ecore_x_window_size_get (ecore_x_window_root_first_get(), &w, NULL);
226    evas_object_resize (wd->win_detail, w, wd->detail_view_height);
227 #endif
228
229    edje_object_signal_callback_add(wd->edje_detail, "request,detail,hide", "", _detail_hide_cb, obj);
230    evas_object_show (wd->edje_detail);
231 }
232
233 static void
234 _show(void *data, Evas *e, Evas_Object *obj, void *event_info)
235 {  
236    Widget_Data *wd = elm_widget_data_get(obj);   
237    if (!wd) return;
238
239    if (wd->mode == ELM_TICKERNOTI_DEFAULT) 
240      {
241         evas_object_hide (wd->win_detail);
242         _make_notification_window (wd->win_indi);
243         evas_object_show (wd->win_indi);
244         edje_object_signal_emit (wd->edje_indi, "effect,show", "bg_1line");
245      }
246    else if (wd->mode == ELM_TICKERNOTI_DETAILVIEW) 
247      {
248         evas_object_hide (wd->win_indi);
249         _make_notification_window (wd->win_detail);
250         evas_object_show (wd->win_detail);
251         edje_object_signal_emit (wd->edje_detail, "effect,show", "bg_2line");
252      }
253 }
254
255 static void
256 _hide(void *data, Evas *e, Evas_Object *obj, void *event_info)
257 {
258    Widget_Data *wd = elm_widget_data_get(obj);
259
260    if (!wd) return;
261    evas_object_hide (obj); 
262    evas_object_hide (wd->win_indi);
263    evas_object_hide (wd->win_detail);
264 }
265
266 /**
267  * Add a tickernoti object to @p parent
268  *
269  * @param parent The parent object
270  *
271  * @return The tickernoti object, or NULL upon failure
272  *
273  * @ingroup TickerNoti
274  */
275 EAPI Evas_Object *
276 elm_tickernoti_add(Evas_Object *parent)
277 {
278    Evas_Object *obj;
279    Evas *e;
280    Widget_Data *wd;
281
282    wd = ELM_NEW(Widget_Data);
283    wd->win_indi = _create_window (parent, "indi");
284    wd->win_detail = _create_window (parent, "detail");
285
286    if (!parent) parent = wd->win_indi;
287
288    e = evas_object_evas_get(parent);
289    obj = elm_widget_add(e);
290    ELM_SET_WIDTYPE(widtype, "tickernoti");
291    elm_widget_type_set(obj, "tickernoti");
292    elm_widget_sub_object_add(parent, obj);
293    elm_widget_data_set(obj, wd);
294    elm_widget_del_hook_set(obj, _del_hook);
295    elm_widget_theme_hook_set(obj, _theme_hook);
296    elm_widget_can_focus_set(obj, 0);
297
298    wd->edje_indi = NULL;
299    wd->edje_detail = NULL;
300    wd->icon_indi = NULL;
301    wd->icon_detail = NULL;
302    wd->button_detail = NULL;
303
304    wd->label_indi = NULL;
305    wd->label_detail = NULL;
306
307    wd->indicator_height = 0;
308    wd->angle = 0;
309
310    wd->mode = ELM_TICKERNOTI_DEFAULT;
311
312    _create_tickernoti_indi (obj);
313    _create_tickernoti_detail (obj);
314
315    evas_object_event_callback_add (obj, EVAS_CALLBACK_SHOW, _show, NULL);
316    evas_object_event_callback_add (obj, EVAS_CALLBACK_HIDE, _hide, NULL);
317
318    return obj;
319 }
320
321
322 /**
323  * Set the icon object used on the tickernoti object
324  *
325  * @param obj The tickernotil object
326  * @param icon The icon object will be used on the tickernoti object
327  * @ingroup TickerNoti
328  */
329 EAPI void 
330 elm_tickernoti_icon_set (const Evas_Object *obj, Evas_Object *icon)
331 {
332    ELM_CHECK_WIDTYPE(obj, widtype);
333    Widget_Data *wd = elm_widget_data_get(obj);
334    if (!wd) return;
335    if (!icon) return;
336    edje_object_part_swallow (wd->edje_indi, "icon", icon);
337    wd->icon_indi = icon;
338 }
339
340 /**
341  * Get the icon object used on the tickernoti object
342  *
343  * @param obj The tickernotil object
344  * @return The icon object inside the tickernoti
345  * @ingroup TickerNoti
346  */
347 EAPI Evas_Object *
348 elm_tickernoti_icon_get (const Evas_Object *obj)
349 {
350    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
351    Widget_Data *wd = elm_widget_data_get(obj);
352    if (!wd) return NULL;
353    return wd->icon_indi;
354 }
355
356 /**
357  * Set the label on the tickernoti object
358  *
359  * @param obj The tickernoti object
360  * @param label The label will be used on the tickernoti object
361  *
362  * @ingroup TickerNoti
363  */
364 EAPI void
365 elm_tickernoti_label_set (Evas_Object *obj, const char *label)
366 {
367    ELM_CHECK_WIDTYPE(obj, widtype);
368    Widget_Data *wd = elm_widget_data_get(obj);
369    if (!wd) return;
370    if (!label) label = "";
371    eina_stringshare_replace(&wd->label_indi, label);
372    edje_object_part_text_set(wd->edje_indi, "text", label);
373    _sizing_eval(obj);
374 }
375
376 /**
377  * Get the label used on the tickernoti object
378  *
379  * @param obj The tickernotil object
380  * @return The string inside the label
381  * @ingroup TickerNoti
382  */
383 EAPI const char *
384 elm_tickernoti_label_get (const Evas_Object *obj)
385 {
386    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
387    Widget_Data *wd = elm_widget_data_get(obj);
388    if (!wd) return NULL;
389    return wd->label_indi;
390 }
391
392 /**
393  * Set the detail label on the tickernoti object
394  *
395  * @param obj The tickernoti object
396  * @param label The label will be used on the tickernoti object
397  *
398  * @ingroup TickerNoti
399  */
400 EAPI void
401 elm_tickernoti_detailview_label_set (Evas_Object *obj, const char *label)
402 {
403    ELM_CHECK_WIDTYPE(obj, widtype);
404    Widget_Data *wd = elm_widget_data_get(obj);
405    if (!wd) return;
406    if (!label) label = "";
407    eina_stringshare_replace(&wd->label_detail, label);
408    edje_object_part_text_set(wd->edje_detail, "text", label);
409    _sizing_eval(obj);
410 }
411
412 /**
413  * Get the detail label used on the tickernoti object
414  *
415  * @param obj The tickernotil object
416  * @return The string inside the label
417  * @ingroup TickerNoti
418  */
419 EAPI const char *
420 elm_tickernoti_detailview_label_get (const Evas_Object *obj)
421 {
422    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
423    Widget_Data *wd = elm_widget_data_get(obj);
424    if (!wd) return NULL;
425    return wd->label_detail;
426 }
427
428 /**
429  * Set the button object used on the tickernoti object
430  *
431  * @param obj The tickernotil object
432  * @param button The button object will be used on the tickernoti object
433  * @ingroup TickerNoti
434  */
435 EAPI void 
436 elm_tickernoti_detailview_button_set (const Evas_Object *obj, Evas_Object *button)
437 {
438    ELM_CHECK_WIDTYPE(obj, widtype);
439    Widget_Data *wd = elm_widget_data_get(obj);
440    if (!wd) return;
441    if (!button) return;
442    edje_object_part_swallow (wd->edje_detail, "button", button);
443    wd->button_detail = button;
444 }
445
446 /**
447  * Get the button object used on the tickernoti object
448  *
449  * @param obj The tickernotil object
450  * @return The button object inside the tickernoti
451  * @ingroup TickerNoti
452  */
453 EAPI Evas_Object *
454 elm_tickernoti_detailview_button_get (const Evas_Object *obj)
455 {
456    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
457    Widget_Data *wd = elm_widget_data_get(obj);
458    if (!wd) return NULL;
459    return wd->button_detail;
460 }
461
462 /**
463  * Set the detail icon object used on the tickernoti object
464  *
465  * @param obj The tickernotil object
466  * @param icon The icon object will be used on the tickernoti object
467  * @ingroup TickerNoti
468  */
469 EAPI void 
470 elm_tickernoti_detailview_icon_set (const Evas_Object *obj, Evas_Object *icon)
471 {
472    ELM_CHECK_WIDTYPE(obj, widtype);
473    Widget_Data *wd = elm_widget_data_get(obj);
474    if (!wd) return;
475    if (!icon) return;
476    edje_object_part_swallow (wd->edje_detail, "icon", icon);
477    wd->icon_detail = icon;
478 }
479
480 /**
481  * Get the detail icon object used on the tickernoti object
482  *
483  * @param obj The tickernotil object
484  * @return The icon object inside the tickernoti
485  * @ingroup TickerNoti
486  */
487 EAPI Evas_Object *
488 elm_tickernoti_detailview_icon_get (const Evas_Object *obj)
489 {
490    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
491    Widget_Data *wd = elm_widget_data_get(obj);
492    if (!wd) return NULL;
493    return wd->icon_detail;
494 }
495
496 /**
497  * Get the rotation used on the tickernoti object
498  *
499  * @param obj The tickernotil object
500  * @return The rotation angle 
501  * @ingroup TickerNoti
502  */
503 EAPI int
504 elm_tickernoti_rotation_get (const Evas_Object *obj)
505 {
506    ELM_CHECK_WIDTYPE(obj, widtype) -1;
507    Widget_Data *wd = elm_widget_data_get(obj);
508    if (!wd) return -1;
509    return wd->angle;
510 }
511
512 /**
513  * Set the rotation used on the tickernoti object
514  *
515  * @param obj The tickernotil object
516  * @param angle The rotation angle(in degree) will be used on the tickernoti object
517  * @ingroup TickerNoti
518  */
519 EAPI void
520 elm_tickernoti_rotation_set (const Evas_Object *obj, int angle)
521 {
522    ELM_CHECK_WIDTYPE(obj, widtype);
523    Widget_Data *wd = elm_widget_data_get(obj);
524    Evas_Coord x, y, w, h;
525
526    if (!wd) return;
527    if (angle%90 != 0) return;
528
529    if (angle >= 0)
530      angle = angle%360;
531    else
532      angle = angle - (angle/360 - 1)*360;
533
534    wd->angle = angle;
535 #ifdef HAVE_ELEMENTARY_X
536    Evas_Coord root_w, root_h;
537    /* 
538    * manual calculate win_tickernoti_indi window position & size 
539    *  - win_indi is not full size window (480 x 27)
540    */
541    ecore_x_window_size_get (ecore_x_window_root_first_get(), &root_w, &root_h);
542 #endif
543    evas_object_geometry_get (wd->win_indi, &x, &y, &w, &h);
544
545    if (evas_object_visible_get (wd->win_detail))
546      evas_object_geometry_get (wd->win_detail, &x, &y, &w, &h);
547
548    /* rotate win */
549    switch (angle) 
550      {
551       case 90:
552 #ifdef HAVE_ELEMENTARY_X
553          w = root_h;
554 #endif
555          x = 0;
556          y = 0;
557          break;
558       case 270:
559 #ifdef HAVE_ELEMENTARY_X
560          w = root_h;
561 #endif
562 #ifdef HAVE_ELEMENTARY_X
563          x = root_w-h;
564 #endif
565          y = 0;
566          break;
567       case 180:
568 #ifdef HAVE_ELEMENTARY_X
569          w = root_w;
570 #endif
571          x = 0;
572 #ifdef HAVE_ELEMENTARY_X
573          y = root_h-h;
574 #endif
575          break;
576       default:
577       case 0:
578 #ifdef HAVE_ELEMENTARY_X
579          w = root_w;
580 #endif
581          x = 0;
582          y = 0;
583          break;
584      }
585
586 /* indicator */
587    elm_win_rotation_with_resize_set (wd->win_indi, angle);
588    evas_object_move (wd->win_indi, x, y);
589    evas_object_resize (wd->win_indi, w, wd->indicator_height);
590    if (evas_object_visible_get (wd->win_indi)) 
591      {
592 #ifdef HAVE_ELEMENTARY_X
593         _make_notification_window (wd->win_indi);
594 #endif
595      }
596 /* detail */
597    elm_win_rotation_with_resize_set (wd->win_detail, angle);
598    evas_object_move (wd->win_detail, x, y);
599    evas_object_resize (wd->win_detail, w, wd->detail_view_height);
600    if (evas_object_visible_get (wd->win_detail))  
601      {
602 #ifdef HAVE_ELEMENTARY_X
603         _make_notification_window (wd->win_detail);
604 #endif
605      }
606 }
607
608 /**
609  * Get the view mode on the tickernoti object
610  *
611  * @param obj The tickernotil object
612  * @return The view mode
613  * @ingroup TickerNoti
614  */
615 EAPI Elm_Tickernoti_Mode
616 elm_tickernoti_mode_get (const Evas_Object *obj)
617 {
618    ELM_CHECK_WIDTYPE(obj, widtype) -1;
619    Widget_Data *wd = elm_widget_data_get(obj);
620    if (!wd) return -1;
621    return wd->mode;
622 }
623
624 /**
625  * Set the view mode used on the tickernoti object
626  *
627  * @param obj The tickernotil object
628  * @param mode The view mode will be used on the tickernoti object
629  * @ingroup TickerNoti
630  */
631 EAPI void
632 elm_tickernoti_mode_set (const Evas_Object *obj, Elm_Tickernoti_Mode mode)
633 {
634    ELM_CHECK_WIDTYPE(obj, widtype);
635    Widget_Data *wd = elm_widget_data_get(obj);
636    if (!wd) return;
637
638    switch(mode){
639       case ELM_TICKERNOTI_DEFAULT:
640       case ELM_TICKERNOTI_DETAILVIEW:
641          wd->mode = mode;
642          break;
643       default:
644          break;
645    }
646    printf("wd->mode : %d\n", wd->mode);
647 }
648
649 /**
650  * Get the detail view window(elm_win) on the tickernoti object
651  *
652  * @param obj The tickernotil object
653  * @return detail view window(elm_win) object
654  * @ingroup TickerNoti
655  */
656 EAPI Evas_Object *
657 elm_tickernoti_detailview_get (const Evas_Object *obj)
658 {
659    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
660    Widget_Data *wd = elm_widget_data_get(obj);
661    if (!wd) return NULL;
662    return wd->win_detail;
663 }
664