forked from enlightenment/efl
1. brian wang's patch for setting item count in a block, and homogenous
genlist mode, button repeat stuff. thanks very muchly also - i added calc idler self-timer check. if it spends more than 1 frametime (time between frames - this is what it deems as "too much") on calculation, then it breaks the idle and goes back to mainloop. could make it half a frametime - but this will do for now. SVN revision: 45479
This commit is contained in:
parent
93edc1c626
commit
591957a330
|
@ -9,3 +9,5 @@ Christopher Michael <devilhorns@devilhorns.us>
|
|||
Marco Trevisan (Treviño) <mail@3v1n0.net>
|
||||
Michael Bouchaud <michael.bouchaud@gmail.com>
|
||||
Jonathan Atton (Watchwolf) <jonathan.atton@gmail.com>
|
||||
Brian Wang <brian.wang.0721@gmail.com>
|
||||
|
||||
|
|
|
@ -374,6 +374,9 @@ extern "C" {
|
|||
EAPI const char *elm_button_label_get(Evas_Object *obj);
|
||||
EAPI void elm_button_icon_set(Evas_Object *obj, Evas_Object *icon);
|
||||
EAPI Evas_Object *elm_button_icon_get(Evas_Object *obj);
|
||||
EAPI void elm_button_autorepeat_set(Evas_Object *obj, Eina_Bool on);
|
||||
EAPI void elm_button_autorepeat_initital_timeout_set(Evas_Object *obj, double t);
|
||||
EAPI void elm_button_autorepeat_gap_timeout_set(Evas_Object *obj, double t);
|
||||
EINA_DEPRECATED EAPI void elm_button_style_set(Evas_Object *obj, const char *style);
|
||||
/* available styles:
|
||||
* default
|
||||
|
@ -383,6 +386,7 @@ extern "C" {
|
|||
*/
|
||||
/* smart callbacks called:
|
||||
* "clicked" - the user clicked the button
|
||||
* "repeated" - the user pressed the button without releasing it
|
||||
*/
|
||||
|
||||
typedef enum _Elm_Scroller_Policy
|
||||
|
@ -882,6 +886,8 @@ extern "C" {
|
|||
EAPI void elm_genlist_no_select_mode_set(Evas_Object *obj, Eina_Bool no_select);
|
||||
EAPI void elm_genlist_compress_mode_set(Evas_Object *obj, Eina_Bool compress);
|
||||
EAPI void elm_genlist_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce);
|
||||
EAPI void elm_genlist_homogeneous_set(Evas_Object *obj, Eina_Bool homogeneous);
|
||||
EAPI void elm_genlist_block_count_set(Evas_Object *obj, int n);
|
||||
/* available item styles:
|
||||
* default
|
||||
* default_style - The text part is a textblock
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/*
|
||||
*
|
||||
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
||||
*/
|
||||
#include <Elementary.h>
|
||||
#include "elm_priv.h"
|
||||
|
||||
|
@ -237,6 +241,7 @@
|
|||
* have a specific style that overrides any theme the user or system sets up
|
||||
* you can use elm_theme_overlay_add() to add such a file.
|
||||
*/
|
||||
|
||||
typedef struct _Widget_Data Widget_Data;
|
||||
typedef struct _Item_Block Item_Block;
|
||||
typedef struct _Pan Pan;
|
||||
|
@ -260,18 +265,24 @@ struct _Widget_Data
|
|||
Eina_Bool no_select : 1;
|
||||
Eina_Bool bring_in : 1;
|
||||
Eina_Bool compress : 1;
|
||||
Eina_Bool homogeneous : 1;
|
||||
int item_width;
|
||||
int item_height;
|
||||
int max_items_per_block;
|
||||
};
|
||||
|
||||
struct _Item_Block
|
||||
{
|
||||
EINA_INLIST;
|
||||
int count;
|
||||
int num;
|
||||
Widget_Data *wd;
|
||||
Eina_List *items;
|
||||
Evas_Coord x, y, w, h, minw, minh;
|
||||
Eina_Bool realized : 1;
|
||||
Eina_Bool changed : 1;
|
||||
Eina_Bool updateme : 1;
|
||||
Eina_Bool showme : 1;
|
||||
};
|
||||
|
||||
struct _Elm_Genlist_Item
|
||||
|
@ -691,12 +702,12 @@ _item_realize(Elm_Genlist_Item *it, int in, int calc)
|
|||
elm_widget_sub_object_add(it->wd->obj, it->base);
|
||||
|
||||
if (it->flags & ELM_GENLIST_ITEM_SUBITEMS) strncpy(buf, "tree", sizeof(buf));
|
||||
else strncpy(buf, "item", sizeof(buf));
|
||||
if (it->wd->compress) strncat(buf, "_compress", sizeof(buf));
|
||||
else strncpy(buf, "item", sizeof(buf));
|
||||
if (it->wd->compress) strncat(buf, "_compress", sizeof(buf) - strlen(buf));
|
||||
|
||||
if (in & 0x1) strncat(buf, "_odd", sizeof(buf));
|
||||
strncat(buf, "/", sizeof(buf));
|
||||
strncat(buf, it->itc->item_style, sizeof(buf));
|
||||
if (in & 0x1) strncat(buf, "_odd", sizeof(buf) - strlen(buf));
|
||||
strncat(buf, "/", sizeof(buf) - strlen(buf));
|
||||
strncat(buf, it->itc->item_style, sizeof(buf) - strlen(buf));
|
||||
|
||||
_elm_theme_set(it->base, "genlist", buf, elm_widget_style_get(it->wd->obj));
|
||||
it->spacer = evas_object_rectangle_add(evas_object_evas_get(it->wd->obj));
|
||||
|
@ -736,71 +747,90 @@ _item_realize(Elm_Genlist_Item *it, int in, int calc)
|
|||
edje_object_signal_emit(it->base, "elm,state,expanded", "elm");
|
||||
}
|
||||
|
||||
if (it->itc->func.label_get)
|
||||
if (calc && it->wd->homogeneous && it->wd->item_width)
|
||||
{
|
||||
const Eina_List *l;
|
||||
const char *key;
|
||||
|
||||
it->labels = _stringlist_get(edje_object_data_get(it->base, "labels"));
|
||||
EINA_LIST_FOREACH(it->labels, l, key)
|
||||
/* homogenous genlist shortcut */
|
||||
if (!it->mincalcd)
|
||||
{
|
||||
char *s = it->itc->func.label_get(it->data, it->wd->obj, l->data);
|
||||
|
||||
if (s)
|
||||
{
|
||||
edje_object_part_text_set(it->base, l->data, s);
|
||||
free(s);
|
||||
}
|
||||
it->w = it->minw = it->wd->item_width;
|
||||
it->h = it->minh = it->wd->item_height;
|
||||
it->mincalcd = EINA_TRUE;
|
||||
}
|
||||
}
|
||||
if (it->itc->func.icon_get)
|
||||
else
|
||||
{
|
||||
const Eina_List *l;
|
||||
const char *key;
|
||||
|
||||
it->icons = _stringlist_get(edje_object_data_get(it->base, "icons"));
|
||||
EINA_LIST_FOREACH(it->icons, l, key)
|
||||
if (it->itc->func.label_get)
|
||||
{
|
||||
Evas_Object *ic = it->itc->func.icon_get(it->data, it->wd->obj, l->data);
|
||||
const Eina_List *l;
|
||||
const char *key;
|
||||
|
||||
if (ic)
|
||||
it->labels = _stringlist_get(edje_object_data_get(it->base, "labels"));
|
||||
EINA_LIST_FOREACH(it->labels, l, key)
|
||||
{
|
||||
it->icon_objs = eina_list_append(it->icon_objs, ic);
|
||||
edje_object_part_swallow(it->base, key, ic);
|
||||
evas_object_show(ic);
|
||||
elm_widget_sub_object_add(it->wd->obj, ic);
|
||||
char *s = it->itc->func.label_get(it->data, it->wd->obj, l->data);
|
||||
|
||||
if (s)
|
||||
{
|
||||
edje_object_part_text_set(it->base, l->data, s);
|
||||
free(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (it->itc->func.state_get)
|
||||
{
|
||||
const Eina_List *l;
|
||||
const char *key;
|
||||
|
||||
it->states = _stringlist_get(edje_object_data_get(it->base, "states"));
|
||||
EINA_LIST_FOREACH(it->states, l, key)
|
||||
if (it->itc->func.icon_get)
|
||||
{
|
||||
Eina_Bool on = it->itc->func.state_get(it->data, it->wd->obj, l->data);
|
||||
const Eina_List *l;
|
||||
const char *key;
|
||||
|
||||
if (on)
|
||||
it->icons = _stringlist_get(edje_object_data_get(it->base, "icons"));
|
||||
EINA_LIST_FOREACH(it->icons, l, key)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
|
||||
edje_object_signal_emit(it->base, buf, "elm");
|
||||
Evas_Object *ic = it->itc->func.icon_get(it->data, it->wd->obj, l->data);
|
||||
|
||||
if (ic)
|
||||
{
|
||||
it->icon_objs = eina_list_append(it->icon_objs, ic);
|
||||
edje_object_part_swallow(it->base, key, ic);
|
||||
evas_object_show(ic);
|
||||
elm_widget_sub_object_add(it->wd->obj, ic);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!it->mincalcd)
|
||||
{
|
||||
Evas_Coord mw = -1, mh = -1;
|
||||
if (it->itc->func.state_get)
|
||||
{
|
||||
const Eina_List *l;
|
||||
const char *key;
|
||||
|
||||
elm_coords_finger_size_adjust(1, &mw, 1, &mh);
|
||||
edje_object_size_min_restricted_calc(it->base, &mw, &mh, mw, mh);
|
||||
elm_coords_finger_size_adjust(1, &mw, 1, &mh);
|
||||
it->w = it->minw = mw;
|
||||
it->h = it->minh = mh;
|
||||
it->mincalcd = EINA_TRUE;
|
||||
it->states = _stringlist_get(edje_object_data_get(it->base, "states"));
|
||||
EINA_LIST_FOREACH(it->states, l, key)
|
||||
{
|
||||
Eina_Bool on = it->itc->func.state_get(it->data, it->wd->obj, l->data);
|
||||
|
||||
if (on)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
|
||||
edje_object_signal_emit(it->base, buf, "elm");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!it->mincalcd)
|
||||
{
|
||||
Evas_Coord mw = -1, mh = -1;
|
||||
|
||||
elm_coords_finger_size_adjust(1, &mw, 1, &mh);
|
||||
edje_object_size_min_restricted_calc(it->base, &mw, &mh, mw, mh);
|
||||
elm_coords_finger_size_adjust(1, &mw, 1, &mh);
|
||||
it->w = it->minw = mw;
|
||||
it->h = it->minh = mh;
|
||||
it->mincalcd = EINA_TRUE;
|
||||
|
||||
if (in == 0 && it->wd->homogeneous)
|
||||
{
|
||||
it->wd->item_width = mw;
|
||||
it->wd->item_height = mh;
|
||||
}
|
||||
}
|
||||
if (!calc) evas_object_show(it->base);
|
||||
}
|
||||
if (!calc) evas_object_show(it->base);
|
||||
it->realized = EINA_TRUE;
|
||||
}
|
||||
|
||||
|
@ -829,22 +859,35 @@ _item_unrealize(Elm_Genlist_Item *it)
|
|||
}
|
||||
|
||||
static int
|
||||
_item_block_recalc(Item_Block *itb, int in)
|
||||
_item_block_recalc(Item_Block *itb, int in, int qadd)
|
||||
{
|
||||
const Eina_List *l;
|
||||
Elm_Genlist_Item *it;
|
||||
Evas_Coord minw = 0, minh = 0;
|
||||
int showme = 0;
|
||||
int showme = 0, changed = 0;
|
||||
Evas_Coord y = 0;
|
||||
|
||||
itb->num = in;
|
||||
EINA_LIST_FOREACH(itb->items, l, it)
|
||||
{
|
||||
if (it->delete_me) continue;
|
||||
showme |= it->showme;
|
||||
if (!itb->realized)
|
||||
{
|
||||
_item_realize(it, in, 1);
|
||||
_item_unrealize(it);
|
||||
if (qadd)
|
||||
{
|
||||
if (!it->mincalcd) changed = 1;
|
||||
if (changed)
|
||||
{
|
||||
_item_realize(it, in, 1);
|
||||
_item_unrealize(it);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_item_realize(it, in, 1);
|
||||
_item_unrealize(it);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -975,14 +1018,13 @@ _calc_job(void *data)
|
|||
Item_Block *chb = NULL;
|
||||
int in = 0, minw_change = 0;
|
||||
|
||||
double t, t_start;
|
||||
|
||||
t_start = ecore_time_get();
|
||||
|
||||
EINA_INLIST_FOREACH(wd->blocks, itb)
|
||||
{
|
||||
int showme = 0;
|
||||
|
||||
itb->num = in;
|
||||
showme = itb->showme;
|
||||
itb->showme = 0;
|
||||
if (chb)
|
||||
{
|
||||
if (itb->realized) _item_block_unrealize(itb);
|
||||
|
@ -990,7 +1032,7 @@ _calc_job(void *data)
|
|||
if (itb->changed)
|
||||
{
|
||||
if (itb->realized) _item_block_unrealize(itb);
|
||||
showme = _item_block_recalc(itb, in);
|
||||
showme = _item_block_recalc(itb, in, 0);
|
||||
chb = itb;
|
||||
}
|
||||
itb->y = y;
|
||||
|
@ -1049,11 +1091,6 @@ _calc_job(void *data)
|
|||
}
|
||||
wd->calc_job = NULL;
|
||||
evas_object_smart_changed(wd->pan_smart);
|
||||
|
||||
t = ecore_time_get();
|
||||
#if 0
|
||||
printf("calc job %1.5f\n", t - t_start);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1111,7 +1148,7 @@ _update_job(void *data)
|
|||
{
|
||||
position = 1;
|
||||
itb->changed = EINA_TRUE;
|
||||
_item_block_recalc(itb, num0);
|
||||
_item_block_recalc(itb, num0, 0);
|
||||
_item_block_position(itb, num0);
|
||||
}
|
||||
}
|
||||
|
@ -1311,6 +1348,7 @@ elm_genlist_add(Evas_Object *parent)
|
|||
|
||||
wd->obj = obj;
|
||||
wd->mode = ELM_LIST_SCROLL;
|
||||
wd->max_items_per_block = 32;
|
||||
|
||||
evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
|
||||
evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
|
||||
|
@ -1502,7 +1540,7 @@ _item_block_add(Widget_Data *wd, Elm_Genlist_Item *it)
|
|||
if (wd->blocks)
|
||||
{
|
||||
itb = (Item_Block *)(wd->blocks);
|
||||
if (itb->count >= 32)
|
||||
if (itb->count >= wd->max_items_per_block)
|
||||
{
|
||||
itb = calloc(1, sizeof(Item_Block));
|
||||
if (!itb) return;
|
||||
|
@ -1527,7 +1565,7 @@ _item_block_add(Widget_Data *wd, Elm_Genlist_Item *it)
|
|||
if (wd->blocks)
|
||||
{
|
||||
itb = (Item_Block *)(wd->blocks->last);
|
||||
if (itb->count >= 32)
|
||||
if (itb->count >= wd->max_items_per_block)
|
||||
{
|
||||
itb = calloc(1, sizeof(Item_Block));
|
||||
if (!itb) return;
|
||||
|
@ -1570,7 +1608,7 @@ _item_block_add(Widget_Data *wd, Elm_Genlist_Item *it)
|
|||
_item_del(it->rel);
|
||||
it->rel = NULL;
|
||||
}
|
||||
if (itb->count > 32)
|
||||
if (itb->count > itb->wd->max_items_per_block)
|
||||
{
|
||||
int newc;
|
||||
Item_Block *itb2;
|
||||
|
@ -1604,11 +1642,11 @@ static int
|
|||
_item_idler(void *data)
|
||||
{
|
||||
Widget_Data *wd = data;
|
||||
int n;
|
||||
double t_start, t;
|
||||
int n, showme = 0;
|
||||
double t0, t;
|
||||
|
||||
t_start = ecore_time_get();
|
||||
for (n = 0; (wd->queue) && (n < 4); n++)
|
||||
t0 = ecore_time_get();
|
||||
for (n = 0; (wd->queue) && (n < 128); n++)
|
||||
{
|
||||
Elm_Genlist_Item *it;
|
||||
|
||||
|
@ -1617,14 +1655,14 @@ _item_idler(void *data)
|
|||
it->queued = EINA_FALSE;
|
||||
_item_block_add(wd, it);
|
||||
t = ecore_time_get();
|
||||
// FIXME: call calc job now
|
||||
// if ((t - t_start) > ecore_animator_frametime_get())
|
||||
// {
|
||||
// printf("abort idler\n");
|
||||
// break;
|
||||
// }
|
||||
if (it->block->changed)
|
||||
{
|
||||
showme = _item_block_recalc(it->block, it->block->num, 1);
|
||||
it->block->changed = 0;
|
||||
}
|
||||
if (showme) it->block->showme = 1;
|
||||
if ((t - t0) > (ecore_animator_frametime_get())) break;
|
||||
}
|
||||
// printf("%1.5f\n", t - t_start);
|
||||
if (n > 0)
|
||||
{
|
||||
if (wd->calc_job) ecore_job_del(wd->calc_job);
|
||||
|
@ -2729,3 +2767,43 @@ elm_genlist_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce)
|
|||
Widget_Data *wd = elm_widget_data_get(obj);
|
||||
elm_smart_scroller_bounce_allow_set(wd->scr, h_bounce, v_bounce);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set homogenous mode
|
||||
*
|
||||
* This will enable the homogeneous mode where items are of the same height and width
|
||||
* so that genlist may do the lazy-loading at its maximum. This implies 'compressed' mode
|
||||
*
|
||||
* @param obj The genlist object
|
||||
* @param homogeneous Assume the items within the genlist are of the same height and width
|
||||
*
|
||||
* @ingroup Genlist
|
||||
*/
|
||||
EAPI void
|
||||
elm_genlist_homogeneous_set(Evas_Object *obj, Eina_Bool homogeneous)
|
||||
{
|
||||
Widget_Data *wd = elm_widget_data_get(obj);
|
||||
|
||||
if (homogeneous)
|
||||
elm_genlist_compress_mode_set(obj, 1);
|
||||
wd->homogeneous = homogeneous;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum number of items within an item block
|
||||
*
|
||||
* This will configure the block count to tune to the target with particular performance matrix.
|
||||
*
|
||||
* @param obj The genlist object
|
||||
* @param n Maximum number of items within an item block
|
||||
*
|
||||
* @ingroup Genlist
|
||||
*/
|
||||
EAPI void
|
||||
elm_genlist_block_count_set(Evas_Object *obj, int n)
|
||||
{
|
||||
Widget_Data *wd = elm_widget_data_get(obj);
|
||||
wd->max_items_per_block = n;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue