more work on genlist!

SVN revision: 39002
This commit is contained in:
Carsten Haitzler 2009-02-12 13:39:43 +00:00
parent 1099280784
commit bb9742a604
4 changed files with 765 additions and 206 deletions

View File

@ -7021,4 +7021,419 @@ collections {
}
}
///////////////////////////////////////////////////////////////////////////////
group { name: "elm/genlist/item/default/default";
data.item: "stacking" "above";
data.item: "selectraise" "on";
data.item: "labels" "elm.text";
data.item: "icons" "elm.swallow.icon elm.swallow.end";
// data.item: "states" "";
images {
image: "bt_sm_base1.png" COMP;
image: "bt_sm_shine.png" COMP;
image: "bt_sm_hilight.png" COMP;
image: "ilist_1.png" COMP;
image: "ilist_item_shadow.png" COMP;
}
parts {
part {
name: "base_sh";
mouse_events: 0;
description {
state: "default" 0.0;
align: 0.0 0.0;
min: 0 10;
fixed: 1 1;
rel1 {
to: "base";
relative: 0.0 1.0;
offset: 0 0;
}
rel2 {
to: "base";
relative: 1.0 1.0;
offset: -1 0;
}
image {
normal: "ilist_item_shadow.png";
}
fill.smooth: 0;
}
}
part {
name: "base";
mouse_events: 0;
description {
state: "default" 0.0;
image {
normal: "ilist_1.png";
border: 2 2 2 2;
}
fill.smooth: 0;
}
}
part { name: "bg";
mouse_events: 0;
description { state: "default" 0.0;
visible: 0;
color: 255 255 255 0;
rel1 {
relative: 0.0 0.0;
offset: -5 -5;
}
rel2 {
relative: 1.0 1.0;
offset: 4 4;
}
image {
normal: "bt_sm_base1.png";
border: 6 6 6 6;
}
}
description { state: "selected" 0.0;
inherit: "default" 0.0;
visible: 1;
color: 255 255 255 255;
rel1 {
relative: 0.0 0.0;
offset: -2 -2;
}
rel2 {
relative: 1.0 1.0;
offset: 1 1;
}
}
}
part { name: "elm.swallow.icon";
type: SWALLOW;
description { state: "default" 0.0;
fixed: 1 0;
align: 0.0 0.5;
rel1 {
relative: 0.0 0.0;
offset: 4 4;
}
rel2 {
relative: 0.0 1.0;
offset: 4 -5;
}
}
}
part { name: "elm.swallow.end";
type: SWALLOW;
description { state: "default" 0.0;
fixed: 1 0;
align: 1.0 0.5;
aspect: 1.0 1.0;
aspect_preference: VERTICAL;
rel1 {
relative: 1.0 0.0;
offset: -5 4;
}
rel2 {
relative: 1.0 1.0;
offset: -5 -5;
}
}
}
part { name: "elm.text";
type: TEXT;
effect: SOFT_SHADOW;
mouse_events: 0;
scale: 1;
description {
state: "default" 0.0;
// min: 16 16;
rel1 {
to_x: "elm.swallow.icon";
relative: 1.0 0.0;
offset: 0 4;
}
rel2 {
to_x: "elm.swallow.end";
relative: 0.0 1.0;
offset: -1 -5;
}
color: 0 0 0 255;
color3: 0 0 0 0;
text {
font: "Sans";
size: 10;
min: 1 1;
// min: 0 1;
align: 0.0 0.5;
}
}
description { state: "selected" 0.0;
inherit: "default" 0.0;
color: 224 224 224 255;
color3: 0 0 0 64;
}
}
part { name: "fg1";
mouse_events: 0;
description { state: "default" 0.0;
visible: 0;
color: 255 255 255 0;
rel1.to: "bg";
rel2.relative: 1.0 0.5;
rel2.to: "bg";
image {
normal: "bt_sm_hilight.png";
border: 6 6 6 0;
}
}
description { state: "selected" 0.0;
inherit: "default" 0.0;
visible: 1;
color: 255 255 255 255;
}
}
part { name: "fg2";
mouse_events: 0;
description { state: "default" 0.0;
visible: 0;
color: 255 255 255 0;
rel1.to: "bg";
rel2.to: "bg";
image {
normal: "bt_sm_shine.png";
border: 6 6 6 0;
}
}
description { state: "selected" 0.0;
inherit: "default" 0.0;
visible: 1;
color: 255 255 255 255;
}
}
part {
name: "event";
type: RECT;
repeat_events: 1;
description {
state: "default" 0.0;
color: 0 0 0 0;
}
}
}
programs {
program {
name: "go_active";
signal: "elm,state,selected";
source: "elm";
action: STATE_SET "selected" 0.0;
target: "bg";
target: "fg1";
target: "fg2";
target: "elm.text";
}
program {
name: "go_passive";
signal: "elm,state,unselected";
source: "elm";
action: STATE_SET "default" 0.0;
target: "bg";
target: "fg1";
target: "fg2";
target: "elm.text";
transition: LINEAR 0.1;
}
}
}
group { name: "elm/genlist/item_odd/default/default";
data.item: "stacking" "below";
data.item: "selectraise" "on";
data.item: "labels" "elm.text";
data.item: "icons" "elm.swallow.icon elm.swallow.end";
// data.item: "states" "";
images {
image: "bt_sm_base1.png" COMP;
image: "bt_sm_shine.png" COMP;
image: "bt_sm_hilight.png" COMP;
image: "ilist_2.png" COMP;
}
parts {
part {
name: "base";
mouse_events: 0;
description {
state: "default" 0.0;
image {
normal: "ilist_2.png";
border: 2 2 2 2;
}
fill.smooth: 0;
}
}
part { name: "bg";
mouse_events: 0;
description { state: "default" 0.0;
visible: 0;
color: 255 255 255 0;
rel1 {
relative: 0.0 0.0;
offset: -5 -5;
}
rel2 {
relative: 1.0 1.0;
offset: 4 4;
}
image {
normal: "bt_sm_base1.png";
border: 6 6 6 6;
}
}
description { state: "selected" 0.0;
inherit: "default" 0.0;
visible: 1;
color: 255 255 255 255;
rel1 {
relative: 0.0 0.0;
offset: -2 -2;
}
rel2 {
relative: 1.0 1.0;
offset: 1 1;
}
}
}
part {
name: "elm.swallow.icon";
type: SWALLOW;
description { state: "default" 0.0;
fixed: 1 0;
align: 0.0 0.5;
rel1 {
relative: 0.0 0.0;
offset: 4 4;
}
rel2 {
relative: 0.0 1.0;
offset: 4 -5;
}
}
}
part {
name: "elm.swallow.end";
type: SWALLOW;
description { state: "default" 0.0;
fixed: 1 0;
align: 1.0 0.5;
rel1 {
relative: 1.0 0.0;
offset: -5 4;
}
rel2 {
relative: 1.0 1.0;
offset: -5 -5;
}
}
}
part {
name: "elm.text";
type: TEXT;
effect: SOFT_SHADOW;
mouse_events: 0;
scale: 1;
description {
state: "default" 0.0;
// min: 16 16;
rel1 {
to_x: "elm.swallow.icon";
relative: 1.0 0.0;
offset: 0 4;
}
rel2 {
to_x: "elm.swallow.end";
relative: 0.0 1.0;
offset: -1 -5;
}
color: 0 0 0 255;
color3: 0 0 0 0;
text {
font: "Sans";
size: 10;
min: 1 1;
// min: 0 1;
align: 0.0 0.5;
}
}
description { state: "selected" 0.0;
inherit: "default" 0.0;
color: 224 224 224 255;
color3: 0 0 0 64;
}
}
part { name: "fg1";
mouse_events: 0;
description { state: "default" 0.0;
visible: 0;
color: 255 255 255 0;
rel1.to: "bg";
rel2.relative: 1.0 0.5;
rel2.to: "bg";
image {
normal: "bt_sm_hilight.png";
border: 6 6 6 0;
}
}
description { state: "selected" 0.0;
inherit: "default" 0.0;
visible: 1;
color: 255 255 255 255;
}
}
part { name: "fg2";
mouse_events: 0;
description { state: "default" 0.0;
visible: 0;
color: 255 255 255 0;
rel1.to: "bg";
rel2.to: "bg";
image {
normal: "bt_sm_shine.png";
border: 6 6 6 0;
}
}
description { state: "selected" 0.0;
inherit: "default" 0.0;
visible: 1;
color: 255 255 255 255;
}
}
part {
name: "event";
type: RECT;
repeat_events: 1;
description {
state: "default" 0.0;
color: 0 0 0 0;
}
}
}
programs {
program {
name: "go_active";
signal: "elm,state,selected";
source: "elm";
action: STATE_SET "selected" 0.0;
target: "bg";
target: "fg1";
target: "fg2";
target: "elm.text";
}
program {
name: "go_passive";
signal: "elm,state,unselected";
source: "elm";
action: STATE_SET "default" 0.0;
target: "bg";
target: "fg1";
target: "fg2";
target: "elm.text";
transition: LINEAR 0.1;
}
}
}
}

