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