3 * Copyright (c) 2009 Samsung Electronics, Inc.
\r
4 * All rights reserved.
\r
6 * This software is a confidential and proprietary information
\r
7 * of Samsung Electronics, Inc. ("Confidential Information"). You
\r
8 * shall not disclose such Confidential Information and shall use
\r
9 * it only in accordance with the terms of the license agreement
\r
10 * you entered into with Samsung Electronics.
\r
15 * @addtogroup Tab Tab
\r
16 * @ingroup Elementary
\r
18 * This is a Tab. It can contain label and icon objects.
\r
19 * You can change the location of items.
\r
24 #include <stdbool.h>
\r
27 #include <Elementary.h>
\r
28 #include "elm_priv.h"
\r
31 #define EAPI __attribute__ ((visibility("default")))
\r
35 #define BASIC_SLOT_NUMBER 3
\r
36 #define KEYDOWN_INTERVAL 0.6
\r
40 #define LANDSCAPE_GAP 10
\r
42 #define MAX_ARGS 512
\r
44 #define _EDJ(x) (Evas_Object *)elm_layout_edje_get(x)
\r
45 #define ELM_MAX(v1, v2) (((v1) > (v2)) ? (v1) : (v2))
\r
48 // internal data structure of tab object
\r
49 typedef struct _Widget_Data Widget_Data;
\r
54 Evas_Object *object;
\r
55 Evas_Object *parent;
\r
57 Evas_Object *moving_obj;
\r
58 Evas_Object *box[MAX_ITEM];
\r
61 Evas_Coord x, y, w, h;
\r
77 Eina_Bool edit_disable;
\r
79 Ecore_Event_Handler *move_event;
\r
80 Ecore_Event_Handler *up_event;
\r
83 struct _Elm_Tab_Item
\r
91 void (*func)(void *data, Evas_Object *obj, void *event_info);
\r
93 Eina_Bool selected : 1;
\r
96 static void _del_hook(Evas_Object *obj);
\r
97 static void _theme_hook(Evas_Object *obj);
\r
98 static void _sizing_eval(Evas_Object *obj);
\r
99 static void _sub_del(void *data, Evas_Object *obj, void *event_info);
\r
101 static void _tab_object_move(void *data, Evas *e, Evas_Object *obj, void *event_info);
\r
102 static void _tab_object_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
\r
103 static void _tab_object_show(void *data, Evas *e, Evas_Object *obj, void *event_info);
\r
104 static void _tab_object_hide(void *data, Evas *e, Evas_Object *obj, void *event_info);
\r
106 static void light_check(Widget_Data *wd);
\r
107 static void select_check(Widget_Data *wd);
\r
108 static void edit_up_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info);
\r
109 static int _selected_box(Elm_Tab_Item *it);
\r
110 static int _move_obj_to_left(Widget_Data *wd);
\r
111 static int _move_obj_to_right(Widget_Data *wd);
\r
112 static void item_down_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info);
\r
113 static void press_move_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info);
\r
114 static void press_down_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info);
\r
115 static void press_up_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info);
\r
116 void tab_item_cb(void *data, Evas_Object *obj, const char *emission, const char *source);
\r
119 _del_hook(Evas_Object *obj)
\r
121 Widget_Data *wd = elm_widget_data_get(obj);
\r
122 Elm_Tab_Item *item;
\r
127 evas_object_smart_member_del(wd->edje);
\r
128 evas_object_del(wd->edje);
\r
132 EINA_LIST_FREE(wd->items, item){
\r
133 eina_stringshare_del(item->label);
\r
134 if (item->icon) evas_object_del(item->icon);
\r
135 if(item->base) evas_object_del(item->base);
\r
140 evas_object_smart_member_del(wd->ebx);
\r
141 evas_object_del(wd->ebx);
\r
149 _theme_hook(Evas_Object *obj)
\r
151 const Eina_List *l;
\r
152 Elm_Tab_Item *item;
\r
153 char buf[MAX_ARGS];
\r
154 Widget_Data *wd = elm_widget_data_get(obj);
\r
157 if(wd->mode == PORTRAIT){
\r
158 snprintf(buf, sizeof(buf), "bg_portrait_%d", wd->view_slot_num);
\r
159 }else if(wd->mode == LANDSCAPE){
\r
160 snprintf(buf, sizeof(buf), "bg_landscape_%d", wd->view_slot_num);
\r
162 _elm_theme_object_set(obj, wd->edje, "tab", buf, elm_widget_style_get(obj));
\r
164 EINA_LIST_FOREACH(wd->items, l, item){
\r
165 _elm_theme_object_set(obj, item->base, "tab", "item", elm_widget_style_get(item->obj));
\r
167 edje_object_part_text_set(item->base, "elm.text", item->label);
\r
173 // ms = ((double)wd->icon_size * _elm_config->scale);
\r
174 evas_object_size_hint_min_set(item->icon, 24, 24);
\r
175 evas_object_size_hint_max_set(item->icon, 40, 40);
\r
176 edje_object_part_swallow(item->base, "elm.swallow.icon", item->icon);
\r
177 evas_object_show(item->icon);
\r
178 elm_widget_sub_object_add(obj, item->icon);
\r
181 if (item->label && item->icon){
\r
182 edje_object_signal_emit(item->base, "elm,state,icon_text", "elm");
\r
189 _sub_del(void *data, Evas_Object *obj, void *event_info)
\r
191 Widget_Data *wd = elm_widget_data_get(obj);
\r
192 //Evas_Object *sub = event_info;
\r
195 if (sub == wd->icon)
\r
197 edje_object_signal_emit(wd->btn, "elm,state,icon,hidden", "elm");
\r
198 evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
\r
199 _changed_size_hints, obj);
\r
201 edje_object_message_signal_process(wd->btn);
\r
208 _sizing_eval(Evas_Object *obj)
\r
210 Widget_Data *wd = elm_widget_data_get(obj);
\r
214 DBG("[%s]\n", __func__);
\r
216 _tab_object_move(obj, NULL, obj, NULL);
\r
217 _tab_object_resize(obj, NULL, obj, NULL);
\r
221 * Add a new tab object
\r
223 * @param parent The parent object
\r
224 * @return The new object or NULL if it cannot be created
\r
228 EAPI Evas_Object *elm_tab_add(Evas_Object *parent) {
\r
229 Evas_Object *obj = NULL;
\r
230 Widget_Data *wd = NULL;
\r
231 Evas_Coord x, y, w, h;
\r
232 char buf[MAX_ARGS];
\r
234 wd = ELM_NEW(Widget_Data);
\r
235 wd->evas = evas_object_evas_get(parent);
\r
236 if (wd->evas == NULL) return NULL;
\r
237 obj = elm_widget_add(wd->evas);
\r
238 if(obj == NULL) return NULL;
\r
239 elm_widget_type_set(obj, "tab");
\r
240 elm_widget_sub_object_add(parent, obj);
\r
241 elm_widget_data_set(obj, wd);
\r
242 elm_widget_del_hook_set(obj, _del_hook);
\r
243 elm_widget_theme_hook_set(obj, _theme_hook);
\r
246 wd->parent = parent;
\r
247 evas_object_geometry_get(parent, &x, &y, &w, &h);
\r
254 wd->edit_disable = EINA_FALSE;
\r
255 wd->cur_first_slot = 1;
\r
256 //wd->view_slot_num = BASIC_SLOT_NUMBER;
\r
257 wd->view_slot_num = 3;
\r
261 wd->ebx = edje_object_add(wd->evas);
\r
262 if(wd->ebx == NULL)
\r
264 _elm_theme_object_set(obj, wd->ebx, "tab", "dim", "default");
\r
265 evas_object_resize(wd->ebx, wd->w, wd->h);
\r
266 evas_object_move(wd->ebx, wd->x, wd->y);
\r
267 evas_object_hide(wd->ebx);
\r
268 evas_object_event_callback_add(wd->ebx, EVAS_CALLBACK_MOUSE_UP, edit_up_cb, wd);
\r
271 /* load background edj */
\r
272 wd->edje = edje_object_add(wd->evas);
\r
273 snprintf(buf, sizeof(buf), "bg_portrait_%d", wd->view_slot_num);
\r
274 _elm_theme_object_set(obj, wd->edje, "tab", buf, "default");
\r
275 if(wd->edje == NULL) {
\r
276 printf("Cannot load bg edj\n");
\r
280 evas_object_event_callback_add(wd->edje, EVAS_CALLBACK_MOUSE_DOWN, press_down_cb, wd);
\r
281 evas_object_event_callback_add(wd->edje, EVAS_CALLBACK_MOUSE_UP, press_up_cb, wd);
\r
282 evas_object_show(wd->edje);
\r
285 evas_object_event_callback_add(wd->edje, EVAS_CALLBACK_RESIZE, _tab_object_resize, obj);
\r
286 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _tab_object_move, obj);
\r
287 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _tab_object_show, obj);
\r
288 evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _tab_object_hide, obj);
\r
292 // evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
\r
294 evas_object_smart_member_add(wd->ebx, obj);
\r
295 elm_widget_resize_object_set(obj, wd->edje);
\r
305 * Set the mode of tab object
\r
307 * @param obj The tab object
\r
308 * @param mode The mode of tab
\r
312 EAPI void elm_tab_set(Evas_Object *obj, int mode)
\r
315 char buf[MAX_ARGS];
\r
317 const Eina_List *l;
\r
318 Elm_Tab_Item *item;
\r
321 printf("Invalid argument: tab object is NULL\n");
\r
324 wd = elm_widget_data_get(obj);
\r
326 printf("Cannot get smart data\n");
\r
330 EINA_LIST_FOREACH(wd->items, l, item){
\r
331 edje_object_part_unswallow(wd->edje, item->base);
\r
334 evas_object_del(wd->edje);
\r
336 evas_object_smart_member_del(wd->ebx);
\r
337 // elm_widget_resize_object_set(obj, wd->edje);
\r
340 if(mode >= ELM_TAB_PORTRAIT_2 && mode <= ELM_TAB_PORTRAIT_4){
\r
341 snprintf(buf, sizeof(buf), "bg_portrait_%d", mode);
\r
342 }else if(mode >= ELM_TAB_LANDSCAPE_2 && mode <= ELM_TAB_LANDSCAPE_5){
\r
343 snprintf(buf, sizeof(buf), "bg_landscape_%d", mode - LANDSCAPE_GAP);
\r
345 wd->edje = edje_object_add(wd->evas);
\r
346 if(wd->edje == NULL) {
\r
347 printf("Cannot load bg edj\n");
\r
351 _elm_theme_object_set(obj, wd->edje, "tab", buf, elm_widget_style_get(obj));
\r
353 evas_object_event_callback_add(wd->edje, EVAS_CALLBACK_MOUSE_DOWN, press_down_cb, wd);
\r
354 evas_object_event_callback_add(wd->edje, EVAS_CALLBACK_MOUSE_UP, press_up_cb, wd);
\r
355 evas_object_show(wd->edje);
\r
357 evas_object_smart_member_add(wd->ebx, obj);
\r
358 elm_widget_resize_object_set(obj, wd->edje);
\r
360 evas_object_event_callback_add(wd->edje, EVAS_CALLBACK_RESIZE, _tab_object_resize, obj);
\r
361 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _tab_object_move, obj);
\r
362 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _tab_object_show, obj);
\r
363 evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _tab_object_hide, obj);
\r
365 EINA_LIST_FOREACH(wd->items, l, item){
\r
366 snprintf(buf, sizeof(buf), "slot_%d", item->slot);
\r
367 edje_object_part_swallow(wd->edje, buf, item->base);
\r
371 // set current mode
\r
372 if(mode < 10) wd->mode = PORTRAIT;
\r
373 else wd->mode = LANDSCAPE;
\r
375 wd->view_slot_num = mode % LANDSCAPE_GAP;
\r
379 evas_object_resize(wd->edje, wd->w, wd->h);
\r
385 * @param obj The tab object
\r
386 * @param icon The icon of item
\r
387 * @param label The label of item
\r
388 * @param func Callback function of item
\r
389 * @param data The data of callback function
\r
390 * @return The item of tab
\r
394 EAPI Elm_Tab_Item *elm_tab_item_add(Evas_Object *obj, Evas_Object *icon, const char *label, void (*func) (void *data, Evas_Object *obj, void *event_info), const void *data)
\r
396 char buf[MAX_ARGS];
\r
401 printf("Invalid argument: tab object is NULL\n");
\r
404 wd = elm_widget_data_get(obj);
\r
406 printf("Cannot get smart data\n");
\r
410 it = ELM_NEW(Elm_Tab_Item);
\r
412 printf("Cannot add item");
\r
415 wd->items = eina_list_append(wd->items, it);
\r
417 it->label = eina_stringshare_add(label);
\r
422 it->base = edje_object_add(evas_object_evas_get(obj));
\r
423 if(it->base == NULL) {
\r
424 printf("Cannot load bg edj\n");
\r
427 _elm_theme_object_set(obj, it->base, "tab", "item", elm_widget_style_get(obj));
\r
428 elm_widget_sub_object_add(obj, it->base);
\r
430 edje_object_signal_callback_add(it->base, "elm,action,click", "elm", tab_item_cb, (void *)it);
\r
433 edje_object_part_text_set(it->base, "elm.text", it->label);
\r
439 // ms = ((double)wd->icon_size * _elm_config->scale);
\r
440 evas_object_size_hint_min_set(it->icon, 24, 24);
\r
441 evas_object_size_hint_max_set(it->icon, 40, 40);
\r
442 edje_object_part_swallow(it->base, "elm.swallow.icon", it->icon);
\r
443 evas_object_show(it->icon);
\r
444 elm_widget_sub_object_add(obj, it->icon);
\r
447 if (it->label && it->icon){
\r
448 edje_object_signal_emit(it->base, "elm,state,icon_text", "elm");
\r
452 it->slot = wd->num;
\r
453 snprintf(buf, sizeof(buf), "slot_%d", wd->num);
\r
454 edje_object_part_swallow(wd->edje, buf, it->base);
\r
462 * Delete item from tab by index
\r
464 * @param it The item of tab
\r
468 EAPI void elm_tab_item_del(Elm_Tab_Item *it)
\r
472 char buf[MAX_ARGS];
\r
474 const Eina_List *l;
\r
475 Elm_Tab_Item *item;
\r
477 if(it->obj == NULL) {
\r
478 printf("Invalid argument: tab object is NULL\n");
\r
481 wd = elm_widget_data_get(it->obj);
\r
483 printf("Cannot get smart data\n");
\r
487 edje_object_part_unswallow(wd->edje, it->base);
\r
489 EINA_LIST_FOREACH(wd->items, l, item){
\r
491 edje_object_part_unswallow(wd->edje, item->base);
\r
492 snprintf(buf, sizeof(buf), "slot_%d", i-1);
\r
493 edje_object_part_swallow(wd->edje, buf, item->base);
\r
501 eina_stringshare_del(it->label);
\r
502 if (it->icon) evas_object_del(it->icon);
\r
503 evas_object_del(it->base);
\r
504 wd->items = eina_list_remove(wd->items, it);
\r
505 wd->num = wd->num - 1;
\r
509 * Select item in tab
\r
511 * @param it The item of tab
\r
515 EAPI void elm_tab_item_select(Elm_Tab_Item *it)
\r
521 * Get the icon of item
\r
523 * @param it The item of tab
\r
524 * @return The icon object
\r
528 EAPI Evas_Object *elm_tab_item_icon_get(Elm_Tab_Item *it)
\r
534 * Get the label of item
\r
536 * @param it The item of tab
\r
537 * @return the label of item
\r
541 EAPI const char *elm_tab_item_label_get(Elm_Tab_Item *it)
\r
547 * Set the label of item
\r
549 * @param it The item of tab
\r
550 * @param label The label of item
\r
554 EAPI void elm_tab_item_label_set(Elm_Tab_Item *it, const char *label)
\r
556 if(!it->base) return;
\r
558 edje_object_part_text_set(it->base, "elm.text", label);
\r
562 * Set the badge of item.
\r
564 * @param it The item of tab
\r
565 * @param badge The number in item badge. If -1, badge is not visible. Otherwise, it is just number.
\r
569 EAPI void elm_tab_item_badge_set(Elm_Tab_Item *it, const int badge)
\r
571 char buf[MAX_ARGS];
\r
573 if(!it->base) return;
\r
575 if(it->badge == badge) return;
\r
578 printf("elm_tab_item_badge_set : second parameter range not availble. (-1 <= badge < 1000)\n");
\r
585 edje_object_signal_emit(it->base, "elm,badge,unvisible", "elm");
\r
587 if(it->badge > 1000) {
\r
588 printf("Badge Number is too large. ( badge < 1000)\n");
\r
592 snprintf(buf, sizeof(buf), "%d", it->badge);
\r
593 edje_object_part_text_set(it->base, "elm.text.badge", buf);
\r
595 if(it->badge > 100){
\r
596 edje_object_signal_emit(it->base, "elm,badge,text_normal", "elm");
\r
598 edje_object_signal_emit(it->base, "elm,badge,text_small", "elm");
\r
600 edje_object_signal_emit(it->base, "elm,badge,visible", "elm");
\r
605 * Get the selected item.
\r
607 * @param obj The tab object
\r
611 EAPI Elm_Tab_Item *elm_tab_selected_item_get(Evas_Object *obj)
\r
613 const Eina_List *l;
\r
614 Elm_Tab_Item *item;
\r
616 if(obj == NULL) return NULL;
\r
618 Widget_Data *wd = elm_widget_data_get(obj);
\r
619 if(!wd || !wd->items) return NULL;
\r
621 EINA_LIST_FOREACH(wd->items, l, item){
\r
622 if(item->selected) return item;
\r
629 * Get the first item.
\r
631 * @param obj The tab object
\r
635 EAPI Elm_Tab_Item *elm_tab_first_item_get(Evas_Object *obj)
\r
637 if(obj == NULL) return NULL;
\r
639 Widget_Data *wd = elm_widget_data_get(obj);
\r
640 if(!wd || !wd->items) return NULL;
\r
642 return eina_list_data_get(wd->items);
\r
646 * Get the last item.
\r
648 * @param obj The tab object
\r
652 EAPI Elm_Tab_Item *elm_tab_last_item_get(Evas_Object *obj)
\r
654 if(obj == NULL) return NULL;
\r
656 Widget_Data *wd = elm_widget_data_get(obj);
\r
657 if(!wd || !wd->items) return NULL;
\r
659 return eina_list_data_get(eina_list_last(wd->items));
\r
665 * @param obj The tab object
\r
669 EAPI Eina_List *elm_tab_items_get(Evas_Object *obj)
\r
671 if(obj == NULL) return NULL;
\r
673 Widget_Data *wd = elm_widget_data_get(obj);
\r
674 if(!wd || !wd->items) return NULL;
\r
680 * Get the previous item.
\r
682 * @param it The item of tab
\r
683 * @return The previous item of the parameter item
\r
687 EAPI Elm_Tab_Item *elm_tab_item_prev(Elm_Tab_Item *it)
\r
689 const Eina_List *l;
\r
690 Elm_Tab_Item *item;
\r
692 if(it->obj == NULL) return NULL;
\r
694 Widget_Data *wd = elm_widget_data_get(it->obj);
\r
695 if(!wd || !wd->items) return NULL;
\r
697 EINA_LIST_FOREACH(wd->items, l, item){
\r
699 l = eina_list_prev(l);
\r
700 if(!l) return NULL;
\r
701 return eina_list_data_get(l);
\r
709 * Get the next item.
\r
711 * @param obj The tab object
\r
712 * @return The next item of the parameter item
\r
716 EAPI Elm_Tab_Item *elm_tab_item_next(Elm_Tab_Item *it)
\r
718 const Eina_List *l;
\r
719 Elm_Tab_Item *item;
\r
721 if(it->obj == NULL) return NULL;
\r
723 Widget_Data *wd = elm_widget_data_get(it->obj);
\r
724 if(!wd || !wd->items) return NULL;
\r
726 EINA_LIST_FOREACH(wd->items, l, item){
\r
728 l = eina_list_next(l);
\r
729 if(!l) return NULL;
\r
730 return eina_list_data_get(l);
\r
738 * Move the tab object
\r
740 * @param obj The tab object
\r
741 * @param direction the direction of movement
\r
745 EAPI void elm_tab_move(Evas_Object *obj, int direction)
\r
750 printf("Invalid argument: tab object is NULL\n");
\r
753 wd = elm_widget_data_get(obj);
\r
755 printf("Cannot get smart data\n");
\r
759 if(direction == ELM_TAB_MOVE_LEFT){
\r
760 _move_obj_to_left(wd);
\r
761 }else if(direction == ELM_TAB_MOVE_RIGHT){
\r
762 _move_obj_to_right(wd);
\r
767 * Set the edit mode of the tab disable
\r
769 * @param obj The tab object
\r
770 * @param disable if 1, edit mode is disable.
\r
774 EAPI void elm_tab_edit_disable_set(Evas_Object *obj, Eina_Bool disable)
\r
779 printf("Invalid argument: tab object is NULL\n");
\r
782 wd = elm_widget_data_get(obj);
\r
784 printf("Cannot get smart data\n");
\r
788 wd->edit_disable = disable;
\r
792 * Get the availability for the edit mode of the tab
\r
794 * @param obj The tab object
\r
795 * @return disable or not
\r
799 EAPI Eina_Bool elm_tab_edit_disable_get(Evas_Object *obj)
\r
804 printf("Invalid argument: tab object is NULL\n");
\r
808 wd = elm_widget_data_get(obj);
\r
810 printf("Cannot get smart data\n");
\r
814 return wd->edit_disable;
\r
819 ///////////////////////////////////////////////////////////////////
\r
821 // basic utility function
\r
823 ////////////////////////////////////////////////////////////////////
\r
825 static void light_check(Widget_Data *wd)
\r
827 edje_object_signal_emit(wd->edje, "off_light", "light");
\r
829 if(wd->view_slot_num > wd->num) return;
\r
831 if(wd->cur_first_slot > 1){
\r
832 edje_object_signal_emit(wd->edje, "left", "light");
\r
834 if(wd->cur_first_slot + wd->view_slot_num - 1 != wd->num){
\r
835 edje_object_signal_emit(wd->edje, "right", "light");
\r
839 static void select_check(Widget_Data *wd)
\r
843 const Eina_List *l;
\r
844 Elm_Tab_Item *item;
\r
846 EINA_LIST_FOREACH(wd->items, l, item){
\r
847 if(wd->cur_first_slot <= i && wd->cur_first_slot + wd->view_slot_num > i){
\r
848 if(item->selected){
\r
849 edje_object_signal_emit(item->base, "selected", "elm");
\r
854 // snprintf(buf, sizeof(buf), "show_partition_%d_%d", i, i+1);
\r
855 // edje_object_signal_emit(wd->edje, buf, "elm");
\r
858 edje_object_signal_emit(item->base, "unselected", "elm");
\r
863 // snprintf(buf, sizeof(buf), "hide_partition_%d_%d", selected, selected+1);
\r
864 // edje_object_signal_emit(wd->edje, buf, "elm");
\r
865 // snprintf(buf, sizeof(buf), "hide_partition_%d_%d", selected-1, selected);
\r
866 // edje_object_signal_emit(wd->edje, buf, "elm");
\r
869 static int _selected_box(Elm_Tab_Item *it)
\r
874 char buf[MAX_ARGS];
\r
875 const Eina_List *l;
\r
876 Elm_Tab_Item *item;
\r
877 Widget_Data *wd = elm_widget_data_get(it->obj);
\r
879 EINA_LIST_FOREACH(wd->items, l, item){
\r
880 edje_object_signal_emit(item->base, "unselected", "elm");
\r
881 item->selected = EINA_FALSE;
\r
883 icon = edje_object_part_swallow_get(item->base, "elm.swallow.icon");
\r
885 if(strcmp(evas_object_type_get(icon), "edje") == 0){
\r
886 edje_object_signal_emit(icon, "elm,state,unselected", "elm");
\r
889 edje_object_signal_emit(_EDJ(icon), "elm,state,unselected", "elm");
\r
894 edje_object_signal_emit(it->base, "selected", "elm");
\r
895 snprintf(buf, sizeof(buf), "selected_%d", i);
\r
896 edje_object_signal_emit(wd->edje, buf, "elm");
\r
899 if(strcmp(evas_object_type_get(icon), "edje") == 0){
\r
900 edje_object_signal_emit(icon, "elm,state,selected", "elm");
\r
903 edje_object_signal_emit(_EDJ(icon), "elm,state,selected", "elm");
\r
906 item->selected = EINA_TRUE;
\r
913 if(!check) return EXIT_FAILURE;
\r
915 if (it->func) it->func((void *)(it->data), it->obj, it);
\r
916 evas_object_smart_callback_call(it->obj, "clicked", it);
\r
918 // select_check(wd);
\r
920 return EXIT_SUCCESS;
\r
923 ///////////////////////////////////////////////////////////////////
\r
925 // general function
\r
927 ////////////////////////////////////////////////////////////////////
\r
929 static int _move_obj_to_left(Widget_Data *wd)
\r
931 char buf[MAX_ARGS];
\r
934 first_slot = wd->cur_first_slot + wd->view_slot_num;
\r
935 if(first_slot + wd->view_slot_num > wd->num){
\r
936 first_slot = wd->num - wd->view_slot_num +1;
\r
939 snprintf(buf, sizeof(buf), "step_%d", first_slot);
\r
940 edje_object_signal_emit(wd->edje, buf, "elm");
\r
941 wd->cur_first_slot = first_slot;
\r
947 return EXIT_SUCCESS;
\r
950 static int _move_obj_to_right(Widget_Data *wd)
\r
952 char buf[MAX_ARGS];
\r
955 first_slot = wd->cur_first_slot - wd->view_slot_num;
\r
956 if(first_slot < 1){
\r
960 snprintf(buf, sizeof(buf), "step_%d", first_slot);
\r
961 edje_object_signal_emit(wd->edje, buf, "elm");
\r
962 wd->cur_first_slot = first_slot;
\r
968 return EXIT_SUCCESS;
\r
971 static void edit_up_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info)
\r
973 char buf[MAX_ARGS];
\r
975 Widget_Data *wd = (Widget_Data *)data;
\r
976 const Eina_List *l;
\r
977 Elm_Tab_Item *item;
\r
979 EINA_LIST_FOREACH(wd->items, l, item){
\r
980 if(item->selected){
\r
981 edje_object_signal_emit(item->base, "selected", "elm");
\r
982 icon = edje_object_part_swallow_get(item->base, "elm.swallow.icon");
\r
984 if(strcmp(evas_object_type_get(icon), "edje") == 0){
\r
985 edje_object_signal_emit(icon, "elm,state,selected", "elm");
\r
988 edje_object_signal_emit(_EDJ(icon), "elm,state,selected", "elm");
\r
992 edje_object_signal_callback_add(item->base, "elm,action,click", "elm", tab_item_cb, item);
\r
993 evas_object_event_callback_del(item->base, EVAS_CALLBACK_MOUSE_DOWN, item_down_cb);
\r
996 evas_object_event_callback_del(wd->edje, EVAS_CALLBACK_MOUSE_DOWN, press_down_cb);
\r
997 evas_object_event_callback_add(wd->edje, EVAS_CALLBACK_MOUSE_DOWN, press_down_cb, wd);
\r
998 evas_object_event_callback_del(wd->edje, EVAS_CALLBACK_MOUSE_UP, press_up_cb);
\r
999 evas_object_event_callback_add(wd->edje, EVAS_CALLBACK_MOUSE_UP, press_up_cb, wd);
\r
1001 snprintf(buf, sizeof(buf), "step_%d", wd->cur_first_slot);
\r
1002 edje_object_signal_emit(wd->edje, buf, "elm");
\r
1005 evas_object_hide(wd->ebx);
\r
1008 static int item_move_cb(void *data, int type, void *event_info)
\r
1011 Ecore_Event_Mouse_Move *ev = event_info;
\r
1012 Evas_Coord x, y, w, h, mx, my, mw, mh, ex, ey;
\r
1013 Widget_Data *wd = (Widget_Data *)data;
\r
1015 obj = wd->moving_obj;
\r
1017 evas_object_geometry_get(obj, NULL, NULL ,&w, &h);
\r
1018 evas_object_geometry_get(wd->edje, &ex, &ey , NULL, NULL);
\r
1019 edje_object_part_geometry_get(wd->edje, "bg_b", &mx, &my ,&mw, &mh);
\r
1021 if(ev->x < ex + mx + w/2) x = ex + mx;
\r
1022 else if(ev->x > ex + mx + mw - w/2) x = ex + mx + mw - w;
\r
1023 else x = ev->x - w/2;
\r
1025 if(ev->y < ey + my + h) y = ey + my;
\r
1026 else if(ev->y > ey + my + mh) y = ey + my + mh - h;
\r
1027 else y = ev->y - h;
\r
1029 evas_object_move(obj, x, y);
\r
1034 static int sort_cb(const void *d1, const void *d2)
\r
1036 Elm_Tab_Item *item1, *item2;
\r
1038 item1 = (Elm_Tab_Item *)d1;
\r
1039 item2 = (Elm_Tab_Item *)d2;
\r
1041 return item1->slot > item2->slot ? 1 : -1;
\r
1044 static int item_up_cb(void *data, int type, void *event_info)
\r
1047 Ecore_Event_Mouse_Button *ev = event_info;
\r
1048 char buf[MAX_ARGS];
\r
1049 Evas_Coord x, y, w, h;
\r
1051 const Eina_List *l;
\r
1052 Elm_Tab_Item *item;
\r
1053 Elm_Tab_Item *edit_to_item, *edit_from_item;
\r
1054 Widget_Data *wd = (Widget_Data *)data;
\r
1056 obj = wd->moving_obj;
\r
1059 EINA_LIST_FOREACH(wd->items, l, item){
\r
1061 if(item->base == obj) continue;
\r
1062 evas_object_geometry_get(item->base, &x, &y, &w, &h);
\r
1063 if(x < ev->x && ev->x < x+w && y < ev->y && ev->y < y+h){
\r
1068 if(wd->edit_to > 0 && wd->edit_to <= wd->num){
\r
1070 edit_to_item = eina_list_nth(wd->items, wd->edit_to-1);
\r
1071 edit_from_item = eina_list_nth(wd->items, wd->edit_from-1);
\r
1073 edje_object_part_unswallow(wd->edje, edit_to_item->base);
\r
1074 snprintf(buf, sizeof(buf), "slot_%d", wd->edit_from);
\r
1075 edje_object_part_swallow(wd->edje, buf, edit_to_item->base);
\r
1076 edit_to_item->slot = wd->edit_from;
\r
1078 snprintf(buf, sizeof(buf), "slot_%d", wd->edit_to);
\r
1079 edje_object_part_swallow(wd->edje, buf, edit_from_item->base);
\r
1080 edit_from_item->slot = wd->edit_to;
\r
1082 wd->items = eina_list_sort(wd->items, eina_list_count(wd->items), sort_cb);
\r
1085 wd->edit_to = wd->edit_from;
\r
1086 snprintf(buf, sizeof(buf), "slot_%d", wd->edit_from);
\r
1087 edje_object_part_swallow(wd->edje, buf, obj);
\r
1090 ecore_event_handler_del(wd->move_event);
\r
1091 wd->move_event = NULL;
\r
1092 ecore_event_handler_del(wd->up_event);
\r
1093 wd->up_event = NULL;
\r
1095 return EXIT_SUCCESS;
\r
1098 static void item_down_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info)
\r
1100 Evas_Event_Mouse_Down *ev = event_info;
\r
1101 Evas_Coord x, y, w, h;
\r
1102 Widget_Data *wd = (Widget_Data *)data;
\r
1103 const Eina_List *l;
\r
1104 Elm_Tab_Item *item;
\r
1106 wd->moving_obj = obj;
\r
1108 EINA_LIST_FOREACH(wd->items, l, item){
\r
1109 if(item->base == obj) wd->edit_from = item->slot;
\r
1112 edje_object_part_unswallow(wd->edje, obj);
\r
1113 evas_object_geometry_get(obj, &x, &y, &w, &h);
\r
1114 evas_object_move(obj, ev->output.x - w/2 , ev->output.y - h);
\r
1115 edje_object_signal_emit(obj, "edit", "elm");
\r
1117 wd->up_event = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, item_up_cb, (void *)wd);
\r
1118 wd->move_event = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, item_move_cb, (void *)wd);
\r
1121 static void edit_mode(void *data)
\r
1123 Evas_Object *icon;
\r
1124 const Eina_List *l;
\r
1125 Elm_Tab_Item *item;
\r
1126 Widget_Data *wd = (Widget_Data *)data;
\r
1128 edje_object_signal_emit(wd->edje, "edit", "elm");
\r
1130 if((int)(wd->num/wd->view_slot_num) < 2){
\r
1131 edje_object_signal_emit(wd->edje, "edit_2", "elm");
\r
1133 edje_object_signal_emit(wd->edje, "edit_3", "elm");
\r
1136 // delete normal mode callback & add normal mode callback
\r
1137 EINA_LIST_FOREACH(wd->items, l, item){
\r
1138 edje_object_signal_emit(item->base, "unselected", "elm");
\r
1139 icon = edje_object_part_swallow_get(item->base, "elm.swallow.icon");
\r
1141 if(strcmp(evas_object_type_get(icon), "edje") == 0){
\r
1142 edje_object_signal_emit(icon, "elm,state,unselected", "elm");
\r
1145 edje_object_signal_emit(_EDJ(icon), "elm,state,unselected", "elm");
\r
1148 edje_object_signal_callback_del(item->base, "elm,action,click", "elm", tab_item_cb);
\r
1149 evas_object_event_callback_add(item->base, EVAS_CALLBACK_MOUSE_DOWN, item_down_cb, wd);
\r
1151 evas_object_event_callback_del(wd->edje, EVAS_CALLBACK_MOUSE_DOWN, press_down_cb);
\r
1152 evas_object_event_callback_del(wd->edje, EVAS_CALLBACK_MOUSE_UP, press_up_cb);
\r
1153 evas_object_show(wd->ebx);
\r
1155 edje_object_signal_emit(wd->edje, "off_light", "light");
\r
1159 static int tab_timer_cb(void* data)
\r
1161 Widget_Data *wd = (Widget_Data *)data;
\r
1163 if(wd->time > KEYDOWN_INTERVAL){
\r
1164 evas_object_event_callback_del(wd->edje, EVAS_CALLBACK_MOUSE_MOVE, press_move_cb);
\r
1166 if(!wd->edit_disable) edit_mode(wd);
\r
1169 ecore_timer_del(wd->timer);
\r
1177 return EXIT_FAILURE;
\r
1180 static void press_move_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info)
\r
1182 Evas_Event_Mouse_Down *ev = event_info;
\r
1183 Widget_Data *wd = (Widget_Data *)data;
\r
1185 if(abs(wd->tab_down_x-ev->output.x) > 10 || abs(wd->tab_down_y-ev->output.y) > 10){
\r
1187 ecore_timer_del(wd->timer);
\r
1193 static void press_down_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info)
\r
1195 Evas_Event_Mouse_Down *ev = event_info;
\r
1196 Widget_Data *wd = (Widget_Data *)data;
\r
1199 wd->tab_down_x = ev->output.x;
\r
1200 wd->tab_down_y = ev->output.y;
\r
1203 wd->timer = ecore_timer_add(0.1, tab_timer_cb, wd);
\r
1205 evas_object_event_callback_add(wd->edje, EVAS_CALLBACK_MOUSE_MOVE, press_move_cb, wd);
\r
1208 static void press_up_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info)
\r
1210 Evas_Event_Mouse_Up *ev = event_info;
\r
1211 Widget_Data *wd = (Widget_Data *)data;
\r
1212 Evas_Coord x, y, w, h;
\r
1214 evas_object_event_callback_del(wd->edje, EVAS_CALLBACK_MOUSE_MOVE, press_move_cb);
\r
1216 if(wd->time < KEYDOWN_INTERVAL){
\r
1218 ecore_timer_del(wd->timer);
\r
1225 evas_object_geometry_get(wd->edje, &x, &y, &w, &h);
\r
1227 if(ev->output.y > y+(h*1.5) && abs(ev->output.x - wd->tab_down_x) < wd->w/10){
\r
1228 if(!wd->edit_disable) edit_mode(wd);
\r
1230 // return if dont need to move
\r
1231 if(wd->num <= wd->view_slot_num) return;
\r
1233 if(wd->flag == true){
\r
1234 if(abs(wd->tab_down_y - ev->output.y) < wd->h){
\r
1235 if((wd->tab_down_x - ev->output.x ) > wd->w / 4){
\r
1236 _move_obj_to_left(wd);
\r
1237 }else if((ev->output.x - wd->tab_down_x) > wd->w / 4){
\r
1238 _move_obj_to_right(wd);
\r
1246 void tab_item_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
\r
1248 Elm_Tab_Item *it = (Elm_Tab_Item *)data;
\r
1249 if(it->obj == NULL)
\r
1251 Widget_Data *wd = elm_widget_data_get(it->obj);
\r
1255 if(wd->time > KEYDOWN_INTERVAL) return;
\r
1256 _selected_box(it);
\r
1259 ///////////////////////////////////////////////////////////////////
\r
1261 // Smart Object basic function
\r
1263 ////////////////////////////////////////////////////////////////////
\r
1265 static void _tab_object_move(void *data, Evas *e, Evas_Object *obj, void *event_info)
\r
1267 DBG("%s", __func__);
\r
1273 wd = elm_widget_data_get((Evas_Object *)data);
\r
1276 evas_object_geometry_get(wd->edje, &x, &y, NULL, NULL);
\r
1281 evas_object_move(wd->edje, x, y);
\r
1285 static void _tab_object_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
\r
1287 DBG("%s", __func__);
\r
1293 wd = elm_widget_data_get((Evas_Object *)data);
\r
1296 evas_object_geometry_get(wd->edje, NULL, NULL, &w, &h);
\r
1301 evas_object_resize(wd->edje, w, h);
\r
1303 evas_object_geometry_get(wd->parent, NULL, NULL, &w, &h);
\r
1304 evas_object_resize(wd->ebx, w, h);
\r
1308 static void _tab_object_show(void *data, Evas *e, Evas_Object *obj, void *event_info)
\r
1310 DBG("%s", __func__);
\r
1315 wd = elm_widget_data_get((Evas_Object *)data);
\r
1318 evas_object_show(wd->edje);
\r
1323 static void _tab_object_hide(void *data, Evas *e, Evas_Object *obj, void *event_info)
\r
1325 DBG("%s", __func__);
\r
1330 wd = elm_widget_data_get((Evas_Object *)data);
\r
1333 evas_object_hide(wd->edje);
\r
1334 evas_object_hide(wd->ebx);
\r