From: Carsten Haitzler Date: Thu, 10 Sep 2009 09:25:11 +0000 (+0000) Subject: index all happy worky fun fun! X-Git-Tag: v1.0.0~5263 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=61b0d4e7f3420a99c1deda31d8147103d9e9c7fa;p=platform%2Fupstream%2Felementary.git index all happy worky fun fun! SVN revision: 42379 --- diff --git a/data/themes/default.edc b/data/themes/default.edc index 8c10373..cbf88fa 100644 --- a/data/themes/default.edc +++ b/data/themes/default.edc @@ -5762,7 +5762,6 @@ collections { /////////////////////////////////////////////////////////////////////////////// group { name: "elm/list/item/default"; data.item: "stacking" "above"; - data.item: "selectraise" "on"; images { image: "bt_sm_base1.png" COMP; image: "bt_sm_shine.png" COMP; @@ -13077,63 +13076,52 @@ collections { image: "bt_shine.png" COMP; } parts { - part { name: "0"; + part { name: "clip"; type: RECT; mouse_events: 0; description { state: "default" 0.0; - rel1.to: "elm.swallow.index.0"; - rel1.offset: -1 -1; - rel2.to: "elm.swallow.index.0"; - rel2.offset: 0 0; - color: 0 100 0 50; + visible: 0; + color: 255 255 255 0; + } + description { state: "active" 0.0; + visible: 1; + color: 255 255 255 255; } } - part { name: "1"; + part { name: "clip2"; type: RECT; mouse_events: 0; + clip_to: "clip"; description { state: "default" 0.0; - rel1.to: "elm.swallow.index.1"; - rel1.offset: -1 -1; - rel2.to: "elm.swallow.index.1"; - rel2.offset: 0 0; - color: 100 0 0 50; + visible: 0; + color: 255 255 255 0; } - } - part { name: "elm.swallow.index.0"; - type: SWALLOW; - description { state: "default" 0.0; - align: 1.0 0.5; - rel1 { - relative: 1.0 0.0; - offset: -3 2; - } - rel2 { - relative: 1.0 1.0; - offset: -3 -3; - } + description { state: "active" 0.0; + visible: 1; + color: 255 255 255 255; } } - part { name: "elm.swallow.index.1"; + part { name: "elm.swallow.index.0"; type: SWALLOW; + clip_to: "clip"; description { state: "default" 0.0; align: 1.0 0.5; rel1 { - to_x: "elm.swallow.index.0"; - relative: 0.0 0.0; - offset: -3 2; + relative: 1.0 0.5; + offset: -1 5; } rel2 { - to_x: "elm.swallow.index.0"; - relative: 0.0 1.0; - offset: -3 -3; + relative: 1.0 0.5; + offset: -1 -6; } } } part { name: "button_image"; mouse_events: 1; + clip_to: "clip"; description { state: "default" 0.0; rel1 { - to: "elm.text"; + to: "elm.text.body"; offset: -5 -5; } rel2 { @@ -13147,28 +13135,59 @@ collections { image.middle: SOLID; } } + part { name: "elm.text.body"; + type: TEXT; + effect: SOFT_SHADOW; + mouse_events: 0; + scale: 1; + clip_to: "clip"; + description { state: "default" 0.0; + align: 1.0 0.5; + rel1 { + to: "elm.text"; + relative: 0.0 0.0; + offset: 5 0; + } + rel2 { + to: "elm.text"; + relative: 0.0 1.0; + offset: 5 -1; + } + color: 224 224 224 255; + color3: 0 0 0 64; + text { + font: "Sans,Edje-Vera"; + size: 20; + min: 1 1; + align: 1.0 0.5; + } + } + } part { name: "elm.text"; type: TEXT; effect: SOFT_SHADOW; mouse_events: 0; scale: 1; + clip_to: "clip"; description { state: "default" 0.0; - align: 0.0 0.5; + align: 1.0 0.5; rel1 { - to: "elm.swallow.index.1"; + to_x: "elm.swallow.event.0"; + to_y: "elm.dragable.pointer"; relative: 0.0 0.5; - offset: -8 0; + offset: -16 0; } rel2 { - to: "elm.swallow.index.1"; + to_x: "elm.swallow.event.0"; + to_y: "elm.dragable.pointer"; relative: 0.0 0.5; - offset: -8 -1; + offset: -16 -1; } - color: 224 224 224 255; + color: 255 0 0 255; color3: 0 0 0 64; text { font: "Sans,Edje-Vera"; - size: 10; + size: 20; min: 1 1; align: 1.0 0.5; } @@ -13176,6 +13195,7 @@ collections { } part { name: "over1"; mouse_events: 0; + clip_to: "clip"; description { state: "default" 0.0; rel1 { to: "button_image"; @@ -13194,6 +13214,7 @@ collections { mouse_events: 1; repeat_events: 1; ignore_flags: ON_HOLD; + clip_to: "clip"; description { state: "default" 0.0; rel1 { to: "button_image"; @@ -13207,13 +13228,36 @@ collections { } } } - part { name: "elm.swallow.event"; + part { name: "elm.dragable.pointer"; + type: RECT; + mouse_events: 0; + dragable { + x: 1 1 0; + y: 1 1 0; + } + clip_to: "clip"; + description { state: "default" 0.0; + fixed: 1 1; + min: 8 8; + max: 8 8; + rel1 { + relative: 0.0 0.0; + offset: 0 0; + } + rel2 { + relative: 0.0 0.0; + offset: 0 0; + } + color: 0 0 255 128; + } + } + part { name: "elm.swallow.event.0"; type: SWALLOW; description { state: "default" 0.0; align: 1.0 0.5; rel1 { relative: 1.0 0.0; - offset: -1 9; + offset: -1 0; } rel2 { relative: 1.0 1.0; @@ -13222,72 +13266,198 @@ collections { } } } + programs { + program { name: "active"; + signal: "elm,state,active"; + source: "elm"; + action: STATE_SET "active" 0.0; + transition: DECELERATE 0.5; + target: "clip"; + } + program { name: "inactive"; + signal: "elm,state,inactive"; + source: "elm"; + action: STATE_SET "default" 0.0; + transition: DECELERATE 0.5; + target: "clip"; + } + } } group { name: "elm/index/item/vertical/default"; + data.item: "stacking" "above"; + data.item: "selectraise" "on"; images { + image: "ilist_1.png" COMP; + image: "ilist_item_shadow.png" COMP; } parts { - part { name: "0"; - type: RECT; - mouse_events: 0; - description { state: "default" 0.0; - color: 100 100 0 50; - } - } + part { + name: "base_sh"; + mouse_events: 0; + description { + state: "default" 0.0; + align: 0.0 0.0; + min: 0 10; + fixed: 1 1; + rel1 { + to: "base"; + relative: 0.0 1.0; + offset: 0 0; + } + rel2 { + to: "base"; + relative: 1.0 1.0; + offset: -1 0; + } + image { + normal: "ilist_item_shadow.png"; + } + fill.smooth: 0; + } + } + part { + name: "base"; + mouse_events: 0; + description { + state: "default" 0.0; + image { + normal: "ilist_1.png"; + border: 2 2 2 2; + } + fill.smooth: 0; + } + description { state: "active" 0.0; + inherit: "default" 0.0; + rel1 { + offset: -16 0; + } + } + } part { name: "elm.text"; - type: TEXT; - mouse_events: 0; - scale: 1; - description { state: "default" 0.0; - rel1 { - offset: 1 1; + type: TEXT; + mouse_events: 0; + scale: 1; + description { + state: "default" 0.0; +// min: 16 16; + rel1 { + to: "base"; + relative: 0.0 0.0; + offset: 4 4; } - rel2 { - offset: -2 -2; + rel2 { + to: "base"; + relative: 1.0 1.0; + offset: -5 -5; } - color: 0 0 0 255; - text { - font: "Sans,Edje-Vera"; - size: 10; - min: 1 1; - align: 1.0 0.5; - } - } + color: 0 0 0 128; + text { + font: "Sans"; + size: 10; + min: 1 1; +// min: 0 1; + align: 0.0 0.5; + } + } + description { state: "active" 0.0; + inherit: "default" 0.0; + color: 0 0 0 255; + } + } + } + programs { + program { name: "active"; + signal: "elm,state,active"; + source: "elm"; + action: STATE_SET "active" 0.0; + transition: DECELERATE 0.5; + target: "elm.text"; + target: "base"; + } + program { name: "inactive"; + signal: "elm,state,inactive"; + source: "elm"; + action: STATE_SET "default" 0.0; + transition: DECELERATE 0.5; + target: "elm.text"; + target: "base"; } } } group { name: "elm/index/item_odd/vertical/default"; + data.item: "stacking" "below"; images { + image: "ilist_2.png" COMP; } parts { - part { name: "0"; - type: RECT; - mouse_events: 0; - description { state: "default" 0.0; - color: 100 50 0 50; - } - } + part { + name: "base"; + mouse_events: 0; + description { + state: "default" 0.0; + image { + normal: "ilist_2.png"; + border: 2 2 2 2; + } + fill.smooth: 0; + } + description { state: "active" 0.0; + inherit: "default" 0.0; + rel1 { + offset: -16 0; + } + } + } part { name: "elm.text"; - type: TEXT; - mouse_events: 0; - scale: 1; - description { state: "default" 0.0; - rel1 { - offset: 1 1; + type: TEXT; + mouse_events: 0; + scale: 1; + description { + state: "default" 0.0; +// min: 16 16; + rel1 { + to: "base"; + relative: 0.0 0.0; + offset: 4 4; } - rel2 { - offset: -2 -2; + rel2 { + to: "base"; + relative: 1.0 1.0; + offset: -5 -5; } - color: 0 0 0 255; - text { - font: "Sans,Edje-Vera"; - size: 10; - min: 1 1; - align: 1.0 0.5; - } - } + color: 0 0 0 128; + text { + font: "Sans"; + size: 10; + min: 1 1; +// min: 0 1; + align: 0.0 0.5; + } + } + description { state: "active" 0.0; + inherit: "default" 0.0; + color: 0 0 0 255; + } + } + } + programs { + program { name: "active"; + signal: "elm,state,active"; + source: "elm"; + action: STATE_SET "active" 0.0; + transition: DECELERATE 0.5; + target: "elm.text"; + target: "base"; + } + program { name: "inactive"; + signal: "elm,state,inactive"; + source: "elm"; + action: STATE_SET "default" 0.0; + transition: DECELERATE 0.5; + target: "elm.text"; + target: "base"; } } } diff --git a/src/bin/test_index.c b/src/bin/test_index.c index 8fe91dc..a3913d5 100644 --- a/src/bin/test_index.c +++ b/src/bin/test_index.c @@ -4,11 +4,34 @@ static Elm_Genlist_Item_Class itci; char *gli_label_get(const void *data, Evas_Object *obj, const char *part) { char buf[256]; - snprintf(buf, sizeof(buf), "Item # %i", (int)data); + int j = (int)data; + snprintf(buf, sizeof(buf), "%c%c", + 'A' + ((j >> 4) & 0xf), + 'a' + ((j ) & 0xf) + ); return strdup(buf); } -void gli_del(const void *data, Evas_Object *obj) + +void +index_changed2(void *data, Evas_Object *obj, void *event_info) +{ + // called on a change but delayed in case multiple changes happen in a + // short timespan + elm_genlist_item_top_bring_in(event_info); +} + +void +index_changed(void *data, Evas_Object *obj, void *event_info) { + // this is calld on every change, no matter how often + // elm_genlist_item_bring_in(event_info); +} + +void +index_selected(void *data, Evas_Object *obj, void *event_info) +{ + // called on final select + elm_genlist_item_top_bring_in(event_info); } void @@ -16,7 +39,7 @@ test_index(void *data, Evas_Object *obj, void *event_info) { Evas_Object *win, *bg, *gl, *id; Elm_Genlist_Item *it; - int i; + int i, j; win = elm_win_add(NULL, "index", ELM_WIN_BASIC); elm_win_title_set(win, "Index"); @@ -35,28 +58,34 @@ test_index(void *data, Evas_Object *obj, void *event_info) id = elm_index_add(win); evas_object_size_hint_weight_set(id, 1.0, 1.0); elm_win_resize_object_add(win, id); + evas_object_show(id); itci.item_style = "default"; itci.func.label_get = gli_label_get; itci.func.icon_get = NULL; itci.func.state_get = NULL; - itci.func.del = gli_del; + itci.func.del = NULL; + j = 0; for (i = 0; i < 100; i++) { - // FIXME: add to index too it = elm_genlist_item_append(gl, &itci, - i/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_NONE, NULL/* func */, + (void *)j/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_NONE, NULL/* func */, NULL/* func data */); - if ((i % 10) == 0) + if ((j & 0xf) == 0) { char buf[32]; - snprintf(buf, sizeof(buf), "%i", i / 10); + snprintf(buf, sizeof(buf), "%c", 'A' + ((j >> 4) & 0xf)); elm_index_item_append(id, buf, it); } + j += 2; } + evas_object_smart_callback_add(id, "delay,changed", index_changed2, NULL); + evas_object_smart_callback_add(id, "changed", index_changed, NULL); + evas_object_smart_callback_add(id, "selected", index_selected, NULL); + elm_index_item_go(id, 0); evas_object_resize(win, 320, 480); evas_object_show(win); diff --git a/src/lib/Elementary.h.in b/src/lib/Elementary.h.in index c5f5c9a..b99125a 100644 --- a/src/lib/Elementary.h.in +++ b/src/lib/Elementary.h.in @@ -703,6 +703,9 @@ extern "C" { EAPI void elm_genlist_item_disabled_set(Elm_Genlist_Item *item, Eina_Bool disabled); EAPI Eina_Bool elm_genlist_item_disabled_get(const Elm_Genlist_Item *item); EAPI void elm_genlist_item_show(Elm_Genlist_Item *item); + EAPI void elm_genlist_item_bring_in(Elm_Genlist_Item *item); + EAPI void elm_genlist_item_top_show(Elm_Genlist_Item *item); + EAPI void elm_genlist_item_top_bring_in(Elm_Genlist_Item *item); EAPI void elm_genlist_item_del(Elm_Genlist_Item *item); EAPI const void *elm_genlist_item_data_get(const Elm_Genlist_Item *item); EAPI void elm_genlist_item_data_set(Elm_Genlist_Item *it, const void *data); @@ -817,6 +820,8 @@ extern "C" { EAPI void elm_index_item_append_relative(Evas_Object *obj, const char *letter, const void *item, const void *relative); EAPI void elm_index_item_prepend_relative(Evas_Object *obj, const char *letter, const void *item, const void *relative); EAPI void elm_index_item_del(Evas_Object *obj, const void *item); + EAPI void elm_index_item_clear(Evas_Object *obj); + EAPI void elm_index_item_go(Evas_Object *obj, int level); /* smart callbacks called: */ diff --git a/src/lib/elm_genlist.c b/src/lib/elm_genlist.c index 5d16076..0eae85a 100644 --- a/src/lib/elm_genlist.c +++ b/src/lib/elm_genlist.c @@ -264,6 +264,7 @@ struct _Widget_Data Eina_Bool longpressed : 1; Eina_Bool wasselected : 1; Eina_Bool no_select : 1; + Eina_Bool bring_in : 1; }; struct _Item_Block @@ -994,11 +995,18 @@ _calc_job(void *data) if (showme) { wd->show_item->showme = 0; - elm_smart_scroller_child_region_show(wd->scr, - wd->show_item->x + wd->show_item->block->x, - wd->show_item->y + wd->show_item->block->y, - wd->show_item->block->w, - wd->show_item->h); + if (wd->bring_in) + elm_smart_scroller_region_bring_in(wd->scr, + wd->show_item->x + wd->show_item->block->x, + wd->show_item->y + wd->show_item->block->y, + wd->show_item->block->w, + wd->show_item->h); + else + elm_smart_scroller_child_region_show(wd->scr, + wd->show_item->x + wd->show_item->block->x, + wd->show_item->y + wd->show_item->block->y, + wd->show_item->block->w, + wd->show_item->h); wd->show_item = NULL; showme = 0; } @@ -2076,6 +2084,7 @@ elm_genlist_item_show(Elm_Genlist_Item *it) if ((it->queued) || (!it->mincalcd)) { it->wd->show_item = it; + it->wd->bring_in = 1; it->showme = EINA_TRUE; return; } @@ -2091,10 +2100,117 @@ elm_genlist_item_show(Elm_Genlist_Item *it) } /** - * XXX + * Bring in the given item + * + * This causes genlist to jump to the given item @p it and show it (by scrolling), + * if it is not fully visible. This may use animation to do so and take a + * period of time + * + * @param it The item + * + * @ingroup Genlist + */ +EAPI void +elm_genlist_item_bring_in(Elm_Genlist_Item *it) +{ + if (!it) return; + if (it->delete_me) return; + if ((it->queued) || (!it->mincalcd)) + { + it->wd->show_item = it; + it->wd->bring_in = 1; + it->showme = EINA_TRUE; + return; + } + if (it->wd->show_item) + { + it->wd->show_item->showme = EINA_FALSE; + it->wd->show_item = NULL; + } + elm_smart_scroller_region_bring_in(it->wd->scr, + it->x + it->block->x, + it->y + it->block->y, + it->block->w, it->h); +} + +/** + * Show the given item at the top * - * @param xxx XXX - * @return XXX + * This causes genlist to jump to the given item @p it and show it (by scrolling), + * if it is not fully visible. + * + * @param it The item + * + * @ingroup Genlist + */ +EAPI void +elm_genlist_item_top_show(Elm_Genlist_Item *it) +{ + Evas_Coord ow, oh; + if (!it) return; + if (it->delete_me) return; + if ((it->queued) || (!it->mincalcd)) + { + it->wd->show_item = it; + it->wd->bring_in = 1; + it->showme = EINA_TRUE; + return; + } + if (it->wd->show_item) + { + it->wd->show_item->showme = EINA_FALSE; + it->wd->show_item = NULL; + } + evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh); + elm_smart_scroller_child_region_show(it->wd->scr, + it->x + it->block->x, + it->y + it->block->y, + it->block->w, oh); +} + +/** + * Bring in the given item at the top + * + * This causes genlist to jump to the given item @p it and show it (by scrolling), + * if it is not fully visible. This may use animation to do so and take a + * period of time + * + * @param it The item + * + * @ingroup Genlist + */ +EAPI void +elm_genlist_item_top_bring_in(Elm_Genlist_Item *it) +{ + Evas_Coord ow, oh; + if (!it) return; + if (it->delete_me) return; + if ((it->queued) || (!it->mincalcd)) + { + it->wd->show_item = it; + it->wd->bring_in = 1; + it->showme = EINA_TRUE; + return; + } + if (it->wd->show_item) + { + it->wd->show_item->showme = EINA_FALSE; + it->wd->show_item = NULL; + } + evas_object_geometry_get(it->wd->pan_smart, NULL, NULL, &ow, &oh); + elm_smart_scroller_region_bring_in(it->wd->scr, + it->x + it->block->x, + it->y + it->block->y, + it->block->w, oh); +} + +/** + * Delete a given item + * + * This deletes the item from genlist and calls the genlist item del class + * callback defined in the item class, if it is set. + * + * @param it The item * * @ingroup Genlist */ diff --git a/src/lib/elm_index.c b/src/lib/elm_index.c index 3d8a048..370805c 100644 --- a/src/lib/elm_index.c +++ b/src/lib/elm_index.c @@ -19,11 +19,13 @@ typedef struct _Item Item; struct _Widget_Data { Evas_Object *base; - Evas_Object *event; + Evas_Object *event[2]; Evas_Object *bx[2]; // 2 - for now all that's supported Eina_List *items; // 1 list. yes N levels, but only 2 for now and # of items will be small int level; Evas_Coord dx, dy; + Ecore_Timer *delay; + Eina_Bool level_active[2]; Eina_Bool horizontal : 1; Eina_Bool active : 1; Eina_Bool down : 1; @@ -42,13 +44,28 @@ struct _Item static void _del_hook(Evas_Object *obj); static void _theme_hook(Evas_Object *obj); static void _sizing_eval(Evas_Object *obj); -static void _index_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 _del_hook(Evas_Object *obj) { Widget_Data *wd = elm_widget_data_get(obj); -// if (wd->label) eina_stringshare_del(wd->label); + Item *it; + Eina_List *l, *clear = NULL; + if (!wd) return; + _index_box_clear(obj, wd->bx[wd->level], wd->level); + _index_box_clear(obj, wd->bx[0], 0); + EINA_LIST_FOREACH(wd->items, l, it) + { + clear = eina_list_append(clear, it); + } + EINA_LIST_FREE(clear, it) + { + _item_free(it); + } + if (wd->delay) ecore_timer_del(wd->delay); free(wd); } @@ -56,18 +73,20 @@ static void _theme_hook(Evas_Object *obj) { Widget_Data *wd = elm_widget_data_get(obj); + _index_box_clear(obj, wd->bx[0], 0); + _index_box_clear(obj, wd->bx[1], 1); if (wd->horizontal) _elm_theme_set(wd->base, "index", "base/horizontal", elm_widget_style_get(obj)); else _elm_theme_set(wd->base, "index", "base/vertical", elm_widget_style_get(obj)); - edje_object_part_swallow(wd->base, "elm.swallow.event", wd->event); + edje_object_part_swallow(wd->base, "elm.swallow.event.0", wd->event[0]); edje_object_part_swallow(wd->base, "elm.swallow.index.0", wd->bx[0]); if (edje_object_part_exists(wd->base, "elm.swallow.index.1")) { if (!wd->bx[1]) { wd->bx[1] = _els_smart_box_add(evas_object_evas_get(wd->base)); - _els_smart_box_orientation_set(wd->bx[1], 0); + _els_smart_box_orientation_set(wd->bx[1], wd->horizontal); _els_smart_box_homogenous_set(wd->bx[1], 1); elm_widget_sub_object_add(obj, wd->bx[1]); } @@ -79,10 +98,35 @@ _theme_hook(Evas_Object *obj) evas_object_del(wd->bx[1]); wd->bx[1] = NULL; } + if (edje_object_part_exists(wd->base, "elm.swallow.event.1")) + { + if (!wd->event[1]) + { + Evas_Coord minw, minh; + + wd->event[1] = evas_object_rectangle_add(evas_object_evas_get(wd->base)); + evas_object_color_set(wd->event[1], 0, 0, 0, 0); + evas_object_size_hint_min_set(wd->event[1], minw, minh); + minw = minh = 0; + elm_coords_finger_size_adjust(1, &minw, 1, &minh); + elm_widget_sub_object_add(obj, wd->event[1]); + } + edje_object_part_swallow(wd->base, "elm.swallow.event.1", wd->event[1]); + } + else if (wd->event[1]) + { + evas_object_del(wd->event[1]); + wd->event[1] = NULL; + } edje_object_message_signal_process(wd->base); edje_object_scale_set(wd->base, elm_widget_scale_get(obj) * _elm_config->scale); _sizing_eval(obj); - if (wd->active) _index_eval(obj); + _index_box_auto_fill(obj, wd->bx[0], 0); + if (wd->active) + { + if (wd->level == 1) + _index_box_auto_fill(obj, wd->bx[1], 1); + } } static void @@ -137,56 +181,210 @@ _item_free(Item *it) // FIXME: always have index filled static void -_index_eval(Evas_Object *obj) +_index_box_auto_fill(Evas_Object *obj, Evas_Object *box, int level) { Widget_Data *wd = elm_widget_data_get(obj); - if (wd->active) + Eina_List *l; + Item *it, **itfit = NULL; + Evas_Coord mw, mh, w, h; + int i; + char buf[1024]; + + if (wd->level_active[level]) return; + i = 0; + evas_object_geometry_get(box, NULL, NULL, &w, &h); + EINA_LIST_FOREACH(wd->items, l, it) { - Eina_List *l; - Item *it; - Evas_Coord mw, mh; - int i; + Evas_Object *o; + const char *stacking; - i = 0; - EINA_LIST_FOREACH(wd->items, l, it) + if (it->level != level) continue; + o = edje_object_add(evas_object_evas_get(obj)); + it->base = o; + if (i & 0x1) + _elm_theme_set(o, "index", "item_odd/vertical", "default"); + else + _elm_theme_set(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); + elm_widget_sub_object_add(obj, o); + _els_smart_box_pack_end(box, o); + stacking = edje_object_data_get(o, "stacking"); + if (stacking) { - Evas_Object *o; - - if (it->level != wd->level) break; - o = edje_object_add(evas_object_evas_get(obj)); - if (i & 0x1) - _elm_theme_set(o, "index", "item_odd/vertical", "default"); - else - _elm_theme_set(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); - elm_widget_sub_object_add(obj, o); - _els_smart_box_pack_end(wd->bx[0], o); - evas_object_show(o); - it->base = o; - i++; + if (!strcmp(stacking, "below")) evas_object_lower(o); + else if (!strcmp(stacking, "above")) evas_object_raise(o); + } + evas_object_show(o); + i++; + evas_object_size_hint_min_get(box, &mw, &mh); + if (mh > h) + { + _index_box_clear(obj, box, level); + if (i > 0) + { + // FIXME: only i objects fit! try again. overflows right now + } } - edje_object_part_swallow(wd->base, "elm.swallow.index.0", wd->bx[0]); } - else + snprintf(buf, sizeof(buf), "elm.swallow.index.%i", level); +// evas_object_size_hint_min_get(box, &mw, &mh); +// evas_object_size_hint_min_set(box, mw, 0); + edje_object_part_swallow(wd->base, buf, box); + wd->level_active[level] = 1; +} + +static void +_index_box_clear(Evas_Object *obj, Evas_Object *box, int level) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Eina_List *l; + Item *it; + char buf[1024]; + + if (!wd->level_active[level]) return; + EINA_LIST_FOREACH(wd->items, l, it) { - Eina_List *l; - Item *it; - Evas_Coord mw, mh; - int i; - - i = 0; + if (!it->base) continue; + if (it->level != level) continue; + evas_object_del(it->base); + it->base = 0; + } + snprintf(buf, sizeof(buf), "elm.swallow.index.%i", level); + edje_object_part_swallow(wd->base, buf, box); + wd->level_active[level] = 0; +} + +static int +_delay_change(void *data) +{ + Widget_Data *wd = elm_widget_data_get(data); + wd->delay = NULL; + void *d; + d = (void *)elm_index_item_selected_get(data, wd->level); + if (d) evas_object_smart_callback_call(data, "delay,changed", d); + return 0; +} + +static void +_sel_eval(Evas_Object *obj, Evas_Coord evx, Evas_Coord evy) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Item *it, *it_closest, *it_last; + Eina_List *l; + Evas_Coord x, y, w, h, bx, by, bw, bh, xx, yy; + double cdv = 0.5; + Evas_Coord dist; + Eina_Bool change = 0; + char *label = NULL, *last = NULL; + int i; + + for (i = 0; i <= wd->level; i++) + { + it_last = NULL; + it_closest = NULL; + dist = 0x7fffffff; + evas_object_geometry_get(wd->bx[i], &bx, &by, &bw, &bh); EINA_LIST_FOREACH(wd->items, l, it) { - if (!it->base) continue; - evas_object_del(it->base); - it->base = 0; + 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; + it->selected = 0; + } + evas_object_geometry_get(it->base, &x, &y, &w, &h); + xx = x + (w / 2); + yy = y + (h / 2); + x = evx - xx; + y = evy - yy; + x = (x * x) + (y * y); + if ((x < dist) || (!it_closest)) + { + if (wd->horizontal) + cdv = (double)(xx - bx) / (double)bw; + else + cdv = (double)(yy - by) / (double)bh; + it_closest = it; + dist = x; + } + } + if ((i == 0) && (wd->level == 0)) + { + 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) + { + change = 1; + if (it_last) + { + const char *stacking, *selectraise; + + it = it_last; + edje_object_signal_emit(it->base, "elm,state,inactive", "elm"); + stacking = edje_object_data_get(it->base, "stacking"); + selectraise = edje_object_data_get(it->base, "selectraise"); + if ((selectraise) && (!strcmp(selectraise, "on"))) + { + if ((stacking) && (!strcmp(stacking, "below"))) + evas_object_lower(it->base); + } + } + if (it_closest) + { + const char *selectraise; + + it = it_closest; + edje_object_signal_emit(it->base, "elm,state,active", "elm"); + selectraise = edje_object_data_get(it->base, "selectraise"); + if ((selectraise) && (!strcmp(selectraise, "on"))) + evas_object_raise(it->base); + evas_object_smart_callback_call((void *)obj, "changed", it->data); + if (wd->delay) ecore_timer_del(wd->delay); + wd->delay = ecore_timer_add(0.2, _delay_change, obj); + } + } + if (it_closest) + { + it = it_closest; + if (!last) + last = strdup(it->letter); + else + { + if (!label) label = strdup(last); + else + { + label = realloc(label, strlen(label) + strlen(last) + 1); + strcat(label, last); + } + free(last); + last = strdup(it->letter); + } } - edje_object_part_swallow(wd->base, "elm.swallow.index.0", wd->bx[0]); } + 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); + free(label); + free(last); } static void @@ -205,11 +403,13 @@ _mouse_down(void *data, Evas *e, Evas_Object *o, void *event_info) Evas_Coord x, y; if (ev->button != 1) return; wd->down = 1; - printf("down!\n"); - evas_object_geometry_get(o, &x, &y, NULL, NULL); + + evas_object_geometry_get(wd->base, &x, &y, NULL, NULL); wd->dx = ev->canvas.x - x; 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", wd->dx, wd->dy); } static void @@ -217,10 +417,13 @@ _mouse_up(void *data, Evas *e, Evas_Object *o, void *event_info) { Widget_Data *wd = elm_widget_data_get(data); Evas_Event_Mouse_Up *ev = event_info; + void *d; if (ev->button != 1) return; wd->down = 0; - printf("up!\n"); + d = (void *)elm_index_item_selected_get(data, wd->level); + if (d) evas_object_smart_callback_call(data, "selected", d); elm_index_active_set(data, 0); + edje_object_signal_emit(wd->base, "elm,state,level,0", "elm"); } static void @@ -229,10 +432,13 @@ _mouse_move(void *data, Evas *e, Evas_Object *o, 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; + Eina_List *l; + Item *it; + char buf[1024]; if (!wd->down) return; elm_coords_finger_size_adjust(1, &minw, 1, &minh); - evas_object_geometry_get(o, &x, &y, NULL, NULL); + evas_object_geometry_get(wd->base, &x, &y, NULL, NULL); x = ev->cur.canvas.x - x; y = ev->cur.canvas.y - y; dx = x - wd->dx; @@ -241,6 +447,7 @@ _mouse_move(void *data, Evas *e, Evas_Object *o, void *event_info) dy = y - wd->dy; ady = dy; if (ady < 0) ady = -dy; + edje_object_part_drag_value_set(wd->base, "elm.dragable.pointer", x, y); if (wd->horizontal) { } @@ -249,20 +456,25 @@ _mouse_move(void *data, Evas *e, Evas_Object *o, void *event_info) if (adx > minw) { if (wd->level == 0) - { - printf("level up\n"); + { wd->level = 1; + snprintf(buf, sizeof(buf), "elm,state,level,%i", wd->level); + edje_object_signal_emit(wd->base, buf, "elm"); + evas_object_smart_callback_call(data, "level,up", NULL); } } else { if (wd->level == 1) { - printf("level down\n"); wd->level = 0; + snprintf(buf, sizeof(buf), "elm,state,level,%i", wd->level); + edje_object_signal_emit(wd->base, buf, "elm"); + evas_object_smart_callback_call(data, "level,down", NULL); } } } + _sel_eval(data, ev->cur.canvas.x, ev->cur.canvas.y); } /** @@ -298,19 +510,28 @@ elm_index_add(Evas_Object *parent) elm_widget_resize_object_set(obj, wd->base); o = evas_object_rectangle_add(e); - wd->event = o; + wd->event[0] = o; evas_object_color_set(o, 0, 0, 0, 0); minw = minh = 0; elm_coords_finger_size_adjust(1, &minw, 1, &minh); evas_object_size_hint_min_set(o, minw, minh); - edje_object_part_swallow(wd->base, "elm.swallow.event", o); + edje_object_part_swallow(wd->base, "elm.swallow.event.0", o); elm_widget_sub_object_add(obj, o); 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); evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move, obj); evas_object_show(o); - + if (edje_object_part_exists(wd->base, "elm.swallow.event.1")) + { + o = evas_object_rectangle_add(e); + wd->event[1] = o; + evas_object_color_set(o, 0, 0, 0, 0); + evas_object_size_hint_min_set(o, minw, minh); + edje_object_part_swallow(wd->base, "elm.swallow.event.1", o); + elm_widget_sub_object_add(obj, o); + } + wd->bx[0] = _els_smart_box_add(e); _els_smart_box_orientation_set(wd->bx[0], 0); _els_smart_box_homogenous_set(wd->bx[0], 1); @@ -347,7 +568,17 @@ elm_index_active_set(Evas_Object *obj, Eina_Bool active) if (!wd) return; if (wd->active == active) return; wd->active = active; - _index_eval(obj); + wd->level = 0; + if (wd->active) + { + _index_box_clear(obj, wd->bx[1], 1); + _index_box_auto_fill(obj, wd->bx[0], 0); + edje_object_signal_emit(wd->base, "elm,state,active", "elm"); + } + else + { + edje_object_signal_emit(wd->base, "elm,state,inactive", "elm"); + } } /** @@ -364,7 +595,6 @@ elm_index_item_level_set(Evas_Object *obj, int level) if (!wd) return; if (wd->level == level) return; wd->level = level; - _index_eval(obj); } /** @@ -419,7 +649,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); - if (wd->active) _index_eval(obj); + _index_box_clear(obj, wd->bx[wd->level], wd->level); } /** @@ -438,7 +668,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); - if (wd->active) _index_eval(obj); + _index_box_clear(obj, wd->bx[wd->level], wd->level); } /** @@ -468,7 +698,7 @@ elm_index_item_append_relative(Evas_Object *obj, const char *letter, const void } if (!it) return; wd->items = eina_list_append_relative(wd->items, it, it_rel); - if (wd->active) _index_eval(obj); + _index_box_clear(obj, wd->bx[wd->level], wd->level); } /** @@ -498,7 +728,7 @@ elm_index_item_prepend_relative(Evas_Object *obj, const char *letter, const void } if (!it) return; wd->items = eina_list_prepend_relative(wd->items, it, it_rel); - if (wd->active) _index_eval(obj); + _index_box_clear(obj, wd->bx[wd->level], wd->level); } /** @@ -517,5 +747,50 @@ elm_index_item_del(Evas_Object *obj, const void *item) it = _item_find(obj, item); if (!it) return; _item_free(it); - if (wd->active) _index_eval(obj); + _index_box_clear(obj, wd->bx[wd->level], wd->level); +} + +/** + * XXX + * + * @param obj The index object + * + * @ingroup Index + */ +EAPI void +elm_index_item_clear(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Item *it; + Eina_List *l, *clear = NULL; + if (!wd) return; + _index_box_clear(obj, wd->bx[wd->level], wd->level); + EINA_LIST_FOREACH(wd->items, l, it) + { + if (it->level != wd->level) continue; + clear = eina_list_append(clear, it); + } + EINA_LIST_FREE(clear, it) + { + _item_free(it); + } +} + +/** + * XXX + * + * @param obj The index object + * + * @ingroup Index + */ +EAPI void +elm_index_item_go(Evas_Object *obj, int level) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Item *it; + if (!wd) return; + // XXX + _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/els_scroller.c b/src/lib/els_scroller.c index 29e2249..ea851a3 100644 --- a/src/lib/els_scroller.c +++ b/src/lib/els_scroller.c @@ -967,9 +967,28 @@ elm_smart_scroller_paging_set(Evas_Object *obj, double pagerel_h, double pagerel void elm_smart_scroller_region_bring_in(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) { - Evas_Coord px, py, vw, vh, cw, ch; - + Evas_Coord mx = 0, my = 0, cw = 0, ch = 0, px = 0, py = 0, nx, ny; + API_ENTRY return; + sd->pan_func.max_get(sd->pan_obj, &mx, &my); + sd->pan_func.child_size_get(sd->pan_obj, &cw, &ch); + sd->pan_func.get(sd->pan_obj, &px, &py); + + nx = px; + if (x < px) nx = x; + else if ((x + w) > (px + (cw - mx))) + { + nx = x + w - (cw - mx); + if (nx > x) nx = x; + } + ny = py; + if (y < py) ny = y; + else if ((y + h) > (py + (ch - my))) + { + ny = y + h - (ch - my); + if (ny > y) ny = y; + } + if ((nx == px) && (ny == py)) return; if ((sd->down.bounce_x_animator) || (sd->down.bounce_y_animator) || (sd->scrollto.x.animator) || (sd->scrollto.y.animator)) { @@ -1012,14 +1031,11 @@ elm_smart_scroller_region_bring_in(Evas_Object *obj, Evas_Coord x, Evas_Coord y, sd->down.ax = 0; sd->down.ay = 0; } - elm_smart_scroller_child_pos_get(sd->smart_obj, &px, &py); - elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &vw, &vh); - sd->pan_func.child_size_get(sd->pan_obj, &cw, &ch); - x = x + (vw - w) / 2; + x = nx; if (x < 0) x = 0; else if ((x + w) > cw) x = cw - w; _smart_scrollto_x(sd, 1.0, x); - y = y + (vh - h) / 2; + y = ny; if (y < 0) y = 0; else if ((y + h) > ch) y = ch - h; _smart_scrollto_y(sd, 1.0, y);