Tizen 2.1 release
[platform/core/uifw/e17.git] / src / modules / notification / e_mod_box.c
1 #include "e_mod_main.h"
2
3 /* Notification box protos */
4 static Notification_Box *_notification_box_new(const char *id,
5                                                Evas       *evas);
6 static void              _notification_box_free(Notification_Box *b);
7 static void              _notification_box_evas_set(Notification_Box *b,
8                                                     Evas             *evas);
9 static void              _notification_box_empty(Notification_Box *b);
10 static void              _notification_box_resize_handle(Notification_Box *b);
11 static void              _notification_box_empty_handle(Notification_Box *b);
12 static Eina_List        *_notification_box_find(E_Notification_Urgency urgency);
13
14 /* Notification box icons protos */
15 static Notification_Box_Icon *_notification_box_icon_new(Notification_Box *b,
16                                                          E_Notification   *n,
17                                                          E_Border         *bd,
18                                                          unsigned int      id);
19 static void                   _notification_box_icon_free(Notification_Box_Icon *ic);
20 static void                   _notification_box_icon_fill(Notification_Box_Icon *ic,
21                                                           E_Notification        *n);
22 static void                   _notification_box_icon_fill_label(Notification_Box_Icon *ic);
23 static void                   _notification_box_icon_empty(Notification_Box_Icon *ic);
24 static Notification_Box_Icon *_notification_box_icon_find(Notification_Box *b,
25                                                           E_Border         *bd,
26                                                           unsigned int      n_id);
27 static void _notification_box_icon_signal_emit(Notification_Box_Icon *ic,
28                                                char                  *sig,
29                                                char                  *src);
30
31 /* Utils */
32 static E_Border *_notification_find_source_border(E_Notification *n);
33
34 /* Notification box callbacks */
35 void
36 notification_box_notify(E_Notification *n,
37                         unsigned int    replaces_id,
38                         unsigned int    id)
39 {
40    Eina_List *n_box;
41    E_Border *bd;
42    Notification_Box *b;
43    Notification_Box_Icon *ic = NULL;
44
45    bd = _notification_find_source_border(n);
46
47    n_box = _notification_box_find(e_notification_hint_urgency_get(n));
48    EINA_LIST_FREE(n_box, b)
49      {
50         if (bd || replaces_id)
51           ic = _notification_box_icon_find(b, bd, replaces_id);
52         if (ic)
53           {
54              e_notification_unref(ic->notif);
55              e_notification_ref(n);
56              ic->notif = n;
57              ic->n_id = id;
58              _notification_box_icon_empty(ic);
59              _notification_box_icon_fill(ic, n);
60           }
61         else
62           {
63              ic = _notification_box_icon_new(b, n, bd, id);
64              if (!ic) continue;
65              b->icons = eina_list_append(b->icons, ic);
66              e_box_pack_end(b->o_box, ic->o_holder);
67           }
68         _notification_box_empty_handle(b);
69         _notification_box_resize_handle(b);
70         _gc_orient(b->inst->gcc, b->inst->gcc->gadcon->orient);
71      }
72 }
73
74 void
75 notification_box_shutdown(void)
76 {
77    Notification_Box *b;
78
79    EINA_LIST_FREE(notification_cfg->n_box, b)
80      {
81         if (b) _notification_box_free(b);
82      }
83 }
84
85 void
86 notification_box_visible_set(Notification_Box *b, Eina_Bool visible)
87 {
88    Eina_List *l;
89    Notification_Box_Icon *ic;
90    Ecore_Cb cb = (Ecore_Cb)(visible ? evas_object_show : evas_object_hide);
91
92    if (b->o_box) cb(b->o_box);
93    if (b->o_empty) cb(b->o_empty);
94    EINA_LIST_FOREACH(b->icons, l, ic)
95      {
96         if (!ic) continue;
97         cb(ic->o_holder);
98         cb(ic->o_holder2);
99         cb(ic->o_icon);
100         cb(ic->o_icon2);
101      }
102 }
103
104 Notification_Box *
105 notification_box_get(const char *id,
106                      Evas       *evas)
107 {
108    Eina_List *l;
109    Notification_Box *b;
110
111    /* Find old config */
112    EINA_LIST_FOREACH(notification_cfg->n_box, l, b)
113      {
114         if (b->id == id)
115           {
116              _notification_box_evas_set(b, evas);
117              notification_box_visible_set(b, EINA_TRUE);
118              return b;
119           }
120      }
121
122    b = _notification_box_new(id, evas);
123    notification_cfg->n_box = eina_list_append(notification_cfg->n_box, b);
124    return b;
125 }
126
127 Config_Item *
128 notification_box_config_item_get(const char *id)
129 {
130    Config_Item *ci;
131
132    GADCON_CLIENT_CONFIG_GET(Config_Item, notification_cfg->items, _gc_class, id);
133
134    ci = E_NEW(Config_Item, 1);
135    ci->id = eina_stringshare_add(id);
136    ci->show_label = 1;
137    ci->show_popup = 1;
138    ci->focus_window = 1;
139    ci->store_low = 1;
140    ci->store_normal = 1;
141    ci->store_critical = 0;
142    notification_cfg->items = eina_list_append(notification_cfg->items, ci);
143
144    return ci;
145 }
146
147 void
148 notification_box_orient_set(Notification_Box *b,
149                             int               horizontal)
150 {
151    e_box_orientation_set(b->o_box, horizontal);
152    e_box_align_set(b->o_box, 0.5, 0.5);
153 }
154
155 void
156 notification_box_cb_obj_moveresize(void        *data,
157                                    Evas        *e __UNUSED__,
158                                    Evas_Object *obj __UNUSED__,
159                                    void        *event_info __UNUSED__)
160 {
161    Instance *inst;
162
163    inst = data;
164    _notification_box_resize_handle(inst->n_box);
165 }
166
167 Eina_Bool
168 notification_box_cb_border_remove(void *data __UNUSED__,
169                                   int   type __UNUSED__,
170                                   E_Event_Border_Remove *ev)
171 {
172    Notification_Box_Icon *ic;
173    Eina_List *l;
174    Instance *inst;
175
176    EINA_LIST_FOREACH(notification_cfg->instances, l, inst)
177      {
178         Notification_Box *b;
179
180         if (!inst) continue;
181         b = inst->n_box;
182
183         ic = _notification_box_icon_find(b, ev->border, 0);
184         if (!ic) continue;
185         b->icons = eina_list_remove(b->icons, ic);
186         _notification_box_icon_free(ic);
187         _notification_box_empty_handle(b);
188         _notification_box_resize_handle(b);
189         _gc_orient(inst->gcc, inst->gcc->gadcon->orient);
190      }
191    return ECORE_CALLBACK_RENEW;
192 }
193
194 static Notification_Box *
195 _notification_box_new(const char *id,
196                       Evas       *evas)
197 {
198    Notification_Box *b;
199
200    b = E_NEW(Notification_Box, 1);
201    b->id = eina_stringshare_ref(id);
202    b->o_box = e_box_add(evas);
203    e_box_homogenous_set(b->o_box, 1);
204    e_box_orientation_set(b->o_box, 1);
205    e_box_align_set(b->o_box, 0.5, 0.5);
206    _notification_box_empty(b);
207    return b;
208 }
209
210 static void
211 _notification_box_free(Notification_Box *b)
212 {
213    _notification_box_empty(b);
214    eina_stringshare_del(b->id);
215    free(b);
216 }
217
218 static void
219 _notification_box_evas_set(Notification_Box *b,
220                            Evas             *evas)
221 {
222    Eina_List *new_icons = NULL;
223    Notification_Box_Icon *ic, *new_ic;
224
225    if (b->o_box) evas_object_del(b->o_box);
226    if (b->o_empty) evas_object_del(b->o_empty);
227    b->o_empty = NULL;
228    b->o_box = e_box_add(evas);
229
230    e_box_homogenous_set(b->o_box, 1);
231    e_box_orientation_set(b->o_box, 1);
232    e_box_align_set(b->o_box, 0.5, 0.5);
233
234    EINA_LIST_FREE(b->icons, ic)
235      {
236         if (!ic) continue;
237
238         new_ic = _notification_box_icon_new(b, ic->notif, ic->border, ic->n_id);
239         _notification_box_icon_free(ic);
240         new_icons = eina_list_append(new_icons, new_ic);
241
242         e_box_pack_end(b->o_box, new_ic->o_holder);
243      }
244    b->icons = new_icons;
245    _notification_box_empty_handle(b);
246    _notification_box_resize_handle(b);
247 }
248
249 static void
250 _notification_box_empty(Notification_Box *b)
251 {
252    Notification_Box_Icon *ic;
253    EINA_LIST_FREE(b->icons, ic)
254      _notification_box_icon_free(ic);
255    _notification_box_empty_handle(b);
256 }
257
258 static void
259 _notification_box_resize_handle(Notification_Box *b)
260 {
261    Notification_Box_Icon *ic;
262    Evas_Coord w, h;
263
264    evas_object_geometry_get(b->o_box, NULL, NULL, &w, &h);
265    if (e_box_orientation_get(b->o_box))
266      w = h;
267    else
268      h = w;
269    e_box_freeze(b->o_box);
270    EINA_LIST_FREE(b->icons, ic)
271      e_box_pack_options_set(ic->o_holder, 1, 1, 0, 0, 0.5, 0.5, w, h, w, h);
272    e_box_thaw(b->o_box);
273 }
274
275 static Eina_List *
276 _notification_box_find(E_Notification_Urgency urgency)
277 {
278    Eina_List *l, *n_box = NULL;
279    Instance *inst;
280
281    EINA_LIST_FOREACH(notification_cfg->instances, l, inst)
282      {
283         if ((urgency == E_NOTIFICATION_URGENCY_LOW) && (!inst->ci->store_low))
284           continue;
285         if ((urgency == E_NOTIFICATION_URGENCY_NORMAL) && (!inst->ci->store_normal))
286           continue;
287         if ((urgency == E_NOTIFICATION_URGENCY_CRITICAL) && (!inst->ci->store_critical))
288           continue;
289         n_box = eina_list_append(n_box, inst->n_box);
290      }
291    return n_box;
292 }
293
294 static void
295 _notification_box_icon_free(Notification_Box_Icon *ic)
296 {
297    _notification_box_icon_empty(ic);
298    evas_object_del(ic->o_holder);
299    evas_object_del(ic->o_holder2);
300    if (ic->border) e_object_unref(E_OBJECT(ic->border));
301    if (ic->notif) e_notification_unref(ic->notif);
302    free(ic);
303 }
304
305 static void
306 _notification_box_icon_fill(Notification_Box_Icon *ic,
307                             E_Notification        *n)
308 {
309    void *img;
310    const char *icon_path;
311    Evas_Object *app_icon;
312    Evas_Object *dummy = NULL;
313    int w, h = 0;
314
315    if ((icon_path = e_notification_app_icon_get(n)) && *icon_path)
316      {
317         if (!memcmp(icon_path, "file://", 7)) icon_path += 7;
318         app_icon = evas_object_image_add(evas_object_evas_get(ic->n_box->o_box));
319         evas_object_image_load_scale_down_set(app_icon, 1);
320         evas_object_image_load_size_set(app_icon, 80, 80);
321         evas_object_image_file_set(app_icon, icon_path, NULL);
322         evas_object_image_fill_set(app_icon, 0, 0, 80, 80);
323      }
324    else if ((img = e_notification_hint_icon_data_get(n)))
325      {
326         app_icon = e_notification_image_evas_object_add(evas_object_evas_get(ic->n_box->o_box), img);
327      }
328    else
329      {
330         char buf[PATH_MAX];
331
332         snprintf(buf, sizeof(buf), "%s/e-module-notification.edj", notification_mod->dir);
333         dummy = edje_object_add(evas_object_evas_get(ic->n_box->o_box));
334         if (!e_theme_edje_object_set(dummy, "base/theme/modules/notification",
335                                      "modules/notification/logo"))
336           edje_object_file_set(dummy, buf, "modules/notification/logo");
337         evas_object_resize(dummy, 80, 80);
338         app_icon = (Evas_Object*)edje_object_part_object_get(dummy, "image");
339      }
340    evas_object_image_size_get(app_icon, &w, &h);
341
342    ic->o_icon = e_icon_add(evas_object_evas_get(ic->n_box->o_box));
343    e_icon_alpha_set(ic->o_icon, 1);
344    e_icon_data_set(ic->o_icon, evas_object_image_data_get(app_icon, 0), w, h);
345    edje_object_part_swallow(ic->o_holder, "e.swallow.content", ic->o_icon);
346    evas_object_pass_events_set(ic->o_icon, 1);
347    evas_object_show(ic->o_icon);
348
349    ic->o_icon2 = e_icon_add(evas_object_evas_get(ic->n_box->o_box));
350    e_icon_alpha_set(ic->o_icon2, 1);
351    e_icon_data_set(ic->o_icon2, evas_object_image_data_get(app_icon, 0), w, h);
352    edje_object_part_swallow(ic->o_holder2, "e.swallow.content", ic->o_icon2);
353    evas_object_pass_events_set(ic->o_icon2, 1);
354    evas_object_show(ic->o_icon2);
355
356    if (dummy) evas_object_del(dummy);
357    evas_object_del(app_icon);
358    _notification_box_icon_fill_label(ic);
359 }
360
361 static void
362 _notification_box_icon_fill_label(Notification_Box_Icon *ic)
363 {
364    const char *label = NULL;
365
366    if (ic->border)
367      label = ic->border->client.netwm.name;
368
369    if (!label) label = e_notification_app_name_get(ic->notif);
370    edje_object_part_text_set(ic->o_holder, "e.text.label", label);
371    edje_object_part_text_set(ic->o_holder2, "e.text.label", label);
372 }
373
374 static void
375 _notification_box_icon_empty(Notification_Box_Icon *ic)
376 {
377    if (ic->o_icon) evas_object_del(ic->o_icon);
378    if (ic->o_icon2) evas_object_del(ic->o_icon2);
379    ic->o_icon2 = ic->o_icon = NULL;
380 }
381
382 static Notification_Box_Icon *
383 _notification_box_icon_find(Notification_Box *b,
384                             E_Border         *bd,
385                             unsigned int      n_id)
386 {
387    Eina_List *l;
388    Notification_Box_Icon *ic;
389
390    EINA_LIST_FOREACH(b->icons, l, ic)
391      {
392         if (!ic) continue;
393         if ((ic->border == bd) || (ic->n_id == n_id))
394           return ic;
395      }
396
397    return NULL;
398 }
399
400 static void
401 _notification_box_icon_signal_emit(Notification_Box_Icon *ic,
402                                    char                  *sig,
403                                    char                  *src)
404 {
405    if (ic->o_holder)
406      edje_object_signal_emit(ic->o_holder, sig, src);
407    if (ic->o_icon)
408      edje_object_signal_emit(ic->o_icon, sig, src);
409    if (ic->o_holder2)
410      edje_object_signal_emit(ic->o_holder2, sig, src);
411    if (ic->o_icon2)
412      edje_object_signal_emit(ic->o_icon2, sig, src);
413 }
414
415 static E_Border *
416 _notification_find_source_border(E_Notification *n)
417 {
418    const char *app_name;
419    Eina_List *l;
420    E_Border *bd;
421
422    if (!(app_name = e_notification_app_name_get(n))) return NULL;
423
424    EINA_LIST_FOREACH(e_border_client_list(), l, bd)
425      {
426         size_t app, test;
427
428         if ((!bd) || ((!bd->client.icccm.name) && (!bd->client.icccm.class))) continue;
429         /* We can't be sure that the app_name really match the application name.
430          * Some plugin put their name instead. But this search gives some good
431          * results.
432          */
433         app = strlen(app_name);
434         if (bd->client.icccm.name)
435           {
436              test = eina_strlen_bounded(bd->client.icccm.name, app + 1);
437              if (!strncasecmp(bd->client.icccm.name, app_name, (app < test) ? app : test))
438                return bd;
439           }
440         if (bd->client.icccm.class)
441           {
442              test = eina_strlen_bounded(bd->client.icccm.class, app + 1);
443              if (!strncasecmp(bd->client.icccm.class, app_name, (app < test) ? app : test))
444                return bd;
445           }
446      }
447    return NULL;
448 }
449
450 static void
451 _notification_box_cb_menu_configuration(Notification_Box *b,
452                                         E_Menu      *m __UNUSED__,
453                                         E_Menu_Item *mi __UNUSED__)
454 {
455    Eina_List *l;
456    E_Config_Dialog *cfd;
457
458    EINA_LIST_FOREACH(notification_cfg->config_dialog, l, cfd)
459      {
460         if (cfd->data == b->inst->ci) return;
461      }
462    config_notification_box_module(b->inst->ci);
463 }
464
465 static void
466 _notification_box_cb_empty_mouse_down(Notification_Box *b,
467                                       Evas        *e __UNUSED__,
468                                       Evas_Object *obj __UNUSED__,
469                                       Evas_Event_Mouse_Down *ev)
470 {
471    E_Menu *m;
472    E_Menu_Item *mi;
473    int cx, cy, cw, ch;
474
475    m = e_menu_new();
476    mi = e_menu_item_new(m);
477    e_menu_item_label_set(mi, _("Settings"));
478    e_util_menu_item_theme_icon_set(mi, "preferences-system");
479    e_menu_item_callback_set(mi, (E_Menu_Cb)_notification_box_cb_menu_configuration, b);
480
481    m = e_gadcon_client_util_menu_items_append(b->inst->gcc, m, 0);
482    e_gadcon_canvas_zone_geometry_get(b->inst->gcc->gadcon,
483                                      &cx, &cy, &cw, &ch);
484    e_menu_activate_mouse(m,
485                          e_util_zone_current_get(e_manager_current_get()),
486                          cx + ev->output.x, cy + ev->output.y, 1, 1,
487                          E_MENU_POP_DIRECTION_DOWN, ev->timestamp);
488    evas_event_feed_mouse_up(b->inst->gcc->gadcon->evas, ev->button,
489                             EVAS_BUTTON_NONE, ev->timestamp, NULL);
490 }
491
492 static void
493 _notification_box_cb_icon_move(Notification_Box_Icon *ic,
494                                Evas        *e __UNUSED__,
495                                Evas_Object *obj __UNUSED__,
496                                void        *event_info __UNUSED__)
497 {
498    Evas_Coord x, y;
499
500    evas_object_geometry_get(ic->o_holder, &x, &y, NULL, NULL);
501    evas_object_move(ic->o_holder2, x, y);
502    evas_object_raise(ic->o_holder2);
503 }
504
505 static void
506 _notification_box_cb_icon_resize(Notification_Box_Icon *ic,
507                                  Evas        *e __UNUSED__,
508                                  Evas_Object *obj __UNUSED__,
509                                  void        *event_info __UNUSED__)
510 {
511    Evas_Coord w, h;
512
513    evas_object_geometry_get(ic->o_holder, NULL, NULL, &w, &h);
514    evas_object_resize(ic->o_holder2, w, h);
515    evas_object_raise(ic->o_holder2);
516 }
517
518
519 static Eina_Bool
520 _notification_box_cb_icon_mouse_still_in(Notification_Box_Icon *ic)
521 {
522    e_notification_timeout_set(ic->notif, 0);
523    e_notification_hint_urgency_set(ic->notif, 4);
524    ic->popup = notification_popup_notify(ic->notif,
525                                          e_notification_id_get(ic->notif),
526                                          e_notification_app_name_get(ic->notif));
527    ecore_timer_del(ic->mouse_in_timer);
528    ic->mouse_in_timer = NULL;
529    return EINA_FALSE;
530 }
531
532
533 static void
534 _notification_box_cb_icon_mouse_in(Notification_Box_Icon *ic,
535                                    Evas        *e __UNUSED__,
536                                    Evas_Object *obj __UNUSED__,
537                                    void        *event_info __UNUSED__)
538 {
539    Config_Item *ci;
540
541    if ((!ic) || !ic->n_box || !ic->n_box->inst) return;
542    if (!(ci = ic->n_box->inst->ci)) return;
543
544    _notification_box_icon_signal_emit(ic, "e,state,focused", "e");
545    if (ci->show_label)
546      {
547         _notification_box_icon_fill_label(ic);
548         _notification_box_icon_signal_emit(ic, "e,action,show,label", "e");
549      }
550    if (ci->show_popup && !ic->popup && !ic->mouse_in_timer)
551      ic->mouse_in_timer = ecore_timer_add(0.5, (Ecore_Task_Cb)_notification_box_cb_icon_mouse_still_in, ic);
552 }
553
554 static void
555 _notification_box_cb_icon_mouse_out(Notification_Box_Icon *ic,
556                                     Evas        *e __UNUSED__,
557                                     Evas_Object *obj __UNUSED__,
558                                     void        *event_info __UNUSED__)
559 {
560    _notification_box_icon_signal_emit(ic, "e,state,unfocused", "e");
561    if (ic->n_box->inst->ci->show_label)
562      _notification_box_icon_signal_emit(ic, "e,action,hide,label", "e");
563
564    if (ic->mouse_in_timer)
565      {
566         ecore_timer_del(ic->mouse_in_timer);
567         ic->mouse_in_timer = NULL;
568      }
569    if (ic->popup)
570      {
571         notification_popup_close(e_notification_id_get(ic->notif));
572         ic->popup = 0;
573      }
574 }
575
576 static void
577 _notification_box_cb_icon_mouse_up(Notification_Box_Icon *ic,
578                                    Evas        *e __UNUSED__,
579                                    Evas_Object *obj __UNUSED__,
580                                    Evas_Event_Mouse_Up *ev)
581 {
582    Notification_Box *b;
583
584    b = ic->n_box;
585    if (ev->button != 1) return;
586
587    if (b->inst->ci->focus_window && ic->border)
588      {
589         e_border_uniconify(ic->border);
590         e_desk_show(ic->border->desk);
591         e_border_show(ic->border);
592         e_border_raise(ic->border);
593         e_border_focus_set(ic->border, 1, 1);
594      }
595    b->icons = eina_list_remove(b->icons, ic);
596    _notification_box_icon_free(ic);
597    _notification_box_empty_handle(b);
598    _notification_box_resize_handle(b);
599    _gc_orient(b->inst->gcc, b->inst->gcc->gadcon->orient);
600 }
601
602 static void
603 _notification_box_cb_icon_mouse_down(Notification_Box_Icon *ic,
604                                      Evas        *e __UNUSED__,
605                                      Evas_Object *obj __UNUSED__,
606                                      Evas_Event_Mouse_Down *ev)
607 {
608    E_Menu *m;
609    E_Menu_Item *mi;
610    int cx, cy, cw, ch;
611
612    if (ev->button != 3) return;
613
614    m = e_menu_new();
615    mi = e_menu_item_new(m);
616    e_menu_item_label_set(mi, _("Settings"));
617    e_util_menu_item_theme_icon_set(mi, "preferences-system");
618    e_menu_item_callback_set(mi, (E_Menu_Cb)_notification_box_cb_menu_configuration, ic->n_box);
619
620    m = e_gadcon_client_util_menu_items_append(ic->n_box->inst->gcc, m, 0);
621    e_gadcon_canvas_zone_geometry_get(ic->n_box->inst->gcc->gadcon,
622                                      &cx, &cy, &cw, &ch);
623    e_menu_activate_mouse(m,
624                          e_util_zone_current_get(e_manager_current_get()),
625                          cx + ev->output.x, cy + ev->output.y, 1, 1,
626                          E_MENU_POP_DIRECTION_DOWN, ev->timestamp);
627 }
628
629 static void
630 _notification_box_empty_handle(Notification_Box *b)
631 {
632    if (!b->icons)
633      {
634         Evas_Coord w, h;
635         if (b->o_empty) return;
636
637         b->o_empty = evas_object_rectangle_add(evas_object_evas_get(b->o_box));
638         evas_object_event_callback_add(b->o_empty, EVAS_CALLBACK_MOUSE_DOWN,
639                                        (Evas_Object_Event_Cb)_notification_box_cb_empty_mouse_down, b);
640         evas_object_color_set(b->o_empty, 0, 0, 0, 0);
641         evas_object_show(b->o_empty);
642         e_box_pack_end(b->o_box, b->o_empty);
643         evas_object_geometry_get(b->o_box, NULL, NULL, &w, &h);
644         if (e_box_orientation_get(b->o_box))
645           w = h;
646         else
647           h = w;
648         e_box_pack_options_set(b->o_empty,
649                                1, 1, /* fill */
650                                1, 1, /* expand */
651                                0.5, 0.5, /* align */
652                                w, h, /* min */
653                                9999, 9999 /* max */
654                                );
655      }
656    else if (b->o_empty)
657      {
658         evas_object_del(b->o_empty);
659         b->o_empty = NULL;
660      }
661 }
662
663 static Notification_Box_Icon *
664 _notification_box_icon_new(Notification_Box *b,
665                            E_Notification   *n,
666                            E_Border         *bd,
667                            unsigned int      id)
668 {
669    Notification_Box_Icon *ic;
670
671    ic = E_NEW(Notification_Box_Icon, 1);
672    if (bd) e_object_ref(E_OBJECT(bd));
673    e_notification_ref(n);
674    ic->label = e_notification_app_name_get(n);
675    ic->n_box = b;
676    ic->n_id = id;
677    ic->border = bd;
678    ic->notif = n;
679    ic->o_holder = edje_object_add(evas_object_evas_get(b->o_box));
680    e_theme_edje_object_set(ic->o_holder, "base/theme/modules/ibox",
681                            "e/modules/ibox/icon");
682    evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOUSE_IN,
683                                   (Evas_Object_Event_Cb)_notification_box_cb_icon_mouse_in, ic);
684    evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOUSE_OUT,
685                                   (Evas_Object_Event_Cb)_notification_box_cb_icon_mouse_out, ic);
686    evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOUSE_DOWN,
687                                   (Evas_Object_Event_Cb)_notification_box_cb_icon_mouse_down, ic);
688    evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOUSE_UP,
689                                   (Evas_Object_Event_Cb)_notification_box_cb_icon_mouse_up, ic);
690    evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_MOVE,
691                                   (Evas_Object_Event_Cb)_notification_box_cb_icon_move, ic);
692    evas_object_event_callback_add(ic->o_holder, EVAS_CALLBACK_RESIZE,
693                                   (Evas_Object_Event_Cb)_notification_box_cb_icon_resize, ic);
694    evas_object_show(ic->o_holder);
695
696    ic->o_holder2 = edje_object_add(evas_object_evas_get(b->o_box));
697    e_theme_edje_object_set(ic->o_holder2, "base/theme/modules/ibox",
698                            "e/modules/ibox/icon_overlay");
699    evas_object_layer_set(ic->o_holder2, 9999);
700    evas_object_pass_events_set(ic->o_holder2, 1);
701    evas_object_show(ic->o_holder2);
702
703    _notification_box_icon_fill(ic, n);
704    return ic;
705 }