View File

@ -2086,13 +2086,13 @@ my_bt_29(void *data, Evas_Object *obj, void *event_info)
evas_object_size_hint_weight_set(gl, 1.0, 1.0);
evas_object_show(gl);
itc1.style = "default";
itc1.style = "default";
itc1.func.label_get = gl_label_get;
itc1.func.icon_get = gl_icon_get;
itc1.func.icon_get = gl_icon_get;
itc1.func.state_get = gl_state_get;
itc1.func.del = gl_del;
itc1.func.del = gl_del;
for (i = 0; i < 2000; i++)
for (i = 0; i < 10000; i++)
{
gli = elm_genlist_item_append(gl, &itc1, (void *)i/* item data */,
NULL/* parent */, ELM_GENLIST_ITEM_NONE,

View File

@ -540,17 +540,15 @@ extern "C" {
//// (incomplete - medium priority)
// * entry selection conflicts with finger scroll (make selection start/stop work on signals?)
// * disabled not supported
// * tab widget focusing (not useful for touchscreen tho...)
// * on the fly theme changes - test (should work)
// * need a hold-scroll counter in elm_widget
// * add fullscreen mode on/off for windows
// * hoversel only vertical right now - make horizontal
// * set scaling per widget (and if scaling should be inherited by children)
// * when entries are in a scroller and change size, the scroller shows scrollbars. fix. same for selecting. for 1 line entries in a scroller should only have scroll arrow indicators.
//
//// (more widgets/features - medium priority)
// * biglist widget (restricted format label + icon intended for massive lists)
// * treeview widget (like biglist - but items can expand to sub-items)
// * genlist widget (complex list widget - harder to use than normal simple list, but handles huge lists of items etc.)
// * tree feature fir genlist widget (like biglist - but items can expand to sub-items)
// * radio + group handling
// * checkbox (like toggle)
// * pager (for pushing/popping pages and going back and forward and flipping)
@ -577,7 +575,7 @@ extern "C" {
// * dialpad widget - need one with a phone dialpad
// * file selector widget
// * progress bar widget
// * generic "tacho" widget (set min/max labels - and up to 3 intermediate labels)
// * generic "tacho" widget (set min/max labels - and up to 3 intermediate labels etc.)
// * status widget (busy, stalled, running, etc.)
// * full window in window widget (so move/resize of window object does as you'd expect a child window to do within the canvas)
//
@ -588,19 +586,24 @@ extern "C" {
// * use evas's new box instead of a box smart
// * use evas's table instead of a table smart
// * use stack for win widget
// * prepend or append theme files from code for an app to allow an app to augment the theme eithe rby forcibly overriding things with its own theme file (so it can ship some custom elements that always override user theme) and so it can also provide a final (even after default) fallback for "extended" styles of its own (but thus allowing themes to overried its extensions if they want)
// * determine prefix of app dynamically and export calls to get prefix info
// * load config from file
// * load config from x prpoerty
// * handle finger size property and on-the-fly changes like scaling does
// * somehow a pdf(ps) viewer widget that doesnt make it gpl (lgpl)
// * emotion widget?
// * emotion widget
// * ewebkit widget
// * flash (gnash) widget
// * need url and path entry modes for vkbd
// * return list of toplevel window objects
// * widgets should show who is focused (not useful for touchscreen)
// * focus should have an object that is layered above all others (definable layer) that moves + resizes (slides about - animated) from one focused widget to the next for focus. also emit focus/unfocus signals too
// * scroller could do with page up/down/left/right buttons and and idea of a page size
// * current sizing tree inefficient
// * need a way to filter entry data for entry (eg for phone numbers)
// * win should emit signals based on vkbd type - if it gets a message and is a vkbd win
// * win needs a way of setting aspect too
// * use the wrong call on the wrong widget and *BOOM*
// * use the wrong call on the wrong widget and *BOOM* ... crashland
//
//////////////////////////////////////////////////////////////////////////////
#endif

View File

@ -8,6 +8,7 @@ typedef struct _Pan Pan;
struct _Widget_Data
{
Evas_Object *obj;
Evas_Object *scr;
Evas_Object *pan_smart;
Evas_Object *content;
@ -15,6 +16,9 @@ struct _Widget_Data
Eina_Inlist *blocks;
Pan *pan;
Evas_Coord pan_x, pan_y, minw, minh;
Ecore_Job *calc_job;
Ecore_Idler *queue_idler;
Eina_List *queue;
Evas_Bool min_w : 1;
Evas_Bool min_h : 1;
};
@ -24,7 +28,6 @@ struct _Item_Block
Eina_Inlist __header;
int count;
Widget_Data *wd;
Evas_Object *obj;
Eina_List *items;
Evas_Coord x, y, w, h, minw, minh;
Evas_Bool realized : 1;
@ -34,17 +37,11 @@ struct _Item_Block
struct _Item
{
Eina_Inlist __header;
Widget_Data *wd;
Item_Block *block;
Eina_Inlist *subblocks; // not done yet
Eina_Inlist *subitems; // not done yet
Eina_Inlist *subblocks; // FIXME: not done yet
Eina_Inlist *subitems; // FIXME: not done yet
Evas_Coord x, y, w, h, minw, minh;
Evas_Bool realized : 1;
Evas_Bool selected : 1;
Evas_Bool expanded : 1; // not done yet
Evas_Bool disabled : 1;
Evas_Bool mincalcd : 1;
const Elm_Genlist_Item_Class *itc;
const void *data;
Elm_Genlist_Item *parent; // not done yet
@ -55,6 +52,15 @@ struct _Item
} func;
Evas_Object *base;
Eina_List *labels, *icons, *states;
Evas_Bool realized : 1;
Evas_Bool selected : 1;
Evas_Bool expanded : 1; // FIXME: not done yet
Evas_Bool disabled : 1;
Evas_Bool mincalcd : 1;
Evas_Bool queued : 1;
};
struct _Pan {
@ -154,6 +160,231 @@ _resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
_sizing_eval(data);
}
static Eina_List *
_stringlist_get(const char *str)
{
Eina_List *list = NULL;
const char *s, *b;
if (!str) return NULL;
for (b = s = str; 1; s++)
{
if ((*s == ' ') || (*s == 0))
{
char *t = malloc(s - b + 1);
if (t)
{
strncpy(t, b, s - b);
t[s - b] = 0;
list = eina_list_append(list, eina_stringshare_add(t));
free(t);
}
b = s + 1;
}
if (*s == 0) break;
}
return list;
}
static void
_stringlist_free(Eina_List *list)
{
while (list)
{
eina_stringshare_del(list->data);
list = eina_list_remove_list(list, list);
}
}
static void
_item_realize(Item *it, int in, int calc)
{
const char *stacking;
char buf[1024];
if (it->realized) return;
it->base = edje_object_add(evas_object_evas_get(it->wd->obj));
evas_object_smart_member_add(it->base, it->wd->pan_smart);
elm_widget_sub_object_add(it->wd->obj, it->base);
if (in & 0x1)
snprintf(buf, sizeof(buf), "%s/%s", "item_odd", it->itc->style);
else
snprintf(buf, sizeof(buf), "%s/%s", "item", it->itc->style);
_elm_theme_set(it->base, "genlist", buf, "default");
if (!calc)
{
stacking = edje_object_data_get(it->base, "stacking");
if (stacking)
{
if (!strcmp(stacking, "below")) evas_object_lower(it->base);
else if (!strcmp(stacking, "above")) evas_object_raise(it->base);
}
// FIXME: hook callbacks
// evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_DOWN,
// _mouse_down, it);
// evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_UP,
// _mouse_up, it);
}
if (it->itc->func.label_get)
{
Eina_List *l;
it->labels = _stringlist_get(edje_object_data_get(it->base, "labels"));
for (l = it->labels; l; l = l->next)
{
const char *key = l->data;
char *s = it->itc->func.label_get(it->data, l->data);
if (s)
{
edje_object_part_text_set(it->base, l->data, s);
free(s);
}
}
}
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->minw = mw;
it->minh = mh;
it->mincalcd = 1;
}
if (!calc) evas_object_show(it->base);
it->realized = 1;
}
static void
_item_unrealize(Item *it)
{
if (!it->realized) return;
evas_object_del(it->base);
it->base = NULL;
_stringlist_free(it->labels);
it->labels = NULL;
_stringlist_free(it->icons);
it->icons = NULL;
_stringlist_free(it->states);
it->states = NULL;
it->realized = 0;
}
static void
_item_block_recalc(Item_Block *itb, int in)
{
Eina_List *l;
Evas_Coord minw = 0, minh = 0;
for (l = itb->items; l; l = l->next)
{
Item *it = l->data;
if (!itb->realized)
{
_item_realize(it, in, 1);
_item_unrealize(it);
}
else
_item_realize(it, in, 0);
minh += it->minh;
if (minw < it->minw) minw = it->minw;
in++;
}
itb->minw = minw;
itb->minh = minh;
itb->changed = 0;
/* force an evas norender to garbage collect deleted objects */
evas_norender(evas_object_evas_get(itb->wd->obj));
}
static void
_item_block_realize(Item_Block *itb, int in)
{
Eina_List *l;
if (itb->realized) return;
for (l = itb->items; l; l = l->next)
{
Item *it = l->data;
_item_realize(it, in, 0);
in++;
}
itb->realized = 1;
}
static void
_item_block_unrealize(Item_Block *itb)
{
Eina_List *l;
if (!itb->realized) return;
for (l = itb->items; l; l = l->next)
{
Item *it = l->data;
_item_unrealize(it);
}
itb->realized = 0;
}
static void
_item_block_position(Item_Block *itb)
{
Eina_List *l;
Evas_Coord y = 0, ox, oy;
evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, NULL, NULL);
for (l = itb->items; l; l = l->next)
{
Item *it = l->data;
it->x = 0;
it->y = y;
it->w = itb->w;
it->h = it->minh;
evas_object_resize(it->base, it->w, it->h);
evas_object_move(it->base,
ox + itb->x + it->x - itb->wd->pan_x,
oy + itb->y + it->y - itb->wd->pan_y);
evas_object_show(it->base);
y += it->h;
}
itb->realized = 1;
}
static void
_calc_job(void *data)
{
Widget_Data *wd = data;
Eina_Inlist *il;
Evas_Coord minw = 0, minh = 0, x = 0, y = 0, ow, oh;
int bn, in;
for (bn = 0, in = 0, il = wd->blocks; il; il = il->next, bn++)
{
Item_Block *itb = (Item_Block *)il;
if (itb->changed)
_item_block_recalc(itb, in);
itb->y = y;
itb->x = 0;
itb->w = itb->minw;
itb->h = itb->minh;
minh += itb->minh;
if (minw < itb->minw) minw = itb->minw;
itb->h = itb->minh;
y += itb->minh;
in += itb->count;
}
evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh);
if (minw < ow) minw = ow;
if ((minw != wd->minw) || (minh != wd->minh))
{
wd->minw = minw;
wd->minh = minh;
evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
}
wd->calc_job = NULL;
evas_object_smart_changed(wd->pan_smart);
}
static void
_pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
{
@ -230,148 +461,12 @@ _pan_del(Evas_Object *obj)
static void
_pan_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
{
Pan *sd = evas_object_smart_data_get(obj);
Evas_Coord ow, oh;
evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
if ((ow == w) && (oh == h)) return;
evas_object_smart_changed(obj);
}
static void
_item_realize(Item *it, int in)
{
const char *stacking;
if (it->realized) return;
it->base = edje_object_add(evas_object_evas_get(it->block->obj));
// FIXME: hook callbacks
// evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_DOWN,
// _mouse_down, it);
// evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_UP,
// _mouse_up, it);
evas_object_smart_member_add(it->base, it->block->wd->pan_smart);
elm_widget_sub_object_add(it->block->obj, it->base);
if (in & 0x1)
_elm_theme_set(it->base, "list", "item_odd", "default");
else
_elm_theme_set(it->base, "list", "item", "default");
stacking = edje_object_data_get(it->base, "stacking");
if (stacking)
{
if (!strcmp(stacking, "below"))
evas_object_lower(it->base);
else if (!strcmp(stacking, "above"))
evas_object_raise(it->base);
}
if (it->itc->func.label_get)
{
char *s = it->itc->func.label_get(it->data, "xxx");
if (s)
{
edje_object_part_text_set(it->base, "elm.text", s);
free(s);
}
}
// FIXME: need to get all labels, all icons and all states and all labels
evas_object_show(it->base);
if (!it->mincalcd)
{
Evas_Coord mw, mh;
mw = 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->minw = mw;
it->minh = mh;
it->mincalcd = 1;
}
it->realized = 1;
}
static void
_item_unrealize(Item *it)
{
if (!it->realized) return;
evas_object_del(it->base);
it->base = NULL;
it->realized = 0;
}
static void
_item_block_recalc(Item_Block *itb, int in)
{
Eina_List *l;
Evas_Coord minw = 0, minh = 0;
for (l = itb->items; l; l = l->next)
{
Item *it = l->data;
_item_realize(it, in);
if (!itb->realized) _item_unrealize(it);
minh += it->minh;
if (minw < it->minw) minw = it->minw;
in++;
}
itb->minw = minw;
itb->minh = minh;
itb->changed = 0;
}
static void
_item_block_realize(Item_Block *itb, int in)
{
Eina_List *l;
if (itb->realized) return;
for (l = itb->items; l; l = l->next)
{
Item *it = l->data;
_item_realize(it, in);
in++;
}
itb->realized = 1;
}
static void
_item_block_unrealize(Item_Block *itb)
{
Eina_List *l;
if (!itb->realized) return;
for (l = itb->items; l; l = l->next)
{
Item *it = l->data;
_item_unrealize(it);
}
itb->realized = 0;
}
static void
_item_block_position(Item_Block *itb)
{
Eina_List *l;
Evas_Coord y = 0, ox, oy;
evas_object_geometry_get(itb->wd->pan_smart, &ox, &oy, NULL, NULL);
for (l = itb->items; l; l = l->next)
{
Item *it = l->data;
it->x = 0;
it->y = y;
it->w = itb->w;
it->h = it->minh;
evas_object_resize(it->base, it->w, it->h);
evas_object_move(it->base,
ox + itb->x + it->x - itb->wd->pan_x,
oy + itb->y + it->y - itb->wd->pan_y);
y += it->h;
}
itb->realized = 1;
if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
}
static void
@ -379,46 +474,21 @@ _pan_calculate(Evas_Object *obj)
{
Pan *sd = evas_object_smart_data_get(obj);
Eina_Inlist *il;
Evas_Coord minw = 0, minh = 0, x = 0, y = 0, ow, oh;
Evas_Coord ow, oh;
int bn, in;
for (bn = 0, in = 0, il = sd->wd->blocks; il; il = il->next, bn++)
{
Item_Block *itb = (Item_Block *)il;
if (itb->changed)
_item_block_recalc(itb, in);
itb->y = y;
itb->x = 0;
itb->w = itb->minw;
itb->h = itb->minh;
minh += itb->minh;
if (minw < itb->minw) minw = itb->minw;
itb->h = itb->minh;
y += itb->minh;
in += itb->count;
}
evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
if (minw < ow) minw = ow;
if ((minw != sd->wd->minw) || (minh != sd->wd->minh))
{
sd->wd->minw = minw;
sd->wd->minh = minh;
evas_object_smart_callback_call(obj, "changed", NULL);
}
// FIXME: calcualte new geom
for (bn = 0, in = 0, il = sd->wd->blocks; il; il = il->next, bn++)
{
Item_Block *itb = (Item_Block *)il;
itb->w = minw;
itb->w = sd->wd->minw;
if (ELM_RECTS_INTERSECT(itb->x - sd->wd->pan_x,
itb->y - sd->wd->pan_y,
itb->w, itb->h,
0, 0, ow, oh))
{
if (!itb->realized)
if ((!itb->realized) || (itb->changed))
{
printf("REALIZE BN # %i [%i %i, %ix%i]\n", bn, itb->x, itb->y, itb->w, itb->h);
_item_block_realize(itb, in);
}
_item_block_position(itb);
@ -427,7 +497,6 @@ _pan_calculate(Evas_Object *obj)
{
if (itb->realized)
{
printf("UNREALIZE BN # %i [%i %i, %ix%i]\n", bn, itb->x, itb->y, itb->w, itb->h);
_item_block_unrealize(itb);
}
}
@ -453,6 +522,8 @@ elm_genlist_add(Evas_Object *parent)
wd->scr = elm_smart_scroller_add(e);
elm_widget_resize_object_set(obj, wd->scr);
wd->obj = obj;
if (!smart)
{
@ -489,7 +560,7 @@ elm_genlist_add(Evas_Object *parent)
}
static Item *
_item_new(Evas_Object *obj, const Elm_Genlist_Item_Class *itc,
_item_new(Widget_Data *wd, const Elm_Genlist_Item_Class *itc,
const void *data, Elm_Genlist_Item *parent,
Elm_Genlist_Item_Flags flags,
void (*func) (void *data, Evas_Object *obj, void *event_info), const void *func_data)
@ -498,6 +569,7 @@ _item_new(Evas_Object *obj, const Elm_Genlist_Item_Class *itc,
it = calloc(1, sizeof(Item));
if (!it) return NULL;
it->wd = wd;
it->itc = itc;
it->data = data;
it->parent = parent;
@ -508,7 +580,7 @@ _item_new(Evas_Object *obj, const Elm_Genlist_Item_Class *itc,
}
static void
_item_block_add(Widget_Data *wd, Evas_Object *obj, Item *it, Item *itpar, Item *itrel)
_item_block_add(Widget_Data *wd, Item *it, Item *itpar, Item *itrel, int before)
{
Item_Block *itb;
@ -517,9 +589,28 @@ _item_block_add(Widget_Data *wd, Evas_Object *obj, Item *it, Item *itpar, Item *
newblock:
itb = calloc(1, sizeof(Item_Block));
if (!itb) return;
wd->blocks = eina_inlist_append(wd->blocks, (Eina_Inlist *)itb);
itb->obj = obj;
itb->wd = wd;
if (!it->parent)
{
if (itrel)
{
if (!itrel->block)
printf("EEEK itrel has no block!\n");
else
{
if (before)
wd->blocks = eina_inlist_prepend_relative(wd->blocks, (Eina_Inlist *)itb, (Eina_Inlist *)(itrel->block));
else
wd->blocks = eina_inlist_append_relative(wd->blocks, (Eina_Inlist *)itb, (Eina_Inlist *)(itrel->block));
}
}
else
wd->blocks = eina_inlist_append(wd->blocks, (Eina_Inlist *)itb);
}
else
{
// FIXME: tree not handled.
}
}
else
{
@ -530,7 +621,62 @@ _item_block_add(Widget_Data *wd, Evas_Object *obj, Item *it, Item *itpar, Item *
itb->count++;
itb->changed = 1;
it->block = itb;
evas_object_smart_changed(wd->pan_smart);
if (itb->wd->calc_job) ecore_job_del(itb->wd->calc_job);
itb->wd->calc_job = ecore_job_add(_calc_job, itb->wd);
}
static int
_item_idler(void *data)
{
Widget_Data *wd = data;
int n;
for (n = 0; (wd->queue) && (n < 16); n++)
{
Item *itrel, *it;
it = wd->queue->data;
wd->queue = eina_list_remove_list(wd->queue, wd->queue);
it->queued = 0;
if (!it->parent)
{
itrel = (Item *)(((Eina_Inlist *)it)->prev);
if (itrel) _item_block_add(wd, it, NULL, itrel, 0);
else
{
itrel = (Item *)(((Eina_Inlist *)it)->next);
if (itrel && itrel->queued)
_item_block_add(wd, it, NULL, NULL, 0);
else
_item_block_add(wd, it, NULL, itrel, 1);
}
}
else
{
// FIXME: tree. not done yet
}
}
if (n > 0)
{
// queue a draw
if (wd->calc_job) ecore_job_del(wd->calc_job);
wd->calc_job = ecore_job_add(_calc_job, wd);
}
if (!wd->queue)
{
wd->queue_idler = NULL;
return 0;
}
return 1;
}
static void
_item_queue(Widget_Data *wd, Item *it)
{
if (it->queued) return;
if (!wd->queue_idler) wd->queue_idler = ecore_idler_add(_item_idler, wd);
it->queued = 1;
wd->queue = eina_list_append(wd->queue, it);
}
EAPI Elm_Genlist_Item *
@ -540,21 +686,16 @@ elm_genlist_item_append(Evas_Object *obj, const Elm_Genlist_Item_Class *itc,
void (*func) (void *data, Evas_Object *obj, void *event_info), const void *func_data)
{
Widget_Data *wd = elm_widget_data_get(obj);
Item *itpar, *itrel;
Item *it = _item_new(obj, itc, data, parent, flags, func, func_data);
Item *itpar;
Item *it = _item_new(wd, itc, data, parent, flags, func, func_data);
if (!it) return NULL;
if (!parent)
{
wd->items = eina_inlist_append(wd->items, (Eina_Inlist *)it);
itrel = (Item *)(((Eina_Inlist *)it)->prev);
_item_block_add(wd, obj, it, NULL, itrel);
}
if (!it->parent)
wd->items = eina_inlist_append(wd->items, (Eina_Inlist *)it);
else
{
// FIXME: tree. not done yet
itpar = (Item *)parent;
itpar->subitems = eina_inlist_append(itpar->subitems, (Eina_Inlist *)it);
}
_item_queue(wd, it);
return (Elm_Genlist_Item *)it;
}