forked from enlightenment/efl
elementary: fix reordering bug.
NOTE: queue and item list should have the same order, but that's not the case. SVN revision: 65915
This commit is contained in:
parent
5b3283d6b5
commit
8832e77e58
|
@ -45,7 +45,7 @@ _ls_main_cb(void *data, Eio_File *handler __UNUSED__, const char *file)
|
||||||
eina_stringshare_add(file),
|
eina_stringshare_add(file),
|
||||||
NULL,
|
NULL,
|
||||||
ELM_GENLIST_ITEM_NONE,
|
ELM_GENLIST_ITEM_NONE,
|
||||||
(Eina_Compare_Cb) strcmp,
|
(Eina_Compare_Cb) strcoll,
|
||||||
_sel_file,
|
_sel_file,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3192,8 +3192,23 @@ _item_new(Widget_Data *wd,
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static Item_Block *
|
||||||
_item_block_add(Widget_Data *wd,
|
_item_block_new(Widget_Data *wd, Eina_Bool prepend)
|
||||||
|
{
|
||||||
|
Item_Block *itb;
|
||||||
|
|
||||||
|
itb = calloc(1, sizeof(Item_Block));
|
||||||
|
if (!itb) return NULL;
|
||||||
|
itb->wd = wd;
|
||||||
|
if (prepend)
|
||||||
|
wd->blocks = eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
|
||||||
|
else
|
||||||
|
wd->blocks = eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
|
||||||
|
return itb;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_item_block_add(Widget_Data *wd,
|
||||||
Elm_Gen_Item *it)
|
Elm_Gen_Item *it)
|
||||||
{
|
{
|
||||||
Item_Block *itb = NULL;
|
Item_Block *itb = NULL;
|
||||||
|
@ -3204,7 +3219,7 @@ newblock:
|
||||||
if (it->item->rel)
|
if (it->item->rel)
|
||||||
{
|
{
|
||||||
itb = calloc(1, sizeof(Item_Block));
|
itb = calloc(1, sizeof(Item_Block));
|
||||||
if (!itb) return;
|
if (!itb) return EINA_FALSE;
|
||||||
itb->wd = wd;
|
itb->wd = wd;
|
||||||
if (!it->item->rel->item->block)
|
if (!it->item->rel->item->block)
|
||||||
{
|
{
|
||||||
|
@ -3241,21 +3256,14 @@ newblock:
|
||||||
itb = (Item_Block *)(wd->blocks);
|
itb = (Item_Block *)(wd->blocks);
|
||||||
if (itb->count >= wd->max_items_per_block)
|
if (itb->count >= wd->max_items_per_block)
|
||||||
{
|
{
|
||||||
itb = calloc(1, sizeof(Item_Block));
|
itb = _item_block_new(wd, EINA_TRUE);
|
||||||
if (!itb) return;
|
if (!itb) return EINA_FALSE;
|
||||||
itb->wd = wd;
|
|
||||||
wd->blocks =
|
|
||||||
eina_inlist_prepend(wd->blocks,
|
|
||||||
EINA_INLIST_GET(itb));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
itb = calloc(1, sizeof(Item_Block));
|
itb = _item_block_new(wd, EINA_TRUE);
|
||||||
if (!itb) return;
|
if (!itb) return EINA_FALSE;
|
||||||
itb->wd = wd;
|
|
||||||
wd->blocks =
|
|
||||||
eina_inlist_prepend(wd->blocks, EINA_INLIST_GET(itb));
|
|
||||||
}
|
}
|
||||||
itb->items = eina_list_prepend(itb->items, it);
|
itb->items = eina_list_prepend(itb->items, it);
|
||||||
}
|
}
|
||||||
|
@ -3266,21 +3274,14 @@ newblock:
|
||||||
itb = (Item_Block *)(wd->blocks->last);
|
itb = (Item_Block *)(wd->blocks->last);
|
||||||
if (itb->count >= wd->max_items_per_block)
|
if (itb->count >= wd->max_items_per_block)
|
||||||
{
|
{
|
||||||
itb = calloc(1, sizeof(Item_Block));
|
itb = _item_block_new(wd, EINA_FALSE);
|
||||||
if (!itb) return;
|
if (!itb) return EINA_FALSE;
|
||||||
itb->wd = wd;
|
|
||||||
wd->blocks =
|
|
||||||
eina_inlist_append(wd->blocks,
|
|
||||||
EINA_INLIST_GET(itb));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
itb = calloc(1, sizeof(Item_Block));
|
itb = _item_block_new(wd, EINA_FALSE);
|
||||||
if (!itb) return;
|
if (!itb) return EINA_FALSE;
|
||||||
itb->wd = wd;
|
|
||||||
wd->blocks =
|
|
||||||
eina_inlist_append(wd->blocks, EINA_INLIST_GET(itb));
|
|
||||||
}
|
}
|
||||||
itb->items = eina_list_append(itb->items, it);
|
itb->items = eina_list_append(itb->items, it);
|
||||||
}
|
}
|
||||||
|
@ -3288,6 +3289,19 @@ newblock:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (it->item->rel->item->queued)
|
||||||
|
{
|
||||||
|
/* NOTE: for a strange reason eina_list and eina_inlist don't have the same property
|
||||||
|
on sorted insertion order, so the queue is not always ordered like the item list.
|
||||||
|
This lead to issue where we depend on a item that is not yet created. As a quick
|
||||||
|
work around, we reschedule the calc of the item and stop reordering the list to
|
||||||
|
prevent any nasty issue to show up here.
|
||||||
|
*/
|
||||||
|
wd->queue = eina_list_append(wd->queue, it);
|
||||||
|
wd->requeue = EINA_TRUE;
|
||||||
|
it->item->queued = EINA_TRUE;
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
itb = it->item->rel->item->block;
|
itb = it->item->rel->item->block;
|
||||||
if (!itb) goto newblock;
|
if (!itb) goto newblock;
|
||||||
if (it->item->before)
|
if (it->item->before)
|
||||||
|
@ -3309,32 +3323,87 @@ newblock:
|
||||||
}
|
}
|
||||||
if (itb->count > itb->wd->max_items_per_block)
|
if (itb->count > itb->wd->max_items_per_block)
|
||||||
{
|
{
|
||||||
int newc;
|
|
||||||
Item_Block *itb2;
|
Item_Block *itb2;
|
||||||
Elm_Gen_Item *it2;
|
Elm_Gen_Item *it2;
|
||||||
|
int newc;
|
||||||
|
Eina_Bool done = EINA_FALSE;
|
||||||
|
|
||||||
newc = itb->count / 2;
|
newc = itb->count / 2;
|
||||||
itb2 = calloc(1, sizeof(Item_Block));
|
|
||||||
if (!itb2) return;
|
if (EINA_INLIST_GET(itb)->prev)
|
||||||
itb2->wd = wd;
|
|
||||||
wd->blocks =
|
|
||||||
eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
|
|
||||||
EINA_INLIST_GET(itb));
|
|
||||||
itb2->changed = EINA_TRUE;
|
|
||||||
while ((itb->count > newc) && (itb->items))
|
|
||||||
{
|
{
|
||||||
Eina_List *l;
|
Item_Block *itbp = (Item_Block *)(EINA_INLIST_GET(itb)->prev);
|
||||||
|
|
||||||
l = eina_list_last(itb->items);
|
if (itbp->count + newc < wd->max_items_per_block / 2)
|
||||||
it2 = l->data;
|
{
|
||||||
itb->items = eina_list_remove_list(itb->items, l);
|
/* moving items to previous block */
|
||||||
itb->count--;
|
while ((itb->count > newc) && (itb->items))
|
||||||
|
{
|
||||||
|
it2 = eina_list_data_get(itb->items);
|
||||||
|
itb->items = eina_list_remove_list(itb->items, itb->items);
|
||||||
|
itb->count--;
|
||||||
|
|
||||||
itb2->items = eina_list_prepend(itb2->items, it2);
|
itbp->items = eina_list_append(itbp->items, it2);
|
||||||
it2->item->block = itb2;
|
it2->item->block = itbp;
|
||||||
itb2->count++;
|
itbp->count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
done = EINA_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!done && EINA_INLIST_GET(itb)->next)
|
||||||
|
{
|
||||||
|
Item_Block *itbn = (Item_Block *)(EINA_INLIST_GET(itb)->next);
|
||||||
|
|
||||||
|
if (itbn->count + newc < wd->max_items_per_block / 2)
|
||||||
|
{
|
||||||
|
/* moving items to next block */
|
||||||
|
while ((itb->count > newc) && (itb->items))
|
||||||
|
{
|
||||||
|
Eina_List *l;
|
||||||
|
|
||||||
|
l = eina_list_last(itb->items);
|
||||||
|
it2 = eina_list_data_get(l);
|
||||||
|
itb->items = eina_list_remove_list(itb->items, l);
|
||||||
|
itb->count--;
|
||||||
|
|
||||||
|
itbn->items = eina_list_prepend(itbn->items, it2);
|
||||||
|
it2->item->block = itbn;
|
||||||
|
itbn->count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
done = EINA_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!done)
|
||||||
|
{
|
||||||
|
/* moving items to new block */
|
||||||
|
itb2 = calloc(1, sizeof(Item_Block));
|
||||||
|
if (!itb2) return EINA_FALSE;
|
||||||
|
itb2->wd = wd;
|
||||||
|
wd->blocks =
|
||||||
|
eina_inlist_append_relative(wd->blocks, EINA_INLIST_GET(itb2),
|
||||||
|
EINA_INLIST_GET(itb));
|
||||||
|
itb2->changed = EINA_TRUE;
|
||||||
|
while ((itb->count > newc) && (itb->items))
|
||||||
|
{
|
||||||
|
Eina_List *l;
|
||||||
|
|
||||||
|
l = eina_list_last(itb->items);
|
||||||
|
it2 = l->data;
|
||||||
|
itb->items = eina_list_remove_list(itb->items, l);
|
||||||
|
itb->count--;
|
||||||
|
|
||||||
|
itb2->items = eina_list_prepend(itb2->items, it2);
|
||||||
|
it2->item->block = itb2;
|
||||||
|
itb2->count++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -3344,16 +3413,16 @@ _queue_process(Widget_Data *wd)
|
||||||
Eina_Bool showme = EINA_FALSE;
|
Eina_Bool showme = EINA_FALSE;
|
||||||
double t0, t;
|
double t0, t;
|
||||||
|
|
||||||
t0 = ecore_time_get();
|
t0 = ecore_loop_time_get();
|
||||||
//evas_event_freeze(evas_object_evas_get(wd->obj));
|
//evas_event_freeze(evas_object_evas_get(wd->obj));
|
||||||
for (n = 0; (wd->queue) && (n < 128); n++)
|
for (n = 0; (wd->queue) && (n < 128); n++)
|
||||||
{
|
{
|
||||||
Elm_Gen_Item *it;
|
Elm_Gen_Item *it;
|
||||||
|
|
||||||
it = wd->queue->data;
|
it = eina_list_data_get(wd->queue);
|
||||||
wd->queue = eina_list_remove_list(wd->queue, wd->queue);
|
wd->queue = eina_list_remove_list(wd->queue, wd->queue);
|
||||||
it->item->queued = EINA_FALSE;
|
it->item->queued = EINA_FALSE;
|
||||||
_item_block_add(wd, it);
|
if (!_item_block_add(wd, it)) continue;
|
||||||
if (!wd->blocks)
|
if (!wd->blocks)
|
||||||
_item_block_realize(it->item->block);
|
_item_block_realize(it->item->block);
|
||||||
t = ecore_time_get();
|
t = ecore_time_get();
|
||||||
|
@ -3417,7 +3486,7 @@ _item_queue(Widget_Data *wd,
|
||||||
{
|
{
|
||||||
if (it->item->queued) return;
|
if (it->item->queued) return;
|
||||||
it->item->queued = EINA_TRUE;
|
it->item->queued = EINA_TRUE;
|
||||||
if (cb)
|
if (cb && !wd->requeue)
|
||||||
wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
|
wd->queue = eina_list_sorted_insert(wd->queue, cb, it);
|
||||||
else
|
else
|
||||||
wd->queue = eina_list_append(wd->queue, it);
|
wd->queue = eina_list_append(wd->queue, it);
|
||||||
|
@ -3715,6 +3784,7 @@ elm_genlist_item_direct_sorted_insert(Evas_Object *obj,
|
||||||
{
|
{
|
||||||
wd->state = eina_inlist_sorted_state_new();
|
wd->state = eina_inlist_sorted_state_new();
|
||||||
eina_inlist_sorted_state_init(wd->state, wd->items);
|
eina_inlist_sorted_state_init(wd->state, wd->items);
|
||||||
|
wd->requeue = EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (it->group)
|
if (it->group)
|
||||||
|
@ -3741,7 +3811,7 @@ elm_genlist_item_direct_sorted_insert(Evas_Object *obj,
|
||||||
it->item->rel->relcount++;
|
it->item->rel->relcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
_item_queue(wd, it, comp);
|
_item_queue(wd, it, _elm_genlist_item_list_compare);
|
||||||
|
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,6 +145,8 @@ struct _Widget_Data
|
||||||
double longpress_timeout; /* longpress timeout. this value comes from _elm_config by default. this can be changed by elm_genlist_longpress_timeout_set() */
|
double longpress_timeout; /* longpress timeout. this value comes from _elm_config by default. this can be changed by elm_genlist_longpress_timeout_set() */
|
||||||
int generation; /* a generation of genlist. when genlist is cleared, this value will be increased and a new generation will start */
|
int generation; /* a generation of genlist. when genlist is cleared, this value will be increased and a new generation will start */
|
||||||
|
|
||||||
|
Eina_Bool requeue : 1;
|
||||||
|
|
||||||
/* The stuff below directly come from gengrid without any thinking */
|
/* The stuff below directly come from gengrid without any thinking */
|
||||||
unsigned int nmax;
|
unsigned int nmax;
|
||||||
Evas_Coord reorder_item_x, reorder_item_y;
|
Evas_Coord reorder_item_x, reorder_item_y;
|
||||||
|
|
Loading…
Reference in New Issue