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