summaryrefslogtreecommitdiff
path: root/src/lib/elementary
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2017-02-22 13:53:03 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2017-02-22 17:05:34 +0900
commit3f41cdf59b091644675f438a21cba5b69e9cdc8e (patch)
tree48d9b1c70ec31c2e34b9535413bb73d91d7f803f /src/lib/elementary
parentaa5414f95d37e285b4af5a5f080daf8f900b9e99 (diff)
genlist: Fix more tree issues (expanded state)
This fixes a lot of cases where a genlist node (of any type) with children may have appeared in the invalid expanded or contracted state. Before this patch, the test case "Genlist tree, Relative insert" looked like below (all items are programmatically added): > A > 1 > 2 > B > 3 > 4 The problem above is that A and B have visible children but still believe they are in contracted state. This patch ensures that A and B will be marked as expanded, but will do so without firing an "expanded" signal and definitely without the "expand,request" signal. After this patch, the test case will look like this: v A > 1 > 2 v B > 3 > 4 Which is more correct. Note that this test case does not handle any expand/contract signal. NOTE: This is a behaviour break!
Diffstat (limited to 'src/lib/elementary')
-rw-r--r--src/lib/elementary/elm_genlist.c97
-rw-r--r--src/lib/elementary/elm_widget_genlist.h2
2 files changed, 74 insertions, 25 deletions
diff --git a/src/lib/elementary/elm_genlist.c b/src/lib/elementary/elm_genlist.c
index e624afe96f..ebc2bc7d90 100644
--- a/src/lib/elementary/elm_genlist.c
+++ b/src/lib/elementary/elm_genlist.c
@@ -165,6 +165,8 @@ static Eina_Bool _item_filtered_get(Elm_Gen_Item *it);
165static void _elm_genlist_tree_effect_stop(Elm_Genlist_Data *sd); 165static void _elm_genlist_tree_effect_stop(Elm_Genlist_Data *sd);
166static Eina_Bool _elm_genlist_tree_effect_setup(Elm_Genlist_Data *sd); 166static Eina_Bool _elm_genlist_tree_effect_setup(Elm_Genlist_Data *sd);
167 167
168static void _item_expanded_set_noevent(Elm_Gen_Item *it, Eina_Bool expanded);
169
168static const Elm_Action key_actions[] = { 170static const Elm_Action key_actions[] = {
169 {"move", _key_action_move}, 171 {"move", _key_action_move},
170 {"select", _key_action_select}, 172 {"select", _key_action_select},
@@ -3610,8 +3612,12 @@ _item_block_del(Elm_Gen_Item *it)
3610 il = EINA_INLIST_GET(itb); 3612 il = EINA_INLIST_GET(itb);
3611 itbn = (Item_Block *)(il->next); 3613 itbn = (Item_Block *)(il->next);
3612 if (it->parent) 3614 if (it->parent)
3613 it->parent->item->items = 3615 {
3614 eina_list_remove(it->parent->item->items, EO_OBJ(it)); 3616 it->parent->item->items =
3617 eina_list_remove(it->parent->item->items, EO_OBJ(it));
3618 if (!it->parent->item->items)
3619 sd->top_level_parent_items--;
3620 }
3615 else 3621 else
3616 { 3622 {
3617 _item_block_position_update(il->next, itb->position); 3623 _item_block_position_update(il->next, itb->position);
@@ -3797,7 +3803,11 @@ _item_del(Elm_Gen_Item *it)
3797 if (sd->expanded_next_item == it) sd->expanded_next_item = NULL; 3803 if (sd->expanded_next_item == it) sd->expanded_next_item = NULL;
3798 if (sd->move_items) sd->move_items = eina_list_remove(sd->move_items, it); 3804 if (sd->move_items) sd->move_items = eina_list_remove(sd->move_items, it);
3799 if (it->parent) 3805 if (it->parent)
3800 it->parent->item->items = eina_list_remove(it->parent->item->items, EO_OBJ(it)); 3806 {
3807 it->parent->item->items = eina_list_remove(it->parent->item->items, EO_OBJ(it));
3808 if (!it->parent->item->items)
3809 sd->top_level_parent_items--;
3810 }
3801 ELM_SAFE_FREE(it->item->swipe_timer, ecore_timer_del); 3811 ELM_SAFE_FREE(it->item->swipe_timer, ecore_timer_del);
3802 _elm_genlist_item_del_serious(it); 3812 _elm_genlist_item_del_serious(it);
3803 3813
@@ -6252,6 +6262,8 @@ _elm_genlist_item_append(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, const Elm_Ge
6252 Eina_List *ll = _list_last_recursive(it->parent->item->items); 6262 Eina_List *ll = _list_last_recursive(it->parent->item->items);
6253 6263
6254 if (ll) eo_it2 = ll->data; 6264 if (ll) eo_it2 = ll->data;
6265 if (!it->parent->item->items)
6266 sd->top_level_parent_items++;
6255 it->parent->item->items = 6267 it->parent->item->items =
6256 eina_list_append(it->parent->item->items, EO_OBJ(it)); 6268 eina_list_append(it->parent->item->items, EO_OBJ(it));
6257 if (!eo_it2) eo_it2 = EO_OBJ(it->parent); 6269 if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
@@ -6264,6 +6276,7 @@ _elm_genlist_item_append(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, const Elm_Ge
6264 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2)); 6276 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
6265 it->item->rel = it2; 6277 it->item->rel = it2;
6266 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it); 6278 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
6279 _item_expanded_set_noevent(it->parent, EINA_TRUE);
6267 } 6280 }
6268 it->item->before = EINA_FALSE; 6281 it->item->before = EINA_FALSE;
6269 _item_queue(sd, it, NULL); 6282 _item_queue(sd, it, NULL);
@@ -6303,6 +6316,8 @@ _elm_genlist_item_prepend(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, const Elm_G
6303 Eina_List *ll = it->parent->item->items; 6316 Eina_List *ll = it->parent->item->items;
6304 6317
6305 if (ll) eo_it2 = ll->data; 6318 if (ll) eo_it2 = ll->data;
6319 if (!it->parent->item->items)
6320 sd->top_level_parent_items++;
6306 it->parent->item->items = 6321 it->parent->item->items =
6307 eina_list_prepend(it->parent->item->items, EO_OBJ(it)); 6322 eina_list_prepend(it->parent->item->items, EO_OBJ(it));
6308 if (!eo_it2) eo_it2 = EO_OBJ(it->parent); 6323 if (!eo_it2) eo_it2 = EO_OBJ(it->parent);
@@ -6311,6 +6326,7 @@ _elm_genlist_item_prepend(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, const Elm_G
6311 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2)); 6326 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(it2));
6312 it->item->rel = it2; 6327 it->item->rel = it2;
6313 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it); 6328 it2->item->rel_revs = eina_list_append(it2->item->rel_revs, it);
6329 _item_expanded_set_noevent(it->parent, EINA_TRUE);
6314 } 6330 }
6315 it->item->before = EINA_TRUE; 6331 it->item->before = EINA_TRUE;
6316 _item_queue(sd, it, NULL); 6332 _item_queue(sd, it, NULL);
@@ -6353,15 +6369,23 @@ _elm_genlist_item_insert_after(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, const
6353 } 6369 }
6354 else 6370 else
6355 { 6371 {
6372 if (!it->parent->item->items)
6373 sd->top_level_parent_items++;
6356 it->parent->item->items = 6374 it->parent->item->items =
6357 eina_list_append_relative(it->parent->item->items, EO_OBJ(it), eo_after); 6375 eina_list_append_relative(it->parent->item->items, EO_OBJ(it), eo_after);
6376 _item_expanded_set_noevent(it->parent, EINA_TRUE);
6358 } 6377 }
6359 6378
6360 if (after->item->items && after->item->expanded) 6379 if (after->item->items)
6361 { 6380 {
6362 eo_after = eina_list_last_data_get(after->item->items); 6381 Eina_List *ll = _list_last_recursive(after->item->items);
6363 after = efl_data_scope_get(eo_after, ELM_GENLIST_ITEM_CLASS); 6382 if (ll)
6383 {
6384 eo_after = ll->data;
6385 after = efl_data_scope_get(eo_after, ELM_GENLIST_ITEM_CLASS);
6386 }
6364 } 6387 }
6388
6365 sd->items = eina_inlist_append_relative 6389 sd->items = eina_inlist_append_relative
6366 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after)); 6390 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(after));
6367 6391
@@ -6408,8 +6432,11 @@ _elm_genlist_item_insert_before(Eo *obj, Elm_Genlist_Data *sd, const Elm_Genlist
6408 } 6432 }
6409 else 6433 else
6410 { 6434 {
6435 if (!it->parent->item->items)
6436 sd->top_level_parent_items++;
6411 it->parent->item->items = 6437 it->parent->item->items =
6412 eina_list_prepend_relative(it->parent->item->items, EO_OBJ(it), eo_before); 6438 eina_list_prepend_relative(it->parent->item->items, EO_OBJ(it), eo_before);
6439 _item_expanded_set_noevent(it->parent, EINA_TRUE);
6413 } 6440 }
6414 sd->items = eina_inlist_prepend_relative 6441 sd->items = eina_inlist_prepend_relative
6415 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before)); 6442 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(before));
@@ -6466,7 +6493,7 @@ _elm_genlist_item_sorted_insert(Eo *obj, Elm_Genlist_Data *sd, const Elm_Genlist
6466 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel)); 6493 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6467 it->item->before = EINA_TRUE; 6494 it->item->before = EINA_TRUE;
6468 } 6495 }
6469 else if (cmp_result < 0) 6496 else // if (cmp_result < 0)
6470 { 6497 {
6471 it->parent->item->items = eina_list_append_relative_list 6498 it->parent->item->items = eina_list_append_relative_list
6472 (it->parent->item->items, eo_it, l); 6499 (it->parent->item->items, eo_it, l);
@@ -6482,6 +6509,7 @@ _elm_genlist_item_sorted_insert(Eo *obj, Elm_Genlist_Data *sd, const Elm_Genlist
6482 } 6509 }
6483 else 6510 else
6484 { 6511 {
6512 // parent had no child
6485 rel = it->parent; 6513 rel = it->parent;
6486 6514
6487 it->parent->item->items = eina_list_prepend 6515 it->parent->item->items = eina_list_prepend
@@ -6489,15 +6517,17 @@ _elm_genlist_item_sorted_insert(Eo *obj, Elm_Genlist_Data *sd, const Elm_Genlist
6489 sd->items = eina_inlist_append_relative 6517 sd->items = eina_inlist_append_relative
6490 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel)); 6518 (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(rel));
6491 it->item->before = EINA_FALSE; 6519 it->item->before = EINA_FALSE;
6492 it->parent->item->expanded = EINA_TRUE; 6520 sd->top_level_parent_items++;
6493 } 6521 }
6494 6522
6495 sd->has_tree_items = EINA_TRUE;
6496 ELM_SAFE_FREE(sd->state, eina_inlist_sorted_state_free); 6523 ELM_SAFE_FREE(sd->state, eina_inlist_sorted_state_free);
6524
6525 // ensure expanded state is on
6526 _item_expanded_set_noevent(it->parent, EINA_TRUE);
6497 } 6527 }
6498 else 6528 else
6499 { 6529 {
6500 if (!sd->state && !sd->has_tree_items) 6530 if (!sd->state && !sd->top_level_parent_items)
6501 { 6531 {
6502 sd->state = eina_inlist_sorted_state_new(); 6532 sd->state = eina_inlist_sorted_state_new();
6503 eina_inlist_sorted_state_init(sd->state, sd->items); 6533 eina_inlist_sorted_state_init(sd->state, sd->items);
@@ -6507,8 +6537,7 @@ _elm_genlist_item_sorted_insert(Eo *obj, Elm_Genlist_Data *sd, const Elm_Genlist
6507 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP) 6537 if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
6508 sd->group_items = eina_list_append(sd->group_items, it); 6538 sd->group_items = eina_list_append(sd->group_items, it);
6509 6539
6510 if (!sd->items) sd->has_tree_items = EINA_FALSE; 6540 if (!sd->top_level_parent_items)
6511 if (!sd->has_tree_items)
6512 { 6541 {
6513 sd->items = eina_inlist_sorted_state_insert 6542 sd->items = eina_inlist_sorted_state_insert
6514 (sd->items, EINA_INLIST_GET(it), _elm_genlist_item_compare, 6543 (sd->items, EINA_INLIST_GET(it), _elm_genlist_item_compare,
@@ -6536,10 +6565,14 @@ _elm_genlist_item_sorted_insert(Eo *obj, Elm_Genlist_Data *sd, const Elm_Genlist
6536 cmp = comp(EO_OBJ(it), EO_OBJ(rel)); 6565 cmp = comp(EO_OBJ(it), EO_OBJ(rel));
6537 if (cmp < 0) break; 6566 if (cmp < 0) break;
6538 prev_rel = rel; 6567 prev_rel = rel;
6539 if (rel->item->items && rel->item->expanded) 6568 if (rel->item->items)
6540 { 6569 {
6541 eo_rel = eina_list_last_data_get(rel->item->items); 6570 Eina_List *ll = _list_last_recursive(rel->item->items);
6542 rel = efl_data_scope_get(eo_rel, ELM_GENLIST_ITEM_CLASS); 6571 if (ll)
6572 {
6573 eo_rel = ll->data;
6574 rel = efl_data_scope_get(eo_rel, ELM_GENLIST_ITEM_CLASS);
6575 }
6543 } 6576 }
6544 if (!EINA_INLIST_GET(rel)->next) 6577 if (!EINA_INLIST_GET(rel)->next)
6545 { 6578 {
@@ -6908,7 +6941,7 @@ _elm_genlist_expanded_next_item_get(Elm_Gen_Item *it)
6908} 6941}
6909 6942
6910static void 6943static void
6911_elm_genlist_move_items_set(Elm_Gen_Item *it) 6944_elm_genlist_move_items_set(Elm_Gen_Item *it, Eina_Bool expanded)
6912{ 6945{
6913 Eina_List *l, *ll; 6946 Eina_List *l, *ll;
6914 Elm_Gen_Item *it2 = NULL; 6947 Elm_Gen_Item *it2 = NULL;
@@ -6918,7 +6951,7 @@ _elm_genlist_move_items_set(Elm_Gen_Item *it)
6918 sd->expanded_next_item = 6951 sd->expanded_next_item =
6919 _elm_genlist_expanded_next_item_get(it); 6952 _elm_genlist_expanded_next_item_get(it);
6920 6953
6921 if (it->item->expanded) 6954 if (expanded)
6922 { 6955 {
6923 Elm_Object_Item *eo_item; 6956 Elm_Object_Item *eo_item;
6924 l = elm_genlist_realized_items_get((sd)->obj); 6957 l = elm_genlist_realized_items_get((sd)->obj);
@@ -6971,6 +7004,25 @@ _event_block_rect_update(const Evas_Object *obj)
6971 evas_object_move(sd->event_block_rect, ox, oy); 7004 evas_object_move(sd->event_block_rect, ox, oy);
6972} 7005}
6973 7006
7007static void
7008_item_expanded_set_noevent(Elm_Gen_Item *it, Eina_Bool expanded)
7009{
7010 EINA_SAFETY_ON_NULL_RETURN(it);
7011
7012 if (it->item->expanded == expanded) return;
7013 it->item->expanded = expanded;
7014 if (expanded)
7015 {
7016 if (it->realized)
7017 edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
7018 }
7019 else
7020 {
7021 if (it->realized)
7022 edje_object_signal_emit(VIEW(it), SIGNAL_CONTRACTED, "elm");
7023 }
7024}
7025
6974EOLIAN static void 7026EOLIAN static void
6975_elm_genlist_item_expanded_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool expanded) 7027_elm_genlist_item_expanded_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_Bool expanded)
6976{ 7028{
@@ -6980,18 +7032,16 @@ _elm_genlist_item_expanded_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_B
6980 expanded = !!expanded; 7032 expanded = !!expanded;
6981 if (it->item->expanded == expanded) return; 7033 if (it->item->expanded == expanded) return;
6982 if (it->item->type != ELM_GENLIST_ITEM_TREE) return; 7034 if (it->item->type != ELM_GENLIST_ITEM_TREE) return;
6983 it->item->expanded = expanded;
6984 sd->expanded_item = it; 7035 sd->expanded_item = it;
6985 _elm_genlist_move_items_set(it); 7036 _elm_genlist_move_items_set(it, expanded);
6986 7037
6987 if (sd->tree_effect_enabled) 7038 if (sd->tree_effect_enabled)
6988 _event_block_rect_update(WIDGET(it)); 7039 _event_block_rect_update(WIDGET(it));
6989 7040
6990 if (it->item->expanded) 7041 if (expanded)
6991 { 7042 {
6992 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_EXPAND; 7043 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_EXPAND;
6993 if (it->realized) 7044 _item_expanded_set_noevent(it, EINA_TRUE);
6994 edje_object_signal_emit(VIEW(it), SIGNAL_EXPANDED, "elm");
6995 efl_event_callback_legacy_call 7045 efl_event_callback_legacy_call
6996 (WIDGET(it), ELM_GENLIST_EVENT_EXPANDED, EO_OBJ(it)); 7046 (WIDGET(it), ELM_GENLIST_EVENT_EXPANDED, EO_OBJ(it));
6997 sd->auto_scroll_enabled = EINA_TRUE; 7047 sd->auto_scroll_enabled = EINA_TRUE;
@@ -7001,8 +7051,7 @@ _elm_genlist_item_expanded_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Eina_B
7001 else 7051 else
7002 { 7052 {
7003 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_CONTRACT; 7053 sd->move_effect_mode = ELM_GENLIST_TREE_EFFECT_CONTRACT;
7004 if (it->realized) 7054 _item_expanded_set_noevent(it, EINA_FALSE);
7005 edje_object_signal_emit(VIEW(it), SIGNAL_CONTRACTED, "elm");
7006 efl_event_callback_legacy_call 7055 efl_event_callback_legacy_call
7007 (WIDGET(it), ELM_GENLIST_EVENT_CONTRACTED, EO_OBJ(it)); 7056 (WIDGET(it), ELM_GENLIST_EVENT_CONTRACTED, EO_OBJ(it));
7008 sd->auto_scroll_enabled = EINA_FALSE; 7057 sd->auto_scroll_enabled = EINA_FALSE;
diff --git a/src/lib/elementary/elm_widget_genlist.h b/src/lib/elementary/elm_widget_genlist.h
index fbc9695673..b913da3ca3 100644
--- a/src/lib/elementary/elm_widget_genlist.h
+++ b/src/lib/elementary/elm_widget_genlist.h
@@ -145,6 +145,7 @@ struct _Elm_Genlist_Data
145 void *filter_data; 145 void *filter_data;
146 unsigned int processed_count; 146 unsigned int processed_count;
147 unsigned int filtered_count; 147 unsigned int filtered_count;
148 unsigned int top_level_parent_items;
148 Ecore_Idle_Enterer *queue_filter_enterer; 149 Ecore_Idle_Enterer *queue_filter_enterer;
149 Eina_Hash *size_caches; 150 Eina_Hash *size_caches;
150 151
@@ -200,7 +201,6 @@ struct _Elm_Genlist_Data
200 Eina_Bool item_looping_on : 1; 201 Eina_Bool item_looping_on : 1;
201 202
202 Eina_Bool tree_effect_animator : 1; 203 Eina_Bool tree_effect_animator : 1;
203 Eina_Bool has_tree_items : 1; // FIXME: count up & down
204}; 204};
205 205
206typedef struct _Item_Block Item_Block; 206typedef struct _Item_Block Item_Block;