Added files elm_gridbox.c and elm_softkey.c
[framework/uifw/elementary.git] / src / lib / elm_softkey.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 /**
5  * @addtogroup Softkey Softkey
6  *
7  * This is a softkey
8  */
9
10 /**
11  * internal data structure of softkey object
12  */
13 #define BTN_ANIMATOR_MAX        4
14 #define PANEL_ANIMATOR_MAX      1
15 typedef struct _Widget_Data Widget_Data;
16
17 struct _Widget_Data {
18         Evas_Object *lay;
19         Evas_Object *button[2];
20         Evas_Object *bg_rect;
21         Evas_Object *panel;
22         Evas_Object *glow_obj;
23
24         Evas_Coord x, y, w, h;
25         Evas_Coord glow_w, glow_h;
26         Evas_Coord win_h;
27         Evas_Coord panel_height;
28         Ecore_Animator *animator;
29         Eina_List *items;
30         unsigned int panel_btn_idx;
31         Eina_Bool button_show[2];
32         Eina_Bool show_panel :1;
33         Eina_Bool animating :1;
34         Eina_Bool is_horizontal;
35         double scale_factor;
36         int max_button;
37         Eina_Bool panel_suppported;
38 };
39
40 struct _Elm_Softkey_Item {
41         Evas_Object *obj;
42         Evas_Object *base;
43         Evas_Object *icon;
44         const char *label;
45         void (*func)(void *data, Evas_Object *obj, void *event_info);
46         const void *data;
47         Eina_Bool disabled :1;
48 };
49
50 static void _item_disable(Elm_Softkey_Item *it, Eina_Bool disabled);
51 static void _del_hook(Evas_Object *obj);
52 static void _theme_hook(Evas_Object *obj);
53 static void _sizing_eval(Evas_Object *obj);
54 static void _sub_del(void *data, Evas_Object *obj, void *event_info);
55
56 /*
57  * callback functions
58  */
59 static void _softkey_down_cb(void *data, Evas_Object *obj,
60                 const char *emission, const char *source);
61 static void _softkey_up_cb(void *data, Evas_Object *obj, const char *emission,
62                 const char *source);
63
64 static void _panel_down_cb(void *data, Evas *e, Evas_Object *obj,
65                 void *event_info);
66 static void _panel_up_cb(void *data, Evas *e, Evas_Object *obj,
67                 void *event_info);
68
69 static void _more_btn_click_cb(void *data, Evas_Object *obj,
70                 const char *emission, const char *source);
71 static void _close_btn_click_cb(void *data, Evas_Object *obj,
72                 const char *emission, const char *source);
73 static void _bg_click_cb(void *data, Evas *e, Evas_Object *obj,
74                 void *event_info);
75
76 static int _show_button_animator_cb(void *data);
77 static int _hide_button_animator_cb(void *data);
78 static int _panel_up_animator_cb(void *data);
79 static int _panel_down_animator_cb(void *data);
80
81 /*
82  * internal function
83  */
84 static int
85                 _show_button(Evas_Object *obj, Elm_Softkey_Type type, Eina_Bool show);
86 static int _delete_button(Evas_Object *obj);
87
88 static void _softkey_object_move(void *data, Evas *e, Evas_Object *obj,
89                 void *event_info);
90 static void _softkey_object_resize(void *data, Evas *e, Evas_Object *obj,
91                 void *event_info);
92 static void _softkey_object_show(void *data, Evas *e, Evas_Object *obj,
93                 void *event_info);
94 static void _softkey_object_hide(void *data, Evas *e, Evas_Object *obj,
95                 void *event_info);
96
97 static void _icon_disable(Evas_Object *icon, Eina_Bool disabled) {
98         Evas_Object *edj;
99
100         if (!icon)
101                 return;
102         edj = elm_layout_edje_get(icon);
103
104         if (disabled) {
105                 if (!edj) {
106                         edje_object_signal_emit(icon, "elm,state,disabled", "elm");
107                 } else {
108                         edje_object_signal_emit(edj, "elm,state,disabled", "elm");
109                 }
110         } else {
111                 if (!edj) {
112                         edje_object_signal_emit(icon, "elm,state,enabled", "elm");
113                 } else {
114                         edje_object_signal_emit(edj, "elm,state,enabled", "elm");
115                 }
116         }
117 }
118
119 static void _item_disable(Elm_Softkey_Item *it, Eina_Bool disabled) {
120         Widget_Data *wd = elm_widget_data_get(it->obj);
121         if (!wd)
122                 return;
123         if (it->disabled == disabled)
124                 return;
125         it->disabled = disabled;
126         if (it->disabled) {
127                 edje_object_signal_emit(it->base, "elm,state,disabled", "elm");
128         } else {
129                 edje_object_signal_emit(it->base, "elm,state,enabled", "elm");
130         }
131
132         _icon_disable(it->icon, disabled);
133 }
134
135 static void _del_hook(Evas_Object *obj) {
136         int i;
137         Evas_Object *btn;
138         Widget_Data *wd = elm_widget_data_get(obj);
139
140         if (!wd)
141                 return;
142
143         if (wd->lay) {
144                 evas_object_smart_member_del(wd->lay);
145                 evas_object_del(wd->lay);
146                 wd->lay = NULL;
147         }
148
149         /* delete button */
150         for (i = 0; i < 2; i++) {
151                 btn = wd->button[i];
152                 if (btn != NULL) {
153                         evas_object_smart_member_del(btn);
154                         _delete_button(btn);
155                 }
156         }
157
158         /* delete background */
159         if (wd->bg_rect) {
160                 evas_object_smart_member_del(wd->bg_rect);
161                 evas_object_del(wd->bg_rect);
162                 wd->bg_rect = NULL;
163         }
164
165         /* delete panel */
166         if (wd->panel) {
167                 elm_softkey_panel_del(obj);
168                 //<Commenting as clean up for panel is being done in method elm_softkey_panel_del()
169                 /*evas_object_smart_member_del(wd->panel);
170                  evas_object_del(wd->panel);
171                  wd->panel = NULL;*/
172                 //<Commenting as clean up for panel is being done in method elm_softkey_panel_del()
173         }
174
175         /* delete glow effect image */
176         if (wd->glow_obj) {
177                 evas_object_del(wd->glow_obj);
178                 wd->glow_obj = NULL;
179         }
180
181         free(wd);
182 }
183
184 static void _theme_hook(Evas_Object *obj) {
185         Elm_Softkey_Item* item;
186         Widget_Data *wd = elm_widget_data_get(obj);
187         Elm_Softkey_Item *it;
188         const Eina_List *l;
189
190         if (!wd) {
191                 return;
192         }
193         _elm_theme_object_set(obj, wd->lay, "softkey", "bg", elm_widget_style_get(
194                         obj));
195         _elm_theme_object_set(obj, wd->glow_obj, "softkey", "glow", "default");
196
197         if (wd->button[ELM_SK_LEFT_BTN]) {
198
199                 item = evas_object_data_get(wd->button[ELM_SK_LEFT_BTN], "item_data");
200                 _elm_theme_object_set(obj, wd->button[ELM_SK_LEFT_BTN], "softkey",
201                                 "button_left", elm_widget_style_get(obj));
202
203                 elm_softkey_item_label_set(item, item->label);
204
205         }
206
207         if (wd->button[ELM_SK_RIGHT_BTN]) {
208
209                 item = evas_object_data_get(wd->button[ELM_SK_RIGHT_BTN], "item_data");
210
211                 _elm_theme_object_set(obj, wd->button[ELM_SK_RIGHT_BTN], "softkey",
212                                 "button_right", elm_widget_style_get(obj));
213
214                 elm_softkey_item_label_set(item, item->label);
215
216         }
217
218         if (wd->panel) {
219                 _elm_theme_object_set(obj, wd->panel, "softkey", "panel",
220                                 elm_widget_style_get(obj));
221                 if (wd->panel_btn_idx > 0) {
222                         //show more button 
223                         edje_object_signal_emit(wd->lay, "more_btn_show", "");
224 EINA_LIST_FOREACH               (wd->items, l, it)
225                 {
226                         _elm_theme_object_set(obj, it->base, "softkey", "panel_button", elm_widget_style_get(obj));
227                         if(it->label) {
228                                 edje_object_part_text_set(it->base, "elm.text", it->label); // set text
229                         }
230                 }
231         }
232 }
233
234 _sizing_eval( obj );
235 }
236
237 static void _sub_del(void *data, Evas_Object *obj, void *event_info) {
238         Widget_Data *wd = elm_widget_data_get(obj);
239         Evas_Object *sub = event_info;
240         const Eina_List *l;
241         Elm_Softkey_Item *it;
242         if (!wd)
243                 return;
244
245 EINA_LIST_FOREACH(wd->items, l, it)
246 {
247         if(sub == it->icon) {
248                 it->icon = NULL;
249         }
250         break;
251 }
252 }
253
254 static void _sizing_eval(Evas_Object *obj) {
255         Widget_Data *wd = elm_widget_data_get(obj);
256
257         if (!wd)
258                 return;
259
260         _softkey_object_move(obj, NULL, obj, NULL);
261         _softkey_object_resize(obj, NULL, obj, NULL);
262 }
263
264 static int _panel_up_animator_cb(void *data) {
265         int max = PANEL_ANIMATOR_MAX;
266         static int progress = 0;
267         Widget_Data *wd;
268         Evas_Coord ypos;
269
270         wd = elm_widget_data_get(data);
271         if (!wd)
272                 return 0;
273
274         progress++;
275         wd->animating = EINA_TRUE;
276
277         if (progress > max) {
278                 if (!wd->animator)
279                         return 0;
280                 ecore_animator_del(wd->animator);
281                 wd->animating = EINA_FALSE;
282                 wd->show_panel = EINA_TRUE;
283                 progress = 0;
284                 return 0;
285         }
286
287         /* move up panel */
288         if (wd->panel) {
289                 ypos = wd->win_h - (wd->panel_height * progress / max);
290                 evas_object_move(wd->panel, 0, ypos);
291         }
292
293         return 1;
294 }
295
296 static int _panel_down_animator_cb(void *data) {
297         int max = PANEL_ANIMATOR_MAX;
298         static int progress = 0;
299         Widget_Data *wd;
300         Evas_Coord ypos;
301
302         wd = elm_widget_data_get(data);
303         if (!wd)
304                 return 0;
305
306         progress++;
307         wd->animating = EINA_TRUE;
308
309         if (progress > max) {
310                 if (!wd->animator)
311                         return 0;
312                 ecore_animator_del(wd->animator);
313                 wd->animating = EINA_FALSE;
314                 wd->animator = ecore_animator_add(_show_button_animator_cb, data);
315                 wd->show_panel = EINA_FALSE;
316                 progress = 0;
317
318                 evas_object_smart_callback_call(data, "panel,hide", NULL);
319
320                 return 0;
321         }
322
323         /* move down panel */
324         if (wd->panel) {
325                 ypos = wd->win_h - wd->panel_height + (wd->panel_height * progress
326                                 / max);
327                 evas_object_move(wd->panel, 0, ypos);
328         }
329
330         return 1;
331 }
332
333 static int _hide_button_animator_cb(void *data) {
334         int max = BTN_ANIMATOR_MAX;
335         static int progress = 0;
336         Widget_Data *wd;
337         Evas_Coord btn_w, xpos;
338
339         wd = elm_widget_data_get(data);
340         if (!wd)
341                 return 0;
342
343         progress++;
344         wd->animating = EINA_TRUE;
345
346         if (progress > max) {
347                 if (!wd->animator)
348                         return 0;
349                 ecore_animator_del(wd->animator);
350                 wd->animating = EINA_FALSE;
351                 wd->animator = ecore_animator_add(_panel_up_animator_cb, data);
352                 progress = 0;
353                 return 0;
354         }
355
356         /* move left button */
357         if (wd->button[ELM_SK_LEFT_BTN]) {
358                 edje_object_part_geometry_get(wd->button[ELM_SK_LEFT_BTN],
359                                 "button_rect", NULL, NULL, &btn_w, NULL);
360
361                 xpos = -1 * btn_w * progress / max;
362                 evas_object_move(wd->button[ELM_SK_LEFT_BTN], xpos, wd->y);
363         }
364
365         /* move right button */
366         if (wd->button[ELM_SK_RIGHT_BTN]) {
367                 edje_object_part_geometry_get(wd->button[ELM_SK_RIGHT_BTN],
368                                 "button_rect", NULL, NULL, &btn_w, NULL);
369
370                 xpos = (wd->w - btn_w) + (btn_w * progress / max);
371                 evas_object_move(wd->button[ELM_SK_RIGHT_BTN], xpos, wd->y);
372         }
373
374         return 1;
375 }
376
377 static int _show_button_animator_cb(void *data) {
378         int max = BTN_ANIMATOR_MAX;
379         static int progress = 0;
380         Widget_Data *wd;
381         Evas_Coord btn_w, xpos;
382
383         wd = elm_widget_data_get(data);
384         if (!wd)
385                 return 0;
386
387         progress++;
388
389         wd->animating = EINA_TRUE;
390
391         if (progress > max) {
392                 if (!wd->animator)
393                         return 0;
394                 ecore_animator_del(wd->animator);
395                 wd->animating = EINA_FALSE;
396                 progress = 0;
397                 return 0;
398         }
399
400         /* move left button */
401         if (wd->button[ELM_SK_LEFT_BTN]) {
402                 edje_object_part_geometry_get(wd->button[ELM_SK_LEFT_BTN],
403                                 "button_rect", NULL, NULL, &btn_w, NULL);
404
405                 xpos = (-1 * btn_w) + (btn_w * progress / max);
406                 evas_object_move(wd->button[ELM_SK_LEFT_BTN], xpos, wd->y);
407         }
408
409         /* move right button */
410         if (wd->button[ELM_SK_RIGHT_BTN]) {
411                 edje_object_part_geometry_get(wd->button[ELM_SK_RIGHT_BTN],
412                                 "button_rect", NULL, NULL, &btn_w, NULL);
413
414                 xpos = wd->w - (btn_w * progress / max);
415                 evas_object_move(wd->button[ELM_SK_RIGHT_BTN], xpos, wd->y);
416         }
417
418         return 1;
419 }
420
421 static void _more_btn_click_cb(void *data, Evas_Object *obj,
422                 const char *emission, const char *source) {
423         Widget_Data *wd;
424         wd = elm_widget_data_get(data);
425         if (!wd)
426                 return;
427
428         evas_object_smart_callback_call(data, "panel,show", NULL);
429
430         if (!wd->panel)
431                 return;
432         evas_object_show(wd->panel);
433
434         if (wd->bg_rect) {
435                 evas_object_show(wd->bg_rect);
436         }
437
438         if (wd->animating == EINA_FALSE) {
439                 wd->animator = ecore_animator_add(_hide_button_animator_cb, data);
440         }
441 }
442
443 static void _close_panel(Evas_Object *obj) {
444         Widget_Data *wd;
445         wd = elm_widget_data_get(obj);
446         if (!wd)
447                 return;
448
449         if (wd->bg_rect) {
450                 evas_object_hide(wd->bg_rect);
451         }
452
453         if (!wd->panel)
454                 return;
455
456         if (wd->animating == EINA_FALSE) {
457                 wd->animator = ecore_animator_add(_panel_down_animator_cb, obj);
458         }
459 }
460
461 static void _bg_click_cb(void *data, Evas *e, Evas_Object *obj,
462                 void *event_info) {
463         _close_panel(data);
464 }
465
466 static void _close_btn_click_cb(void *data, Evas_Object *obj,
467                 const char *emission, const char *source) {
468         _close_panel(data);
469 }
470
471 static int _show_button(Evas_Object *obj, Elm_Softkey_Type type, Eina_Bool show) {
472         if (!obj)
473                 return -1;
474
475         Widget_Data *wd = elm_widget_data_get(obj);
476         Evas_Object *btn = wd->button[type];
477         if (!btn)
478                 return -1;
479
480         /* Make visible button */
481         if (show) {
482                 wd->button_show[type] = EINA_TRUE;
483                 evas_object_show(btn);
484         } else {
485                 wd->button_show[type] = EINA_FALSE;
486                 evas_object_hide(btn);
487         }
488
489         return 0;
490 }
491
492 static int _arrange_button(Evas_Object *obj, Elm_Softkey_Type type) {
493         Widget_Data *wd;
494         Evas_Coord btn_w = 0;
495         Evas_Object *btn;
496
497         if (!obj)
498                 return -1;
499         wd = elm_widget_data_get(obj);
500         if (!wd)
501                 return -1;
502
503         btn = wd->button[type];
504         if (!btn)
505                 return -1;
506
507         switch (type) {
508         case ELM_SK_LEFT_BTN:
509                 evas_object_move(btn, wd->x, wd->y);
510                 break;
511         case ELM_SK_RIGHT_BTN:
512                 edje_object_part_geometry_get(btn, "button_rect", NULL, NULL, &btn_w,
513                                 NULL);
514                 evas_object_move(btn, wd->w - btn_w, wd->y);
515                 break;
516         default:
517                 break;
518         }
519
520         return 0;
521 }
522
523 static void _softkey_up_cb(void *data, Evas_Object *obj, const char *emission,
524                 const char *source) {
525         Evas_Object *edj;
526
527         Elm_Softkey_Item *it = (Elm_Softkey_Item *) data;
528         elm_softkey_panel_close(it->obj);
529         if (it->func)
530                 it->func((void *) (it->data), it->obj, it);
531         evas_object_smart_callback_call(it->obj, "clicked", it);
532
533         if (!it->icon)
534                 return;
535         edj = elm_layout_edje_get(it->icon);
536         if (!edj)
537                 return;
538
539         edje_object_signal_emit(edj, "elm,state,unselected", "elm");
540 }
541
542 static void _softkey_down_cb(void *data, Evas_Object *obj,
543                 const char *emission, const char *source) {
544         Evas_Object *edj;
545
546         Elm_Softkey_Item *it = (Elm_Softkey_Item *) data;
547         evas_object_smart_callback_call(it->obj, "press", it);
548
549         if (!it->icon)
550                 return;
551         edj = elm_layout_edje_get(it->icon);
552         if (!edj)
553                 return;
554
555         edje_object_signal_emit(edj, "elm,state,selected", "elm");
556 }
557
558 static void _panel_up_cb(void *data, Evas *e, Evas_Object *obj,
559                 void *event_info) {
560         Elm_Softkey_Item *it = (Elm_Softkey_Item *) data;
561
562         Widget_Data *wd;
563         wd = elm_widget_data_get(it->obj);
564         if (wd == NULL)
565                 return;
566
567         /* hide glow effect */
568         if (wd->glow_obj) {
569                 evas_object_hide(wd->glow_obj);
570         }
571
572         elm_softkey_panel_close(it->obj);
573         if (it->func)
574                 it->func((void *) (it->data), it->obj, it);
575         evas_object_smart_callback_call(it->obj, "clicked", it);
576 }
577
578 static void _panel_down_cb(void *data, Evas *e, Evas_Object *obj,
579                 void *event_info) {
580         Evas_Coord glow_x, glow_y;
581         Widget_Data *wd;
582
583         Elm_Softkey_Item *it = (Elm_Softkey_Item *) data;
584         wd = elm_widget_data_get(it->obj);
585         if (wd == NULL)
586                 return;
587
588         /* show glow effect */
589         if (wd->glow_obj) {
590                 Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down *) event_info;
591                 glow_x = ev->canvas.x - (wd->glow_w / 2);
592                 glow_y = ev->canvas.y - (wd->glow_h / 2);
593
594                 evas_object_move(wd->glow_obj, glow_x, glow_y);
595                 evas_object_show(wd->glow_obj);
596         }
597
598         evas_object_smart_callback_call(it->obj, "press", it);
599 }
600
601 static int _delete_button(Evas_Object *obj) {
602         if (!obj)
603                 return -1;
604
605         if (obj) {
606                 evas_object_del(obj);
607                 obj = NULL;
608         }
609
610         return 0;
611 }
612
613 static void _calc_win_height(Widget_Data *wd) {
614         wd->win_h = wd->y + wd->h;
615
616         if (wd->bg_rect) {
617                 evas_object_resize(wd->bg_rect, wd->w, wd->win_h);
618         }
619
620         if (wd->show_panel) {
621                 evas_object_move(wd->panel, wd->x, (wd->win_h - wd->panel_height));
622         } else {
623                 evas_object_move(wd->panel, wd->x, wd->win_h);
624         }
625 }
626
627 static void _softkey_object_move(void *data, Evas *e, Evas_Object *obj,
628                 void *event_info) {
629         Widget_Data *wd;
630         int i;
631         Evas_Coord x, y;
632
633         if (!data)
634                 return;
635         wd = elm_widget_data_get((Evas_Object *) data);
636         if (!wd)
637                 return;
638
639         evas_object_geometry_get(wd->lay, &x, &y, NULL, NULL);
640
641         wd->x = x;
642         wd->y = y;
643
644         //      evas_object_move(wd->lay, x, y);
645
646         for (i = 0; i < 2; i++) {
647                 _arrange_button((Evas_Object *) data, i);
648         }
649
650         _calc_win_height(wd);
651 }
652
653 static void _softkey_object_resize(void *data, Evas *e, Evas_Object *obj,
654                 void *event_info) {
655         Widget_Data *wd;
656         Evas_Object *btn;
657         int i;
658         Evas_Coord btn_w;
659         Evas_Coord w, h;
660
661         if (!data)
662                 return;
663         wd = elm_widget_data_get((Evas_Object *) data);
664         if (!wd)
665                 return;
666
667         evas_object_geometry_get(wd->lay, NULL, NULL, &w, &h);
668
669         wd->w = w;
670         wd->h = h;
671
672         if (!wd->lay)
673                 return;
674         evas_object_resize(wd->lay, w, h);
675
676         /* resize button */
677         for (i = 0; i < 2; i++) {
678                 btn = wd->button[i];
679                 if (btn != NULL) {
680                         edje_object_part_geometry_get(btn, "button_rect", NULL, NULL,
681                                         &btn_w, NULL);
682                         evas_object_resize(btn, btn_w, h);
683                         _arrange_button((Evas_Object *) data, i);
684                 }
685         }
686
687         if (wd->w >= wd->win_h) {
688                 _softkey_horizontal_set(data, EINA_TRUE);
689         } else {
690                 _softkey_horizontal_set(data, EINA_FALSE);
691         }
692         _calc_win_height(wd);
693 }
694
695 static void _softkey_object_show(void *data, Evas *e, Evas_Object *obj,
696                 void *event_info) {
697         Widget_Data *wd = NULL;
698         Evas_Object *btn;
699         int i;
700         if (data == NULL)
701                 return;
702         wd = elm_widget_data_get((Evas_Object *) data);
703         if (wd == NULL)
704                 return;
705
706         if (wd->lay) {
707                 evas_object_show(wd->lay);
708         }
709
710         /* show button */
711         for (i = 0; i < 2; i++) {
712                 btn = wd->button[i];
713                 if (btn != NULL && wd->button_show[i] == EINA_TRUE) {
714                         evas_object_show(btn);
715                         //evas_object_clip_set(btn, evas_object_clip_get((Evas_Object *)data));
716                 }
717         }
718         if (wd->panel_btn_idx > 0) {
719                 /* show more button */
720                 edje_object_signal_emit(wd->lay, "more_btn_show", "");
721         }
722 }
723
724 static void _softkey_object_hide(void *data, Evas *e, Evas_Object *obj,
725                 void *event_info) {
726         Widget_Data *wd = NULL;
727         Evas_Object *btn;
728         int i;
729
730         if (data == NULL)
731                 return;
732         wd = elm_widget_data_get((Evas_Object *) data);
733         if (wd == NULL)
734                 return;
735
736         if (wd->lay) {
737                 evas_object_hide(wd->lay);
738         }
739
740         /* hide button */
741         for (i = 0; i < 2; i++) {
742                 btn = wd->button[i];
743                 if (btn != NULL) {
744                         evas_object_hide(btn);
745                 }
746         }
747
748         if (wd->panel_btn_idx > 0) {
749                 /* hide more button */
750                 edje_object_signal_emit(wd->lay, "more_btn_hide", "");
751         }
752 }
753
754 /**
755  * Add a new softkey to the parent
756
757  * @param parent the parent of the smart object
758  * @return              Evas_Object* pointer of softkey(evas object) or NULL
759  * @ingroup             Softkey 
760  */
761 EAPI Evas_Object *
762 elm_softkey_add(Evas_Object *parent) {
763         Evas_Object *obj = NULL;
764         Widget_Data *wd = NULL;
765         Evas *e;
766
767         wd = ELM_NEW(Widget_Data);
768         e = evas_object_evas_get(parent);
769         if (e == NULL)
770                 return NULL;
771         obj = elm_widget_add(e);
772         elm_widget_type_set(obj, "softkey");
773         elm_widget_sub_object_add(parent, obj);
774         elm_widget_data_set(obj, wd);
775         elm_widget_del_hook_set(obj, _del_hook);
776         elm_widget_theme_hook_set(obj, _theme_hook);
777
778         /* load background edj */
779         wd->lay = edje_object_add(e);
780         _elm_theme_object_set(obj, wd->lay, "softkey", "bg", "default");
781         if (wd->lay == NULL) {
782                 printf("Cannot load bg edj\n");
783                 return NULL;
784         }
785         elm_widget_resize_object_set(obj, wd->lay);
786         edje_object_signal_callback_add(wd->lay, "clicked", "more_btn",
787                         _more_btn_click_cb, obj);
788
789         evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
790                         _softkey_object_resize, obj);
791         evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE,
792                         _softkey_object_move, obj);
793         evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW,
794                         _softkey_object_show, obj);
795         evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE,
796                         _softkey_object_hide, obj);
797         wd->is_horizontal = EINA_FALSE;
798         wd->panel_suppported = EINA_TRUE;
799         wd->scale_factor = elm_scale_get();
800         if (wd->scale_factor == 0.0) {
801                 wd->scale_factor = 1.0;
802         }
803
804         /* load glow effect */
805         wd->glow_obj = edje_object_add(e);
806         _elm_theme_object_set(obj, wd->glow_obj, "softkey", "glow", "default");
807         evas_object_geometry_get(wd->glow_obj, NULL, NULL, &wd->glow_w, &wd->glow_h);
808         evas_object_resize(wd->glow_obj, wd->glow_w, wd->glow_h);
809
810         // FIXME
811         evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
812
813         //      _sizing_eval(obj);
814
815         return obj;
816 }
817
818 EAPI void _softkey_horizontal_set(Evas_Object *obj, Eina_Bool horizontal_mode) {
819         Widget_Data *wd;
820         char buff[32];
821         if (!obj)
822                 return;
823         wd = elm_widget_data_get(obj);
824         if (!wd)
825                 return;
826         wd->is_horizontal = horizontal_mode;
827         if (wd->panel) {
828                 if ((edje_object_data_get(wd->panel, "max_item_count") == NULL)
829                                 || (edje_object_data_get(wd->panel, "panel_height") == NULL)
830                                 || (edje_object_data_get(wd->panel, "panel_height_horizontal")
831                                                 == NULL)) {
832                         wd->panel_suppported = EINA_FALSE;
833                 } else
834                         wd->panel_suppported = EINA_TRUE;
835                 if (wd->panel_suppported == EINA_TRUE) {
836                         if (wd->is_horizontal == EINA_TRUE) {
837                                 sprintf(buff, "button_%d", (wd->panel_btn_idx + wd->max_button));
838                                 edje_object_signal_emit(wd->panel, buff, "panel_rect");
839                                 wd->panel_height = (int) (atoi(edje_object_data_get(wd->panel,
840                                                 buff)) * wd->scale_factor);
841                                 evas_object_resize(
842                                                 wd->panel,
843                                                 wd->w,
844                                                 ((int) (atoi(edje_object_data_get(wd->panel,
845                                                                 "panel_height_horizontal")) * wd->scale_factor)));
846                         } else {
847                                 sprintf(buff, "button_%d", (wd->panel_btn_idx));
848                                 edje_object_signal_emit(wd->panel, buff, "panel_rect");
849                                 wd->panel_height = (int) (atoi(edje_object_data_get(wd->panel,
850                                                 buff)) * wd->scale_factor);
851                                 evas_object_resize(wd->panel, wd->w, ((int) (atoi(
852                                                 edje_object_data_get(wd->panel, "panel_height"))
853                                                 * wd->scale_factor)));
854                         }
855                 }
856                 _calc_win_height(wd);
857         }
858
859 }
860
861 /**
862  * add side button of softkey
863  * @param       obj     softkey object 
864  * @param       type softkey button type
865  * @param       icon The icon object to use for the item
866  * @param       label The text label to use for the item
867  * @param       func Convenience function to call when this item is selected
868  * @param       data Data to pass to convenience function
869  * @return      A handle to the item added
870  * 
871  * @ingroup     Softkey  
872  */
873 EAPI Elm_Softkey_Item *
874 elm_softkey_button_add(Evas_Object *obj, Elm_Softkey_Type type,
875                 Evas_Object *icon, const char *label, void(*func)(void *data,
876                                 Evas_Object *obj, void *event_info), const void *data) {
877         Widget_Data *wd;
878         Evas* evas;
879         char button_type[64];
880         Elm_Softkey_Item *it;
881
882         if (!obj)
883                 return NULL;
884         wd = elm_widget_data_get(obj);
885         if (!wd)
886                 return NULL;
887
888         if (wd->button[type]) {
889                 printf("already created.\n");
890                 return NULL;
891         }
892
893         /* set item data */
894         it = ELM_NEW(Elm_Softkey_Item);
895         it->obj = obj;
896         it->func = func;
897         it->data = data;
898
899         /* get evas */
900         evas = evas_object_evas_get(obj);
901         if (!evas)
902                 return NULL;
903
904         /* load button edj */
905         if (wd->button[type] == NULL) {
906                 if (type == ELM_SK_LEFT_BTN) {
907                         strcpy(button_type, "button_left");
908                 } else {
909                         strcpy(button_type, "button_right");
910                 }
911
912                 it->base = wd->button[type] = edje_object_add(evas);
913                 if (!wd->button[type])
914                         return NULL;
915                 _elm_theme_object_set(obj, wd->button[type], "softkey", button_type,
916                                 elm_widget_style_get(obj));
917
918                 wd->button_show[type] = EINA_TRUE;
919                 if (evas_object_visible_get(obj)) {
920                         evas_object_show(wd->button[type]);
921                 }
922                 evas_object_smart_member_add(wd->button[type], obj);
923
924                 edje_object_signal_callback_add(wd->button[type], "elm,action,down",
925                                 "", _softkey_down_cb, it);
926                 edje_object_signal_callback_add(wd->button[type], "elm,action,click",
927                                 "", _softkey_up_cb, it);
928
929                 evas_object_clip_set(wd->button[type], evas_object_clip_get(obj));
930                 if (wd->panel)
931                         evas_object_raise(wd->panel);
932         }
933
934         _sizing_eval(obj);
935
936         elm_softkey_item_label_set(it, label);
937         elm_softkey_item_icon_set(it, icon);
938
939         evas_object_data_set(wd->button[type], "item_data", it);
940
941         return it;
942 }
943
944 /**
945  * delete side button of softkey
946  * @param       obj     softkey object 
947  * @param       type softkey button type
948  * 
949  * @ingroup     Softkey  
950  */
951 EAPI void elm_softkey_button_del(Evas_Object *obj, Elm_Softkey_Type type) {
952         Widget_Data *wd;
953         Elm_Softkey_Item *it;
954         Evas_Object *btn;
955
956         if (!obj) {
957                 printf("Invalid argument: softkey object is NULL\n");
958                 return;
959         }
960
961         wd = elm_widget_data_get(obj);
962         if (!wd)
963                 return;
964
965         btn = wd->button[type];
966         if (!btn)
967                 return;
968
969         it = evas_object_data_get(btn, "item_data");
970         free(it);
971
972         evas_object_smart_member_del(btn);
973         _delete_button(btn);
974         wd->button[type] = NULL;
975 }
976
977 /**
978  * show button of softkey
979  * @param       obj     softkey object 
980  * @param       type    softkey button type
981  *
982  * @ingroup     Softkey  
983  */
984 EAPI void elm_softkey_button_show(Evas_Object *obj, Elm_Softkey_Type type) {
985         _show_button(obj, type, EINA_TRUE);
986 }
987
988 /**
989  * hide button of softkey
990  * @param       obj     softkey object 
991  * @param       type    softkey button type
992  *
993  * @ingroup     Softkey  
994  */
995 EAPI void elm_softkey_button_hide(Evas_Object *obj, Elm_Softkey_Type type) {
996         _show_button(obj, type, EINA_FALSE);
997 }
998
999 /**
1000  * add item in panel
1001  * @param       obj     softkey object 
1002  * @param       icon The icon object
1003  * @param       label The text label to use for the item
1004  * @param       func Convenience function to call when this item is selected
1005  * @param       data Data to pass to convenience function
1006  * @return      A handle to the item added
1007  * 
1008  * @ingroup     Softkey  
1009  */
1010 EAPI Elm_Softkey_Item *
1011 elm_softkey_panel_item_add(Evas_Object *obj, Evas_Object *icon,
1012                 const char *label, void(*func)(void *data, Evas_Object *obj,
1013                                 void *event_info), const void *data) {
1014         Widget_Data *wd;
1015         Evas *evas;
1016         char button_name[32];
1017         Evas_Object *btn;
1018         Elm_Softkey_Item *it;
1019         char buff[PATH_MAX];
1020
1021         wd = elm_widget_data_get(obj);
1022         if (!wd) {
1023                 printf("Cannot get smart data\n");
1024                 return NULL;
1025         }
1026
1027         /* set item data */
1028         it = ELM_NEW(Elm_Softkey_Item);
1029         wd->items = eina_list_append(wd->items, it);
1030         it->obj = obj;
1031         it->label = eina_stringshare_add(label);
1032         it->icon = icon;
1033         it->func = func;
1034         it->data = data;
1035
1036         /* get evas */
1037         evas = evas_object_evas_get(obj);
1038         if (!evas)
1039                 return NULL;
1040
1041         if (wd->panel == NULL) {
1042                 /* create panel */
1043                 wd->bg_rect = evas_object_rectangle_add(evas);
1044                 if (!wd->bg_rect)
1045                         return NULL;
1046                 evas_object_color_set(wd->bg_rect, 10, 10, 10, 150);
1047                 evas_object_pass_events_set(wd->bg_rect, 0);
1048
1049                 if (wd->bg_rect) {
1050                         evas_object_resize(wd->bg_rect, wd->w, wd->win_h);
1051                         evas_object_event_callback_add(wd->bg_rect, EVAS_CALLBACK_MOUSE_UP,
1052                                         _bg_click_cb, obj);
1053                         evas_object_smart_member_add(wd->bg_rect, obj);
1054                 }
1055
1056                 wd->panel = edje_object_add(evas);
1057                 if (!wd->panel)
1058                         return NULL;
1059                 _elm_theme_object_set(obj, wd->panel, "softkey", "panel",
1060                                 elm_widget_style_get(obj));
1061
1062                 evas_object_move(wd->panel, 0, wd->win_h);
1063                 edje_object_signal_callback_add(wd->panel, "clicked", "close_btn",
1064                                 _close_btn_click_cb, obj);
1065                 evas_object_smart_member_add(wd->panel, obj);
1066                 if (evas_object_visible_get(obj)) {
1067                         evas_object_show(wd->panel);
1068                 }
1069                 wd->panel_height = 0;
1070                 if ((edje_object_data_get(wd->panel, "max_item_count") == NULL)
1071                                 || (edje_object_data_get(wd->panel, "panel_height") == NULL)
1072                                 || (edje_object_data_get(wd->panel, "panel_height_horizontal")
1073                                                 == NULL)) {
1074                         //If this key is not found in data section, then it means the panel won't come.
1075                         wd->max_button = 0;
1076                         // delete panel 
1077                         if (wd->panel) {
1078                                 elm_softkey_panel_del(obj);
1079                         }
1080                         wd->panel_suppported = EINA_FALSE;
1081                         return NULL;
1082                 } else {
1083                         wd->max_button = (int) (atoi(edje_object_data_get(wd->panel,
1084                                         "max_item_count")));
1085                         if (wd->is_horizontal) {
1086                                 evas_object_resize(
1087                                                 wd->panel,
1088                                                 wd->w,
1089                                                 ((int) (atoi(edje_object_data_get(wd->panel,
1090                                                                 "panel_height_horizontal")) * wd->scale_factor)));
1091                         } else {
1092                                 evas_object_resize(wd->panel, wd->w, ((int) (atoi(
1093                                                 edje_object_data_get(wd->panel, "panel_height"))
1094                                                 * wd->scale_factor)));
1095                         }
1096                 }
1097
1098                 evas_object_clip_set(wd->panel, evas_object_clip_get(obj));
1099         }
1100
1101         if (wd->panel_btn_idx >= wd->max_button)
1102                 return NULL;
1103
1104         wd->panel_btn_idx++;
1105
1106         if (evas_object_visible_get(obj)) {
1107                 /* show more button */
1108                 edje_object_signal_emit(wd->lay, "more_btn_show", "");
1109         }
1110
1111         /* load panel button */
1112         it->base = btn = edje_object_add(evas);
1113         if (!btn)
1114                 return NULL;
1115         _elm_theme_object_set(obj, btn, "softkey", "panel_button",
1116                         elm_widget_style_get(obj));
1117
1118         edje_object_part_text_set(btn, "elm.text", label); /* set text */
1119         edje_object_message_signal_process(btn);
1120
1121         evas_object_event_callback_add(btn, EVAS_CALLBACK_MOUSE_DOWN,
1122                         _panel_down_cb, it);
1123         evas_object_event_callback_add(btn, EVAS_CALLBACK_MOUSE_UP, _panel_up_cb,
1124                         it);
1125
1126         /* swallow button */
1127         sprintf(button_name, "panel_button_area_%d", wd->panel_btn_idx);
1128         edje_object_part_swallow(wd->panel, button_name, btn);
1129         if (wd->is_horizontal) {
1130                 sprintf(buff, "button_%d", wd->max_button + wd->panel_btn_idx);
1131                 edje_object_signal_emit(wd->panel, buff, "panel_rect");
1132                 wd->panel_height = (int) (atoi(edje_object_data_get(wd->panel, buff))
1133                                 * wd->scale_factor);
1134         } else {
1135                 sprintf(buff, "button_%d", wd->panel_btn_idx);
1136                 edje_object_signal_emit(wd->panel, buff, "panel_rect");
1137                 wd->panel_height = (int) (atoi(edje_object_data_get(wd->panel, buff))
1138                                 * wd->scale_factor);
1139         }
1140
1141         return it;
1142 }
1143
1144 /**
1145  * delete panel
1146
1147  * @param obj softkey object
1148  * @return int 0 (SUCCESS) or -1 (FAIL)
1149  *
1150  * @ingroup Softkey
1151  */
1152 EAPI int elm_softkey_panel_del(Evas_Object *obj) {
1153         Widget_Data *wd;
1154         char button_name[32];
1155         Evas_Object *btn;
1156         int i;
1157         Elm_Softkey_Item *it;
1158
1159         wd = elm_widget_data_get(obj);
1160         if (!wd)
1161                 return -1;
1162         if (wd->panel == NULL)
1163                 return -1;
1164
1165         for (i = 1; i <= wd->panel_btn_idx; i++) {
1166                 sprintf(button_name, "panel_button_area_%d", i);
1167                 btn = edje_object_part_swallow_get(wd->panel, button_name);
1168                 _delete_button(btn);
1169         }
1170
1171         EINA_LIST_FREE(wd->items, it)
1172         {
1173                 eina_stringshare_del(it->label);
1174                 free(it);
1175         }
1176
1177         wd->panel_btn_idx = 0;
1178         wd->panel_height = 0;
1179
1180         //hide more button
1181         edje_object_signal_emit(wd->lay, "more_btn_hide", "");
1182
1183         if (wd->panel) {
1184                 evas_object_move(wd->panel, 0, wd->win_h);
1185                 evas_object_clip_unset(wd->panel);
1186                 //<Added to delete the panel completely>
1187                 evas_object_smart_member_del(wd->panel);
1188                 evas_object_del(wd->panel);
1189                 wd->panel = NULL;
1190                 //<Added to delete the panel completely>
1191         }
1192
1193         return 0;
1194 }
1195
1196 /**
1197  * sliding up panel if it is closed
1198
1199  * @param obj softkey object
1200  * @return int 0 (SUCCESS) or -1 (FAIL)
1201  *
1202  * @ingroup Softkey
1203  */
1204 EAPI int elm_softkey_panel_open(Evas_Object *obj) {
1205         Widget_Data *wd;
1206         wd = elm_widget_data_get(obj);
1207
1208         if (!wd)
1209                 return -1;
1210         if (!wd->panel)
1211                 return -1;
1212
1213         if (wd->show_panel == EINA_FALSE) {
1214                 _more_btn_click_cb(obj, NULL, NULL, NULL);
1215         }
1216
1217         return 0;
1218 }
1219
1220 /**
1221  * sliding down panel if it is opened
1222
1223  * @param obj softkey object
1224  * @return int 0 (SUCCESS) or -1 (FAIL)
1225  *
1226  * @ingroup Softkey
1227  */
1228 EAPI int elm_softkey_panel_close(Evas_Object *obj) {
1229         Widget_Data *wd;
1230         wd = elm_widget_data_get(obj);
1231         if (!wd)
1232                 return -1;
1233
1234         if (wd->panel == NULL)
1235                 return -1;
1236
1237         if (wd->show_panel == EINA_TRUE) {
1238                 _close_btn_click_cb(obj, obj, NULL, NULL);
1239         }
1240
1241         return 0;
1242 }
1243
1244 /**
1245  * Set the icon of an softkey item
1246  *
1247  * @param it The item to set the icon
1248  * @param icon The icon object
1249  *
1250  * @ingroup Softkey
1251  */
1252 EAPI void elm_softkey_item_icon_set(Elm_Softkey_Item *it, Evas_Object *icon) {
1253         if (!it)
1254                 return;
1255
1256         if ((it->icon != icon) && (it->icon))
1257                 elm_widget_sub_object_del(it->obj, it->icon);
1258
1259         if ((icon) && (it->icon != icon)) {
1260                 it->icon = icon;
1261                 elm_widget_sub_object_add(it->obj, icon);
1262                 //evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
1263                 //edje_object_part_swallow(it->base, "elm.swallow.content", icon);
1264                 edje_object_part_swallow(it->base, "elm.swallow.icon", icon);
1265                 edje_object_signal_emit(it->base, "elm,state,icon,visible", "elm");
1266                 edje_object_message_signal_process(it->base);
1267                 _sizing_eval(it->obj);
1268         } else
1269                 it->icon = icon;
1270 }
1271
1272 /**
1273  * Get the icon of an softkey item
1274  *
1275  * @param it The item to get the icon
1276  * @return The icon object
1277  *
1278  * @ingroup Softkey
1279  */
1280 EAPI Evas_Object *
1281 elm_softkey_item_icon_get(Elm_Softkey_Item *it) {
1282         if (!it)
1283                 return NULL;
1284         return it->icon;
1285 }
1286
1287 /**
1288  * Get the text label of an softkey item
1289  *
1290  * @param it The item to set the label
1291  * @param label label
1292  *
1293  * @ingroup Softkey
1294  */
1295 EAPI void elm_softkey_item_label_set(Elm_Softkey_Item *it, const char *label) {
1296         if (!it)
1297                 return;
1298         if (it->label)
1299                 eina_stringshare_del(it->label);
1300
1301         if (label) {
1302                 it->label = eina_stringshare_add(label);
1303                 edje_object_signal_emit(it->base, "elm,state,text,visible", "elm");
1304
1305                 /* set text */
1306                 edje_object_part_text_set(it->base, "elm.text", label == NULL ? ""
1307                                 : label);
1308         } else {
1309                 it->label = NULL;
1310                 edje_object_signal_emit(it->base, "elm,state,text,hidden", "elm");
1311         }
1312         edje_object_message_signal_process(it->base);
1313 }
1314
1315 /**
1316  * Set the item callback function 
1317  *
1318  * @param it Item to set callback function.
1319  * @param func callback function pointer.
1320  * @param data callback function argument data.
1321  *
1322  * @ingroup Softkey
1323  */
1324 EAPI void elm_softkey_item_callback_set(Elm_Softkey_Item* item, void(*func)(
1325                 void *data, Evas_Object *obj, void *event_info), const void *data) {
1326         if (!item)
1327                 return;
1328
1329         item->func = func;
1330         item->data = data;
1331
1332 }
1333
1334 /**
1335  * Get the text label of an softkey item
1336  *
1337  * @param it The item to get the label
1338  * @return The text label of the softkey item
1339  *
1340  * @ingroup Softkey
1341  */
1342 EAPI const char *
1343 elm_softkey_item_label_get(Elm_Softkey_Item *it) {
1344         if (!it)
1345                 return NULL;
1346         return it->label;
1347 }
1348
1349 EAPI Eina_Bool elm_softkey_item_disabled_get(Elm_Softkey_Item *it) {
1350         if (!it)
1351                 return EINA_FALSE;
1352         return it->disabled;
1353 }
1354
1355 EAPI void elm_softkey_item_disabled_set(Elm_Softkey_Item *it,
1356                 Eina_Bool disabled) {
1357         if (!it)
1358                 return;
1359         _item_disable(it, disabled);
1360 }