Merge branch 'intefl/svn_merge' of ssh://165.213.149.219:29418/slp/pkgs/e/elementary...
[framework/uifw/elementary.git] / src / lib / elm_conform.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 #ifndef MIN
5 # define MIN(a,b) ((a) < (b)) ? (a) : (b)
6 #endif
7
8 #ifndef MAX
9 # define MAX(a,b) ((a) < (b)) ? (b) : (a)
10 #endif
11
12 typedef struct _Widget_Data Widget_Data;
13 struct _Widget_Data
14 {
15    Evas_Object *base;
16    Evas_Object *shelf, *panel, *virtualkeypad, *sliding_win;
17    Evas_Object *content;
18    Evas_Object *scroller;
19    Evas_Object *layout;
20    int is_sliding_win_visible;
21 #ifdef HAVE_ELEMENTARY_X
22    Ecore_Event_Handler *prop_hdl;
23    Ecore_X_Virtual_Keyboard_State vkb_state;
24 #endif
25    struct
26    {
27       Ecore_Animator *animator; // animaton timer
28       double start; // time started
29       Evas_Coord auto_x, auto_y; // desired delta
30       Evas_Coord x, y; // current delta
31    } delta;
32    Ecore_Job *show_region_job;
33 };
34
35 /* Enum to identify conformant swallow parts */
36 typedef enum _Conformant_Part_Type Conformant_Part_Type;
37 enum _Conformant_Part_Type
38 {
39    ELM_CONFORM_INDICATOR_PART      = 1,
40    ELM_CONFORM_SOFTKEY_PART        = 2,
41    ELM_CONFORM_VIRTUAL_KEYPAD_PART = 4,
42    ELM_CONFORM_SLIDING_WIN_PART    = 8
43 };
44
45 #define SUB_TYPE_COUNT 2
46 static char *sub_type[SUB_TYPE_COUNT] = { "scroller", "genlist" };
47
48 /* local function prototypes */
49 static const char *widtype = NULL;
50 static void _del_pre_hook(Evas_Object *obj);
51 static void _del_hook(Evas_Object *obj);
52 static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
53 static void _theme_hook(Evas_Object *obj);
54 static void _content_set_hook(Evas_Object *obj,
55                               const char *part,
56                               Evas_Object *content);
57 static Evas_Object *_content_get_hook(const Evas_Object *obj,
58                                       const char *part);
59 static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *part);
60 static void _swallow_conformant_parts(Evas_Object *obj);
61 static void _conformant_part_size_set(Evas_Object *obj,
62                                       Evas_Object *sobj,
63                                       Evas_Coord sx,
64                                       Evas_Coord sy,
65                                       Evas_Coord sw,
66                                       Evas_Coord sh);
67 static void _conformant_part_sizing_eval(Evas_Object *obj,
68                                          Conformant_Part_Type part_type);
69 static void _conformant_move_resize_event_cb(void *data,
70                                              Evas *e,
71                                              Evas_Object *obj,
72                                              void *event_info);
73 static void _sizing_eval(Evas_Object *obj);
74 static void _show_region_job(void *data);
75 static Eina_Bool _prop_change(void *data, int type, void *event);
76 static void _changed_size_hints(void *data, Evas *e,
77                                 Evas_Object *obj,
78                                 void *event_info);
79
80 /* local functions */
81 static void
82 _del_pre_hook(Evas_Object *obj)
83 {
84    Widget_Data *wd = elm_widget_data_get(obj);
85    if (!wd) return;
86 #ifdef HAVE_ELEMENTARY_X
87    if (wd->prop_hdl) ecore_event_handler_del(wd->prop_hdl);
88 #endif
89 }
90
91 static void
92 _del_hook(Evas_Object *obj)
93 {
94    Widget_Data *wd = elm_widget_data_get(obj);
95
96    if (!wd) return;
97    if (wd->show_region_job) ecore_job_del(wd->show_region_job);
98    free(wd);
99 }
100
101 static void
102 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
103 {
104    Widget_Data *wd = elm_widget_data_get(obj);
105
106    if (!wd) return;
107    edje_object_mirrored_set(wd->base, rtl);
108 }
109
110 static void
111 _theme_hook(Evas_Object *obj)
112 {
113    Widget_Data *wd = elm_widget_data_get(obj);
114
115    if (!wd) return;
116    _elm_widget_mirrored_reload(obj);
117    _mirrored_set(obj, elm_widget_mirrored_get(obj));
118    _elm_theme_object_set(obj, wd->base, "conformant", "base",
119                          elm_widget_style_get(obj));
120    _swallow_conformant_parts(obj);
121
122    if (wd->content)
123      edje_object_part_swallow(wd->base, "elm.swallow.content", wd->content);
124    edje_object_scale_set(wd->base, elm_widget_scale_get(obj)
125                          * _elm_config->scale);
126    _sizing_eval(obj);
127 }
128
129 static void
130 _content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
131 {
132    ELM_CHECK_WIDTYPE(obj, widtype);
133    Widget_Data *wd;
134
135    if (part && strcmp(part, "default")) return;
136    wd = elm_widget_data_get(obj);
137    if (!wd) return;
138    if (wd->content == content) return;
139    if (wd->content) evas_object_del(wd->content);
140    wd->content = content;
141    if (content)
142      {
143         elm_widget_sub_object_add(obj, content);
144         evas_object_event_callback_add(content,
145                                        EVAS_CALLBACK_CHANGED_SIZE_HINTS,
146                                        _changed_size_hints, obj);
147         edje_object_part_swallow(wd->base, "elm.swallow.content", content);
148      }
149    _sizing_eval(obj);
150 }
151
152 static Evas_Object *
153 _content_get_hook(const Evas_Object *obj, const char *part)
154 {
155    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
156    Widget_Data *wd;
157
158    if (part && strcmp(part, "default")) return NULL;
159    wd = elm_widget_data_get(obj);
160    if (!wd) return NULL;
161    return wd->content;
162 }
163
164 static Evas_Object *
165 _content_unset_hook(Evas_Object *obj, const char *part)
166 {
167    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
168    Widget_Data *wd;
169    Evas_Object *content;
170    if (part && strcmp(part, "default")) return NULL;
171    wd = elm_widget_data_get(obj);
172    if ((!wd) || (!wd->content)) return NULL;
173    content = wd->content;
174    elm_widget_sub_object_del(obj, wd->content);
175    evas_object_event_callback_del_full(wd->content,
176                                        EVAS_CALLBACK_CHANGED_SIZE_HINTS,
177                                        _changed_size_hints, obj);
178    edje_object_part_unswallow(wd->base, wd->content);
179    wd->content = NULL;
180    return content;
181 }
182
183 static void
184 _sizing_eval(Evas_Object *obj)
185 {
186    Widget_Data *wd = elm_widget_data_get(obj);
187    Evas_Coord mw = -1, mh = -1;
188
189    if (!wd) return;
190    edje_object_size_min_calc(wd->base, &mw, &mh);
191    evas_object_size_hint_min_set(obj, mw, mh);
192    evas_object_size_hint_max_set(obj, -1, -1);
193 }
194
195 /* Example of env vars:
196  * ILLUME_KBD="0, 0, 800, 301"
197  * ILLUME_IND=0,0,800,32
198  * ILLUME_STK="0,568,800,32
199  */
200 static Eina_Bool
201 _conformant_part_geometry_env_get(const char *part, int *sx, int *sy, int *sw, int *sh)
202 {
203    const char delimiters[] = " ,;";
204    char *env_val, *token;
205    char buf[PATH_MAX];
206    int tsx, tsy, tsw;
207
208    if (!(env_val = getenv(part))) return EINA_FALSE;
209
210    /* strtok would modify env var if not copied to a buffer */
211    strncpy(buf, env_val, sizeof(buf));
212
213    token = strtok(buf, delimiters);
214    if (!token) return EINA_FALSE;
215    tsx = atoi(token);
216
217    token = strtok(NULL, delimiters);
218    if (!token) return EINA_FALSE;
219    tsy = atoi(token);
220
221    token = strtok(NULL, delimiters);
222    if (!token) return EINA_FALSE;
223    tsw = atoi(token);
224
225    token = strtok(NULL, delimiters);
226    if (!token) return EINA_FALSE;
227    *sh = atoi(token);
228
229    *sx = tsx;
230    *sy = tsy;
231    *sw = tsw;
232
233    return EINA_TRUE;
234 }
235
236 static void
237 _conformant_part_size_set(Evas_Object *obj, Evas_Object *sobj, Evas_Coord sx,
238                           Evas_Coord sy, Evas_Coord sw, Evas_Coord sh)
239 {
240    Evas_Coord cx, cy, cw, ch;
241    Evas_Coord part_height = 0, part_width = 0;
242
243    evas_object_geometry_get(obj, &cx, &cy, &cw, &ch);
244
245    /* Part overlapping with conformant */
246    if ((cx < (sx + sw)) && ((cx + cw) > sx)
247             && (cy < (sy + sh)) && ((cy + ch) > sy))
248      {
249         part_height = MIN((cy + ch), (sy + sh)) - MAX(cy, sy);
250         part_width = MIN((cx + cw), (sx + sw)) - MAX(cx, sx);
251      }
252
253    evas_object_size_hint_min_set(sobj, part_width, part_height);
254    evas_object_size_hint_max_set(sobj, part_width, part_height);
255 }
256
257 static void
258 _conformant_part_sizing_eval(Evas_Object *obj, Conformant_Part_Type part_type)
259 {
260    Ecore_X_Window zone = 0, xwin;
261    Evas_Object *top;
262    int sx = -1, sy = -1, sw = -1, sh = -1;
263    Widget_Data *wd = elm_widget_data_get(obj);
264
265    if (!wd) return;
266
267    top = elm_widget_top_get(obj);
268 #ifdef HAVE_ELEMENTARY_X
269    xwin = elm_win_xwindow_get(top);
270    if (xwin)
271      zone = ecore_x_e_illume_zone_get(xwin);
272 #endif
273
274    if (part_type & ELM_CONFORM_INDICATOR_PART)
275      {
276         if ((!_conformant_part_geometry_env_get("ILLUME_IND",
277                                                 &sx, &sy, &sw, &sh)) && (xwin))
278           {
279 #ifdef HAVE_ELEMENTARY_X
280            //No information of the indicator geometry, reset the geometry.
281              if (!ecore_x_e_illume_indicator_geometry_get(zone, &sx, &sy, &sw, &sh))
282                sx = sy = sw = sh = 0;
283 #else
284              ;
285 #endif
286           }
287         _conformant_part_size_set(obj, wd->shelf, sx, sy, sw, sh);
288      }
289    if (part_type & ELM_CONFORM_VIRTUAL_KEYPAD_PART)
290      {
291         if ((!_conformant_part_geometry_env_get("ILLUME_KBD",
292                                                 &sx, &sy, &sw, &sh)) && (xwin))
293           {
294 #ifdef HAVE_ELEMENTARY_X
295            //No information of the keyboard geometry, reset the geometry.
296            if (!ecore_x_e_illume_keyboard_geometry_get(zone, &sx, &sy, &sw, &sh))
297              sx = sy = sw = sh = 0;
298 #else
299              ;
300 #endif
301           }
302         _conformant_part_size_set(obj,wd->virtualkeypad, sx, sy, sw, sh);
303      }
304    if (part_type & ELM_CONFORM_SOFTKEY_PART)
305      {
306         if ((!_conformant_part_geometry_env_get("ILLUME_STK",
307                                                 &sx, &sy, &sw, &sh)) && (xwin))
308           {
309 #ifdef HAVE_ELEMENTARY_X
310            //No information of the softkey geometry, reset the geometry.
311            if (!ecore_x_e_illume_softkey_geometry_get(zone, &sx, &sy, &sw, &sh))
312              sx = sy = sw = sh = 0;
313 #else
314              ;
315 #endif
316           }
317         _conformant_part_size_set(obj, wd->panel, sx, sy, sw, sh);
318      }
319 }
320
321 static void
322 _swallow_conformant_parts(Evas_Object *obj)
323 {
324    Widget_Data *wd = elm_widget_data_get(obj);
325
326    wd->scroller = NULL;
327    if (!wd->shelf)
328      {
329         wd->shelf = evas_object_rectangle_add(evas_object_evas_get(obj));
330         elm_widget_sub_object_add(obj, wd->shelf);
331         evas_object_size_hint_min_set(wd->shelf, -1, 0);
332         evas_object_size_hint_max_set(wd->shelf, -1, 0);
333      }
334    else
335      _conformant_part_sizing_eval(obj, ELM_CONFORM_INDICATOR_PART);
336    evas_object_color_set(wd->shelf, 0, 0, 0, 0);
337    edje_object_part_swallow(wd->base, "elm.swallow.shelf", wd->shelf);
338
339    if (!wd->virtualkeypad)
340      {
341         wd->virtualkeypad = evas_object_rectangle_add(evas_object_evas_get(obj));
342         elm_widget_sub_object_add(obj, wd->virtualkeypad);
343         evas_object_size_hint_min_set(wd->virtualkeypad, -1, 0);
344         evas_object_size_hint_max_set(wd->virtualkeypad, -1, 0);
345      }
346    else
347      _conformant_part_sizing_eval(obj, ELM_CONFORM_VIRTUAL_KEYPAD_PART);
348    evas_object_color_set(wd->virtualkeypad, 0, 0, 0, 0);
349    edje_object_part_swallow(wd->base, "elm.swallow.virtualkeypad",
350                             wd->virtualkeypad);
351
352    if (!wd->sliding_win)
353      {
354         wd->sliding_win = evas_object_rectangle_add(evas_object_evas_get(obj));
355         elm_widget_sub_object_add(obj, wd->sliding_win);
356         evas_object_size_hint_min_set(wd->sliding_win, -1, 0);
357         evas_object_size_hint_max_set(wd->sliding_win, -1, 0);
358      }
359 #ifdef HAVE_ELEMENTARY_X
360    else
361      _conformant_part_sizing_eval(obj, ELM_CONFORM_SLIDING_WIN_PART);
362 #endif
363    evas_object_color_set(wd->sliding_win, 0, 0, 0, 0);
364
365    if (!wd->panel)
366      {
367         wd->panel = evas_object_rectangle_add(evas_object_evas_get(obj));
368         elm_widget_sub_object_add(obj, wd->panel);
369         evas_object_size_hint_min_set(wd->panel, -1, 0);
370         evas_object_size_hint_max_set(wd->panel, -1, 0);
371      }
372    else
373      _conformant_part_sizing_eval(obj, ELM_CONFORM_SOFTKEY_PART);
374    evas_object_color_set(wd->panel, 0, 0, 0, 0);
375    edje_object_part_swallow(wd->base, "elm.swallow.panel", wd->panel);
376 }
377
378 static void
379 _changed_size_hints(void *data, Evas *e __UNUSED__,
380                     Evas_Object *obj __UNUSED__,
381                     void *event_info __UNUSED__)
382 {
383    Widget_Data *wd = elm_widget_data_get(data);
384
385    if (!wd) return;
386    _sizing_eval(data);
387 }
388
389 static void
390 _sub_del(void *data, Evas_Object *obj __UNUSED__, void *event_info)
391 {
392    Widget_Data *wd = elm_widget_data_get(data);
393    Evas_Object *sub = event_info;
394 if (!wd) return;
395    if (sub == wd->content)
396      {
397         evas_object_event_callback_del_full(sub,
398                                             EVAS_CALLBACK_CHANGED_SIZE_HINTS,
399                                             _changed_size_hints, data);
400         wd->content = NULL;
401         _sizing_eval(data);
402      }
403 }
404
405 /* unused now - but meant to be for making sure the focused widget is always
406  * visible when the vkbd comes and goes by moving the conformant obj (and thus
407  * its children) to  show the focused widget (and if focus changes follow)
408
409 static Evas_Object *
410 _focus_object_get(const Evas_Object *obj)
411 {
412    Evas_Object *win, *foc;
413
414    win = elm_widget_top_get(obj);
415    if (!win) return NULL;
416    foc = elm_widget_top_get(win);
417 }
418
419 static void
420 _focus_object_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
421 {
422    evas_object_geometry_get(obj, x, y, w, h);
423 }
424
425 static void
426 _focus_change_del(void *data, Evas_Object *obj, void *event_info)
427 {
428    // called from toplevel when the focused window shanges
429 }
430
431 static void
432 _autoscroll_move(Evas_Object *obj)
433 {
434    // move conformant edje by delta to show focused widget
435 }
436
437 static void
438 _autoscroll_mode_enable(Evas_Object *obj)
439 {
440 // called when autoscroll mode should be on - content area smaller than
441 // its min size
442 // 1. get focused object
443 // 2. if not in visible conformant area calculate delta needed to
444 //    get it in
445 // 3. store delta and call _autoscroll_move() which either asanimates
446 //    or jumps right there
447 }
448
449 static void
450 _autoscroll_mode_disable(Evas_Object *obj)
451 {
452 // called when autoscroll mode should be off - set delta to 0 and
453 // call _autoscroll_move()
454 }
455  */
456
457 static void
458 _conformant_move_resize_event_cb(void *data __UNUSED__, Evas *e __UNUSED__,
459                                  Evas_Object *obj, void *event_info __UNUSED__)
460 {
461    Conformant_Part_Type part_type;
462    Widget_Data *wd = elm_widget_data_get(obj);
463
464    if (!wd) return;
465    part_type =  (ELM_CONFORM_INDICATOR_PART |
466                  ELM_CONFORM_SOFTKEY_PART |
467                  ELM_CONFORM_VIRTUAL_KEYPAD_PART |
468                  ELM_CONFORM_SLIDING_WIN_PART);
469    _conformant_part_sizing_eval(obj, part_type);
470 }
471
472 // showing the focused/important region.
473 static void
474 _content_resize_event_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj
475                          __UNUSED__, void *event_info __UNUSED__)
476 {
477    Evas_Object *conformant = (Evas_Object *)data;
478    Widget_Data *wd = elm_widget_data_get(conformant);
479
480    if (!wd) return;
481 #ifdef HAVE_ELEMENTARY_X
482    if ((wd->vkb_state == ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF)
483             && (!wd->is_sliding_win_visible)) return;
484 #endif
485
486    if (wd->show_region_job) ecore_job_del(wd->show_region_job);
487    wd->show_region_job = ecore_job_add(_show_region_job, conformant);
488 }
489
490 static void
491 _show_region_job(void *data)
492 {
493    Evas_Object *focus_obj;
494    Evas_Object *conformant = (Evas_Object *)data;
495    Widget_Data *wd = elm_widget_data_get(conformant);
496
497    if (!wd) return;
498
499    focus_obj = elm_widget_focused_object_get(conformant);
500    if (focus_obj)
501      {
502         Evas_Coord x, y, w, h;
503
504         elm_widget_show_region_get(focus_obj, &x, &y, &w, &h);
505
506         if (h < _elm_config->finger_size)
507           h = _elm_config->finger_size;
508
509         elm_widget_show_region_set(focus_obj, x, y, w, h, EINA_TRUE);
510      }
511
512    wd->show_region_job = NULL;
513 }
514
515 #ifdef HAVE_ELEMENTARY_X
516 static void
517 _update_autoscroll_objs(void *data)
518 {
519    const char *type;
520    int i;
521    Evas_Object *sub, *top_scroller = NULL;
522    Evas_Object *conformant = (Evas_Object *)data;
523    Widget_Data *wd = elm_widget_data_get(data);
524
525    if (!wd) return;
526
527    sub = elm_widget_focused_object_get(conformant);
528    //Look up for Top most scroller in the Focus Object hierarchy inside Conformant.
529
530    while (sub)
531      {
532         type = elm_widget_type_get(sub);
533         if (!strcmp(type, "conformant")) break;
534         for (i = 0; i < SUB_TYPE_COUNT; i++)
535           if (!strcmp(type, sub_type[i]))
536             {
537                top_scroller = sub;
538                break;
539             }
540         sub = elm_object_parent_widget_get(sub);
541      }
542
543    //If the scroller got changed by app, replace it.
544    if (top_scroller != wd->scroller)
545      {
546         if (wd->scroller) evas_object_event_callback_del(wd->scroller,
547                                                    EVAS_CALLBACK_RESIZE,
548                                                    _content_resize_event_cb);
549         wd->scroller = top_scroller;
550         if (wd->scroller) evas_object_event_callback_add(wd->scroller,
551                                                    EVAS_CALLBACK_RESIZE,
552                                                    _content_resize_event_cb,
553                                                    data);
554      }
555 }
556
557 static Eina_Bool
558 _prop_change(void *data, int type __UNUSED__, void *event)
559 {
560    Ecore_X_Event_Window_Property *ev;
561    Widget_Data *wd = elm_widget_data_get(data);
562
563    if (!wd) return ECORE_CALLBACK_PASS_ON;
564    ev = event;
565    if (ev->atom == ECORE_X_ATOM_E_ILLUME_ZONE)
566      {
567         Conformant_Part_Type part_type;
568
569         part_type =  (ELM_CONFORM_INDICATOR_PART |
570                       ELM_CONFORM_SOFTKEY_PART |
571                       ELM_CONFORM_VIRTUAL_KEYPAD_PART |
572                       ELM_CONFORM_SLIDING_WIN_PART);
573         _conformant_part_sizing_eval(data, part_type);
574      }
575    else if (ev->atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_GEOMETRY)
576      _conformant_part_sizing_eval(data, ELM_CONFORM_INDICATOR_PART);
577    else if (ev->atom == ECORE_X_ATOM_E_ILLUME_SOFTKEY_GEOMETRY)
578      _conformant_part_sizing_eval(data, ELM_CONFORM_SOFTKEY_PART);
579    else if (ev->atom == ECORE_X_ATOM_E_ILLUME_KEYBOARD_GEOMETRY)
580      _conformant_part_sizing_eval(data, ELM_CONFORM_VIRTUAL_KEYPAD_PART);
581    else if (ev->atom == ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_GEOMETRY)
582      _conformant_part_sizing_eval(data, ELM_CONFORM_SLIDING_WIN_PART);
583    else if (ev->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
584      {
585         Ecore_X_Window zone;
586
587         printf("Keyboard Geometry Changed\n");
588         zone = ecore_x_e_illume_zone_get(ev->win);
589         wd->vkb_state = ecore_x_e_virtual_keyboard_state_get(zone);
590         if (wd->vkb_state == ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF)
591           {
592              evas_object_size_hint_min_set(wd->virtualkeypad, -1, 0);
593              evas_object_size_hint_max_set(wd->virtualkeypad, -1, 0);
594           }
595         else
596           _update_autoscroll_objs(data);
597      }
598    else if (ev->atom == ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_STATE)
599      {
600         Ecore_X_Window zone;
601
602         zone = ecore_x_e_illume_zone_get(ev->win);
603         wd->is_sliding_win_visible = ecore_x_e_illume_sliding_win_state_get(zone);
604
605         if (!wd->is_sliding_win_visible)
606           {
607              evas_object_size_hint_min_set(wd->sliding_win, -1, 0);
608              evas_object_size_hint_max_set(wd->sliding_win, -1, 0);
609           }
610         else
611           _update_autoscroll_objs(data);
612      }
613
614    return ECORE_CALLBACK_PASS_ON;
615 }
616 #endif
617
618 EAPI Evas_Object *
619 elm_conformant_add(Evas_Object *parent)
620 {
621    Evas_Object *obj;
622    Evas *e;
623    Widget_Data *wd;
624
625    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
626
627    ELM_SET_WIDTYPE(widtype, "conformant");
628    elm_widget_type_set(obj, "conformant");
629    elm_widget_sub_object_add(parent, obj);
630    elm_widget_data_set(obj, wd);
631    elm_widget_del_pre_hook_set(obj, _del_pre_hook);
632    elm_widget_del_hook_set(obj, _del_hook);
633    elm_widget_theme_hook_set(obj, _theme_hook);
634    elm_widget_can_focus_set(obj, EINA_FALSE);
635    elm_widget_content_set_hook_set(obj, _content_set_hook);
636    elm_widget_content_get_hook_set(obj, _content_get_hook);
637    elm_widget_content_unset_hook_set(obj, _content_unset_hook);
638
639    wd->base = edje_object_add(e);
640    _elm_theme_object_set(obj, wd->base, "conformant", "base", "default");
641    elm_widget_resize_object_set(obj, wd->base);
642
643    wd->layout = elm_layout_add(obj);
644    edje_object_part_swallow(wd->base, "elm.swallow.content", wd->layout);
645    elm_layout_theme_set(wd->layout, "conformant", "layout", "content");
646
647    _swallow_conformant_parts(obj);
648
649 #ifdef HAVE_ELEMENTARY_X
650    Evas_Object *top = elm_widget_top_get(obj);
651    Ecore_X_Window xwin = elm_win_xwindow_get(top);
652
653    if ((xwin) && (!elm_win_inlined_image_object_get(top)))
654      {
655         wd->prop_hdl = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY,
656                                                _prop_change, obj);
657         wd->vkb_state = ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF;
658      }
659    // FIXME: get kbd region prop
660 #endif
661
662    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
663                                        _conformant_move_resize_event_cb, obj);
664    evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE,
665                                        _conformant_move_resize_event_cb, obj);
666    evas_object_smart_callback_add(wd->layout, "sub-object-del", _sub_del, obj);
667
668
669    _mirrored_set(obj, elm_widget_mirrored_get(obj));
670    _sizing_eval(obj);
671    return obj;
672 }
673
674 EAPI void
675 elm_conformant_content_set(Evas_Object *obj, Evas_Object *content)
676 {
677    _content_set_hook(obj, NULL, content);
678 }
679
680 EAPI Evas_Object *
681 elm_conformant_content_get(const Evas_Object *obj)
682 {
683    return _content_get_hook(obj, NULL);
684 }
685
686 EAPI Evas_Object *
687 elm_conformant_content_unset(Evas_Object *obj)
688 {
689    return _content_unset_hook(obj, NULL);
690 }
691
692 EINA_DEPRECATED EAPI Evas_Object *
693 elm_conformant_content_area_get(const Evas_Object *obj)
694 {
695    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
696    Widget_Data *wd = elm_widget_data_get(obj);
697
698    if (!wd) return NULL;
699    /*Finger waggle warning*/
700    _elm_dangerous_call_check(__FUNCTION__);
701
702    return wd->layout;
703 }