elementary/map - map supports language,changed
[framework/uifw/elementary.git] / src / lib / elm_notify.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3 #include "elm_widget_notify.h"
4
5 EAPI const char ELM_NOTIFY_SMART_NAME[] = "elm_notify";
6
7 static const char SIG_BLOCK_CLICKED[] = "block,clicked";
8 static const char SIG_TIMEOUT[] = "timeout";
9 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
10    {SIG_BLOCK_CLICKED, ""},
11    {SIG_TIMEOUT, ""},
12    {NULL, NULL}
13 };
14
15 EVAS_SMART_SUBCLASS_NEW
16   (ELM_NOTIFY_SMART_NAME, _elm_notify, Elm_Notify_Smart_Class,
17   Elm_Container_Smart_Class, elm_container_smart_class_get, NULL);
18
19 static void
20 _notify_theme_apply(Evas_Object *obj)
21 {
22    const char *style = elm_widget_style_get(obj);
23    double ax, ay;
24
25    ELM_NOTIFY_DATA_GET(obj, sd);
26
27    ax = sd->horizontal_align;
28    ay = sd->vertical_align;
29    if ((elm_widget_mirrored_get(obj)) && (ax != ELM_NOTIFY_ALIGN_FILL)) ax = 1.0 - ax;
30
31    if (ay == 0.0)
32      elm_widget_theme_object_set(obj, sd->notify, "notify", "top", style);
33    else if (ay == 1.0)
34      elm_widget_theme_object_set(obj, sd->notify, "notify", "bottom", style);
35    else if (ax == 0.0)
36         elm_widget_theme_object_set(obj, sd->notify, "notify", "left", style);
37    else if (ax == 1.0)
38         elm_widget_theme_object_set(obj, sd->notify, "notify", "right", style);
39    else
40      elm_widget_theme_object_set(obj, sd->notify, "notify", "center", style);
41 }
42
43 /**
44  * Moves notification to orientation.
45  *
46  * This function moves notification to orientation
47  * according to object RTL orientation.
48  *
49  * @param obj notification object.
50  *
51  * @param orient notification orientation.
52  *
53  * @internal
54  **/
55 static void
56 _notify_move_to_orientation(Evas_Object *obj)
57 {
58    Evas_Coord minw = -1, minh = -1;
59    Evas_Coord x, y, w, h;
60    double ax, ay;
61
62    ELM_NOTIFY_DATA_GET(obj, sd);
63
64    evas_object_geometry_get(obj, &x, &y, &w, &h);
65    edje_object_size_min_get(sd->notify, &minw, &minh);
66    edje_object_size_min_restricted_calc(sd->notify, &minw, &minh, minw, minh);
67
68    ax = sd->horizontal_align;
69    ay = sd->vertical_align;
70    if ((elm_widget_mirrored_get(obj)) && (ax != ELM_NOTIFY_ALIGN_FILL)) ax = 1.0 - ax;
71
72    if (ax == ELM_NOTIFY_ALIGN_FILL) minw = w;
73    if (ay == ELM_NOTIFY_ALIGN_FILL) minh = h;
74
75    x = x + ((w - minw) * ax);
76    y = y + ((h - minh) * ay);
77
78         evas_object_move(sd->notify, x, y);
79 }
80
81 static void
82 _block_events_theme_apply(Evas_Object *obj)
83 {
84    ELM_NOTIFY_DATA_GET(obj, sd);
85
86    const char *style = elm_widget_style_get(obj);
87
88    elm_layout_theme_set(sd->block_events, "notify", "block_events", style);
89 }
90
91 static void
92 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
93 {
94    ELM_NOTIFY_DATA_GET(obj, sd);
95    edje_object_mirrored_set(sd->notify, rtl);
96    _notify_move_to_orientation(obj);
97 }
98
99 static void
100 _sizing_eval(Evas_Object *obj)
101 {
102    Evas_Coord x, y, w, h;
103
104    ELM_NOTIFY_DATA_GET(obj, sd);
105
106    if (!sd->parent) return;
107    evas_object_geometry_get(sd->parent, &x, &y, &w, &h);
108    evas_object_move(obj, x, y);
109    evas_object_resize(obj, w, h);
110 }
111
112 static Eina_Bool
113 _elm_notify_smart_theme(Evas_Object *obj)
114 {
115    ELM_NOTIFY_DATA_GET(obj, sd);
116
117    if (!ELM_WIDGET_CLASS(_elm_notify_parent_sc)->theme(obj)) return EINA_FALSE;
118
119    _mirrored_set(obj, elm_widget_mirrored_get(obj));
120
121    _notify_theme_apply(obj);
122    if (sd->block_events) _block_events_theme_apply(obj);
123
124    edje_object_scale_set
125      (sd->notify, elm_widget_scale_get(obj) * elm_config_scale_get());
126
127    _sizing_eval(obj);
128
129    return EINA_TRUE;
130 }
131
132 static void
133 _calc(Evas_Object *obj)
134 {
135    Evas_Coord minw = -1, minh = -1;
136    Evas_Coord x, y, w, h;
137
138    ELM_NOTIFY_DATA_GET(obj, sd);
139
140    _sizing_eval(obj);
141
142    evas_object_geometry_get(obj, &x, &y, &w, &h);
143
144    edje_object_size_min_get(sd->notify, &minw, &minh);
145    edje_object_size_min_restricted_calc(sd->notify, &minw, &minh, minw, minh);
146
147    if (sd->horizontal_align == ELM_NOTIFY_ALIGN_FILL) minw = w;
148    if (sd->vertical_align == ELM_NOTIFY_ALIGN_FILL) minh = h;
149
150    if (sd->content)
151      {
152         _notify_move_to_orientation(obj);
153         evas_object_resize(sd->notify, minw, minh);
154      }
155 }
156
157 static void
158 _changed_size_hints_cb(void *data,
159                        Evas *e __UNUSED__,
160                        Evas_Object *obj __UNUSED__,
161                        void *event_info __UNUSED__)
162 {
163    _calc(data);
164 }
165
166 static Eina_Bool
167 _elm_notify_smart_sub_object_del(Evas_Object *obj,
168                                  Evas_Object *sobj)
169 {
170    ELM_NOTIFY_DATA_GET(obj, sd);
171
172    if (!ELM_WIDGET_CLASS(_elm_notify_parent_sc)->sub_object_del(obj, sobj))
173      return EINA_FALSE;
174
175    if (sobj == sd->content)
176      {
177         evas_object_event_callback_del_full
178           (sobj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
179           _changed_size_hints_cb, obj);
180         sd->content = NULL;
181      }
182
183    return EINA_TRUE;
184 }
185
186 static void
187 _block_area_clicked_cb(void *data,
188                        Evas_Object *obj __UNUSED__,
189                        const char *emission __UNUSED__,
190                        const char *source __UNUSED__)
191 {
192    evas_object_smart_callback_call(data, SIG_BLOCK_CLICKED, NULL);
193 }
194
195 static void
196 _restack_cb(void *data __UNUSED__,
197             Evas *e __UNUSED__,
198             Evas_Object *obj,
199             void *event_info __UNUSED__)
200 {
201    ELM_NOTIFY_DATA_GET(obj, sd);
202
203    evas_object_layer_set(sd->notify, evas_object_layer_get(obj));
204 }
205
206 static void
207 _elm_notify_smart_resize(Evas_Object *obj,
208                          Evas_Coord w,
209                          Evas_Coord h)
210 {
211    ELM_WIDGET_CLASS(_elm_notify_parent_sc)->base.resize(obj, w, h);
212
213    _calc(obj);
214 }
215
216 static void
217 _elm_notify_smart_move(Evas_Object *obj,
218                        Evas_Coord x,
219                        Evas_Coord y)
220 {
221    ELM_WIDGET_CLASS(_elm_notify_parent_sc)->base.move(obj, x, y);
222
223    _calc(obj);
224 }
225
226 static Eina_Bool
227 _timer_cb(void *data)
228 {
229    Evas_Object *obj = data;
230
231    ELM_NOTIFY_DATA_GET(obj, sd);
232
233    sd->timer = NULL;
234    if (!evas_object_visible_get(obj)) goto end;
235
236    evas_object_hide(obj);
237    evas_object_smart_callback_call(obj, SIG_TIMEOUT, NULL);
238
239 end:
240    return ECORE_CALLBACK_CANCEL;
241 }
242
243 static void
244 _timer_init(Evas_Object *obj,
245             Elm_Notify_Smart_Data *sd)
246 {
247    if (sd->timer)
248      {
249         ecore_timer_del(sd->timer);
250         sd->timer = NULL;
251      }
252    if (sd->timeout > 0.0)
253      sd->timer = ecore_timer_add(sd->timeout, _timer_cb, obj);
254 }
255
256 static void
257 _elm_notify_smart_show(Evas_Object *obj)
258 {
259    ELM_NOTIFY_DATA_GET(obj, sd);
260
261    ELM_WIDGET_CLASS(_elm_notify_parent_sc)->base.show(obj);
262
263    evas_object_show(sd->notify);
264    if (!sd->allow_events) evas_object_show(sd->block_events);
265    _timer_init(obj, sd);
266    elm_object_focus_set(obj, EINA_TRUE);
267 }
268
269 static void
270 _elm_notify_smart_hide(Evas_Object *obj)
271 {
272    ELM_NOTIFY_DATA_GET(obj, sd);
273
274    ELM_WIDGET_CLASS(_elm_notify_parent_sc)->base.hide(obj);
275
276    evas_object_hide(sd->notify);
277    if (!sd->allow_events) evas_object_hide(sd->block_events);
278    if (sd->timer)
279      {
280         ecore_timer_del(sd->timer);
281         sd->timer = NULL;
282      }
283 }
284
285 static void
286 _parent_del_cb(void *data,
287                Evas *e __UNUSED__,
288                Evas_Object *obj __UNUSED__,
289                void *event_info __UNUSED__)
290 {
291    elm_notify_parent_set(data, NULL);
292    evas_object_hide(data);
293 }
294
295 static void
296 _parent_hide_cb(void *data,
297                 Evas *e __UNUSED__,
298                 Evas_Object *obj __UNUSED__,
299                 void *event_info __UNUSED__)
300 {
301    evas_object_hide(data);
302 }
303
304 static Eina_Bool
305 _elm_notify_smart_focus_next(const Evas_Object *obj,
306                              Elm_Focus_Direction dir,
307                              Evas_Object **next)
308 {
309    Evas_Object *cur;
310
311    ELM_NOTIFY_DATA_GET(obj, sd);
312
313    if (!sd->content)
314      return EINA_FALSE;
315
316    cur = sd->content;
317
318    /* Try to cycle focus on content */
319    return elm_widget_focus_next_get(cur, dir, next);
320 }
321
322 static Eina_Bool
323 _elm_notify_smart_focus_direction(const Evas_Object *obj,
324                                   const Evas_Object *base,
325                                   double degree,
326                                   Evas_Object **direction,
327                                   double *weight)
328 {
329    Evas_Object *cur;
330
331    ELM_NOTIFY_DATA_GET(obj, sd);
332
333    if (!sd->content)
334      return EINA_FALSE;
335
336    cur = sd->content;
337
338    return elm_widget_focus_direction_get(cur, base, degree, direction, weight);
339 }
340
341 static Eina_Bool
342 _elm_notify_smart_content_set(Evas_Object *obj,
343                               const char *part,
344                               Evas_Object *content)
345 {
346    ELM_NOTIFY_DATA_GET(obj, sd);
347
348    if (part && strcmp(part, "default")) return EINA_FALSE;
349    if (sd->content == content) return EINA_TRUE;
350    if (sd->content) evas_object_del(sd->content);
351    sd->content = content;
352
353    if (content)
354      {
355         elm_widget_sub_object_add(obj, content);
356         evas_object_event_callback_add
357           (content, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
358           _changed_size_hints_cb, obj);
359         edje_object_part_swallow(sd->notify, "elm.swallow.content", content);
360      }
361
362    _sizing_eval(obj);
363    _calc(obj);
364
365    return EINA_TRUE;
366 }
367
368 static Evas_Object *
369 _elm_notify_smart_content_get(const Evas_Object *obj,
370                               const char *part)
371 {
372    ELM_NOTIFY_DATA_GET(obj, sd);
373
374    if (part && strcmp(part, "default")) return NULL;
375
376    return sd->content;
377 }
378
379 static Evas_Object *
380 _elm_notify_smart_content_unset(Evas_Object *obj,
381                                 const char *part)
382 {
383    Evas_Object *content;
384
385    ELM_NOTIFY_DATA_GET(obj, sd);
386
387    if (part && strcmp(part, "default")) return NULL;
388    if (!sd->content) return NULL;
389
390    content = sd->content;
391    elm_widget_sub_object_del(obj, sd->content);
392    edje_object_part_unswallow(sd->notify, content);
393
394    return content;
395 }
396
397 static void
398 _elm_notify_smart_add(Evas_Object *obj)
399 {
400    EVAS_SMART_DATA_ALLOC(obj, Elm_Notify_Smart_Data);
401
402    ELM_WIDGET_CLASS(_elm_notify_parent_sc)->base.add(obj);
403
404    priv->allow_events = EINA_TRUE;
405
406    priv->notify = edje_object_add(evas_object_evas_get(obj));
407    priv->horizontal_align = 0.5;
408    priv->vertical_align = 0.0;
409
410    evas_object_event_callback_add
411      (obj, EVAS_CALLBACK_RESTACK, _restack_cb, obj);
412
413    elm_widget_can_focus_set(obj, EINA_FALSE);
414    elm_notify_align_set(obj, 0.5, 0.0);
415 }
416
417 static void
418 _elm_notify_smart_del(Evas_Object *obj)
419 {
420    ELM_NOTIFY_DATA_GET(obj, sd);
421
422    elm_notify_parent_set(obj, NULL);
423    elm_notify_allow_events_set(obj, EINA_FALSE);
424    if (sd->timer)
425      {
426         ecore_timer_del(sd->timer);
427         sd->timer = NULL;
428      }
429
430    ELM_WIDGET_CLASS(_elm_notify_parent_sc)->base.del(obj);
431 }
432
433 static void
434 _elm_notify_smart_parent_set(Evas_Object *obj,
435                              Evas_Object *parent)
436 {
437    elm_notify_parent_set(obj, parent);
438
439    _sizing_eval(obj);
440 }
441
442 static void
443 _elm_notify_smart_set_user(Elm_Notify_Smart_Class *sc)
444 {
445    ELM_WIDGET_CLASS(sc)->base.add = _elm_notify_smart_add;
446    ELM_WIDGET_CLASS(sc)->base.del = _elm_notify_smart_del;
447
448    ELM_WIDGET_CLASS(sc)->base.resize = _elm_notify_smart_resize;
449    ELM_WIDGET_CLASS(sc)->base.move = _elm_notify_smart_move;
450    ELM_WIDGET_CLASS(sc)->base.show = _elm_notify_smart_show;
451    ELM_WIDGET_CLASS(sc)->base.hide = _elm_notify_smart_hide;
452
453    ELM_WIDGET_CLASS(sc)->parent_set = _elm_notify_smart_parent_set;
454    ELM_WIDGET_CLASS(sc)->theme = _elm_notify_smart_theme;
455    ELM_WIDGET_CLASS(sc)->focus_next = _elm_notify_smart_focus_next;
456    ELM_WIDGET_CLASS(sc)->focus_direction = _elm_notify_smart_focus_direction;
457
458    ELM_WIDGET_CLASS(sc)->sub_object_del = _elm_notify_smart_sub_object_del;
459
460    ELM_CONTAINER_CLASS(sc)->content_set = _elm_notify_smart_content_set;
461    ELM_CONTAINER_CLASS(sc)->content_get = _elm_notify_smart_content_get;
462    ELM_CONTAINER_CLASS(sc)->content_unset = _elm_notify_smart_content_unset;
463 }
464
465 EAPI const Elm_Notify_Smart_Class *
466 elm_notify_smart_class_get(void)
467 {
468    static Elm_Notify_Smart_Class _sc =
469      ELM_NOTIFY_SMART_CLASS_INIT_NAME_VERSION(ELM_NOTIFY_SMART_NAME);
470    static const Elm_Notify_Smart_Class *class = NULL;
471    Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
472
473    if (class) return class;
474
475    _elm_notify_smart_set(&_sc);
476    esc->callbacks = _smart_callbacks;
477    class = &_sc;
478
479    return class;
480 }
481
482 EAPI Evas_Object *
483 elm_notify_add(Evas_Object *parent)
484 {
485    Evas_Object *obj;
486
487    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
488
489    obj = elm_widget_add(_elm_notify_smart_class_new(), parent);
490    if (!obj) return NULL;
491
492    if (!elm_widget_sub_object_add(parent, obj))
493      ERR("could not add %p as sub object of %p", obj, parent);
494
495    return obj;
496 }
497
498 EAPI void
499 elm_notify_parent_set(Evas_Object *obj,
500                       Evas_Object *parent)
501 {
502    ELM_NOTIFY_CHECK(obj);
503    ELM_NOTIFY_DATA_GET(obj, sd);
504
505    if (sd->parent)
506      {
507         evas_object_event_callback_del_full
508           (sd->parent, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
509           _changed_size_hints_cb, obj);
510         evas_object_event_callback_del_full
511           (sd->parent, EVAS_CALLBACK_RESIZE, _changed_size_hints_cb, obj);
512         evas_object_event_callback_del_full
513           (sd->parent, EVAS_CALLBACK_MOVE, _changed_size_hints_cb, obj);
514         evas_object_event_callback_del_full
515           (sd->parent, EVAS_CALLBACK_DEL, _parent_del_cb, obj);
516         evas_object_event_callback_del_full
517           (sd->parent, EVAS_CALLBACK_HIDE, _parent_hide_cb, obj);
518         sd->parent = NULL;
519      }
520
521    if (parent)
522      {
523         sd->parent = parent;
524         evas_object_event_callback_add
525           (parent, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
526           _changed_size_hints_cb, obj);
527         evas_object_event_callback_add
528           (parent, EVAS_CALLBACK_RESIZE, _changed_size_hints_cb, obj);
529         evas_object_event_callback_add
530           (parent, EVAS_CALLBACK_MOVE, _changed_size_hints_cb, obj);
531         evas_object_event_callback_add
532           (parent, EVAS_CALLBACK_DEL, _parent_del_cb, obj);
533         evas_object_event_callback_add
534           (parent, EVAS_CALLBACK_HIDE, _parent_hide_cb, obj);
535         _sizing_eval(obj);
536      }
537
538    _calc(obj);
539 }
540
541 EAPI Evas_Object *
542 elm_notify_parent_get(const Evas_Object *obj)
543 {
544    ELM_NOTIFY_CHECK(obj) NULL;
545    ELM_NOTIFY_DATA_GET(obj, sd);
546
547    return sd->parent;
548 }
549
550 EINA_DEPRECATED EAPI void
551 elm_notify_orient_set(Evas_Object *obj,
552                       Elm_Notify_Orient orient)
553 {
554    double horizontal = 0, vertical = 0;
555
556    switch (orient)
557      {
558       case ELM_NOTIFY_ORIENT_TOP:
559          horizontal = 0.5; vertical = 0.0;
560         break;
561
562       case ELM_NOTIFY_ORIENT_CENTER:
563          horizontal = 0.5; vertical = 0.5;
564         break;
565
566       case ELM_NOTIFY_ORIENT_BOTTOM:
567          horizontal = 0.5; vertical = 1.0;
568         break;
569
570       case ELM_NOTIFY_ORIENT_LEFT:
571          horizontal = 0.0; vertical = 0.5;
572         break;
573
574       case ELM_NOTIFY_ORIENT_RIGHT:
575          horizontal = 1.0; vertical = 0.5;
576         break;
577
578       case ELM_NOTIFY_ORIENT_TOP_LEFT:
579          horizontal = 0.0; vertical = 0.0;
580         break;
581
582       case ELM_NOTIFY_ORIENT_TOP_RIGHT:
583          horizontal = 1.0; vertical = 0.0;
584         break;
585
586       case ELM_NOTIFY_ORIENT_BOTTOM_LEFT:
587          horizontal = 0.0; vertical = 1.0;
588         break;
589
590       case ELM_NOTIFY_ORIENT_BOTTOM_RIGHT:
591          horizontal = 1.0; vertical = 1.0;
592         break;
593
594       case ELM_NOTIFY_ORIENT_LAST:
595         break;
596      }
597    elm_notify_align_set(obj, horizontal, vertical);
598 }
599
600 EINA_DEPRECATED EAPI Elm_Notify_Orient
601 elm_notify_orient_get(const Evas_Object *obj)
602 {
603    Elm_Notify_Orient orient;
604    double horizontal, vertical;
605
606    elm_notify_align_get(obj, &horizontal, &vertical);
607
608    if ((horizontal == 0.5) && (vertical == 0.0))
609      orient = ELM_NOTIFY_ORIENT_TOP;
610    else if ((horizontal == 0.5) && (vertical == 0.5))
611      orient = ELM_NOTIFY_ORIENT_CENTER;
612    else if ((horizontal == 0.5) && (vertical == 1.0))
613      orient = ELM_NOTIFY_ORIENT_BOTTOM;
614    else if ((horizontal == 0.0) && (vertical == 0.5))
615      orient = ELM_NOTIFY_ORIENT_LEFT;
616    else if ((horizontal == 1.0) && (vertical == 0.5))
617      orient = ELM_NOTIFY_ORIENT_RIGHT;
618    else if ((horizontal == 0.0) && (vertical == 0.0))
619      orient = ELM_NOTIFY_ORIENT_TOP_LEFT;
620    else if ((horizontal == 1.0) && (vertical == 0.0))
621      orient = ELM_NOTIFY_ORIENT_TOP_RIGHT;
622    else if ((horizontal == 0.0) && (vertical == 1.0))
623      orient = ELM_NOTIFY_ORIENT_BOTTOM_LEFT;
624    else if ((horizontal == 1.0) && (vertical == 1.0))
625      orient = ELM_NOTIFY_ORIENT_BOTTOM_RIGHT;
626    else
627      orient = ELM_NOTIFY_ORIENT_TOP;
628    return orient;
629 }
630
631 EAPI void
632 elm_notify_timeout_set(Evas_Object *obj,
633                        double timeout)
634 {
635    ELM_NOTIFY_CHECK(obj);
636    ELM_NOTIFY_DATA_GET(obj, sd);
637
638    sd->timeout = timeout;
639    _timer_init(obj, sd);
640 }
641
642 EAPI double
643 elm_notify_timeout_get(const Evas_Object *obj)
644 {
645    ELM_NOTIFY_CHECK(obj) 0.0;
646    ELM_NOTIFY_DATA_GET(obj, sd);
647
648    return sd->timeout;
649 }
650
651 EAPI void
652 elm_notify_allow_events_set(Evas_Object *obj,
653                             Eina_Bool allow)
654 {
655    ELM_NOTIFY_CHECK(obj);
656    ELM_NOTIFY_DATA_GET(obj, sd);
657
658    if (allow == sd->allow_events) return;
659    sd->allow_events = allow;
660    if (!allow)
661      {
662         sd->block_events = elm_layout_add(obj);
663         _block_events_theme_apply(obj);
664         elm_widget_resize_object_set(obj, sd->block_events);
665         elm_layout_signal_callback_add
666           (sd->block_events, "elm,action,click", "elm",
667           _block_area_clicked_cb, obj);
668      }
669    else
670      evas_object_del(sd->block_events);
671 }
672
673 EAPI Eina_Bool
674 elm_notify_allow_events_get(const Evas_Object *obj)
675 {
676    ELM_NOTIFY_CHECK(obj) EINA_FALSE;
677    ELM_NOTIFY_DATA_GET(obj, sd);
678
679    return sd->allow_events;
680 }
681
682 EAPI void
683 elm_notify_align_set(Evas_Object *obj, double horizontal, double vertical)
684 {
685    ELM_NOTIFY_CHECK(obj);
686    ELM_NOTIFY_DATA_GET(obj, sd);
687
688    sd->horizontal_align = horizontal;
689    sd->vertical_align = vertical;
690
691    _notify_theme_apply(obj);
692    _calc(obj);
693 }
694
695 EAPI void
696 elm_notify_align_get(const Evas_Object *obj, double *horizontal, double *vertical)
697 {
698    ELM_NOTIFY_CHECK(obj);
699    ELM_NOTIFY_DATA_GET(obj, sd);
700
701    *horizontal = sd->horizontal_align;
702    *vertical = sd->vertical_align;
703 }