summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Hollerbach <mail@marcel-hollerbach.de>2019-09-03 10:12:19 +0200
committerMarcel Hollerbach <mail@marcel-hollerbach.de>2019-09-10 10:08:09 +0200
commit18d86cd803558831b419a00cac6c2de7584e1470 (patch)
tree99a8fcd047d9316dadf863820b4a95508b65bbbc
parentb02d3a5b219f16979588b3438f0aa58ef28d7ef8 (diff)
collection view fixes
Co-authored-by: Mike Blumenkrantz <zmike@samsung.com>
-rw-r--r--src/lib/elementary/efl_ui_collection_view.c558
1 files changed, 418 insertions, 140 deletions
diff --git a/src/lib/elementary/efl_ui_collection_view.c b/src/lib/elementary/efl_ui_collection_view.c
index 731a4e2431..95cec93a0e 100644
--- a/src/lib/elementary/efl_ui_collection_view.c
+++ b/src/lib/elementary/efl_ui_collection_view.c
@@ -51,6 +51,8 @@ struct _Efl_Ui_Collection_Request
51 uint64_t length; 51 uint64_t length;
52 52
53 Eina_Bool model_requested : 1; 53 Eina_Bool model_requested : 1;
54 Eina_Bool model_fetched : 1;
55 Eina_Bool need_entity : 1;
54 Eina_Bool entity_requested : 1; 56 Eina_Bool entity_requested : 1;
55}; 57};
56 58
@@ -63,7 +65,7 @@ struct _Efl_Ui_Collection_View_Data
63 Efl_Gfx_Entity *sizer; 65 Efl_Gfx_Entity *sizer;
64 Efl_Model *model; 66 Efl_Model *model;
65 67
66 Efl_Ui_Collection_Viewport *viewport[3]; 68 //Efl_Ui_Collection_Viewport *viewport[3];
67 Eina_Rbtree *cache; 69 Eina_Rbtree *cache;
68 70
69 Eina_List *requests; // Array of Efl_Ui_Collection_Request in progress 71 Eina_List *requests; // Array of Efl_Ui_Collection_Request in progress
@@ -81,6 +83,8 @@ struct _Efl_Ui_Collection_View_Data
81 Eina_Bool w : 1; 83 Eina_Bool w : 1;
82 Eina_Bool h : 1; 84 Eina_Bool h : 1;
83 } match_content; 85 } match_content;
86
87 Efl_Ui_Position_Manager_Request_Range current_range, running_range;
84}; 88};
85 89
86struct _Efl_Ui_Collection_View_Focus_Manager_Data 90struct _Efl_Ui_Collection_View_Focus_Manager_Data
@@ -96,6 +100,8 @@ static const char *COLLECTION_VIEW_MANAGED_YES = "yes";
96#define MY_DATA_GET(obj, pd) \ 100#define MY_DATA_GET(obj, pd) \
97 Efl_Ui_Collection_View_Data *pd = efl_data_scope_get(obj, MY_CLASS); 101 Efl_Ui_Collection_View_Data *pd = efl_data_scope_get(obj, MY_CLASS);
98 102
103static void _entity_request(Efl_Ui_Collection_View *obj, Efl_Ui_Collection_Request *request);
104
99static int 105static int
100_cache_tree_lookup(const Eina_Rbtree *node, const void *key, 106_cache_tree_lookup(const Eina_Rbtree *node, const void *key,
101 int length EINA_UNUSED, void *data EINA_UNUSED) 107 int length EINA_UNUSED, void *data EINA_UNUSED)
@@ -103,7 +109,11 @@ _cache_tree_lookup(const Eina_Rbtree *node, const void *key,
103 const Efl_Ui_Collection_Item_Lookup *n = (Efl_Ui_Collection_Item_Lookup *)node; 109 const Efl_Ui_Collection_Item_Lookup *n = (Efl_Ui_Collection_Item_Lookup *)node;
104 const uint64_t *index = key; 110 const uint64_t *index = key;
105 111
106 return n->index - *index; 112 if (n->index > *index)
113 return 1;
114 if (n->index < *index)
115 return -1;
116 return 0;
107} 117}
108 118
109static Eina_Rbtree_Direction 119static Eina_Rbtree_Direction
@@ -150,10 +160,10 @@ _all_cleanup(Efl_Ui_Collection_View_Data *pd)
150{ 160{
151 Efl_Ui_Collection_Request *request; 161 Efl_Ui_Collection_Request *request;
152 Eina_List *l, *ll; 162 Eina_List *l, *ll;
153 unsigned int i; 163 //unsigned int i;
154 164
155 _cache_cleanup(pd); 165 _cache_cleanup(pd);
156 for (i = 0; i < 3; i++) 166 /*for (i = 0; i < 3; i++)
157 { 167 {
158 unsigned int j; 168 unsigned int j;
159 169
@@ -161,7 +171,7 @@ _all_cleanup(Efl_Ui_Collection_View_Data *pd)
161 171
162 for (j = 0; j < pd->viewport[i]->count; j++) 172 for (j = 0; j < pd->viewport[i]->count; j++)
163 _item_cleanup(pd->factory, &(pd->viewport[i]->items[j])); 173 _item_cleanup(pd->factory, &(pd->viewport[i]->items[j]));
164 } 174 }*/
165 175
166 EINA_LIST_FOREACH_SAFE(pd->requests, l, ll, request) 176 EINA_LIST_FOREACH_SAFE(pd->requests, l, ll, request)
167 eina_future_cancel(request->f); 177 eina_future_cancel(request->f);
@@ -173,6 +183,8 @@ _size_from_model(Efl_Model *model, Eina_Size2D *r, const char *width, const char
173 Eina_Value *vw, *vh; 183 Eina_Value *vw, *vh;
174 Eina_Bool success = EINA_FALSE; 184 Eina_Bool success = EINA_FALSE;
175 185
186 EINA_SAFETY_ON_NULL_RETURN_VAL(model, EINA_FALSE);
187
176 vw = efl_model_property_get(model, width); 188 vw = efl_model_property_get(model, width);
177 vh = efl_model_property_get(model, height); 189 vh = efl_model_property_get(model, height);
178 190
@@ -218,12 +230,13 @@ _request_add(Eina_List *requests, Efl_Ui_Collection_Request **request,
218 230
219 if ((*request)->offset + (*request)->length == index) 231 if ((*request)->offset + (*request)->length == index)
220 { 232 {
221 if (need_entity) (*request)->entity_requested = EINA_TRUE; 233 if (need_entity) (*request)->need_entity = EINA_TRUE;
222 (*request)->length += 1; 234 (*request)->length += 1;
235 if ((*request)->length < 1) CRI("ACK");
223 return requests; 236 return requests;
224 } 237 }
225 238
226 requests = eina_list_append(requests, request); 239 requests = eina_list_append(requests, *request);
227 240
228 create: 241 create:
229 *request = calloc(1, sizeof (Efl_Ui_Collection_Request)); 242 *request = calloc(1, sizeof (Efl_Ui_Collection_Request));
@@ -232,7 +245,8 @@ _request_add(Eina_List *requests, Efl_Ui_Collection_Request **request,
232 (*request)->length = 1; 245 (*request)->length = 1;
233 // At this point, we rely on the model caching ability to avoid recreating model 246 // At this point, we rely on the model caching ability to avoid recreating model
234 (*request)->model_requested = EINA_TRUE; 247 (*request)->model_requested = EINA_TRUE;
235 (*request)->entity_requested = !!need_entity; 248 printf("MODEL REQ(%lu) %d\n", index, __LINE__);
249 (*request)->need_entity = !!need_entity;
236 250
237 return requests; 251 return requests;
238} 252}
@@ -244,13 +258,14 @@ _model_fetched_cb(Eo *obj, void *data, const Eina_Value v)
244 Efl_Ui_Collection_Request *request = data; 258 Efl_Ui_Collection_Request *request = data;
245 Efl_Model *child; 259 Efl_Model *child;
246 unsigned int i, len; 260 unsigned int i, len;
247 261printf("MODEL FETCHED %d -> %d\n", request->offset, request->length);
262 request->model_fetched = EINA_TRUE;
248 EINA_VALUE_ARRAY_FOREACH(&v, len, i, child) 263 EINA_VALUE_ARRAY_FOREACH(&v, len, i, child)
249 { 264 {
250 Efl_Ui_Collection_Item_Lookup *insert; 265 Efl_Ui_Collection_Item_Lookup *insert;
251 unsigned int v; 266 //unsigned int v;
252 267
253 for (v = 0; v < 3; ++v) 268 /*for (v = 0; v < 3; ++v)
254 { 269 {
255 if (!pd->viewport[v]) continue; 270 if (!pd->viewport[v]) continue;
256 271
@@ -259,22 +274,44 @@ _model_fetched_cb(Eo *obj, void *data, const Eina_Value v)
259 { 274 {
260 uint64_t index = request->offset + i - pd->viewport[v]->offset; 275 uint64_t index = request->offset + i - pd->viewport[v]->offset;
261 276
277if (!index)
278 printf("MODEL SET %d\n", v);
262 efl_replace(&pd->viewport[v]->items[index].model, child); 279 efl_replace(&pd->viewport[v]->items[index].model, child);
263 child = NULL; 280 child = NULL;
264 break; 281 break;
265 } 282 }
266 } 283 }*/
267 284
268 // When requesting a model, it should not be in the cache prior to the request 285 // When requesting a model, it should not be in the cache prior to the request
269 if (!child) continue; 286 if (!child) continue;
270 287
271 insert = calloc(1, sizeof (Efl_Ui_Collection_Item_Lookup)); 288 uint64_t search_index = request->offset + i;
272 if (!insert) continue;
273 289
274 insert->index = request->offset + i; 290 insert = (void*) eina_rbtree_inline_lookup(pd->cache, &search_index,
275 insert->item.model = efl_ref(child); 291 sizeof (search_index), _cache_tree_lookup,
292 NULL);
293 if (insert)
294 {
295 if (!insert->item.entity && request->need_entity)
296 {
297 //drop the old model here, overwrite with model + view
298 efl_unref(insert->item.model);
299 insert->item.model = efl_ref(child);
300 }
301 else
302 ERR("Inserting a model that was already fetched, dropping new model %d", search_index);
303
304 }
305 else
306 {
307 insert = calloc(1, sizeof (Efl_Ui_Collection_Item_Lookup));
308 if (!insert) continue;
309 insert->index = request->offset + i;
310 insert->item.model = efl_ref(child);
311 pd->cache = eina_rbtree_inline_insert(pd->cache, EINA_RBTREE_GET(insert), _cache_tree_cmp, NULL);
312 printf("INSERTING %lu\n", insert->index);
313 }
276 314
277 pd->cache = eina_rbtree_inline_insert(pd->cache, EINA_RBTREE_GET(insert), _cache_tree_cmp, NULL);
278 } 315 }
279 316
280 return v; 317 return v;
@@ -286,9 +323,16 @@ _model_free_cb(Eo *o, void *data, const Eina_Future *dead_future EINA_UNUSED)
286 MY_DATA_GET(o, pd); 323 MY_DATA_GET(o, pd);
287 Efl_Ui_Collection_Request *request = data; 324 Efl_Ui_Collection_Request *request = data;
288 325
289 if (request->entity_requested) return; 326 if (request->need_entity)
290 pd->requests = eina_list_remove(pd->requests, request); 327 {
291 free(request); 328 if (!request->entity_requested)
329 _entity_request(o, request);
330 }
331 else
332 {
333 pd->requests = eina_list_remove(pd->requests, request);
334 free(request);
335 }
292} 336}
293 337
294static Eina_Value 338static Eina_Value
@@ -319,13 +363,35 @@ _entity_propagate(Efl_Model *model, Efl_Gfx_Entity *entity)
319{ 363{
320 Eina_Size2D item_size; 364 Eina_Size2D item_size;
321 365
322 if (ITEM_SIZE_FROM_MODEL(model, item_size)) return EINA_FALSE; 366 if (!ITEM_SIZE_FROM_MODEL(model, item_size))
367 {
368 if (!ITEM_BASE_SIZE_FROM_MODEL(efl_parent_get(model), item_size))
369 return EINA_FALSE;
370 }
323 371
324 item_size = efl_gfx_hint_size_min_get(entity); 372 item_size = efl_gfx_hint_size_combined_min_get(entity);
325 _size_to_model(model, item_size); 373 _size_to_model(model, item_size);
326 return EINA_TRUE; 374 return EINA_TRUE;
327} 375}
328 376
377static void
378_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
379{
380 printf("DEL0 %p\n", obj);
381}
382
383static void
384_hide(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
385{
386 printf("HIDE0 %p\n", obj);
387}
388
389static void
390_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
391{
392 printf("SHOW0 %p\n", obj);
393}
394
329static Eina_Value 395static Eina_Value
330_entity_fetched_cb(Eo *obj, void *data, const Eina_Value v) 396_entity_fetched_cb(Eo *obj, void *data, const Eina_Value v)
331{ 397{
@@ -335,16 +401,26 @@ _entity_fetched_cb(Eo *obj, void *data, const Eina_Value v)
335 unsigned int i, len; 401 unsigned int i, len;
336 uint64_t updated_start_id; 402 uint64_t updated_start_id;
337 Eina_Bool updated = EINA_FALSE; 403 Eina_Bool updated = EINA_FALSE;
338 404printf("ENTITY FETCHED %d -> %d\n", request->offset, request->length);
339 EINA_VALUE_ARRAY_FOREACH(&v, len, i, child) 405 EINA_VALUE_ARRAY_FOREACH(&v, len, i, child)
340 { 406 {
341 Efl_Ui_Collection_Item_Lookup *lookup; 407 Efl_Ui_Collection_Item_Lookup *lookup;
342 uint64_t search_index; 408 uint64_t search_index;
343 unsigned int v; 409 //unsigned int v;
344 410
345 efl_key_data_set(child, COLLECTION_VIEW_MANAGED, COLLECTION_VIEW_MANAGED_YES); 411 efl_key_data_set(child, COLLECTION_VIEW_MANAGED, COLLECTION_VIEW_MANAGED_YES);
412 /* fix eventing in scroller by ensuring collection items are in the scroller hierarchy */
413 efl_canvas_group_member_add(pd->pan, child);
414 efl_gfx_entity_visible_set(child, EINA_FALSE);
415 if (request->offset + i == 0)
416 {
417 printf("NEW0 %p\n", child);
418 evas_object_event_callback_add(child, EVAS_CALLBACK_DEL, _del, NULL);
419 evas_object_event_callback_add(child, EVAS_CALLBACK_HIDE, _hide, NULL);
420 evas_object_event_callback_add(child, EVAS_CALLBACK_SHOW, _show, NULL);
421 }
346 422
347 for (v = 0; v < 3; ++v) 423/* for (v = 0; v < 3; ++v)
348 { 424 {
349 if (!pd->viewport[v]) continue; 425 if (!pd->viewport[v]) continue;
350 426
@@ -353,7 +429,20 @@ _entity_fetched_cb(Eo *obj, void *data, const Eina_Value v)
353 { 429 {
354 uint64_t index = request->offset + i - pd->viewport[v]->offset; 430 uint64_t index = request->offset + i - pd->viewport[v]->offset;
355 431
432 if (pd->viewport[v]->items[index].entity)
433 {
434 ERR("Entity already existing for id %d", i);
435 efl_unref(pd->viewport[v]->items[index].entity);
436 efl_del(pd->viewport[v]->items[index].entity);
437 pd->viewport[v]->items[index].entity = NULL;
438 }
439
356 efl_replace(&pd->viewport[v]->items[index].entity, child); 440 efl_replace(&pd->viewport[v]->items[index].entity, child);
441if (!pd->viewport[v]->items[index].model)
442 {
443 printf("OFFSET %u\n", pd->viewport[v]->offset);
444 CRI("ACK");
445 }
357 if (_entity_propagate(pd->viewport[v]->items[index].model, child)) 446 if (_entity_propagate(pd->viewport[v]->items[index].model, child))
358 { 447 {
359 if (!updated) 448 if (!updated)
@@ -375,7 +464,7 @@ _entity_fetched_cb(Eo *obj, void *data, const Eina_Value v)
375 child = NULL; 464 child = NULL;
376 break; 465 break;
377 } 466 }
378 } 467 }*/
379 468
380 // When requesting an entity, the model should already be in the cache 469 // When requesting an entity, the model should already be in the cache
381 if (!child) continue; 470 if (!child) continue;
@@ -386,7 +475,18 @@ _entity_fetched_cb(Eo *obj, void *data, const Eina_Value v)
386 sizeof (search_index), _cache_tree_lookup, 475 sizeof (search_index), _cache_tree_lookup,
387 NULL); 476 NULL);
388 477
389 if (!lookup) continue; 478 if (!lookup)
479 {
480 efl_ui_factory_release(pd->factory, child);
481 continue;
482 }
483 if (lookup->item.entity)
484 {
485 ERR("Entity already existing for id %lu", search_index);
486 efl_unref(lookup->item.entity);
487 efl_del(lookup->item.entity);
488 lookup->item.entity = NULL;
489 }
390 490
391 lookup->item.entity = efl_ref(child); 491 lookup->item.entity = efl_ref(child);
392 492
@@ -409,7 +509,14 @@ _entity_fetched_cb(Eo *obj, void *data, const Eina_Value v)
409 } 509 }
410 } 510 }
411 } 511 }
412 512 //flush out the update to the items, in case we have updated anything but not flushed yet.
513 if (updated)
514 {
515 efl_ui_position_manager_entity_item_size_changed(pd->manager,
516 updated_start_id,
517 i - 1);
518 updated = EINA_FALSE;
519 }
413 return v; 520 return v;
414} 521}
415 522
@@ -427,12 +534,12 @@ static Eina_List *
427_cache_size_fetch(Eina_List *requests, Efl_Ui_Collection_Request **request, 534_cache_size_fetch(Eina_List *requests, Efl_Ui_Collection_Request **request,
428 Efl_Ui_Collection_View_Data *pd, 535 Efl_Ui_Collection_View_Data *pd,
429 uint64_t search_index, 536 uint64_t search_index,
430 Efl_Ui_Position_Manager_Batch_Size_Access *target, 537 Efl_Ui_Position_Manager_Size_Batch_Entity *target,
431 Eina_Size2D item_base) 538 Eina_Size2D item_base)
432{ 539{
433 Efl_Ui_Collection_Item_Lookup *lookup; 540 Efl_Ui_Collection_Item_Lookup *lookup;
434 Efl_Model *model; 541 Efl_Model *model;
435 Eina_Size2D item_size; 542 Eina_Size2D item_size = item_base;
436 543
437 if (!pd->cache) goto not_found; 544 if (!pd->cache) goto not_found;
438 545
@@ -447,24 +554,26 @@ _cache_size_fetch(Eina_List *requests, Efl_Ui_Collection_Request **request,
447 // If we do not know the size 554 // If we do not know the size
448 if (!ITEM_SIZE_FROM_MODEL(model, item_size)) 555 if (!ITEM_SIZE_FROM_MODEL(model, item_size))
449 { 556 {
450 // But can calculate it now 557 item_size = efl_gfx_hint_size_combined_min_get(lookup->item.entity);
451 if (!lookup->item.entity) goto not_found; 558 if (item_size.h == 0 && item_size.w == 0)
452 559 ITEM_BASE_SIZE_FROM_MODEL(pd->model, item_size);
453 item_size = efl_gfx_hint_size_min_get(lookup->item.entity); 560 else
454 _size_to_model(model, item_size); 561 _size_to_model(model, item_size);
455 } 562 }
456 563
457 target->size = item_size; 564 target->size = item_size;
458 target->group = EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_NO_GROUP; 565 target->element_depth = 0;
459 566 target->depth_leader = EINA_FALSE;
567 if (!item_size.w || !item_size.h) ERR("NULL SIZE ENT");
460 return requests; 568 return requests;
461 569
462 not_found: 570 not_found:
463 requests = _request_add(requests, request, search_index, EINA_FALSE); 571 requests = _request_add(requests, request, search_index, EINA_FALSE);
464 572
465 target->size = item_base; 573 target->size = item_size;
466 target->group = EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_NO_GROUP; 574 target->element_depth = 0;
467 575 target->depth_leader = EINA_FALSE;
576 if (!item_size.w || !item_size.h) ERR("NULL SIZE ENT");
468 return requests; 577 return requests;
469} 578}
470 579
@@ -472,7 +581,7 @@ static Eina_List *
472_cache_entity_fetch(Eina_List *requests, Efl_Ui_Collection_Request **request, 581_cache_entity_fetch(Eina_List *requests, Efl_Ui_Collection_Request **request,
473 Efl_Ui_Collection_View_Data *pd, 582 Efl_Ui_Collection_View_Data *pd,
474 uint64_t search_index, 583 uint64_t search_index,
475 Efl_Ui_Position_Manager_Batch_Entity_Access *target) 584 Efl_Ui_Position_Manager_Object_Batch_Entity *target)
476{ 585{
477 Efl_Ui_Collection_Item_Lookup *lookup; 586 Efl_Ui_Collection_Item_Lookup *lookup;
478 587
@@ -485,15 +594,18 @@ _cache_entity_fetch(Eina_List *requests, Efl_Ui_Collection_Request **request,
485 if (!lookup->item.entity) goto not_found; 594 if (!lookup->item.entity) goto not_found;
486 595
487 target->entity = lookup->item.entity; 596 target->entity = lookup->item.entity;
488 target->group = EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_NO_GROUP; 597 target->element_depth = 0;
598 target->depth_leader = EINA_FALSE;
489 599
490 return requests; 600 return requests;
491 601
492 not_found: 602 not_found:
603// printf("LINE %d\n", __LINE__);
493 requests = _request_add(requests, request, search_index, EINA_TRUE); 604 requests = _request_add(requests, request, search_index, EINA_TRUE);
494 605
495 target->entity = NULL; 606 target->entity = NULL;
496 target->group = EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_NO_GROUP; 607 target->element_depth = 0;
608 target->depth_leader = EINA_FALSE;
497 609
498 return requests; 610 return requests;
499} 611}
@@ -501,6 +613,8 @@ _cache_entity_fetch(Eina_List *requests, Efl_Ui_Collection_Request **request,
501static void 613static void
502_entity_request(Efl_Ui_Collection_View *obj, Efl_Ui_Collection_Request *request) 614_entity_request(Efl_Ui_Collection_View *obj, Efl_Ui_Collection_Request *request)
503{ 615{
616 if (request->model_requested && (!request->model_fetched)) return;
617 printf("ENTITY REQ %d -> %d\n", request->offset, request->length);
504 request->f = efl_future_then(obj, request->f, 618 request->f = efl_future_then(obj, request->f,
505 .success_type = EINA_VALUE_TYPE_ARRAY, 619 .success_type = EINA_VALUE_TYPE_ARRAY,
506 .success = _entity_fetch_cb); 620 .success = _entity_fetch_cb);
@@ -509,6 +623,7 @@ _entity_request(Efl_Ui_Collection_View *obj, Efl_Ui_Collection_Request *request)
509 .success = _entity_fetched_cb, 623 .success = _entity_fetched_cb,
510 .data = request, 624 .data = request,
511 .free = _entity_free_cb); 625 .free = _entity_free_cb);
626 request->entity_requested = EINA_TRUE;
512} 627}
513 628
514static inline void 629static inline void
@@ -516,11 +631,10 @@ _entity_inflight_request(Efl_Ui_Collection_View *obj,
516 Efl_Ui_Collection_Request *request, 631 Efl_Ui_Collection_Request *request,
517 Efl_Ui_Collection_Request *inflight) 632 Efl_Ui_Collection_Request *inflight)
518{ 633{
519 if (request->entity_requested == EINA_FALSE) return ; 634 if (request->need_entity == EINA_FALSE) return ;
520 if (request->entity_requested == inflight->entity_requested) return ; 635 if (inflight->entity_requested) return ;
521 636
522 _entity_request(obj, inflight); 637 _entity_request(obj, inflight);
523 inflight->entity_requested = EINA_TRUE;
524} 638}
525 639
526static Eina_List * 640static Eina_List *
@@ -529,14 +643,16 @@ _batch_request_flush(Eina_List *requests,
529 Efl_Ui_Collection_View_Data *pd) 643 Efl_Ui_Collection_View_Data *pd)
530{ 644{
531 Efl_Ui_Collection_Request *request; 645 Efl_Ui_Collection_Request *request;
646 Eina_List *ll, *next_list_item;
532 647
533 EINA_LIST_FREE(requests, request) 648 EINA_LIST_FOREACH_SAFE(requests, ll, next_list_item, request)
534 { 649 {
535 // Check request intersection with all pending request 650 // Check request intersection with all pending request
536 Efl_Ui_Collection_Request *inflight; 651 Efl_Ui_Collection_Request *inflight;
537 Efl_Model *model; 652 Efl_Model *model;
538 Eina_List *l; 653 Eina_List *l;
539 654
655if (request->length < 1) CRI("ACK");
540 EINA_LIST_FOREACH(pd->requests, l, inflight) 656 EINA_LIST_FOREACH(pd->requests, l, inflight)
541 { 657 {
542 uint64_t istart = inflight->offset; 658 uint64_t istart = inflight->offset;
@@ -550,11 +666,12 @@ _batch_request_flush(Eina_List *requests,
550 if (rstart >= iend) continue; 666 if (rstart >= iend) continue;
551 667
552 // request included in current inflight request 668 // request included in current inflight request
553 if (rstart >= istart && rend < iend) 669 if (rstart >= istart && rend <= iend)
554 { 670 {
555 _entity_inflight_request(obj, request, inflight); 671 _entity_inflight_request(obj, request, inflight);
556 672
557 // In this case no need to start a request 673 // In this case no need to start a request
674 requests = eina_list_remove_list(requests, ll);
558 free(request); 675 free(request);
559 request = NULL; 676 request = NULL;
560 break; 677 break;
@@ -571,30 +688,34 @@ _batch_request_flush(Eina_List *requests,
571 688
572 rn->offset = iend; 689 rn->offset = iend;
573 rn->length = rend - iend; 690 rn->length = rend - iend;
691 if (rn->length < 1) CRI("ACK");
574 rn->model_requested = request->model_requested; 692 rn->model_requested = request->model_requested;
575 rn->entity_requested = request->entity_requested; 693 printf("MODEL REQ(%lu) %d\n", rn->offset, __LINE__);
694 rn->need_entity = request->need_entity;
576 695
577 requests = eina_list_append(requests, rn); 696 requests = eina_list_append(requests, rn);
578 697
579 request->length = istart - rstart; 698 request->length = istart - rstart;
699 if (request->length < 1) CRI("ACK");
580 _entity_inflight_request(obj, request, inflight); 700 _entity_inflight_request(obj, request, inflight);
581
582 continue; 701 continue;
583 } 702 }
584 703
585 // request overflow left 704 // request overflow left
586 if (rstart < istart && iend > istart && rend < iend) 705 if (rstart < istart && rend > istart && rend <= iend)
587 { 706 {
588 request->length = istart - rstart; 707 request->length = istart - rstart;
708 if (request->length < 1) CRI("ACK");
589 _entity_inflight_request(obj, request, inflight); 709 _entity_inflight_request(obj, request, inflight);
590 continue; 710 continue;
591 } 711 }
592 712
593 // request overflow right 713 // request overflow right
594 if (rstart >= istart && rstart < rend && iend < rend) 714 if (rstart >= istart && rstart < iend && iend <= rend)
595 { 715 {
596 request->offset = iend; 716 request->offset = iend;
597 request->length = rend - iend; 717 request->length = rend - iend;
718 if (request->length < 1) CRI("ACK");
598 _entity_inflight_request(obj, request, inflight); 719 _entity_inflight_request(obj, request, inflight);
599 continue; 720 continue;
600 } 721 }
@@ -606,12 +727,14 @@ _batch_request_flush(Eina_List *requests,
606 // Are we ready yet 727 // Are we ready yet
607 if (!model) 728 if (!model)
608 { 729 {
730 requests = eina_list_remove_list(requests, ll);
609 free(request); 731 free(request);
610 continue; 732 continue;
611 } 733 }
612 // Is the request inside the limit of the model? 734 // Is the request inside the limit of the model?
613 if (request->offset >= efl_model_children_count_get(model)) 735 if (request->offset >= efl_model_children_count_get(model))
614 { 736 {
737 requests = eina_list_remove_list(requests, ll);
615 free(request); 738 free(request);
616 continue; 739 continue;
617 } 740 }
@@ -619,38 +742,37 @@ _batch_request_flush(Eina_List *requests,
619 if (request->offset + request->length >= efl_model_children_count_get(model)) 742 if (request->offset + request->length >= efl_model_children_count_get(model))
620 { 743 {
621 request->length = efl_model_children_count_get(model) - request->offset; 744 request->length = efl_model_children_count_get(model) - request->offset;
745 if (request->length < 1) CRI("ACK");
622 } 746 }
747 if (!request->length) CRI("ACK");
623 748
624 // We now have a request, time to trigger a fetch 749 // We now have a request, time to trigger a fetch
625 // We assume here that we are always fetching the model (model_requested must be true) 750 // We assume here that we are always fetching the model (model_requested must be true)
626 if (!request->model_requested) 751 if (!request->model_requested)
627 { 752 {
628 ERR("Someone forgot to set model_requested for %lu to %lu.", 753 CRI("Someone forgot to set model_requested for %lu to %lu.",
629 request->offset, request->offset + request->length); 754 request->offset, request->offset + request->length);
630 request->model_requested = EINA_TRUE; 755 request->model_requested = EINA_TRUE;
631 } 756 }
757 printf("MODEL REQ FLUSH %lu -> %lu\n", request->offset, request->length);
632 request->f = efl_model_children_slice_get(model, request->offset, request->length); 758 request->f = efl_model_children_slice_get(model, request->offset, request->length);
633 request->f = efl_future_then(obj, request->f, 759 request->f = efl_future_then(obj, request->f,
634 .success = _model_fetched_cb, 760 .success = _model_fetched_cb,
635 .data = request, 761 .data = request,
636 .free = _model_free_cb); 762 .free = _model_free_cb);
637 763
638 if (request->entity_requested) 764 eina_list_move_list(&pd->requests, &requests, ll);
639 _entity_request(obj, request);
640
641 pd->requests = eina_list_append(pd->requests, request);
642 } 765 }
643
644 return NULL; 766 return NULL;
645} 767}
646 768
647static Efl_Ui_Position_Manager_Batch_Result 769static Efl_Ui_Position_Manager_Size_Batch_Result
648_batch_size_cb(void *data, int start_id, Eina_Rw_Slice memory) 770_batch_size_cb(void *data, Efl_Ui_Position_Manager_Size_Call_Config conf, Eina_Rw_Slice memory)
649{ 771{
650 MY_DATA_GET(data, pd); 772 MY_DATA_GET(data, pd);
651 Efl_Ui_Position_Manager_Batch_Size_Access *sizes; 773 Efl_Ui_Position_Manager_Size_Batch_Entity *sizes;
652 Efl_Ui_Collection_Request *request = NULL; 774 Efl_Ui_Collection_Request *request = NULL;
653 Efl_Ui_Position_Manager_Batch_Result result = {-1, 0}; 775 Efl_Ui_Position_Manager_Size_Batch_Result result = {0};
654 Efl_Model *parent; 776 Efl_Model *parent;
655 Eina_List *requests = NULL; 777 Eina_List *requests = NULL;
656 Eina_Size2D item_base; 778 Eina_Size2D item_base;
@@ -668,18 +790,19 @@ _batch_size_cb(void *data, int start_id, Eina_Rw_Slice memory)
668 790
669 sizes = memory.mem; 791 sizes = memory.mem;
670 count = efl_model_children_count_get(parent); 792 count = efl_model_children_count_get(parent);
671 limit = MIN(count - start_id, memory.len); 793 limit = conf.range.end_id - conf.range.start_id;
794// printf("batch_size %u, %d\n", limit, start_id);
672 795
673 // Look in the temporary cache now for the beginning of the buffer 796 // Look in the temporary cache now for the beginning of the buffer
674 if (pd->viewport[0] && ((uint64_t)(start_id + idx) < pd->viewport[0]->offset)) 797 /* if (pd->viewport[0] && ((uint64_t)(conf.range.start_id + idx) < pd->viewport[0]->offset))
675 { 798 {
676 while ((uint64_t)(start_id + idx) < pd->viewport[0]->offset) 799 while ((uint64_t)(conf.range.start_id + idx) < pd->viewport[0]->offset && idx < limit)
677 { 800 {
678 uint64_t search_index = start_id + idx; 801 uint64_t search_index = conf.range.start_id + idx;
679 802// printf("LINE %d\n", __LINE__);
680 requests = _cache_size_fetch(requests, &request, pd, 803 requests = _cache_size_fetch(requests, &request, pd,
681 search_index, &sizes[idx], item_base); 804 search_index, &sizes[idx], item_base);
682 805 if (!sizes[idx].size.w || !sizes[idx].size.h) ERR("NULL SIZE ENT");
683 idx++; 806 idx++;
684 } 807 }
685 } 808 }
@@ -690,15 +813,15 @@ _batch_size_cb(void *data, int start_id, Eina_Rw_Slice memory)
690 if (!pd->viewport[i]) continue; 813 if (!pd->viewport[i]) continue;
691 814
692 while (idx < limit && 815 while (idx < limit &&
693 (pd->viewport[i]->offset <= start_id + idx) && 816 (pd->viewport[i]->offset <= conf.range.start_id + idx) &&
694 (start_id + idx < (pd->viewport[i]->offset + pd->viewport[i]->count))) 817 (conf.range.start_id + idx < (pd->viewport[i]->offset + pd->viewport[i]->count)))
695 { 818 {
696 uint16_t offset = start_id + idx - pd->viewport[i]->offset; 819 uint64_t offset = conf.range.start_id + idx - pd->viewport[i]->offset;
697 Efl_Model *model = pd->viewport[i]->items[offset].model; 820 Efl_Model *model = pd->viewport[i]->items[offset].model;
698 Efl_Gfx_Entity *entity = pd->viewport[i]->items[offset].entity; 821 Efl_Gfx_Entity *entity = pd->viewport[i]->items[offset].entity;
699 Eina_Bool entity_request = EINA_FALSE; 822 Eina_Bool entity_request = EINA_FALSE;
700 823
701 if (!model) 824 if (model)
702 { 825 {
703 Eina_Size2D item_size; 826 Eina_Size2D item_size;
704 Eina_Bool found = EINA_FALSE; 827 Eina_Bool found = EINA_FALSE;
@@ -707,29 +830,44 @@ _batch_size_cb(void *data, int start_id, Eina_Rw_Slice memory)
707 found = EINA_TRUE; 830 found = EINA_TRUE;
708 if (!found && entity) 831 if (!found && entity)
709 { 832 {
710 item_size = efl_gfx_hint_size_min_get(entity); 833 item_size = efl_gfx_hint_size_combined_min_get(entity);
711 _size_to_model(model, item_size); 834 //if the size is 0 here, then we are running into trouble,
712 found = EINA_TRUE; 835 //fetch size from the parent model, where some fallback is defined
836 if (item_size.h == 0 && item_size.w == 0)
837 {
838 ITEM_BASE_SIZE_FROM_MODEL(pd->model, item_size);
839 found = EINA_TRUE;
840 }
841 else
842 {
843 _size_to_model(model, item_size);
844 found = EINA_TRUE;
845 }
846
713 } 847 }
714 848
715 if (found) 849 if (found)
716 { 850 {
717 sizes[idx].size = item_size; 851 sizes[idx].size = item_size;
718 sizes[idx].group = EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_NO_GROUP; 852 sizes[idx].element_depth = 0;
853 sizes[idx].depth_leader = EINA_FALSE;
854 if (!sizes[idx].size.w || !sizes[idx].size.h) ERR("NULL SIZE ENT");
719 goto done; 855 goto done;
720 } 856 }
721 857
722 // We will need an entity to calculate this size 858 // We will need an entity to calculate this size
723 entity_request = EINA_TRUE; 859 entity_request = EINA_TRUE;
724 } 860 }
725 861// printf("LINE %d\n", __LINE__);
726 // No data, add to the requests 862 // No data, add to the requests
727 requests = _request_add(requests, &request, start_id + idx, entity_request); 863 requests = _request_add(requests, &request, conf.range.start_id + idx, entity_request);
728 864
729 sizes[idx].size = item_base; 865 sizes[idx].size = item_base;
730 sizes[idx].group = EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_NO_GROUP; 866 sizes[idx].element_depth = 0;
867 sizes[idx].depth_leader = EINA_FALSE;
731 868
732 done: 869 done:
870 if (!sizes[idx].size.w || !sizes[idx].size.h) ERR("NULL SIZE ENT");
733 idx++; 871 idx++;
734 } 872 }
735 } 873 }
@@ -737,18 +875,43 @@ _batch_size_cb(void *data, int start_id, Eina_Rw_Slice memory)
737 // Look in the temporary cache now for the end of the buffer 875 // Look in the temporary cache now for the end of the buffer
738 while (idx < limit) 876 while (idx < limit)
739 { 877 {
740 uint64_t search_index = start_id + idx; 878 uint64_t search_index = conf.range.start_id + idx;
741 879// printf("%lu LINE %d\n", search_index, __LINE__);
742 requests = _cache_size_fetch(requests, &request, pd, 880 requests = _cache_size_fetch(requests, &request, pd,
743 search_index, &sizes[idx], item_base); 881 search_index, &sizes[idx], item_base);
744 882 if (!sizes[idx].size.w || !sizes[idx].size.h) ERR("NULL SIZE ENT");
745 idx++; 883 idx++;
884 }*/
885 if (conf.cache_request)
886 {
887 printf("CACHING SIZE CALL\n");
888 while (idx < limit)
889 {
890 sizes[idx].depth_leader = EINA_FALSE;
891 sizes[idx].element_depth = 0;
892 sizes[idx].size = item_base;
893 if (!sizes[idx].size.w || !sizes[idx].size.h) ERR("NULL SIZE ENT");
894 idx++;
895 }
746 } 896 }
897 else
898 {
899 while (idx < limit)
900 {
901 uint64_t search_index = conf.range.start_id + idx;
902 // printf("%lu LINE %d\n", search_index, __LINE__);
903 requests = _cache_size_fetch(requests, &request, pd,
904 search_index, &sizes[idx], item_base);
905 if (!sizes[idx].size.w || !sizes[idx].size.h) ERR("NULL SIZE ENT");
906 idx++;
907 }
747 908
748 // Done, but flush request first
749 if (request) requests = eina_list_append(requests, request);
750 909
751 requests = _batch_request_flush(requests, data, pd); 910 // Done, but flush request first
911 if (request) requests = eina_list_append(requests, request);
912
913 requests = _batch_request_flush(requests, data, pd);
914 }
752 915
753 // Get the amount of filled item 916 // Get the amount of filled item
754 result.filled_items = limit; 917 result.filled_items = limit;
@@ -756,13 +919,13 @@ _batch_size_cb(void *data, int start_id, Eina_Rw_Slice memory)
756 return result; 919 return result;
757} 920}
758 921
759static Efl_Ui_Position_Manager_Batch_Result 922static Efl_Ui_Position_Manager_Object_Batch_Result
760_batch_entity_cb(void *data, int start_id, Eina_Rw_Slice memory) 923_batch_entity_cb(void *data, Efl_Ui_Position_Manager_Request_Range range, Eina_Rw_Slice memory)
761{ 924{
762 MY_DATA_GET(data, pd); 925 MY_DATA_GET(data, pd);
763 Efl_Ui_Position_Manager_Batch_Entity_Access *entities; 926 Efl_Ui_Position_Manager_Object_Batch_Entity *entities;
764 Efl_Ui_Collection_Request *request = NULL; 927 Efl_Ui_Collection_Request *request = NULL;
765 Efl_Ui_Position_Manager_Batch_Result result = {-1, 0}; 928 Efl_Ui_Position_Manager_Object_Batch_Result result = {0};
766 Eina_List *requests = NULL; 929 Eina_List *requests = NULL;
767 Efl_Model *parent; 930 Efl_Model *parent;
768 unsigned int i, count, limit; 931 unsigned int i, count, limit;
@@ -772,14 +935,14 @@ _batch_entity_cb(void *data, int start_id, Eina_Rw_Slice memory)
772 935
773 entities = memory.mem; 936 entities = memory.mem;
774 count = efl_model_children_count_get(parent); 937 count = efl_model_children_count_get(parent);
775 limit = MIN(count - start_id, memory.len); 938 limit = range.end_id - range.start_id;;
776 939
777 // Look in the temporary cache now for the beginning of the buffer 940 // Look in the temporary cache now for the beginning of the buffer
778 if (pd->viewport[0] && ((uint64_t)(start_id + idx) < pd->viewport[0]->offset)) 941 /*if (pd->viewport[0] && ((uint64_t)(range.start_id + idx) < pd->viewport[0]->offset))
779 { 942 {
780 while ((uint64_t)(start_id + idx) < pd->viewport[0]->offset) 943 while (idx < limit && (uint64_t)(range.start_id + idx) < pd->viewport[0]->offset)
781 { 944 {
782 uint64_t search_index = start_id + idx; 945 uint64_t search_index = range.start_id + idx;
783 946
784 requests = _cache_entity_fetch(requests, &request, pd, 947 requests = _cache_entity_fetch(requests, &request, pd,
785 search_index, &entities[idx]); 948 search_index, &entities[idx]);
@@ -794,24 +957,27 @@ _batch_entity_cb(void *data, int start_id, Eina_Rw_Slice memory)
794 if (!pd->viewport[i]) continue; 957 if (!pd->viewport[i]) continue;
795 958
796 while (idx < limit && 959 while (idx < limit &&
797 (pd->viewport[i]->offset <= start_id + idx) && 960 (pd->viewport[i]->offset <= range.start_id + idx) &&
798 (start_id + idx < (pd->viewport[i]->offset + pd->viewport[i]->count))) 961 (range.start_id + idx < (pd->viewport[i]->offset + pd->viewport[i]->count)))
799 { 962 {
800 uint16_t offset = start_id + idx - pd->viewport[i]->offset; 963 uint64_t offset = range.start_id + idx - pd->viewport[i]->offset;
801 Efl_Gfx_Entity *entity = pd->viewport[i]->items[offset].entity; 964 Efl_Gfx_Entity *entity = pd->viewport[i]->items[offset].entity;
802 965
803 if (!entity) 966 if (!entity)
804 { 967 {
968// printf("LINE %d\n", __LINE__);
805 // No data, add to the requests 969 // No data, add to the requests
806 requests = _request_add(requests, &request, start_id + idx, EINA_TRUE); 970 requests = _request_add(requests, &request, range.start_id + idx, EINA_TRUE);
807 971
808 entities[idx].entity = NULL; 972 entities[idx].entity = NULL;
809 entities[idx].group = EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_NO_GROUP; 973 entities[idx].depth_leader = EINA_FALSE;
974 entities[idx].element_depth = 0;
810 } 975 }
811 else 976 else
812 { 977 {
813 entities[idx].entity = entity; 978 entities[idx].entity = entity;
814 entities[idx].group = EFL_UI_POSITION_MANAGER_BATCH_GROUP_STATE_NO_GROUP; 979 entities[idx].depth_leader = EINA_FALSE;
980 entities[idx].element_depth = 0;
815 } 981 }
816 982
817 idx++; 983 idx++;
@@ -821,16 +987,28 @@ _batch_entity_cb(void *data, int start_id, Eina_Rw_Slice memory)
821 // Look in the temporary cache now for the end of the buffer 987 // Look in the temporary cache now for the end of the buffer
822 while (idx < limit) 988 while (idx < limit)
823 { 989 {
824 uint64_t search_index = start_id + idx; 990 uint64_t search_index = range.start_id + idx;
825 991
826 requests = _cache_entity_fetch(requests, &request, pd, 992 requests = _cache_entity_fetch(requests, &request, pd,
827 search_index, &entities[idx]); 993 search_index, &entities[idx]);
828 994
829 idx++; 995 idx++;
830 } 996 }*/
997 while (idx < limit)
998 {
999 uint64_t search_index = range.start_id + idx;
831 1000
1001 requests = _cache_entity_fetch(requests, &request, pd,
1002 search_index, &entities[idx]);
1003
1004 idx++;
1005 }
832 // Done, but flush request first 1006 // Done, but flush request first
833 if (request) requests = eina_list_append(requests, request); 1007 if (request)
1008 {
1009 if (request->length < 1) CRI("ACK");
1010 requests = eina_list_append(requests, request);
1011 }
834 1012
835 requests = _batch_request_flush(requests, data, pd); 1013 requests = _batch_request_flush(requests, data, pd);
836 1014
@@ -857,7 +1035,7 @@ flush_min_size(Eo *obj, Efl_Ui_Collection_View_Data *pd)
857 if (!pd->match_content.h) 1035 if (!pd->match_content.h)
858 tmp.h = -1; 1036 tmp.h = -1;
859 1037
860 efl_gfx_hint_size_min_set(obj, tmp); 1038 efl_gfx_hint_size_restricted_min_set(obj, tmp);
861} 1039}
862 1040
863static void 1041static void
@@ -913,7 +1091,7 @@ _viewport_walk_fill(Eina_List *requests,
913 1091
914 check_entity: 1092 check_entity:
915 if (viewport->items[j].entity) continue ; 1093 if (viewport->items[j].entity) continue ;
916 1094// printf("LINE %d\n", __LINE__);
917 requests = _request_add(requests, &current, index, EINA_TRUE); 1095 requests = _request_add(requests, &current, index, EINA_TRUE);
918 } 1096 }
919 1097
@@ -924,12 +1102,85 @@ _viewport_walk_fill(Eina_List *requests,
924} 1102}
925 1103
926static void 1104static void
1105_remove_data(Eo *obj, Efl_Ui_Collection_View_Data *pd, uint64_t remove_index)
1106{
1107 Efl_Ui_Collection_Item_Lookup *lookup;
1108
1109 lookup = (void*) eina_rbtree_inline_lookup(pd->cache, &remove_index,
1110 sizeof (remove_index), _cache_tree_lookup,
1111 NULL);
1112
1113 if (!lookup) return;
1114
1115 pd->cache = (void*) eina_rbtree_inline_remove(pd->cache,
1116 EINA_RBTREE_GET(lookup),
1117 _cache_tree_cmp, NULL);
1118 _cache_item_free(EINA_RBTREE_GET(lookup), pd);
1119 lookup = (void*) eina_rbtree_inline_lookup(pd->cache, &remove_index,
1120 sizeof (remove_index), _cache_tree_lookup,
1121 NULL);
1122
1123 EINA_SAFETY_ON_TRUE_RETURN(!!lookup);
1124}
1125
1126//per idle we are killing off 2 items, one of before and one after the current range.
1127static void
1128_idle_cb(void *data, const Efl_Event *event EINA_UNUSED)
1129{
1130 MY_DATA_GET(data, pd);
1131 Eina_Bool finished = EINA_TRUE;
1132
1133 const unsigned int count = efl_model_children_count_get(pd->model);
1134 const unsigned int length = pd->current_range.end_id - pd->current_range.start_id;
1135 const unsigned int lower_end = MAX((long)pd->current_range.start_id - (long)length/2, 0);
1136 const unsigned int upper_end = pd->current_range.end_id + length/2;
1137 const unsigned int upper_end_idx = count - pd->running_range.end_id;
1138
1139 if (pd->running_range.start_id < lower_end)
1140 {
1141 _remove_data(data, pd, pd->running_range.start_id);
1142 pd->running_range.start_id ++;
1143 finished = EINA_FALSE;
1144 }
1145
1146 if (upper_end_idx > upper_end)
1147 {
1148 _remove_data(data, pd, upper_end_idx);
1149 pd->running_range.end_id ++;
1150 finished = EINA_FALSE;
1151 }
1152
1153 if (finished)
1154 efl_event_callback_del(efl_main_loop_get(), EFL_LOOP_EVENT_IDLE, _idle_cb, data);
1155}
1156
1157static void
1158_manager_content_visible_range_changed_cb(void *data, const Efl_Event *ev)
1159{
1160 Efl_Ui_Position_Manager_Range_Update *event = ev->info;
1161 MY_DATA_GET(data, pd);
1162
1163
1164 printf("RANGE UPDATE %d %d\n", event->start_id, event->end_id);
1165
1166 pd->current_range.start_id = event->start_id;
1167 pd->current_range.end_id = event->end_id;
1168
1169 pd->running_range.start_id = 0;
1170 pd->running_range.end_id = 0;
1171
1172 efl_event_callback_del(efl_main_loop_get(), EFL_LOOP_EVENT_IDLE, _idle_cb, data);
1173 efl_event_callback_add(efl_main_loop_get(), EFL_LOOP_EVENT_IDLE, _idle_cb, data);
1174}
1175
1176#if 0
1177static void
927_manager_content_visible_range_changed_cb(void *data, const Efl_Event *ev) 1178_manager_content_visible_range_changed_cb(void *data, const Efl_Event *ev)
928{ 1179{
929 Efl_Ui_Position_Manager_Range_Update *event = ev->info; 1180 Efl_Ui_Position_Manager_Range_Update *event = ev->info;
930 MY_DATA_GET(data, pd); 1181 MY_DATA_GET(data, pd);
931 Eina_List *requests = NULL; 1182 Eina_List *requests = NULL;
932 unsigned int baseid; 1183 long baseid;
933 unsigned int delta, marginup, margindown; 1184 unsigned int delta, marginup, margindown;
934 uint64_t upperlimit_offset, lowerlimit_offset; 1185 uint64_t upperlimit_offset, lowerlimit_offset;
935 unsigned int i; 1186 unsigned int i;
@@ -942,17 +1193,17 @@ _manager_content_visible_range_changed_cb(void *data, const Efl_Event *ev)
942 // First time setting up the viewport, so trigger request as we see fit 1193 // First time setting up the viewport, so trigger request as we see fit
943 if (!pd->viewport[0]) 1194 if (!pd->viewport[0])
944 { 1195 {
945 Eina_List *requests = NULL; 1196 baseid = pd->start_id - delta;
946
947 baseid = (pd->start_id < delta) ? 0 : pd->start_id - delta;
948 1197
949 for (i = 0; i < 3; i++) 1198 for (i = 0; i < 3; i++)
950 { 1199 {
951 pd->viewport[i] = calloc(1, sizeof (Efl_Ui_Collection_Viewport)); 1200 pd->viewport[i] = calloc(1, sizeof (Efl_Ui_Collection_Viewport));
952 if (!pd->viewport[i]) continue; 1201 if (!pd->viewport[i]) continue;
953 1202
954 pd->viewport[i]->offset = baseid + delta * i; 1203 pd->viewport[i]->offset = MAX(baseid + delta * i, 0);
1204 printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> OOOOFFFSET %d %lu\n", i, pd->viewport[i]->offset);
955 pd->viewport[i]->count = delta; 1205 pd->viewport[i]->count = delta;
1206 printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> COUNT %d %d\n", i, pd->viewport[i]->count);
956 pd->viewport[i]->items = calloc(delta, sizeof (Efl_Ui_Collection_Item)); 1207 pd->viewport[i]->items = calloc(delta, sizeof (Efl_Ui_Collection_Item));
957 if (!pd->viewport[i]->items) continue ; 1208 if (!pd->viewport[i]->items) continue ;
958 1209
@@ -1023,6 +1274,8 @@ _manager_content_visible_range_changed_cb(void *data, const Efl_Event *ev)
1023 pd->viewport[i]->items = items[i]; 1274 pd->viewport[i]->items = items[i];
1024 pd->viewport[i]->count = delta; 1275 pd->viewport[i]->count = delta;
1025 pd->viewport[i]->offset = pd->viewport[0]->offset + delta * i; 1276 pd->viewport[i]->offset = pd->viewport[0]->offset + delta * i;
1277 printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> OOOOFFFSET %d %lu\n", i, pd->viewport[i]->offset);
1278 printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> COUNT %d %d\n", i, pd->viewport[i]->count);
1026 } 1279 }
1027 } 1280 }
1028 1281
@@ -1052,8 +1305,9 @@ _manager_content_visible_range_changed_cb(void *data, const Efl_Event *ev)
1052 target = baseid; 1305 target = baseid;
1053 1306
1054 // cleanup before target 1307 // cleanup before target
1055 for (current = pd->viewport[0]->offset; current < target; current++) 1308 for (current = pd->viewport[t]->offset; current < target; current++)
1056 { 1309 {
1310 if (!j) printf("MODEL CLEAR %d\n", t);
1057 _item_cleanup(pd->factory, &pd->viewport[t]->items[j]); 1311 _item_cleanup(pd->factory, &pd->viewport[t]->items[j]);
1058 1312
1059 j++; 1313 j++;
@@ -1113,6 +1367,8 @@ _manager_content_visible_range_changed_cb(void *data, const Efl_Event *ev)
1113 free(pd->viewport[i]->items); 1367 free(pd->viewport[i]->items);
1114 pd->viewport[i]->items = items[i]; 1368 pd->viewport[i]->items = items[i];
1115 pd->viewport[i]->offset = baseid + delta * i; 1369 pd->viewport[i]->offset = baseid + delta * i;
1370 printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> OOOOFFFSET %d %lu\n", i, pd->viewport[i]->offset);
1371 printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> COUNT %d %d\n", i, pd->viewport[i]->count);
1116 } 1372 }
1117 } 1373 }
1118 1374
@@ -1128,8 +1384,10 @@ _manager_content_visible_range_changed_cb(void *data, const Efl_Event *ev)
1128 request->offset = lowerlimit_offset; 1384 request->offset = lowerlimit_offset;
1129 // This length work over multiple viewport as they are contiguous 1385 // This length work over multiple viewport as they are contiguous
1130 request->length = lowerlimit_offset - pd->viewport[0]->offset; 1386 request->length = lowerlimit_offset - pd->viewport[0]->offset;
1387 if (request->length < 1) CRI("ACK");
1131 request->model_requested = EINA_TRUE; 1388 request->model_requested = EINA_TRUE;
1132 request->entity_requested = EINA_TRUE; 1389// printf("MODEL REQ(%lu) %d\n", request->offset, __LINE__);
1390 request->need_entity = EINA_TRUE;
1133 1391
1134 requests = eina_list_append(requests, request); 1392 requests = eina_list_append(requests, request);
1135 } 1393 }
@@ -1145,8 +1403,10 @@ _manager_content_visible_range_changed_cb(void *data, const Efl_Event *ev)
1145 request->offset = upperlimit_offset; 1403 request->offset = upperlimit_offset;
1146 // This length work over multiple viewport as they are contiguous 1404 // This length work over multiple viewport as they are contiguous
1147 request->length = pd->viewport[2]->offset + pd->viewport[2]->count - upperlimit_offset; 1405 request->length = pd->viewport[2]->offset + pd->viewport[2]->count - upperlimit_offset;
1406 if (request->length < 1) CRI("ACK");
1148 request->model_requested = EINA_TRUE; 1407 request->model_requested = EINA_TRUE;
1149 request->entity_requested = EINA_TRUE; 1408// printf("MODEL REQ(%lu) %d\n", request->offset, __LINE__);
1409 request->need_entity = EINA_TRUE;
1150 1410
1151 requests = eina_list_append(requests, request); 1411 requests = eina_list_append(requests, request);
1152 } 1412 }
@@ -1155,6 +1415,8 @@ _manager_content_visible_range_changed_cb(void *data, const Efl_Event *ev)
1155 requests = _batch_request_flush(requests, data, pd); 1415 requests = _batch_request_flush(requests, data, pd);
1156} 1416}
1157 1417
1418#endif
1419
1158EFL_CALLBACKS_ARRAY_DEFINE(manager_cbs, 1420EFL_CALLBACKS_ARRAY_DEFINE(manager_cbs,
1159 { EFL_UI_POSITION_MANAGER_ENTITY_EVENT_CONTENT_SIZE_CHANGED, _manager_content_size_changed_cb }, 1421 { EFL_UI_POSITION_MANAGER_ENTITY_EVENT_CONTENT_SIZE_CHANGED, _manager_content_size_changed_cb },
1160 { EFL_UI_POSITION_MANAGER_ENTITY_EVENT_CONTENT_MIN_SIZE_CHANGED, _manager_content_min_size_changed_cb }, 1422 { EFL_UI_POSITION_MANAGER_ENTITY_EVENT_CONTENT_MIN_SIZE_CHANGED, _manager_content_min_size_changed_cb },
@@ -1212,10 +1474,6 @@ _efl_ui_collection_view_position_manager_set(Eo *obj, Efl_Ui_Collection_View_Dat
1212 if (pd->manager) 1474 if (pd->manager)
1213 { 1475 {
1214 efl_event_callback_array_del(pd->manager, manager_cbs(), obj); 1476 efl_event_callback_array_del(pd->manager, manager_cbs(), obj);
1215 efl_ui_position_manager_entity_data_access_set(pd->manager,
1216 NULL, NULL, NULL,
1217 NULL, NULL, NULL,
1218 0);
1219 efl_del(pd->manager); 1477 efl_del(pd->manager);
1220 } 1478 }
1221 pd->manager = manager; 1479 pd->manager = manager;
@@ -1227,11 +1485,18 @@ _efl_ui_collection_view_position_manager_set(Eo *obj, Efl_Ui_Collection_View_Dat
1227 1485
1228 efl_parent_set(pd->manager, obj); 1486 efl_parent_set(pd->manager, obj);
1229 efl_event_callback_array_add(pd->manager, manager_cbs(), obj); 1487 efl_event_callback_array_add(pd->manager, manager_cbs(), obj);
1230 efl_ui_position_manager_entity_data_access_set(pd->manager, 1488 switch(efl_ui_position_manager_entity_version(pd->manager, 1))
1231 efl_ref(obj), _batch_entity_cb, _batch_free_cb, 1489 {
1232 efl_ref(obj), _batch_size_cb, _batch_free_cb, 1490 case 1:
1233 count); 1491 efl_ui_position_manager_data_access_v1_data_access_set(pd->manager,
1234 efl_ui_position_manager_entity_viewport_set(pd->manager, efl_ui_scrollable_viewport_geometry_get(obj)); 1492 efl_ref(obj), _batch_entity_cb, NULL,
1493 efl_ref(obj), _batch_size_cb, NULL,
1494 count);
1495 break;
1496 }
1497
1498 if (efl_finalized_get(obj))
1499 efl_ui_position_manager_entity_viewport_set(pd->manager, efl_ui_scrollable_viewport_geometry_get(obj));
1235 efl_ui_layout_orientation_set(pd->manager, pd->direction); 1500 efl_ui_layout_orientation_set(pd->manager, pd->direction);
1236} 1501}
1237 1502
@@ -1270,7 +1535,7 @@ _efl_model_child_added(void *data, const Efl_Event *event)
1270 _cache_cleanup(pd); 1535 _cache_cleanup(pd);
1271 1536
1272 // Check if we really have something to do 1537 // Check if we really have something to do
1273 if (!pd->viewport[0]) goto notify_manager; 1538 /*if (!pd->viewport[0]) goto notify_manager;
1274 1539
1275 // Insert the child in the viewport if necessary 1540 // Insert the child in the viewport if necessary
1276 for (i = 0; i < 3; i++) 1541 for (i = 0; i < 3; i++)
@@ -1311,14 +1576,15 @@ _efl_model_child_added(void *data, const Efl_Event *event)
1311 request->offset = ev->index; 1576 request->offset = ev->index;
1312 request->length = 1; 1577 request->length = 1;
1313 request->model_requested = EINA_TRUE; 1578 request->model_requested = EINA_TRUE;
1314 request->entity_requested = EINA_TRUE; 1579// printf("MODEL REQ(%lu) %d\n", request->offset, __LINE__);
1580 request->need_entity = EINA_TRUE;
1315 1581
1316 requests = eina_list_append(requests, request); 1582 requests = eina_list_append(requests, request);
1317 1583
1318 requests = _batch_request_flush(requests, data, pd); 1584 requests = _batch_request_flush(requests, data, pd);
1319 1585
1320 break; 1586 break;
1321 } 1587 }*/
1322 1588
1323 notify_manager: 1589 notify_manager:
1324 efl_ui_position_manager_entity_item_added(pd->manager, ev->index, NULL); 1590 efl_ui_position_manager_entity_item_added(pd->manager, ev->index, NULL);
@@ -1335,7 +1601,7 @@ _efl_model_child_removed(void *data, const Efl_Event *event)
1335 _cache_cleanup(pd); 1601 _cache_cleanup(pd);
1336 1602
1337 // Check if we really have something to do 1603 // Check if we really have something to do
1338 if (!pd->viewport[0]) goto notify_manager; 1604 /*if (!pd->viewport[0]) goto notify_manager;
1339 1605
1340 // Insert the child in the viewport if necessary 1606 // Insert the child in the viewport if necessary
1341 for (i = 0; i < 3; i++) 1607 for (i = 0; i < 3; i++)
@@ -1377,14 +1643,15 @@ _efl_model_child_removed(void *data, const Efl_Event *event)
1377 request->offset = pd->viewport[2]->offset + pd->viewport[i]->count - 1; 1643 request->offset = pd->viewport[2]->offset + pd->viewport[i]->count - 1;
1378 request->length = 1; 1644 request->length = 1;
1379 request->model_requested = EINA_TRUE; 1645 request->model_requested = EINA_TRUE;
1380 request->entity_requested = EINA_TRUE; 1646// printf("MODEL REQ(%lu) %d\n", request->offset, __LINE__);
1647 request->need_entity = EINA_TRUE;
1381 1648
1382 requests = eina_list_append(requests, request); 1649 requests = eina_list_append(requests, request);
1383 1650
1384 requests = _batch_request_flush(requests, data, pd); 1651 requests = _batch_request_flush(requests, data, pd);
1385 1652
1386 break; 1653 break;
1387 } 1654 }*/
1388 1655
1389 notify_manager: 1656 notify_manager:
1390 efl_ui_position_manager_entity_item_removed(pd->manager, ev->index, NULL); 1657 efl_ui_position_manager_entity_item_removed(pd->manager, ev->index, NULL);
@@ -1441,12 +1708,17 @@ _efl_ui_collection_view_model_changed(void *data, const Efl_Event *event)
1441 efl_ui_view_model_set(efl_added, ev->current)); 1708 efl_ui_view_model_set(efl_added, ev->current));
1442 1709
1443 count = efl_model_children_count_get(model); 1710 count = efl_model_children_count_get(model);
1444 efl_ui_position_manager_entity_data_access_set(pd->manager, 1711 switch(efl_ui_position_manager_entity_version(pd->manager, 1))
1445 efl_ref(data), _batch_entity_cb, _batch_free_cb, 1712 {
1446 efl_ref(data), _batch_size_cb, _batch_free_cb, 1713 case 1:
1447 count); 1714 efl_ui_position_manager_data_access_v1_data_access_set(pd->manager,
1715 efl_ref(data), _batch_entity_cb, NULL,
1716 efl_ref(data), _batch_size_cb, NULL,
1717 count);
1718 break;
1719 }
1448 1720
1449 for (i = 0; i < 3; i++) 1721 /*for (i = 0; i < 3; i++)
1450 { 1722 {
1451 Efl_Ui_Collection_Request *request; 1723 Efl_Ui_Collection_Request *request;
1452 1724
@@ -1458,13 +1730,17 @@ _efl_ui_collection_view_model_changed(void *data, const Efl_Event *event)
1458 1730
1459 request->offset = pd->viewport[i]->offset; 1731 request->offset = pd->viewport[i]->offset;
1460 request->length = pd->viewport[i]->count; 1732 request->length = pd->viewport[i]->count;
1733 if (request->length < 1) CRI("ACK");
1461 request->model_requested = EINA_TRUE; 1734 request->model_requested = EINA_TRUE;
1462 request->entity_requested = EINA_TRUE; 1735// printf("MODEL REQ(%lu) %d\n", request->offset, __LINE__);
1736 request->need_entity = EINA_TRUE;
1463 1737
1464 requests = eina_list_append(requests, request); 1738 requests = eina_list_append(requests, request);
1465 } 1739 }*/
1466 1740
1467 requests = _batch_request_flush(requests, data, pd); 1741 requests = _batch_request_flush(requests, data, pd);
1742
1743 pd->model = model;
1468} 1744}
1469 1745
1470static void 1746static void
@@ -1493,17 +1769,19 @@ _pan_position_changed_cb(void *data, const Efl_Event *ev EINA_UNUSED)
1493} 1769}
1494 1770
1495EFL_CALLBACKS_ARRAY_DEFINE(pan_events_cb, 1771EFL_CALLBACKS_ARRAY_DEFINE(pan_events_cb,
1496 {EFL_UI_PAN_EVENT_PAN_POSITION_CHANGED, _pan_position_changed_cb}, 1772 {EFL_UI_PAN_EVENT_PAN_CONTENT_POSITION_CHANGED, _pan_position_changed_cb},
1497 {EFL_UI_PAN_EVENT_PAN_VIEWPORT_CHANGED, _pan_viewport_changed_cb}, 1773 {EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _pan_viewport_changed_cb},
1774 {EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _pan_viewport_changed_cb},
1498) 1775)
1499 1776
1500static Efl_Object * 1777static Efl_Object *
1501_efl_ui_collection_view_efl_object_constructor(Eo *obj, Efl_Ui_Collection_View_Data *pd) 1778_efl_ui_collection_view_efl_object_constructor(Eo *obj, Efl_Ui_Collection_View_Data *pd)
1502{ 1779{
1780 pd->direction = EFL_UI_LAYOUT_ORIENTATION_VERTICAL;
1503 obj = efl_constructor(efl_super(obj, EFL_UI_COLLECTION_VIEW_CLASS)); 1781 obj = efl_constructor(efl_super(obj, EFL_UI_COLLECTION_VIEW_CLASS));
1504 1782
1505 if (!elm_widget_theme_klass_get(obj)) 1783 if (!elm_widget_theme_klass_get(obj))
1506 elm_widget_theme_klass_set(obj, "collection"); 1784 elm_widget_theme_klass_set(obj, "item_container");
1507 1785
1508 efl_wref_add(efl_add(EFL_CANVAS_RECTANGLE_CLASS, evas_object_evas_get(obj)), &pd->sizer); 1786 efl_wref_add(efl_add(EFL_CANVAS_RECTANGLE_CLASS, evas_object_evas_get(obj)), &pd->sizer);
1509 efl_gfx_color_set(pd->sizer, 0, 0, 0, 0); 1787 efl_gfx_color_set(pd->sizer, 0, 0, 0, 0);
@@ -1619,7 +1897,7 @@ _efl_ui_collection_view_efl_ui_focus_manager_move(Eo *obj, Efl_Ui_Collection_Vie
1619 1897
1620 new_obj = efl_ui_focus_manager_move(efl_super(obj, MY_CLASS), direction); 1898 new_obj = efl_ui_focus_manager_move(efl_super(obj, MY_CLASS), direction);
1621 focus = efl_ui_focus_manager_focus_get(obj); 1899 focus = efl_ui_focus_manager_focus_get(obj);
1622 step = efl_gfx_hint_size_min_get(focus); 1900 step = efl_gfx_hint_size_combined_min_get(focus);
1623 if (!new_obj) 1901 if (!new_obj)
1624 { 1902 {
1625 Eina_Rect pos = efl_gfx_entity_geometry_get(focus); 1903 Eina_Rect pos = efl_gfx_entity_geometry_get(focus);
@@ -1776,7 +2054,7 @@ _efl_ui_collection_view_focus_manager_efl_ui_focus_manager_request_move(Eo *obj,
1776 { 2054 {
1777 unsigned int i; 2055 unsigned int i;
1778 2056
1779 for (i = 0; i < 3; i++) 2057/* for (i = 0; i < 3; i++)
1780 { 2058 {
1781 if (!cpd->viewport[i]) continue; 2059 if (!cpd->viewport[i]) continue;
1782 2060
@@ -1788,7 +2066,7 @@ _efl_ui_collection_view_focus_manager_efl_ui_focus_manager_request_move(Eo *obj,
1788 // We shouldn't get in a case where the available item is NULL 2066 // We shouldn't get in a case where the available item is NULL
1789 if (!new_item) break; // Just in case 2067 if (!new_item) break; // Just in case
1790 _assert_item_available(new_item, new_id, cpd); 2068 _assert_item_available(new_item, new_id, cpd);
1791 } 2069 }*/
1792 } 2070 }
1793 } 2071 }
1794 else 2072 else