From 01e71a2649a2fe296f5d5d7e3e884749342fc175 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Sat, 20 Nov 2010 08:43:43 +0000 Subject: [PATCH] well... many things - genlist, when it is processign quue, or u add.del items will try and stick to viewing an acnhor item. it also handles wrapping text properly now if style has such a thing - a test style with that is there too (message style) for now - found isasue in edje with textblock styles - doesnt change on state change. but anyway - re-wrapping text works.. and it progressively processes the genlist blocks to re-calc sizes etc. etc. so you dont block and so-on. i5ts not too shabby. as for that - store has a generic struct type reader now and is being tested... and get rid of unused var. SVN revision: 54738 --- legacy/elementary/data/themes/default.edc | 310 ++++++++++++++++++++++ legacy/elementary/src/bin/test_store.c | 207 ++++++++------- legacy/elementary/src/lib/elm_genlist.c | 160 ++++++++--- legacy/elementary/src/lib/elm_widget.c | 1 - 4 files changed, 556 insertions(+), 122 deletions(-) diff --git a/legacy/elementary/data/themes/default.edc b/legacy/elementary/data/themes/default.edc index e664f35747..81d42b9e58 100644 --- a/legacy/elementary/data/themes/default.edc +++ b/legacy/elementary/data/themes/default.edc @@ -15431,6 +15431,316 @@ collections { } } } + group { name: "elm/genlist/item_compress/message/default"; + alias: "elm/genlist/item_compress_odd/message/default"; + data.item: "stacking" "above"; + data.item: "selectraise" "on"; + data.item: "labels" "elm.title.1 elm.title.2 elm.text"; +// data.item: "icons" "elm.swallow.icon elm.swallow.end"; + data.item: "treesize" "20"; +// data.item: "states" ""; + images { + image: "bt_sm_base1.png" COMP; + image: "bt_sm_shine.png" COMP; + image: "bt_sm_hilight.png" COMP; + image: "ilist_1.png" COMP; + image: "ilist_item_shadow.png" COMP; + } + styles { + style { name: "genlist_textblock_style"; + base: "font=Sans font_size=10 color=#000 wrap=char"; + tag: "br" "\n"; + tag: "ps" "ps"; + tag: "tab" "\t"; + } + style { name: "genlist_textblock_style2"; + base: "font=Sans font_size=10 color=#fff wrap=char"; + tag: "br" "\n"; + tag: "ps" "ps"; + tag: "tab" "\t"; + } + } + parts { + part { + name: "event"; + type: RECT; + repeat_events: 1; + description { + state: "default" 0.0; + color: 0 0 0 0; + } + } + 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; + } + } + part { name: "bg"; + clip_to: "disclip"; + mouse_events: 0; + description { state: "default" 0.0; + visible: 0; + color: 255 255 255 0; + rel1 { + relative: 0.0 0.0; + offset: -5 -5; + } + rel2 { + relative: 1.0 1.0; + offset: 4 4; + } + image { + normal: "bt_sm_base1.png"; + border: 6 6 6 6; + } + image.middle: SOLID; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + color: 255 255 255 255; + rel1 { + relative: 0.0 0.0; + offset: -2 -2; + } + rel2 { + relative: 1.0 1.0; + offset: 1 1; + } + } + } + part { name: "elm.title.1"; + clip_to: "disclip"; + type: TEXT; + effect: SOFT_SHADOW; + mouse_events: 0; + scale: 1; + description { + state: "default" 0.0; + fixed: 0 1; +// min: 16 16; + rel1 { + relative: 0.0 0.0; + offset: 4 4; + } + rel2 { + relative: 1.0 0.0; + offset: -5 4; + } + color: 0 0 0 255; + color3: 0 0 0 0; + align: 0.0 0.0; + text { + font: "Sans"; + size: 10; + min: 0 1; +// min: 1 1; + align: 0.0 0.0; + } + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + color: 224 224 224 255; + color3: 0 0 0 64; + } + } + part { name: "elm.title.2"; + clip_to: "disclip"; + type: TEXT; + effect: SOFT_SHADOW; + mouse_events: 0; + scale: 1; + description { + state: "default" 0.0; + fixed: 0 1; +// min: 16 16; + rel1 { + to_y: "elm.title.1"; + relative: 0.0 1.0; + offset: 4 0; + } + rel2 { + to_y: "elm.title.1"; + relative: 1.0 1.0; + offset: -5 0; + } + color: 0 0 0 255; + color3: 0 0 0 0; + align: 0.0 0.0; + text { + font: "Sans"; + size: 10; + min: 0 1; +// min: 1 1; + align: 0.0 0.0; + } + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + color: 224 224 224 255; + color3: 0 0 0 64; + } + } + part { name: "elm.text"; + clip_to: "disclip"; + type: TEXTBLOCK; + mouse_events: 0; + scale: 1; + description { + state: "default" 0.0; +// fixed: 0 1; +// min: 16 16; + rel1 { + to_y: "elm.title.2"; + relative: 0.0 1.0; + offset: 4 0; + } + rel2 { + relative: 1.0 1.0; + offset: -5 -5; + } + align: 0.0 0.0; + text { + style: "genlist_textblock_style"; + min: 0 1; +// min: 1 1; + align: 0.0 0.0; + } + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + text { + style: "genlist_textblock_style20"; + } + } + } + part { name: "fg1"; + clip_to: "disclip"; + mouse_events: 0; + description { state: "default" 0.0; + visible: 0; + color: 255 255 255 0; + rel1.to: "bg"; + rel2.relative: 1.0 0.5; + rel2.to: "bg"; + image { + normal: "bt_sm_hilight.png"; + border: 6 6 6 0; + } + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + color: 255 255 255 255; + } + } + part { name: "fg2"; + clip_to: "disclip"; + mouse_events: 0; + description { state: "default" 0.0; + visible: 0; + color: 255 255 255 0; + rel1.to: "bg"; + rel2.to: "bg"; + image { + normal: "bt_sm_shine.png"; + border: 6 6 6 0; + } + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + color: 255 255 255 255; + } + } + part { name: "disclip"; + type: RECT; + description { state: "default" 0.0; + rel1.to: "bg"; + rel2.to: "bg"; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + color: 255 255 255 64; + } + } + } + programs { + // signal: elm,state,%s,active + // a "check" item named %s went active + // signal: elm,state,%s,passive + // a "check" item named %s went passive + // default is passive + program { + name: "go_active"; + signal: "elm,state,selected"; + source: "elm"; + action: STATE_SET "selected" 0.0; + target: "bg"; + target: "fg1"; + target: "fg2"; + target: "elm.title.1"; + target: "elm.title.2"; + } + program { + name: "go_passive"; + signal: "elm,state,unselected"; + source: "elm"; + action: STATE_SET "default" 0.0; + target: "bg"; + target: "fg1"; + target: "fg2"; + target: "elm.title.1"; + target: "elm.title.2"; + transition: LINEAR 0.1; + } + program { + name: "go_disabled"; + signal: "elm,state,disabled"; + source: "elm"; + action: STATE_SET "disabled" 0.0; + target: "disclip"; + } + program { + name: "go_enabled"; + signal: "elm,state,enabled"; + source: "elm"; + action: STATE_SET "default" 0.0; + target: "disclip"; + } + } + } group { name: "elm/genlist/item_compress/default/default"; data.item: "stacking" "above"; data.item: "selectraise" "on"; diff --git a/legacy/elementary/src/bin/test_store.c b/legacy/elementary/src/bin/test_store.c index 62ab5b2af0..2daf6717fc 100644 --- a/legacy/elementary/src/bin/test_store.c +++ b/legacy/elementary/src/bin/test_store.c @@ -32,6 +32,7 @@ typedef struct _Elm_Store_Item_Info_Filesystem Elm_Store_Item_Info_Filesystem; typedef struct _Elm_Store_Item_Mapping Elm_Store_Item_Mapping; typedef struct _Elm_Store_Item_Mapping_Empty Elm_Store_Item_Mapping_Empty; typedef struct _Elm_Store_Item_Mapping_Icon Elm_Store_Item_Mapping_Icon; +typedef struct _Elm_Store_Item_Mapping_Photo Elm_Store_Item_Mapping_Photo; typedef struct _Elm_Store_Item_Mapping_Custom Elm_Store_Item_Mapping_Custom; typedef Eina_Bool (*Elm_Store_Item_List_Cb) (void *data, Elm_Store_Item_Info *info); @@ -54,6 +55,7 @@ typedef enum struct _Elm_Store_Item_Mapping_Icon { + // FIXME: allow edje file icons int w, h; Elm_Icon_Lookup_Order lookup_order; Eina_Bool standard_name : 1; @@ -61,7 +63,6 @@ struct _Elm_Store_Item_Mapping_Icon Eina_Bool smooth : 1; Eina_Bool scale_up : 1; Eina_Bool scale_down : 1; - Eina_Bool preload : 1; }; struct _Elm_Store_Item_Mapping_Empty @@ -69,6 +70,11 @@ struct _Elm_Store_Item_Mapping_Empty Eina_Bool dummy; }; +struct _Elm_Store_Item_Mapping_Photo +{ + int size; +}; + struct _Elm_Store_Item_Mapping_Custom { Elm_Store_Item_Mapping_Cb func; @@ -82,6 +88,7 @@ struct _Elm_Store_Item_Mapping union { Elm_Store_Item_Mapping_Empty empty; Elm_Store_Item_Mapping_Icon icon; + Elm_Store_Item_Mapping_Photo photo; Elm_Store_Item_Mapping_Custom custom; // add more types here } details; @@ -145,7 +152,6 @@ struct _Elm_Store void (*free)(Elm_Store *store); struct { void (*free)(Elm_Store_Item *item); - const char *(*label_get)(Elm_Store_Item *item); } item; Evas_Object *genlist; Ecore_Thread *list_th; @@ -175,16 +181,17 @@ struct _Elm_Store_Item { EINA_INLIST; EINA_MAGIC; - Elm_Store *store; - Elm_Genlist_Item *item; - Ecore_Thread *fetch_th; - Ecore_Job *eval_job; - void *data; + Elm_Store *store; + Elm_Genlist_Item *item; + Ecore_Thread *fetch_th; + Ecore_Job *eval_job; + const Elm_Store_Item_Mapping *mapping; + void *data; LK(lock); - Eina_Bool live : 1; - Eina_Bool was_live : 1; - Eina_Bool realized : 1; - Eina_Bool fetched : 1; + Eina_Bool live : 1; + Eina_Bool was_live : 1; + Eina_Bool realized : 1; + Eina_Bool fetched : 1; }; struct _Elm_Store_Filesystem @@ -221,11 +228,6 @@ _store_cache_trim(Elm_Store *st) LKU(sti->lock); if (sti->fetch_th) { - DBG(".. do cancel [%i] [%i] %p for: %s\n", - sti->live, - sti->fetched, - sti->fetch_th, - elm_store_item_filesystem_path_get(sti)); ecore_thread_cancel(sti->fetch_th); sti->fetch_th = NULL; } @@ -258,11 +260,6 @@ _store_genlist_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, if (sti->eval_job) ecore_job_del(sti->eval_job); if (sti->fetch_th) { - DBG(".. do cancel3 [%i] [%i] %p for: %s\n", - sti->live, - sti->fetched, - sti->fetch_th, - elm_store_item_filesystem_path_get(sti)); ecore_thread_cancel(sti->fetch_th); sti->fetch_th = NULL; } @@ -312,11 +309,7 @@ _store_filesystem_fetch_end(void *data, Ecore_Thread *th) { Elm_Store_Item *sti = data; LKL(sti->lock); - if (sti->data) - { - DBG("------UPDATE: %p %s\n", th, elm_store_item_filesystem_path_get(sti)); - elm_genlist_item_update(sti->item); - } + if (sti->data) elm_genlist_item_update(sti->item); LKU(sti->lock); if (th == sti->fetch_th) sti->fetch_th = NULL; } @@ -326,14 +319,9 @@ static void _store_filesystem_fetch_cancel(void *data, Ecore_Thread *th) { Elm_Store_Item *sti = data; - DBG("------CANCEL: %p %s\n", th, elm_store_item_filesystem_path_get(sti)); LKL(sti->lock); if (th == sti->fetch_th) sti->fetch_th = NULL; - if (sti->data) - { - DBG("------UPDATE: %p %s\n", th, elm_store_item_filesystem_path_get(sti)); - elm_genlist_item_update(sti->item); - } + if (sti->data) elm_genlist_item_update(sti->item); LKU(sti->lock); } @@ -352,37 +340,20 @@ _store_item_eval(void *data) sti->store->realized = eina_list_append(sti->store->realized, sti); sti->realized = EINA_TRUE; if ((sti->store->fetch_thread) && (!sti->fetch_th)) - { - sti->fetch_th = ecore_thread_run(_store_filesystem_fetch_do, - _store_filesystem_fetch_end, - _store_filesystem_fetch_cancel, - sti); - DBG(".. do fetch [%i] [%i] = %p for: %s\n", - sti->live, - sti->fetched, - sti->fetch_th, - elm_store_item_filesystem_path_get(sti)); - } + sti->fetch_th = ecore_thread_run(_store_filesystem_fetch_do, + _store_filesystem_fetch_end, + _store_filesystem_fetch_cancel, + sti); else if ((!sti->store->fetch_thread)) { - DBG(".. do fetch in same thread [%i] [%i] = %p for: %s\n", - sti->live, - sti->fetched, - sti->fetch_th, - elm_store_item_filesystem_path_get(sti)); - _store_filesystem_fetch_do(sti, NULL); - _store_filesystem_fetch_end(sti, NULL); + _store_filesystem_fetch_do(sti, NULL); + _store_filesystem_fetch_end(sti, NULL); } } else { if (sti->fetch_th) { - DBG(".. do cancel2 [%i] [%i] %p for: %s\n", - sti->live, - sti->fetched, - sti->fetch_th, - elm_store_item_filesystem_path_get(sti)); ecore_thread_cancel(sti->fetch_th); sti->fetch_th = NULL; } @@ -416,33 +387,101 @@ _store_genlist_item_unrealized(void *data, Evas_Object *obj __UNUSED__, void *ev sti->eval_job = ecore_job_add(_store_item_eval, sti); } +static const Elm_Store_Item_Mapping * +_store_item_mapping_find(Elm_Store_Item *sti, const char *part) +{ + const Elm_Store_Item_Mapping *m; + + for (m = sti->mapping; m; m ++) + { + if (m->type == ELM_STORE_ITEM_MAPPING_NONE) break; + if (!strcmp(part, m->part)) return m; + } + return NULL; +} + static char * -_store_item_label_get(void *data, Evas_Object *obj __UNUSED__, const char *part __UNUSED__) +_store_item_label_get(void *data, Evas_Object *obj __UNUSED__, const char *part) { Elm_Store_Item *sti = data; const char *s = ""; - // FIXME: use item mapping for partname -> data pointer offset for string LKL(sti->lock); - if ((sti->data) && (sti->store->item.label_get)) - s = sti->store->item.label_get(sti); + if (sti->data) + { + const Elm_Store_Item_Mapping *m = _store_item_mapping_find(sti, part); + if (m) + { + switch (m->type) + { + case ELM_STORE_ITEM_MAPPING_LABEL: + s = *(char **)(((unsigned char *)sti->data) + m->offset); + break; + case ELM_STORE_ITEM_MAPPING_CUSTOM: + if (m->details.custom.func) + s = m->details.custom.func(sti->data, sti, part); + break; + default: + break; + } + } + } LKU(sti->lock); return strdup(s); } static Evas_Object * -_store_item_icon_get(void *data, Evas_Object *obj, const char *part __UNUSED__) +_store_item_icon_get(void *data, Evas_Object *obj, const char *part) { Elm_Store_Item *sti = data; - char buf[PATH_MAX]; LKL(sti->lock); if (sti->data) { - Evas_Object *ic = elm_icon_add(obj); - LKU(sti->lock); - snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR); - elm_icon_file_set(ic, buf, NULL); - evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1); - return ic; + const Elm_Store_Item_Mapping *m = _store_item_mapping_find(sti, part); + if (m) + { + Evas_Object *ic = NULL; + const char *s = NULL; + + switch (m->type) + { + case ELM_STORE_ITEM_MAPPING_ICON: + ic = elm_icon_add(obj); + s = *(char **)(((unsigned char *)sti->data) + m->offset); + elm_icon_order_lookup_set(ic, m->details.icon.lookup_order); + evas_object_size_hint_aspect_set(ic, + EVAS_ASPECT_CONTROL_VERTICAL, + m->details.icon.w, + m->details.icon.h); + elm_icon_smooth_set(ic, m->details.icon.smooth); + elm_icon_no_scale_set(ic, m->details.icon.no_scale); + elm_icon_scale_set(ic, + m->details.icon.scale_up, + m->details.icon.scale_down); + if (s) + { + if (m->details.icon.standard_name) + elm_icon_standard_set(ic, s); + else + elm_icon_file_set(ic, s, NULL); + } + break; + case ELM_STORE_ITEM_MAPPING_PHOTO: + ic = elm_icon_add(obj); + s = *(char **)(((unsigned char *)sti->data) + m->offset); + elm_photo_size_set(ic, m->details.photo.size); + if (s) + elm_photo_file_set(ic, s); + break; + case ELM_STORE_ITEM_MAPPING_CUSTOM: + if (m->details.custom.func) + ic = m->details.custom.func(sti->data, sti, part); + break; + default: + break; + } + LKU(sti->lock); + return ic; + } } LKU(sti->lock); return NULL; @@ -544,6 +583,7 @@ _store_filesystem_list_update(void *data, Ecore_Thread *th __UNUSED__, void *msg EINA_MAGIC_SET(&(sti->base), ELM_STORE_ITEM_MAGIC); sti->base.store = st; sti->base.data = info->base.data; + sti->base.mapping = info->base.mapping; sti->path = eina_stringshare_add(info->path); itc = info->base.item_class; @@ -570,7 +610,7 @@ done: } // public api calls -EAPI Elm_Store * +static Elm_Store * _elm_store_new(size_t size) { Elm_Store *st = calloc(1, size); @@ -609,13 +649,6 @@ _elm_store_filesystem_item_free(Elm_Store_Item *item) eina_stringshare_del(sti->path); } -static const char * -_elm_store_filesystem_item_label_get(Elm_Store_Item *item) -{ - Elm_Store_Item_Filesystem *sti = (Elm_Store_Item_Filesystem *)item; - return sti->path; -} - EAPI Elm_Store * elm_store_filesystem_new(void) { @@ -625,7 +658,6 @@ elm_store_filesystem_new(void) EINA_MAGIC_SET(st, ELM_STORE_FILESYSTEM_MAGIC); st->base.free = _elm_store_filesystem_free; st->base.item.free = _elm_store_filesystem_item_free; - st->base.item.label_get = _elm_store_filesystem_item_label_get; return &st->base; } @@ -648,11 +680,6 @@ elm_store_free(Elm_Store *st) if (sti->eval_job) ecore_job_del(sti->eval_job); if (sti->fetch_th) { - DBG(".. do cancel3 [%i] [%i] %p for: %s\n", - sti->live, - sti->fetched, - sti->fetch_th, - elm_store_item_filesystem_path_get(sti)); ecore_thread_cancel(sti->fetch_th); sti->fetch_th = NULL; } @@ -886,7 +913,10 @@ _st_longpress(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_in } // store callbacks to handle loading/parsing/freeing of store items from src -static Elm_Genlist_Item_Class itc1; +static Elm_Genlist_Item_Class itc1 = +{ + "message", { NULL, NULL, NULL, NULL } +}; static const Elm_Store_Item_Mapping it1_mapping[] = { @@ -898,13 +928,13 @@ static const Elm_Store_Item_Mapping it1_mapping[] = } } }, { ELM_STORE_ITEM_MAPPING_LABEL, - "elm.title.2", ELM_STORE_ITEM_MAPPING_OFFSET(My_Item, from), + "elm.title.2", ELM_STORE_ITEM_MAPPING_OFFSET(My_Item, subject), { .empty = { EINA_TRUE } } }, { ELM_STORE_ITEM_MAPPING_LABEL, - "elm.text", ELM_STORE_ITEM_MAPPING_OFFSET(My_Item, from), + "elm.text", ELM_STORE_ITEM_MAPPING_OFFSET(My_Item, head_content), { .empty = { EINA_TRUE } } }, @@ -917,7 +947,6 @@ static const Elm_Store_Item_Mapping it1_mapping[] = EINA_TRUE, EINA_FALSE, EINA_TRUE, EINA_FALSE, EINA_FALSE, - EINA_TRUE } } }, { ELM_STORE_ITEM_MAPPING_CUSTOM, @@ -985,7 +1014,6 @@ _st_store_fetch(void *data __UNUSED__, Elm_Store_Item *sti) f = fopen(path, "r"); if (!f) return; - DBG("parse %s\n", path); // alloc my item in memory that holds data to show in the list myit = calloc(1, sizeof(My_Item)); if (!myit) @@ -1054,7 +1082,8 @@ _st_store_fetch(void *data __UNUSED__, Elm_Store_Item *sti) } } fclose(f); - myit->head_content = content; + myit->head_content = elm_entry_utf8_to_markup(content); + free(content); elm_store_item_data_set(sti, myit); } // ************************************************************************ @@ -1096,7 +1125,7 @@ test_store(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info evas_object_show(bx); gl = elm_genlist_add(win); - elm_genlist_compress_mode_set(gl, EINA_TRUE); + elm_genlist_height_for_width_mode_set(gl, EINA_TRUE); evas_object_smart_callback_add(gl, "selected", _st_selected, NULL); evas_object_smart_callback_add(gl, "clicked", _st_clicked, NULL); evas_object_smart_callback_add(gl, "longpressed", _st_longpress, NULL); @@ -1105,8 +1134,6 @@ test_store(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info elm_box_pack_end(bx, gl); evas_object_show(gl); - itc1.item_style = "default"; // set up 1 item style to use - st = elm_store_filesystem_new(); elm_store_list_func_set(st, _st_store_list, NULL); elm_store_fetch_func_set(st, _st_store_fetch, NULL); diff --git a/legacy/elementary/src/lib/elm_genlist.c b/legacy/elementary/src/lib/elm_genlist.c index 7e47866b1f..be29903c0a 100644 --- a/legacy/elementary/src/lib/elm_genlist.c +++ b/legacy/elementary/src/lib/elm_genlist.c @@ -272,13 +272,16 @@ struct _Widget_Data Evas_Object *obj, *scr, *pan_smart; Eina_Inlist *items, *blocks; Pan *pan; - Evas_Coord pan_x, pan_y, w, h, minw, minh, realminw; + Evas_Coord pan_x, pan_y, w, h, minw, minh, realminw, prev_viewport_w; Ecore_Job *calc_job, *update_job; Ecore_Idler *queue_idler; + Ecore_Idler *must_recalc_idler; Eina_List *queue, *selected; Elm_Genlist_Item *show_item; Elm_Genlist_Item *last_selected_item; Eina_Inlist *item_cache; + Elm_Genlist_Item *anchor_item; + Evas_Coord anchor_y; Elm_List_Mode mode; Eina_Bool on_hold : 1; Eina_Bool multi : 1; @@ -318,6 +321,7 @@ struct _Item_Block Eina_Bool changed : 1; Eina_Bool updateme : 1; Eina_Bool showme : 1; + Eina_Bool must_recalc : 1; }; struct _Elm_Genlist_Item @@ -399,6 +403,7 @@ struct _Pan { Evas_Object_Smart_Clipped_Data __clipped_data; Widget_Data *wd; + Ecore_Job *resize_job; }; static const char *widtype = NULL; @@ -420,6 +425,7 @@ static Eina_Bool _item_single_select_down(Widget_Data *wd); static Eina_Bool _event_hook(Evas_Object *obj, Evas_Object *src, Evas_Callback_Type type, void *event_info); static Eina_Bool _deselect_all_items(Widget_Data *wd); +static void _pan_calculate(Evas_Object *obj); static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION; @@ -654,6 +660,7 @@ _del_hook(Evas_Object *obj) _item_cache_zero(wd); if (wd->calc_job) ecore_job_del(wd->calc_job); if (wd->update_job) ecore_job_del(wd->update_job); + if (wd->must_recalc_idler) ecore_idler_del(wd->must_recalc_idler); free(wd); } @@ -715,6 +722,25 @@ _sizing_eval(Evas_Object *obj) evas_object_size_hint_min_get(wd->scr, &minw, &minh); evas_object_size_hint_max_get(wd->scr, &maxw, &maxh); minh = -1; + //GGGG: + if (wd->height_for_width) + { + Evas_Coord vw, vh; + + elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh); + if ((vw != 0) && (vw != wd->prev_viewport_w)) + { + Item_Block *itb; + + wd->prev_viewport_w = vw; + EINA_INLIST_FOREACH(wd->blocks, itb) + { + itb->must_recalc = EINA_TRUE; + } + if (wd->calc_job) ecore_job_del(wd->calc_job); + wd->calc_job = ecore_job_add(_calc_job, wd); + } + } if (wd->mode == ELM_LIST_LIMIT) { Evas_Coord vmw, vmh, vw, vh; @@ -769,9 +795,9 @@ _item_block_del(Elm_Genlist_Item *it) il = EINA_INLIST_GET(itb); Item_Block *itbn = (Item_Block *)(il->next); if (it->parent) - it->parent->items = eina_list_remove(it->parent->items, it); + it->parent->items = eina_list_remove(it->parent->items, it); else - it->wd->blocks = eina_inlist_remove(it->wd->blocks, il); + it->wd->blocks = eina_inlist_remove(it->wd->blocks, il); free(itb); if (itbn) itbn->changed = EINA_TRUE; } @@ -823,6 +849,12 @@ _item_del(Elm_Genlist_Item *it) elm_widget_item_pre_notify_del(it); elm_genlist_item_subitems_clear(it); it->wd->walking -= it->walking; + if (it->wd->anchor_item == it) + { + it->wd->anchor_item = (Elm_Genlist_Item *)(EINA_INLIST_GET(it)->next); + if (!it->wd->anchor_item) + it->wd->anchor_item = (Elm_Genlist_Item *)(EINA_INLIST_GET(it)->prev); + } if (it->wd->show_item == it) it->wd->show_item = NULL; if (it->selected) it->wd->selected = eina_list_remove(it->wd->selected, it); if (it->realized) _item_unrealize(it); @@ -840,7 +872,7 @@ _item_del(Elm_Genlist_Item *it) if (it->tooltip.del_cb) it->tooltip.del_cb((void *)it->tooltip.data, it->base.widget, it); - + elm_widget_item_del(it); } @@ -1496,6 +1528,7 @@ _item_realize(Elm_Genlist_Item *it, int in, int calc) if (!it->display_only) elm_coords_finger_size_adjust(1, &mw, 1, &mh); + if (it->wd->height_for_width) mw = it->wd->prev_viewport_w; edje_object_size_min_restricted_calc(it->base.view, &mw, &mh, mw, mh); if (!it->display_only) elm_coords_finger_size_adjust(1, &mw, 1, &mh); @@ -1693,6 +1726,16 @@ _item_block_position(Item_Block *itb, int in) } } +static Eina_Bool +_must_recalc_idler(void *data) +{ + Widget_Data *wd = data; + if (wd->calc_job) ecore_job_del(wd->calc_job); + wd->calc_job = ecore_job_add(_calc_job, wd); + wd->must_recalc_idler = NULL; + return ECORE_CALLBACK_CANCEL; +} + static void _calc_job(void *data) { @@ -1702,13 +1745,17 @@ _calc_job(void *data) Item_Block *chb = NULL; int in = 0, minw_change = 0; Eina_Bool changed = EINA_FALSE; + double t0, t; + Eina_Bool did_must_recalc = EINA_FALSE; if (!wd) return; + //GGGG: + t0 = ecore_time_get(); evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &wd->h); if (wd->w != ow) { wd->w = ow; - if (wd->height_for_width) changed = EINA_TRUE; +// if (wd->height_for_width) changed = EINA_TRUE; } EINA_INLIST_FOREACH(wd->blocks, itb) @@ -1722,15 +1769,18 @@ _calc_job(void *data) { if (itb->realized) _item_block_unrealize(itb); } - if ((itb->changed) || (changed)) + if ((itb->changed) || (changed) || + ((itb->must_recalc) && (!did_must_recalc))) { - if (changed) + if ((changed) || (itb->must_recalc)) { Eina_List *l; Elm_Genlist_Item *it; EINA_LIST_FOREACH(itb->items, l, it) if (it->mincalcd) it->mincalcd = EINA_FALSE; itb->changed = EINA_TRUE; + if (itb->must_recalc) did_must_recalc = EINA_TRUE; + itb->must_recalc = EINA_FALSE; } if (itb->realized) _item_block_unrealize(itb); showme = _item_block_recalc(itb, in, 0, 1); @@ -1740,7 +1790,7 @@ _calc_job(void *data) itb->x = 0; minh += itb->minh; if (minw == -1) minw = itb->minw; - else if (minw < itb->minw) + else if ((!itb->must_recalc) && (minw < itb->minw)) { minw = itb->minw; minw_change = 1; @@ -1790,7 +1840,26 @@ _calc_job(void *data) wd->minh = minh; evas_object_smart_callback_call(wd->pan_smart, "changed", NULL); _sizing_eval(wd->obj); + //HHHH: + if ((wd->anchor_item) && (wd->anchor_item->block)) + { + Elm_Genlist_Item *it; + Evas_Coord it_y; + + it = wd->anchor_item; + it_y = wd->anchor_y; + elm_smart_scroller_child_pos_set(wd->scr, wd->pan_x, + it->block->y + it->y + it_y); + wd->anchor_item = it; + wd->anchor_y = it_y; + } } + t = ecore_time_get(); + if (did_must_recalc) + { + if (!wd->must_recalc_idler) + wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd); + } wd->calc_job = NULL; evas_object_smart_changed(wd->pan_smart); } @@ -1862,7 +1931,9 @@ _update_job(void *data) static void _pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y) { - Pan *sd = evas_object_smart_data_get(obj); + Pan *sd = evas_object_smart_data_get(obj); + Item_Block *itb; + // Evas_Coord ow, oh; // evas_object_geometry_get(obj, NULL, NULL, &ow, &oh); // ow = sd->wd->minw - ow; @@ -1873,10 +1944,31 @@ _pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y) // if (y < 0) y = 0; // if (x > ow) x = ow; // if (y > oh) y = oh; - if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return; - sd->wd->pan_x = x; - sd->wd->pan_y = y; - evas_object_smart_changed(obj); + if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return; + sd->wd->pan_x = x; + sd->wd->pan_y = y; + + EINA_INLIST_FOREACH(sd->wd->blocks, itb) + { + if ((itb->y + itb->h) > y) + { + Elm_Genlist_Item *it; + Eina_List *l2; + + EINA_LIST_FOREACH(itb->items, l2, it) + { + if ((itb->y + it->y) >= y) + { + //HHHH: + sd->wd->anchor_item = it; + sd->wd->anchor_y = -(itb->y + it->y - y); + goto done; + } + } + } + } +done: + evas_object_smart_changed(obj); } static void @@ -1933,9 +2025,22 @@ _pan_del(Evas_Object *obj) Pan *sd = evas_object_smart_data_get(obj); if (!sd) return; + if (sd->resize_job) + { + ecore_job_del(sd->resize_job); + sd->resize_job = NULL; + } _pan_sc.del(obj); } +static void +_pan_resize_job(void *data) +{ + Pan *sd = data; + _sizing_eval(sd->wd->obj); + sd->resize_job = NULL; +} + static void _pan_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) { @@ -1944,23 +2049,11 @@ _pan_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) evas_object_geometry_get(obj, NULL, NULL, &ow, &oh); if ((ow == w) && (oh == h)) return; -/* don't do this... use wd->compress mode - if (sd->wd->mode == ELM_LIST_COMPRESS) - { - Item_Block *itb; - // this is nasty - but no choice. have to mark all as not mincalced. - EINA_INLIST_FOREACH(sd->wd->blocks, itb) - { - Eina_List *l; - Elm_Genlist_Item *it; - - EINA_LIST_FOREACH(itb->items, l, it) - it->mincalcd = EINA_FALSE; - - itb->changed = EINA_TRUE; - } - } - */ + if ((sd->wd->height_for_width) && (ow != w)) + { + if (sd->resize_job) ecore_job_del(sd->resize_job); + sd->resize_job = ecore_job_add(_pan_resize_job, sd); + } if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job); sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd); } @@ -1984,7 +2077,7 @@ _pan_calculate(Evas_Object *obj) cvx, cvy, cvw, cvh)) { if ((!itb->realized) || (itb->changed)) - _item_block_realize(itb, in, 0); + _item_block_realize(itb, in, 0); _item_block_position(itb, in); } else @@ -2628,6 +2721,11 @@ elm_genlist_clear(Evas_Object *obj) ecore_idler_del(wd->queue_idler); wd->queue_idler = NULL; } + if (wd->must_recalc_idler) + { + ecore_idler_del(wd->must_recalc_idler); + wd->must_recalc_idler = NULL; + } if (wd->queue) { eina_list_free(wd->queue); diff --git a/legacy/elementary/src/lib/elm_widget.c b/legacy/elementary/src/lib/elm_widget.c index a1622accb8..c5eb513128 100644 --- a/legacy/elementary/src/lib/elm_widget.c +++ b/legacy/elementary/src/lib/elm_widget.c @@ -2486,7 +2486,6 @@ _if_focused_revert(Evas_Object *obj, Eina_Bool can_focus_only) newest = _newest_focus_order_get(top, &newest_focus_order, can_focus_only); if (newest) { - Smart_Data *sd2 = evas_object_smart_data_get(newest); elm_object_unfocus(newest); elm_object_focus(newest); }