From: Prince Kumar Dubey Date: Wed, 19 May 2010 10:15:18 +0000 (+0530) Subject: [elm_button, elm_index, elm_pagecontrol, elm_segment_control] Updated. X-Git-Tag: beat-winset-test_0.1.1-40~291^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9b5b45b01d32bf06b885e685a6ac0cb583448305;p=framework%2Fuifw%2Felementary.git [elm_button, elm_index, elm_pagecontrol, elm_segment_control] Updated. --- diff --git a/src/lib/Elementary.h.in b/src/lib/Elementary.h.in index be56f07..2cd74c9 100755 --- a/src/lib/Elementary.h.in +++ b/src/lib/Elementary.h.in @@ -428,10 +428,19 @@ extern "C" { EAPI void elm_box_unpack_all(Evas_Object *obj); /* smart callbacks called: */ + typedef enum { + UIControlStateDefault, + UIControlStateHighlighted, + UIControlStateDisabled, + UIControlStateFocused, + UIControlStateReserved + }UIControlState; EAPI Evas_Object *elm_button_add(Evas_Object *parent); EAPI void elm_button_label_set(Evas_Object *obj, const char *label); + EAPI void elm_button_label_set_for_state(Evas_Object *obj, const char *label, UIControlState state); EAPI const char *elm_button_label_get(const Evas_Object *obj); + EAPI const char *elm_button_label_get_for_state(const Evas_Object *obj, UIControlState state); EAPI void elm_button_icon_set(Evas_Object *obj, Evas_Object *icon); EAPI Evas_Object *elm_button_icon_get(const Evas_Object *obj); EAPI void elm_button_autorepeat_set(Evas_Object *obj, Eina_Bool on); @@ -1173,7 +1182,22 @@ extern "C" { EAPI void elm_radio_value_set(Evas_Object *obj, int value); EAPI int elm_radio_value_get(const Evas_Object *obj); EAPI void elm_radio_value_pointer_set(Evas_Object *obj, int *valuep); - + typedef struct _Elm_Segment_Item Elm_Segment_Item; + EAPI Evas_Object *elm_segment_control_add(Evas_Object *parent); + EAPI Elm_Segment_Item * elm_segment_control_add_segment(Evas_Object *obj, Evas_Object *icon, const char *label, Eina_Bool animate); + EAPI void elm_segment_control_insert_segment_at(Evas_Object *obj, Evas_Object *icon, const char *label, unsigned int index, Eina_Bool animate); + EAPI Evas_Object *elm_segment_control_get_segment_at(Evas_Object *obj, unsigned int index); + EAPI void elm_segment_control_delete_segment(Evas_Object *obj, Elm_Segment_Item *item, Eina_Bool animate); + EAPI void elm_segment_control_delete_segment_at(Evas_Object *obj, unsigned int index, Eina_Bool animate); + EAPI const char *elm_segment_control_get_segment_label_at(Evas_Object *obj, unsigned int index); + EAPI Evas_Object *elm_segment_control_get_segment_icon_at(Evas_Object *obj, unsigned int index); + EAPI Elm_Segment_Item *elm_segment_control_selected_segment_get(const Evas_Object *obj, int *value); + EAPI int elm_segment_control_get_segment_count(Evas_Object *obj); + + EAPI Evas_Object *elm_page_control_add(Evas_Object *parent); + EAPI void elm_page_control_page_count_set(Evas_Object *obj, unsigned int page_count); + EAPI void elm_page_control_page_id_set(Evas_Object *obj, unsigned int page_id); + EAPI unsigned int elm_page_control_page_id_get(Evas_Object *obj); EAPI Evas_Object *elm_pager_add(Evas_Object *parent); EAPI void elm_pager_content_push(Evas_Object *obj, Evas_Object *content); EAPI void elm_pager_content_pop(Evas_Object *obj); diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index e7c14ad..6f65744 100755 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -62,6 +62,8 @@ elm_slider.c \ elm_genlist.c \ elm_check.c \ elm_radio.c \ +elm_segment_control.c \ +elm_pagecontrol.c \ elm_pager.c \ elm_progressbar.c \ elm_separator.c \ diff --git a/src/lib/elm_button.c b/src/lib/elm_button.c index 3bccbef..d48cab9 100644 --- a/src/lib/elm_button.c +++ b/src/lib/elm_button.c @@ -24,6 +24,14 @@ struct _Widget_Data double ar_threshold; double ar_interval; Ecore_Timer *timer; + const char *clickedlabel; + const char *focusedlabel; + const char *disabledlabel; + const char *defaultlabel; + int highlightedstate; + int focusedstate; + int disabledstate; + int defaultstate; }; static const char *widtype = NULL; @@ -37,6 +45,8 @@ static void _signal_clicked(void *data, Evas_Object *obj, const char *emission, static void _signal_pressed(void *data, Evas_Object *obj, const char *emission, const char *source); static void _signal_unpressed(void *data, Evas_Object *obj, const char *emission, const char *source); static void _on_focus_hook(void *data, Evas_Object *obj); +static void _set_label(Evas_Object *obj, const char *label); +static void _signal_default_text_set(void *data, Evas_Object *obj, const char *emission, const char *source); static const char SIG_CLICKED[] = "clicked"; static const char SIG_REPEATED[] = "repeated"; @@ -54,6 +64,10 @@ _del_hook(Evas_Object *obj) Widget_Data *wd = elm_widget_data_get(obj); if (!wd) return; if (wd->label) eina_stringshare_del(wd->label); + if (wd->defaultlabel) eina_stringshare_del(wd->defaultlabel); + if (wd->clickedlabel) eina_stringshare_del(wd->clickedlabel); + if (wd->focusedlabel) eina_stringshare_del(wd->focusedlabel); + if (wd->disabledlabel) eina_stringshare_del(wd->disabledlabel); free(wd); } @@ -64,11 +78,19 @@ _on_focus_hook(void *data __UNUSED__, Evas_Object *obj) if (!wd) return; if (elm_widget_focus_get(obj)) { + if(wd->focusedstate) + { + _set_label(obj, wd->focusedlabel); + } edje_object_signal_emit(wd->btn, "elm,action,focus", "elm"); evas_object_focus_set(wd->btn, 1); } else { + if(wd->defaultlabel) + _set_label(obj, wd->defaultlabel); + else + _set_label(obj, wd->label); edje_object_signal_emit(wd->btn, "elm,action,unfocus", "elm"); evas_object_focus_set(wd->btn, 0); } @@ -102,9 +124,21 @@ _disable_hook(Evas_Object *obj) Widget_Data *wd = elm_widget_data_get(obj); if (!wd) return; if (elm_widget_disabled_get(obj)) + { + if(wd->disabledstate ) + { + _set_label(obj, wd->disabledlabel); + } edje_object_signal_emit(wd->btn, "elm,state,disabled", "elm"); + } else + { + if(wd->defaultlabel) + _set_label(obj, wd->defaultlabel); + else + _set_label(obj, wd->label); edje_object_signal_emit(wd->btn, "elm,state,enabled", "elm"); + } } static void @@ -197,7 +231,10 @@ _signal_pressed(void *data, Evas_Object *obj __UNUSED__, const char *emission __ { Widget_Data *wd = elm_widget_data_get(data); if (!wd) return; - + if(wd->highlightedstate) + { + _set_label(data, wd->clickedlabel); + } if (wd->autorepeat && !wd->repeating) { if (wd->ar_threshold <= 0.0) @@ -208,10 +245,27 @@ _signal_pressed(void *data, Evas_Object *obj __UNUSED__, const char *emission __ } static void +_signal_default_text_set(void *data, Evas_Object *obj, const char *emission, const char *source) +{ + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + if(wd->defaultlabel) + _set_label(data, wd->defaultlabel); + else + _set_label(data, wd->label); + return; +} + +static void _signal_unpressed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) { Widget_Data *wd = elm_widget_data_get(data); if (!wd) return; + if(wd->defaultlabel) + _set_label(data, wd->defaultlabel); + else + _set_label(data, wd->label); + evas_object_smart_callback_call(data, "unpressed", NULL); if (wd->timer) { @@ -251,12 +305,18 @@ elm_button_add(Evas_Object *parent) wd->btn = edje_object_add(e); _elm_theme_object_set(obj, wd->btn, "button", "base", "default"); + wd->defaultstate = 0; + wd->highlightedstate = 0; + wd->focusedstate = 0; + wd->disabledstate = 0; edje_object_signal_callback_add(wd->btn, "elm,action,click", "", _signal_clicked, obj); edje_object_signal_callback_add(wd->btn, "elm,action,press", "", _signal_pressed, obj); edje_object_signal_callback_add(wd->btn, "elm,action,unpress", "", _signal_unpressed, obj); + edje_object_signal_callback_add(wd->btn, "elm,action,default,text,set", "", + _signal_default_text_set, obj); elm_widget_resize_object_set(obj, wd->btn); evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj); @@ -293,6 +353,62 @@ elm_button_label_set(Evas_Object *obj, const char *label) _sizing_eval(obj); } +static void +_set_label(Evas_Object *obj, const char *label) +{ + Widget_Data *wd = elm_widget_data_get(obj); + + edje_object_message_signal_process(wd->btn); + edje_object_part_text_set(wd->btn, "elm.text", label); + _sizing_eval(obj); +} +/** + * Set the label for each state of button + * + * @param obj The button object + * @param label The text will be written on the button + * @param state The state of button + * + * @ingroup Button + */ +EAPI void +elm_button_label_set_for_state(Evas_Object *obj, const char *label, UIControlState state) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Coord mw, mh; + + if (!wd) return; + if(label == NULL) return; + + if(state == UIControlStateDefault) + { + wd->defaultstate = UIControlStateDefault; + if (wd->defaultlabel) eina_stringshare_del(wd->defaultlabel); + wd->defaultlabel = eina_stringshare_add(label); + } + if(state == UIControlStateHighlighted) + { + wd->highlightedstate = UIControlStateHighlighted; + if (wd->clickedlabel) eina_stringshare_del(wd->clickedlabel); + wd->clickedlabel = eina_stringshare_add(label); + return; + } + if(state == UIControlStateFocused) + { + wd->focusedstate = UIControlStateFocused; + if (wd->focusedlabel) eina_stringshare_del(wd->focusedlabel); + wd->focusedlabel = eina_stringshare_add(label); + return; + } + if(state == UIControlStateDisabled) + { + wd->disabledstate = UIControlStateDisabled; + if (wd->disabledlabel) eina_stringshare_del(wd->disabledlabel); + wd->disabledlabel = eina_stringshare_add(label); + return; + } +} + EAPI const char * elm_button_label_get(const Evas_Object *obj) { @@ -301,6 +417,32 @@ elm_button_label_get(const Evas_Object *obj) if (!wd) return NULL; return wd->label; } +/** + * get the label of button for each state + * + * @param obj The button object + * @param state The state of button + * @return The title of button for state + * + * @ingroup Button + */ +EAPI const char* +elm_button_label_get_for_state(const Evas_Object *obj, UIControlState state) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + + if(state == UIControlStateDefault) + return wd->defaultlabel; + else if(state == UIControlStateHighlighted) + return wd->highlightedstate; + else if(state == UIControlStateFocused) + return wd->focusedlabel; + else if(state == UIControlStateDisabled) + return wd->disabledlabel; + else + return NULL; +} /** * Set the icon used for the button diff --git a/src/lib/elm_index.c b/src/lib/elm_index.c index af2c1e2..9311bc0 100644 --- a/src/lib/elm_index.c +++ b/src/lib/elm_index.c @@ -8,8 +8,12 @@ * by letter. */ +#define MIN_GRP_SIZE 2 //for symmetry it is 2, otherwise it can be 1 and zero have no meaning. +#define MIN_PIXEL_VALUE 1 //Min pixel value is highly dependent on touch sensitivity support. +#define MIN_OBJ_HEIGHT 24 //should be taken from .edc file. typedef struct _Widget_Data Widget_Data; typedef struct _Item Item; +typedef struct _PlacementPart PlacementPart; struct _Widget_Data { @@ -24,6 +28,13 @@ struct _Widget_Data Eina_Bool horizontal : 1; Eina_Bool active : 1; Eina_Bool down : 1; + int max_supp_items_count; + int tot_items_count[2]; + Evas_Coord pwidth, pheight; + int min_obj_height, max_grp_size; + int items_count; + double scale_factor; + const char *special_char; }; struct _Item @@ -34,15 +45,23 @@ struct _Item int level; Evas_Object *base; Eina_Bool selected : 1; + int size; + const char *vis_letter; }; static const char *widtype = NULL; +struct _PlacementPart +{ + int start; + int count; +}; static void _del_hook(Evas_Object *obj); static void _theme_hook(Evas_Object *obj); static void _sizing_eval(Evas_Object *obj); static void _index_box_auto_fill(Evas_Object *obj, Evas_Object *box, int level); static void _index_box_clear(Evas_Object *obj, Evas_Object *box, int level); static void _item_free(Item *it); +static void _index_process(Evas_Object *obj); static void _del_hook(Evas_Object *obj) @@ -64,7 +83,7 @@ _layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) { Widget_Data *wd = data; if (!wd) return; - _els_box_layout(o, priv, wd->horizontal, 1); + _els_box_layout(o, priv, wd->horizontal, 0); /* making box layout non homogenous */ } static void @@ -147,9 +166,18 @@ _item_new(Evas_Object *obj, const char *letter, const void *item) it = calloc(1, sizeof(Item)); if (!it) return NULL; it->obj = obj; - it->letter = eina_stringshare_add(letter); it->data = item; it->level = wd->level; + it->size = wd->min_obj_height; + if(letter) + { + it->letter = eina_stringshare_add(letter); + it->vis_letter = eina_stringshare_add(letter); + } + else + { + return NULL; + } return it; } @@ -173,6 +201,7 @@ _item_free(Item *it) wd->items = eina_list_remove(wd->items, it); if (it->base) evas_object_del(it->base); eina_stringshare_del(it->letter); + eina_stringshare_del(it->vis_letter); free(it); } @@ -194,6 +223,10 @@ _index_box_auto_fill(Evas_Object *obj, Evas_Object *box, int level) const char *stacking; if (it->level != level) continue; + if(i > wd->max_supp_items_count) + { + break; + } o = edje_object_add(evas_object_evas_get(obj)); it->base = o; if (i & 0x1) @@ -202,9 +235,12 @@ _index_box_auto_fill(Evas_Object *obj, Evas_Object *box, int level) _elm_theme_object_set(obj, o, "index", "item/vertical", "default"); edje_object_part_text_set(o, "elm.text", it->letter); edje_object_size_min_restricted_calc(o, &mw, &mh, 0, 0); - evas_object_size_hint_min_set(o, mw, mh); evas_object_size_hint_weight_set(o, 1.0, 1.0); evas_object_size_hint_align_set(o, -1.0, -1.0); + edje_object_part_text_set(o, "elm.text", it->vis_letter); + evas_object_resize(o, mw, it->size); + evas_object_size_hint_min_set(o, mw, it->size); + evas_object_size_hint_max_set(o, mw, it->size); elm_widget_sub_object_add(obj, o); evas_object_box_append(box, o); stacking = edje_object_data_get(o, "stacking"); @@ -215,6 +251,8 @@ _index_box_auto_fill(Evas_Object *obj, Evas_Object *box, int level) } evas_object_show(o); i++; + if(level == 1) + wd->tot_items_count[1] = i; evas_object_smart_calculate(box); // force a calc so we know the size evas_object_size_hint_min_get(box, &mw, &mh); if (mh > h) @@ -268,6 +306,9 @@ _sel_eval(Evas_Object *obj, Evas_Coord evx, Evas_Coord evy) Eina_List *l; Evas_Coord x, y, w, h, bx, by, bw, bh, xx, yy; double cdv = 0.5; + double cdvv = 0.0; + double dmax = 0.0; + double dmin = 0.0; Evas_Coord dist; Eina_Bool change = 0; char *label = NULL, *last = NULL; @@ -279,18 +320,11 @@ _sel_eval(Evas_Object *obj, Evas_Coord evx, Evas_Coord evy) it_closest = NULL; dist = 0x7fffffff; evas_object_geometry_get(wd->bx[i], &bx, &by, &bw, &bh); + dmin = (double)(wd->min_obj_height*wd->tot_items_count[1])/(2*(double)bh); + dmax = 1-dmin; EINA_LIST_FOREACH(wd->items, l, it) { if (!((it->level == i) && (it->base))) continue; - if ((it->base) && (it->level != wd->level)) - { - if (it->selected) - { - it_closest = it; - break; - } - continue; - } if (it->selected) { it_last = it; @@ -305,7 +339,7 @@ _sel_eval(Evas_Object *obj, Evas_Coord evx, Evas_Coord evy) if ((x < dist) || (!it_closest)) { if (wd->horizontal) - cdv = (double)(xx - bx) / (double)bw; + cdv = (double)(xx - bx) / (double)bw; else cdv = (double)(yy - by) / (double)bh; it_closest = it; @@ -313,8 +347,24 @@ _sel_eval(Evas_Object *obj, Evas_Coord evx, Evas_Coord evy) } } if ((i == 0) && (wd->level == 0)) - edje_object_part_drag_value_set(wd->base, "elm.dragable.index.1", - cdv, cdv); + { + if(cdv > dmax || cdv < dmin) + { + if(cdv > dmax) + { + cdvv = dmax; + } + else + { + cdvv = dmin; + } + edje_object_part_drag_value_set(wd->base, "elm.dragable.index.1", cdv, cdvv); + } + else + { + edje_object_part_drag_value_set(wd->base, "elm.dragable.index.1", cdv, cdv); + } + } if (it_closest) it_closest->selected = 1; if (it_closest != it_last) { @@ -367,13 +417,36 @@ _sel_eval(Evas_Object *obj, Evas_Coord evx, Evas_Coord evy) } if (!label) label = strdup(""); if (!last) last = strdup(""); - edje_object_part_text_set(wd->base, "elm.text.body", label); - edje_object_part_text_set(wd->base, "elm.text", last); + if(wd->level_active[1]) + { + if(wd->level == 0) + { + if(last) + { + edje_object_part_text_set(wd->base, "elm.text.body", last); + edje_object_signal_emit(wd->base, "color_changed", ""); + edje_object_part_text_set(wd->base, "elm.text.last", "_"); + edje_object_signal_emit(wd->base, "hide_2nd_level", ""); + } + } + if( wd->level == 1) + { + edje_object_part_text_set(wd->base, "elm.text", last); + edje_object_signal_emit(wd->base, "hide_first_level", ""); + edje_object_signal_emit(wd->base, "revert_back", ""); + } + } + else + { + edje_object_part_text_set(wd->base, "elm.text.body", last); + edje_object_signal_emit(wd->base, "color_changed", ""); + edje_object_part_text_set(wd->base, "elm.text", last); + } free(label); free(last); } -static void +static void _wheel(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info __UNUSED__) { Widget_Data *wd = elm_widget_data_get(data); @@ -382,7 +455,7 @@ _wheel(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_in if (!wd) return; } -static void +static void _mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info) { Widget_Data *wd = elm_widget_data_get(data); @@ -396,11 +469,11 @@ _mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *eve wd->dy = ev->canvas.y - y; elm_index_active_set(data, 1); _sel_eval(data, ev->canvas.x, ev->canvas.y); - edje_object_part_drag_value_set(wd->base, "elm.dragable.pointer", + edje_object_part_drag_value_set(wd->base, "elm.dragable.pointer", wd->dx, wd->dy); } -static void +static void _mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info) { Widget_Data *wd = elm_widget_data_get(data); @@ -408,6 +481,8 @@ _mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event void *d; if (!wd) return; if (ev->button != 1) return; + if (wd->level == 1 && wd->delay) ecore_timer_del(wd->delay); + wd->delay = NULL; wd->down = 0; d = (void *)elm_index_item_selected_get(data, wd->level); if (d) evas_object_smart_callback_call(data, "selected", d); @@ -415,12 +490,13 @@ _mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event edje_object_signal_emit(wd->base, "elm,state,level,0", "elm"); } -static void +static void _mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info) { Widget_Data *wd = elm_widget_data_get(data); Evas_Event_Mouse_Move *ev = event_info; Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady; + void *d; char buf[1024]; if (!wd) return; if (!wd->down) return; @@ -443,7 +519,7 @@ _mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *eve if (adx > minw) { if (wd->level == 0) - { + { wd->level = 1; snprintf(buf, sizeof(buf), "elm,state,level,%i", wd->level); edje_object_signal_emit(wd->base, buf, "elm"); @@ -457,12 +533,60 @@ _mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *eve wd->level = 0; snprintf(buf, sizeof(buf), "elm,state,level,%i", wd->level); edje_object_signal_emit(wd->base, buf, "elm"); + d = (void *)elm_index_item_selected_get(data, wd->level); + evas_object_smart_callback_call(data, "changed", d); + if (wd->delay) ecore_timer_del(wd->delay); + wd->delay = ecore_timer_add(0.2, _delay_change, data); evas_object_smart_callback_call(data, "level,down", NULL); } } } _sel_eval(data, ev->cur.canvas.x, ev->cur.canvas.y); } +static void +_index_box_refill_job(void *data) +{ + Widget_Data *wd = elm_widget_data_get((Evas_Object *)data); + if (!wd) return; + const char *string; + Evas_Coord pw, ph; + evas_object_geometry_get(wd->base, NULL, NULL, &pw, &ph); + wd->scale_factor = elm_scale_get(); + if ( wd->scale_factor == 0.0 ) { + wd->scale_factor = 1.0; + } + string = edje_object_data_get(wd->base, "min_obj_height"); + if(string) + wd->min_obj_height = (int) (atoi(string))*wd->scale_factor; + else + wd->min_obj_height == MIN_OBJ_HEIGHT*wd->scale_factor; + if(!wd->min_obj_height) + return; + wd->max_grp_size = wd->min_obj_height - 2*MIN_GRP_SIZE; + wd->items_count = ph/wd->min_obj_height; + wd->max_supp_items_count = wd->max_grp_size*(int)((wd->items_count-1)*0.5)+wd->items_count; + if(pw != wd->pwidth && ph != wd->pheight) + { + if(wd->down == 1) + { + wd->active = 0; + elm_index_active_set(data, 1); + } + _index_box_clear((Evas_Object *)data, wd->bx[0], 0); + evas_object_smart_calculate( wd->bx[0]); + elm_index_item_go((Evas_Object *)data, wd->level); + wd->pwidth = pw; + wd->pheight = ph; + } +} +static void _index_object_resize(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Widget_Data *wd; + if(!data) return; + wd = elm_widget_data_get((Evas_Object *)data); + if(!wd) return; + ecore_job_add(_index_box_refill_job, (Evas_Object *)data); +} /** * Add a new index to the parent @@ -492,6 +616,15 @@ elm_index_add(Evas_Object *parent) elm_widget_theme_hook_set(obj, _theme_hook); wd->horizontal = EINA_FALSE; + wd->min_obj_height = 0; + wd->max_grp_size = 0; + wd->items_count = 0; + wd->max_supp_items_count = 0; + wd->tot_items_count[0] = 0; + wd->tot_items_count[1] = 0; + wd->special_char = edje_object_data_get(wd->base, "special_char"); + if(wd->special_char == NULL); + wd->special_char = eina_stringshare_add("*"); wd->base = edje_object_add(e); _elm_theme_object_set(obj, wd->base, "index", "base/vertical", "default"); @@ -505,6 +638,7 @@ elm_index_add(Evas_Object *parent) evas_object_size_hint_min_set(o, minw, minh); edje_object_part_swallow(wd->base, "elm.swallow.event.0", o); elm_widget_sub_object_add(obj, o); + evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _index_object_resize, obj); evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_WHEEL, _wheel, obj); evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, obj); evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, _mouse_up, obj); @@ -539,6 +673,106 @@ elm_index_add(Evas_Object *parent) return obj; } +static int +_group_count(Evas_Object *obj, int extraIndex, int adj_pos, int vis_pos) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + int group_count = MIN_GRP_SIZE; + while(group_count <= wd->max_grp_size) + { + if(extraIndex <= wd->max_grp_size*adj_pos) + { + if(group_count*adj_pos>=extraIndex) + return group_count; + } + else + { + return wd->max_grp_size; + } + group_count+=MIN_GRP_SIZE; + } +} +static void +_index_process(Evas_Object *obj) +{ + int extraIndex; + int j,i, group_count; + Eina_List *l; + Item *it; + int count; + int n; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if(wd->items_count == 0) return; + const int adj_pos = (wd->items_count-1)*0.5; + if(wd->tot_items_count[wd->level] <= wd->max_supp_items_count) + n = wd->tot_items_count[wd->level]; + else + n = wd->max_supp_items_count; + group_count = MIN_GRP_SIZE; + int indx[n]; + const int minh = wd->min_obj_height; + EINA_LIST_FOREACH(wd->items, l, it) + { + it->vis_letter = eina_stringshare_add(it->letter); + it->size = minh; + } + int remainder; + int numberofparts; + int N = wd->items_count; + for(i=0;iitems, l, it) + { + int size = indx[count]; + count++; + if(size == minh) + { + it->vis_letter = eina_stringshare_add(it->letter); + continue; + } + else if(size == 1) + { + eina_stringshare_del(it->vis_letter); + it->vis_letter = eina_stringshare_add(""); + } + else + { + eina_stringshare_del(it->vis_letter); + it->vis_letter = eina_stringshare_add(wd->special_char); + } + it->size = size*wd->scale_factor; + } +} /** * Set the active state of the index programatically * @@ -559,6 +793,7 @@ elm_index_active_set(Evas_Object *obj, Eina_Bool active) if (wd->active) { _index_box_clear(obj, wd->bx[1], 1); + _index_process(obj); _index_box_auto_fill(obj, wd->bx[0], 0); edje_object_signal_emit(wd->base, "elm,state,active", "elm"); } @@ -640,6 +875,7 @@ elm_index_item_append(Evas_Object *obj, const char *letter, const void *item) it = _item_new(obj, letter, item); if (!it) return; wd->items = eina_list_append(wd->items, it); + wd->tot_items_count[wd->level]++; _index_box_clear(obj, wd->bx[wd->level], wd->level); } @@ -663,6 +899,7 @@ elm_index_item_prepend(Evas_Object *obj, const char *letter, const void *item) it = _item_new(obj, letter, item); if (!it) return; wd->items = eina_list_prepend(wd->items, it); + wd->tot_items_count[wd->level]++; _index_box_clear(obj, wd->bx[wd->level], wd->level); } @@ -686,6 +923,7 @@ elm_index_item_append_relative(Evas_Object *obj, const char *letter, const void if (!relative) { elm_index_item_append(obj, letter, item); + wd->tot_items_count[wd->level]++; return; } it = _item_new(obj, letter, item); @@ -693,10 +931,12 @@ elm_index_item_append_relative(Evas_Object *obj, const char *letter, const void if (!it_rel) { elm_index_item_append(obj, letter, item); + wd->tot_items_count[wd->level]++; return; } if (!it) return; wd->items = eina_list_append_relative(wd->items, it, it_rel); + wd->tot_items_count[wd->level]++; _index_box_clear(obj, wd->bx[wd->level], wd->level); } @@ -720,6 +960,7 @@ elm_index_item_prepend_relative(Evas_Object *obj, const char *letter, const void if (!relative) { elm_index_item_prepend(obj, letter, item); + wd->tot_items_count[wd->level]++; return; } it = _item_new(obj, letter, item); @@ -727,10 +968,12 @@ elm_index_item_prepend_relative(Evas_Object *obj, const char *letter, const void if (!it_rel) { elm_index_item_append(obj, letter, item); + wd->tot_items_count[wd->level]++; return; } if (!it) return; wd->items = eina_list_prepend_relative(wd->items, it, it_rel); + wd->tot_items_count[wd->level]++; _index_box_clear(obj, wd->bx[wd->level], wd->level); } @@ -752,6 +995,7 @@ elm_index_item_del(Evas_Object *obj, const void *item) it = _item_find(obj, item); if (!it) return; _item_free(it); + wd->tot_items_count[wd->level]--; _index_box_clear(obj, wd->bx[wd->level], wd->level); } @@ -793,6 +1037,8 @@ elm_index_item_go(Evas_Object *obj, int level __UNUSED__) ELM_CHECK_WIDTYPE(obj, widtype); Widget_Data *wd = elm_widget_data_get(obj); if (!wd) return; + if(level==0) + _index_process(obj); _index_box_auto_fill(obj, wd->bx[0], 0); if (wd->level == 1) _index_box_auto_fill(obj, wd->bx[1], 1); } diff --git a/src/lib/elm_pagecontrol.c b/src/lib/elm_pagecontrol.c new file mode 100755 index 0000000..71c9890 --- /dev/null +++ b/src/lib/elm_pagecontrol.c @@ -0,0 +1,328 @@ +#include +#include "elm_priv.h" + +#define PADDING 9 + +typedef struct _Widget_Data Widget_Data; +typedef struct _Page_Item Page_Item; + +struct _Widget_Data +{ + Evas_Object *base; + Evas_Object *hbox; + int page_count; + Eina_List *page_list; + unsigned int cur_page_id; + Evas_Object *parent; + int padding; + double scale_factor; +}; +struct _Page_Item +{ + Evas_Object *obj; + Evas_Object *base; + const void *data; + int page_id; + Eina_Bool selected :1; +}; + + +static void _theme_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + _elm_theme_object_set(obj, wd->base, "page_control", "base", elm_widget_style_get(obj)); +} + +static void _sizing_eval(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1; + + if (!wd) + return; + elm_coords_finger_size_adjust(1, &minw, 1, &minh); + edje_object_size_min_restricted_calc(wd->base, &minw, &minh, minw, minh); + elm_coords_finger_size_adjust(1, &minw, 1, &minh); + evas_object_size_hint_min_set(obj, -1, -1); + evas_object_size_hint_max_set(obj, -1, -1); +} + +static void _item_free(Evas_Object *obj, Page_Item *it) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) + return; + + if (wd->page_list) + wd->page_list = eina_list_remove(wd->page_list, it); + + if (it->base) + evas_object_del(it->base); + + if (it) + free(it); + it = NULL; + return; +} +static void _del_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Page_Item *it; + Eina_List *l, *clear = NULL; + + EINA_LIST_FOREACH(wd->page_list, l, it) clear = eina_list_append(clear, it); + EINA_LIST_FREE(clear, it) _item_free(obj, it); + + if (wd) + free(wd); + wd = NULL; + + return; +} + +static Page_Item * +_page_find(Evas_Object *obj, unsigned int index) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) + return NULL; + + Page_Item *it; + Eina_List *l; + + int i = 0; + EINA_LIST_FOREACH(wd->page_list, l, it) + { + if (i == index) { + return it; + } + i++; + } + return NULL; +} + +static void _indicator_click_left(void *data, Evas_Object *obj, const char *emission, const char *source) +{ + Widget_Data *wd = elm_widget_data_get((Evas_Object *)data); + if (!wd) + return; + + Page_Item *it; + Eina_List *l; + double cur_position = 0.0; + + if(wd->cur_page_id <= 0) return; + it=_page_find((Evas_Object *)data, wd->cur_page_id); + if(!it) return; + + edje_object_signal_emit(it->base, "elm,state,indicator,off", "elm"); + + it=_page_find((Evas_Object *)data, it->page_id-1); + if(!it) return; + + edje_object_signal_emit(it->base, "elm,state,indicator,on", "elm"); + wd->cur_page_id = it->page_id; + evas_object_smart_callback_call(it->obj, "changed", (void*)wd->cur_page_id); + + if(!wd->page_count) + return; + + cur_position = ((double)wd->cur_page_id)/wd->page_count; + edje_object_part_drag_value_set(wd->base, "elm.drag.part", cur_position, 0.5); +} + +static void _indicator_click_right(void *data, Evas_Object *obj, const char *emission, const char *source) +{ + Widget_Data *wd = elm_widget_data_get((Evas_Object *)data); + if (!wd) + return; + + Page_Item *it; + Eina_List *l; + double cur_position = 0.0; + + if(wd->cur_page_id >= wd->page_count-1) return; + + it=_page_find((Evas_Object *)data, wd->cur_page_id); + if(!it) return; + + edje_object_signal_emit(it->base, "elm,state,indicator,off", "elm"); + + it=_page_find((Evas_Object *)data, it->page_id+1); + if(!it) return; + + edje_object_signal_emit(it->base, "elm,state,indicator,on", "elm"); + wd->cur_page_id = it->page_id; + evas_object_smart_callback_call(it->obj, "changed", (void*)wd->cur_page_id); + + if(!wd->page_count) + return; + + cur_position = ((double)wd->cur_page_id)/wd->page_count; + edje_object_part_drag_value_set(wd->base, "elm.drag.part", cur_position, 0); + +} + +static Page_Item* +_create_item(Evas_Object *obj, unsigned int page_id) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Page_Item *it; + Evas_Coord mw, mh; + it = calloc(1, sizeof(Page_Item)); + if (!it) + return NULL; + + it->obj = obj; + it->selected = EINA_FALSE; + it->data = it; + it->page_id = page_id; + + it->base = edje_object_add(evas_object_evas_get(obj)); + + _elm_theme_object_set(obj, it->base, "page", "item", "default"); + edje_object_size_min_restricted_calc(it->base, &mw, &mh, 0, 0); + evas_object_size_hint_weight_set(it->base, 1.0, 1.0); + evas_object_size_hint_align_set(it->base, -1.0, -1.0); + + evas_object_resize(it->base, mw, mh); + evas_object_size_hint_min_set(it->base, mw, mh); + evas_object_size_hint_max_set(it->base, mw, mh); + + return it; +} + +static void _layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) +{ + Widget_Data *wd = data; + + if (!wd) + return; + _els_box_layout(o, priv, 1, 0); /* making box layout non homogenous */ + return; +} + +EAPI Evas_Object * +elm_page_control_add(Evas_Object *parent) +{ + Evas_Object *obj; + Evas *e; + Widget_Data *wd; + const char *padding; + + wd = ELM_NEW(Widget_Data); + e = evas_object_evas_get(parent); + obj = elm_widget_add(e); + elm_widget_type_set(obj, "page_control"); + elm_widget_sub_object_add(parent, obj); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + + wd->base = edje_object_add(e); + _elm_theme_object_set(obj, wd->base, "page_control", "base", "default"); + elm_widget_resize_object_set(obj, wd->base); + + edje_object_signal_callback_add(wd->base, "elm,state,indicator,click,left", "elm", _indicator_click_left, obj); + edje_object_signal_callback_add(wd->base, "elm,state,indicator,click,right", "elm", _indicator_click_right, obj); + + wd->scale_factor = elm_scale_get(); + if ( wd->scale_factor == 0.0 ) { + wd->scale_factor = 1.0; + } + padding = edje_object_data_get(wd->base, "padding"); + + if(padding) + wd->padding = (int) (atoi(padding)); + else + wd->padding == PADDING; + wd->hbox = evas_object_box_add(e); + evas_object_box_padding_set(wd->hbox, wd->padding, 0); + evas_object_size_hint_weight_set(wd->hbox, 0, 0); + + evas_object_box_layout_set(wd->hbox, _layout, wd, NULL); + elm_widget_sub_object_add(obj, wd->hbox); + + edje_object_part_swallow(wd->base, "elm.swallow.page", wd->hbox); + + evas_object_show(wd->hbox); + + wd->parent = parent; + + wd->page_count = 0; + wd->cur_page_id = 0; + + _sizing_eval(obj); + + return obj; +} + +EAPI void elm_page_control_page_count_set(Evas_Object *obj, unsigned int page_count) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) + return; + if (!page_count) + return; + + Evas_Object *controller; + Page_Item *it; + Evas_Coord mw, mh; + + int i = 0; + for (i = 0; i < page_count; i++) + { + it = _create_item(obj, i); + wd->page_list = eina_list_append(wd->page_list, it); + if (i == 0) + { + edje_object_signal_emit(it->base, "elm,state,indicator,on", "elm"); + evas_object_geometry_get(it->base, NULL, NULL, &mw, &mh); + } + + evas_object_show(it->base); + + evas_object_box_append(wd->hbox, it->base); + evas_object_smart_calculate(wd->hbox); + + } + int width = (mw+wd->padding)*page_count+mw; + evas_object_resize(wd->hbox, width, mh); + evas_object_size_hint_min_set(wd->hbox, width, mh); + evas_object_size_hint_max_set(wd->hbox, width, mh); + evas_object_smart_calculate(wd->hbox); + wd->page_count = page_count; +} + +EAPI +void elm_page_control_page_id_set(Evas_Object *obj, unsigned int page_id) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + if(page_id >= wd->page_count || page_id == wd->cur_page_id) return; + + Page_Item *it; + double cur_position = 0.0; + it=_page_find(obj, wd->cur_page_id); + if(!it) return; + + edje_object_signal_emit(it->base, "elm,state,indicator,off", "elm"); + it = _page_find(obj, page_id); + if(!it) return; + + edje_object_signal_emit(it->base, "elm,state,indicator,on", "elm"); + wd->cur_page_id=page_id; + cur_position = ((double)wd->cur_page_id)/wd->page_count; + edje_object_part_drag_value_set(wd->base, "elm.drag.part", cur_position,0); +} + +EAPI +unsigned int elm_page_control_page_id_get(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + return wd->cur_page_id; +} + diff --git a/src/lib/elm_segment_control.c b/src/lib/elm_segment_control.c new file mode 100755 index 0000000..e743a7d --- /dev/null +++ b/src/lib/elm_segment_control.c @@ -0,0 +1,757 @@ +#include +#include "elm_priv.h" + +/** + * @addtogroup SegmentControl SegmentControl + * + * The SegmentControl button allows for 1 or more selectors to be created to select 1 + * of a set of options. + * + * Signals that you can add callbacks for are: + * + */ +typedef struct _Widget_Data Widget_Data; +struct _Widget_Data +{ + Evas_Object *box; + Evas_Object *base; + Eina_List *seg_ctrl; + Eina_List *queue; + int width, height; + int id; + int item_width; + + Elm_Segment_Item *ani_it; + Ecore_Animator *ani; + unsigned int count; + unsigned int insert_index; + unsigned int del_index; + unsigned int cur_seg_id; +}; + +struct _Elm_Segment_Item +{ + Evas_Object *obj; + Evas_Object *base; + Evas_Object *icon; + const char *label; + Eina_Bool delete_me : 1; + int segment_id; +}; + +static void _sizing_eval(Evas_Object *obj); +static void _signal_segment_on(void *data, Evas_Object *obj, const char *emission, const char *source); +static void _sizing_eval(Evas_Object *obj); +static void _theme_hook(Evas_Object *obj); +static void _item_free(Evas_Object *obj, Elm_Segment_Item *it); +static void _del_hook(Evas_Object *obj); +static void _layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data); +static Elm_Segment_Item * _item_find(Evas_Object *obj, unsigned int index); +static void _update_list(Evas_Object *obj); +static void _refresh_segment_ids(Evas_Object *obj); +static void _state_value_set(Evas_Object *obj); +static void _queue_list(Evas_Object *obj); + +static Elm_Segment_Item* _item_new(Evas_Object *obj, const char *label, Evas_Object *icon); +static Elm_Segment_Item *_item_find(Evas_Object *obj, unsigned int index); + +static int * _animator_animate_add_cb(Evas_Object *obj); +static int * _animator_animate_del_cb(Evas_Object *obj); + + +static void +_signal_segment_on(void *data, Evas_Object *obj, const char *emission, const char *source) +{ + Elm_Segment_Item *item = (Elm_Segment_Item *) data; + Widget_Data *wd = elm_widget_data_get(item->obj); + + if (!wd) + return; + + edje_object_signal_emit(item->base, "elm,state,segment,on", "elm"); + edje_object_signal_emit(item->base, "elm,state,text,change", "elm"); + Elm_Segment_Item *it; + Eina_List *l; + if (item->segment_id == wd->cur_seg_id) + { + wd->cur_seg_id = item->segment_id; + return; + } + int i = 0; + EINA_LIST_FOREACH(wd->seg_ctrl, l, it) + { + if (it->segment_id == wd->cur_seg_id) { + edje_object_signal_emit(it->base, "elm,state,segment,off", "elm"); + edje_object_signal_emit(it->base, "elm,state,text,visible", "elm"); + break; + } + } + wd->cur_seg_id = item->segment_id; + evas_object_smart_callback_call(item->obj, "changed", (void*)wd->cur_seg_id); +} + + +static void +_sizing_eval(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1; + if (!wd) return; + elm_coords_finger_size_adjust(1, &minw, 1, &minh); + elm_coords_finger_size_adjust(1, &minw, 1, &minh); + + evas_object_size_hint_weight_set(wd->base, 1.0, -1.0); + evas_object_size_hint_align_set(wd->base, 1.0, -1.0); + evas_object_size_hint_min_set(wd->base, -1, -1); + evas_object_size_hint_max_set(wd->base, maxw, maxh); + return; +} + +static void +_theme_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + _elm_theme_object_set(obj, obj, "segmented-control", "base", "default"); + + return; +} + +static void +_item_free(Evas_Object *obj, Elm_Segment_Item *it) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + if(wd->seg_ctrl) + wd->seg_ctrl = eina_list_remove(wd->seg_ctrl, it); + + if(it->icon) evas_object_del(it->icon); + if(it->base) evas_object_del(it->base); + if(it->label) eina_stringshare_del(it->label); + + if(it) + free(it); + it = NULL; + return; +} + +static void +_del_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Elm_Segment_Item *it; + Eina_List *l, *clear = NULL; + + EINA_LIST_FOREACH(wd->seg_ctrl, l, it) clear = eina_list_append(clear, it); + EINA_LIST_FREE(clear, it) _item_free(obj, it); + + if(wd) + free(wd); + wd = NULL; + + return; +} + + +static void +_layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) +{ + Widget_Data *wd = data; + if (!wd) return; + _els_box_layout(o, priv, 1, 0); /* making box layout non homogenous */ + + return; +} + +EAPI Evas_Object * +elm_segment_control_add(Evas_Object *parent) +{ + Evas_Object *obj; + Evas *e; + Widget_Data *wd; + Evas_Coord w, h, x, y; + + wd = ELM_NEW(Widget_Data); + e = evas_object_evas_get(parent); + obj = elm_widget_add(e); + elm_widget_type_set(obj, "segmented-control"); + elm_widget_sub_object_add(parent, obj); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + + wd->base = edje_object_add(e); + _elm_theme_object_set(obj, wd->base, "segmented-control", "base", "default"); + elm_widget_resize_object_set(obj, wd->base); + + wd->box = evas_object_box_add(e); + evas_object_box_layout_set(wd->box, _layout, wd, NULL); + elm_widget_sub_object_add(obj, wd->box); + edje_object_part_swallow(wd->base, "elm.swallow.content", wd->box); + evas_object_show(wd->box); + + edje_object_part_geometry_get(wd->base, "layout", &x, &y, &w, &h); + wd->item_width = wd->width = w; + wd->height = h; + wd->id = 0; + wd->del_index = 0; + wd->insert_index = 0; + + return obj; +} + +static Elm_Segment_Item* +_item_new(Evas_Object *obj, const char *label, Evas_Object *icon) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + + Elm_Segment_Item *it; + it = calloc(1, sizeof( Elm_Segment_Item)); + if (!it) return NULL; + Evas_Coord mw, mh; + + if(obj) it->obj = obj; + it->delete_me = EINA_FALSE; + it->segment_id = wd->id; + + it->base = edje_object_add(evas_object_evas_get(obj)); + _elm_theme_object_set(obj, it->base, "segment", "base", elm_object_style_get(it->base)); + + if (it->label) eina_stringshare_del(it->label); + if (label) + { + it->label = eina_stringshare_add(label); + } + else + { + it->label = NULL; + } + + if ((it->icon != icon) && (it->icon)) + elm_widget_sub_object_del(obj, it->icon); + it->icon = icon; + if (icon) + { + elm_widget_sub_object_add(obj, icon); + Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1; + + elm_coords_finger_size_adjust(1, &minw, 1, &minh); + elm_coords_finger_size_adjust(1, &minw, 1, &minh); + + evas_object_size_hint_weight_set(it->base, 1.0, -1.0); + evas_object_size_hint_align_set(it->base, 1.0, -1.0); + evas_object_size_hint_min_set(it->base, -1, -1); + evas_object_size_hint_max_set(it->base, maxw, maxh); + } + + return it; +} + + +static void _update_list(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + Elm_Segment_Item *it; + Eina_List *l; + int i = 0; + wd->count = eina_list_count(wd->seg_ctrl); + + if(wd->count == 1) + { + it = _item_find(obj, 0); + _elm_theme_object_set(obj, it->base, "segment", "base", "single"); + edje_object_signal_emit(it->base, "elm,state,segment,on", "elm"); + edje_object_signal_emit(it->base, "elm,state,text,visible", "elm"); + edje_object_signal_emit(it->base, "elm,state,text,change", "elm"); + edje_object_message_signal_process(it->base); + + edje_object_part_text_set(it->base, "elm.text", it->label); + + edje_object_part_swallow(it->base, "elm.swallow.content", it->icon); + edje_object_signal_emit(it->base, "elm,state,icon,visible", "elm"); + return; + } + + EINA_LIST_FOREACH(wd->seg_ctrl, l, it) + { + if(i==0) + { + _elm_theme_object_set(obj, it->base, "segment", "base", "first"); + } + else if(i==wd->count-1) + { + _elm_theme_object_set(obj, it->base, "segment", "base", "last"); + } + else + { + _elm_theme_object_set(obj, it->base, "segment", "base", "default"); + } + + edje_object_signal_emit(it->base, "elm,state,text,visible", "elm"); + edje_object_message_signal_process(it->base); + + edje_object_part_text_set(it->base, "elm.text", it->label); + + edje_object_part_swallow(it->base, "elm.swallow.content", it->icon); + edje_object_signal_emit(it->base, "elm,state,icon,visible", "elm"); + if(wd->cur_seg_id == i) + { + edje_object_signal_emit(it->base, "elm,state,segment,on", "elm"); + edje_object_signal_emit(it->base, "elm,state,text,change", "elm"); + } + i++; + } +} + + +static void _refresh_segment_ids(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + Elm_Segment_Item *it; + Eina_List *l; + + if (wd->insert_index && wd->cur_seg_id >= wd->insert_index) + { + ++wd->cur_seg_id; + wd->insert_index = 0; + } + if (wd->del_index) + { + if (wd->cur_seg_id >= wd->del_index) + --wd->cur_seg_id; + wd->del_index =0; + } + + int i = 0; + EINA_LIST_FOREACH(wd->seg_ctrl, l, it) + { + it->segment_id = i; + i++; + } +} + +static void _state_value_set(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + Elm_Segment_Item *it; + Eina_List *l; + Evas_Coord w, h, mw, mh, x, y, xx, yy; + int w1=0, w2; + + + unsigned int count = eina_list_count(wd->seg_ctrl); + + if(count > 0) + wd->item_width = wd->width/count; + + + if(wd->ani_it) + { + evas_object_geometry_get(wd->ani_it->base, &x, &y, &w1, NULL); + if(wd->ani_it->delete_me) + { + w1-=(wd->item_width/15); + if( w1< 0) w1 = 0; + } + else + { + w1+=(wd->item_width/15); + if( w1 > wd->item_width ) + w1 = wd->item_width; + } + + w2 = (wd->width-w1)/(count -1); + } + else + w2 = wd->item_width; + + int i=0; + + EINA_LIST_FOREACH(wd->seg_ctrl, l, it) + { + edje_object_size_min_restricted_calc(it->base, &mw, &mh, 0, 0); + evas_object_size_hint_weight_set(it->base, 1.0, 1.0); + evas_object_size_hint_align_set(it->base, -1.0, -1.0); + + if(wd->ani_it && it == wd->ani_it) + { + evas_object_resize(it->base, w1, wd->height); + evas_object_size_hint_min_set(it->base, w1, wd->height); + evas_object_size_hint_max_set(it->base, w1, wd->height); + } + else + { + evas_object_resize(it->base, w2, wd->height); + evas_object_size_hint_min_set(it->base, w2, wd->height); + evas_object_size_hint_max_set(it->base, w2, wd->height); + } + + ++i; + } + + return; +} + + +static int * +_animator_animate_add_cb(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + int w; + evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL); + + if( w < wd->item_width ) + { + _state_value_set(obj); + evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL); + return ECORE_CALLBACK_RENEW; + } + else + { + ecore_animator_del(wd->ani); + wd->ani = NULL; + wd->ani_it = NULL; + return ECORE_CALLBACK_CANCEL; + } +} + + +static int * +_animator_animate_del_cb(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + int w; + evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL); + if( w > 0 ) + { + _state_value_set(obj); + evas_object_geometry_get(wd->ani_it->base, NULL, NULL, &w, NULL); + return ECORE_CALLBACK_RENEW; + } + else + { + _item_free(obj, wd->ani_it ); + _refresh_segment_ids(obj); + ecore_animator_del(wd->ani); + wd->ani = NULL; + wd->ani_it = NULL; + _update_list(obj); + return ECORE_CALLBACK_CANCEL; + } +} + +static void _queue_list(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + Elm_Segment_Item *it; + Eina_List *l; + int i = 0; + EINA_LIST_FOREACH(wd->seg_ctrl, l, it) + { + i++; + } + wd->count = eina_list_count(wd->seg_ctrl); +} + +EAPI Elm_Segment_Item * +elm_segment_control_add_segment(Evas_Object *obj, Evas_Object *icon, const char *label, Eina_Bool animate) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if(!wd) return; + + Evas_Object *seg; + Elm_Segment_Item *it; + + it = _item_new(obj, label, icon); + if(!it) + return; + + wd->seg_ctrl = eina_list_append(wd->seg_ctrl, it); + + _update_list(obj); + + edje_object_signal_callback_add(it->base, "elm,action,segment,click", "elm", _signal_segment_on, it); + ++wd->id; + _refresh_segment_ids(obj); + + if(animate && it->segment_id) + { + if(wd->ani_it == NULL) + { + evas_object_resize(it->base, 1, wd->height); + wd->ani_it = it; + wd->ani = ecore_animator_add( _animator_animate_add_cb, obj ); + } + else + { + wd->queue = eina_list_append(wd->queue, it); + } + } + else + _state_value_set(obj); + evas_object_show( it->base); + + evas_object_box_append(wd->box, it->base); + evas_object_smart_calculate(wd->box); + + return it; +} + + +static Elm_Segment_Item * +_item_find(Evas_Object *obj, unsigned int index) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) + return NULL; + + Elm_Segment_Item *it; + Eina_List *l; + + int i = 0; + EINA_LIST_FOREACH(wd->seg_ctrl, l, it) + { + if (i == index) { + return it; + } + i++; + } + return NULL; +} + + +static Elm_Segment_Item * +_item_search(Evas_Object *obj, Elm_Segment_Item *item) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) + return NULL; + + Elm_Segment_Item *it; + Eina_List *l; + + EINA_LIST_FOREACH(wd->seg_ctrl, l, it) + { + if (it == item) { + return it; + } + } + return NULL; +} + +EAPI void +elm_segment_control_insert_segment_at(Evas_Object *obj, Evas_Object *icon, const char *label, unsigned int index, Eina_Bool animate) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if(!wd) return; + + Elm_Segment_Item *it, *it_rel; + + it = _item_new(obj, label, icon); + it_rel = _item_find(obj, index); + if (!it_rel) + { + wd->seg_ctrl = eina_list_append(wd->seg_ctrl, it); + } + else + { + if (!it) return; + wd->seg_ctrl = eina_list_prepend_relative(wd->seg_ctrl, it, it_rel); + } + edje_object_signal_callback_add(it->base, "elm,action,segment,click", "elm", _signal_segment_on, it); + wd->insert_index = index; + ++wd->id; + _refresh_segment_ids(obj); + + _update_list(obj); + + + if(animate && it->segment_id) + { + if(wd->ani_it == NULL) + { + wd->ani_it = it; + evas_object_resize(it->base, 1, wd->height); + wd->ani = ecore_animator_add( _animator_animate_add_cb, obj ); + } + else + { + wd->queue = eina_list_append(wd->queue, it); + } + } + else + _state_value_set(obj); + + evas_object_show( it->base); + + if(index >= wd->id-1) + { + evas_object_box_append(wd->box, it->base); + } + else + { + evas_object_box_insert_at(wd->box, it->base, index); + } + + evas_object_smart_calculate(wd->box); + + return; +} + + +EAPI void +elm_segment_control_delete_segment(Evas_Object *obj, Elm_Segment_Item *item, Eina_Bool animate) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if(!wd) return; + + if(!item) return; + + Elm_Segment_Item *it; + it = _item_search(obj, item); + + if(!it) + return; + wd->del_index = it->segment_id; + + if(animate && it->segment_id) + { + if(wd->ani_it == NULL) + { + it->delete_me = EINA_TRUE; + wd->ani_it = it; + wd->ani = ecore_animator_add( _animator_animate_del_cb, obj ); + } + else + { + wd->queue = eina_list_append(wd->queue, it); + } + } + else + { + evas_object_box_remove(wd->box, it->base); + evas_object_smart_calculate(wd->box); + _item_free(obj, it); + _refresh_segment_ids(obj); + _state_value_set(obj); + _update_list(obj); + } + --wd->id; + return; +} + + +EAPI void +elm_segment_control_delete_segment_at(Evas_Object *obj, unsigned int index, Eina_Bool animate) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if(!wd) return; + Elm_Segment_Item *it, *it_rel; + + it = _item_find(obj, index); + + if(!it) + return; + + wd->del_index = index; + --wd->id; + if(animate && it->segment_id) + { + if(wd->ani_it == NULL) + { + wd->ani_it = it; + it->delete_me = EINA_TRUE; + wd->ani = ecore_animator_add( _animator_animate_del_cb, obj ); + } + else + { + wd->queue = eina_list_append(wd->queue, it); + } + } + else + { + evas_object_box_remove(wd->box, it->base); + evas_object_smart_calculate(wd->box); + _item_free(obj, it); + _refresh_segment_ids(obj); + _state_value_set(obj); + } + + _update_list(obj); + return; +} + + + +EAPI const char * +elm_segment_control_get_segment_label_at(Evas_Object *obj, unsigned int index) +{ + Elm_Segment_Item *it_rel; + Widget_Data *wd = elm_widget_data_get(obj); + if(!wd) return NULL; + + it_rel = _item_find(obj, index); + + if(it_rel) + return it_rel->label; + + return NULL; +} + + +EAPI Evas_Object * +elm_segment_control_get_segment_icon_at(Evas_Object *obj, unsigned int index) +{ + Elm_Segment_Item *seg_rel; + Widget_Data *wd = elm_widget_data_get(obj); + if(!wd) return NULL; + + seg_rel = _item_find(obj, index); + + if(seg_rel) + return seg_rel->icon; + + return NULL; +} + +EAPI Elm_Segment_Item * +elm_segment_control_selected_segment_get(const Evas_Object *obj, int *value) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if(!wd || !wd->seg_ctrl) return NULL; + + Elm_Segment_Item *it; + Eina_List *l; + + EINA_LIST_FOREACH(wd->seg_ctrl, l, it) + { + if(it->segment_id == wd->cur_seg_id) + { + * value = wd->cur_seg_id; + return it; + } + } + return NULL; +} + +EAPI int +elm_segment_control_get_segment_count(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if(!wd) return 0; + + return wd->id; +}