This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch master
in repository evisum.

View the commit online.

commit 5ea010d277c86cb6e8e6f0b86aedfeadd5740d02
Author: Alastair Poole <[email protected]>
AuthorDate: Sat Mar 28 01:16:29 2026 +0000

    WIP: WIP WIP WIP
---
 src/bin/evisum_ui_widget_example.c  |  71 ++++---------
 src/bin/ui/evisum_ui_process_list.c | 167 ++++++++++++------------------
 src/bin/ui/evisum_ui_process_view.c | 145 ++++++++------------------
 src/bin/ui/evisum_ui_widget_exel.c  | 200 +++++++++++++++++++++++++++---------
 src/bin/ui/evisum_ui_widget_exel.h  |  94 +++++++----------
 5 files changed, 310 insertions(+), 367 deletions(-)

diff --git a/src/bin/evisum_ui_widget_example.c b/src/bin/evisum_ui_widget_example.c
index e779b3e..9eeddb2 100644
--- a/src/bin/evisum_ui_widget_example.c
+++ b/src/bin/evisum_ui_widget_example.c
@@ -36,36 +36,6 @@ _item_del(void *data, Evas_Object *obj EINA_UNUSED) {
     _row_free(data);
 }
 
-static Evas_Object *
-_item_factory(Evas_Object *parent) {
-    Evisum_Ui_Widget_Exel_Item_Cell_Def defs[] = {
-        { .type = EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,
-         .key = "cmd",
-         .align_x = 0.0,
-         .weight_x = EVAS_HINT_EXPAND,
-         .boxed = 1,
-         .spacer = 6,
-         .icon_size = 0 },
-        { .type = EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,
-         .key = "mem_size",
-         .align_x = 1.0,
-         .weight_x = EVAS_HINT_EXPAND,
-         .boxed = 1,
-         .spacer = 6,
-         .icon_size = 0 },
-        { .type = EVISUM_UI_WIDGET_EXEL_ITEM_CELL_PROGRESS,
-         .key = "cpu_usage",
-         .unit_format = "%1.1f %%",
-         .align_x = EVAS_HINT_FILL,
-         .weight_x = EVAS_HINT_EXPAND,
-         .boxed = 0,
-         .spacer = 0,
-         .icon_size = 0 },
-    };
-
-    return evisum_ui_widget_exel_item_row_add(parent, defs, 3);
-}
-
 static Evas_Object *
 _content_get(void *data, Evas_Object *obj, const char *source) {
     Example_Row *row = data;
@@ -76,7 +46,7 @@ _content_get(void *data, Evas_Object *obj, const char *source) {
     if (strcmp(source, "elm.swallow.content")) return NULL;
     if (!row) return NULL;
 
-    wx = evas_object_data_get(obj, "wx");
+    wx = evas_object_data_get(obj, "widget_exel");
     if (!wx) return NULL;
 
     item = evisum_ui_widget_exel_item_cache_object_get(wx);
@@ -156,7 +126,6 @@ elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED) {
     Evas_Object *win, *root;
     Evisum_Ui_Widget_Exel *wx;
     Evisum_Ui_Widget_Exel_Field_Params fp;
-    Evisum_Ui_Widget_Exel_Genlist_Params gp;
     Elm_Genlist_Item_Class itc;
     Ecore_Timer *timer;
 
@@ -180,6 +149,12 @@ elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED) {
         .id = EX_FIELD_CMD,
         .title = "command",
         .desc = "Command",
+        .key = "cmd",
+        .type = EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,
+        .align_x = 0.0,
+        .weight_x = EVAS_HINT_EXPAND,
+        .boxed = EINA_TRUE,
+        .spacer = 6,
         .default_width = 160,
         .min_width = 90,
         .always_visible = EINA_TRUE,
@@ -191,6 +166,12 @@ elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED) {
         .id = EX_FIELD_MEM_SIZE,
         .title = "mem size",
         .desc = "Memory Size",
+        .key = "mem_size",
+        .type = EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,
+        .align_x = 1.0,
+        .weight_x = EVAS_HINT_EXPAND,
+        .boxed = EINA_TRUE,
+        .spacer = 6,
         .default_width = 120,
         .min_width = 80,
         .always_visible = EINA_FALSE,
@@ -202,6 +183,12 @@ elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED) {
         .id = EX_FIELD_CPU_USAGE,
         .title = "cpu %",
         .desc = "CPU Usage",
+        .key = "cpu_usage",
+        .unit_format = "%1.1f %%",
+        .type = EVISUM_UI_WIDGET_EXEL_ITEM_CELL_PROGRESS,
+        .align_x = EVAS_HINT_FILL,
+        .weight_x = EVAS_HINT_EXPAND,
+        .boxed = EINA_FALSE,
         .default_width = 150,
         .min_width = 90,
         .always_visible = EINA_FALSE,
@@ -211,22 +198,7 @@ elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED) {
 
     evisum_ui_widget_exel_fields_apply(wx);
 
-    gp.homogeneous = EINA_TRUE;
-    gp.focus_allow = EINA_TRUE;
-    gp.multi_select = EINA_FALSE;
-    gp.bounce_h = EINA_FALSE;
-    gp.bounce_v = EINA_FALSE;
-    gp.select_mode = ELM_OBJECT_SELECT_MODE_NONE;
-    gp.policy_h = ELM_SCROLLER_POLICY_OFF;
-    gp.policy_v = ELM_SCROLLER_POLICY_AUTO;
-    gp.weight_x = EVAS_HINT_EXPAND;
-    gp.weight_y = EVAS_HINT_EXPAND;
-    gp.align_x = EVAS_HINT_FILL;
-    gp.align_y = EVAS_HINT_FILL;
-    gp.data_key = "wx";
-    gp.data = ""
-
-    evisum_ui_widget_exel_genlist_attach(wx, &gp);
+    elm_box_pack_end(root, evisum_ui_widget_exel_genlist_add(wx, root));
 
     itc.item_style = "full";
     itc.func.text_get = NULL;
@@ -234,9 +206,6 @@ elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED) {
     itc.func.filter_get = NULL;
     itc.func.del = _item_del;
 
-    evisum_ui_widget_exel_genlist_unrealized_release_enable(wx, EINA_TRUE);
-    evisum_ui_widget_exel_item_cache_configure(wx, _item_factory, 16);
-
     _fill_demo_rows(wx, &itc);
     timer = ecore_timer_add(1.0, _update_timer_cb, wx);
     evas_object_data_set(win, "timer", timer);
diff --git a/src/bin/ui/evisum_ui_process_list.c b/src/bin/ui/evisum_ui_process_list.c
index 88ba061..9008e8e 100644
--- a/src/bin/ui/evisum_ui_process_list.c
+++ b/src/bin/ui/evisum_ui_process_list.c
@@ -120,12 +120,6 @@ _evisum_ui_process_list_field_meta_get(Proc_Field id) {
     return &_proc_field_info[id];
 }
 
-static Eina_Bool
-_evisum_ui_process_list_fields_enabled(const Evisum_Ui_Process_List_View *view, Proc_Field id) {
-    if (!view || !view->ui) return 0;
-    return evisum_ui_widget_exel_field_enabled_get(view->widget_exel, id);
-}
-
 static int
 _evisum_ui_process_list_field_default_width_get(Proc_Field id) {
     if (id == PROC_FIELD_CMD) return 2.0 * ELM_SCALE_SIZE(BTN_WIDTH);
@@ -154,6 +148,53 @@ _evisum_ui_process_list_field_sort_get(Proc_Field id) {
     return info->sort;
 }
 
+static Eina_Bool
+_evisum_ui_process_list_field_row_def_get(Proc_Field id, Evisum_Ui_Widget_Exel_Item_Cell_Def *def) {
+    if (!def) return EINA_FALSE;
+
+    *def = (Evisum_Ui_Widget_Exel_Item_Cell_Def) {
+        .type = EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,
+        .align_x = 1.0,
+        .weight_x = EXPAND,
+        .boxed = EINA_TRUE,
+        .spacer = ELM_SCALE_SIZE(6),
+        .icon_size = 0,
+    };
+
+    switch (id) {
+        case PROC_FIELD_CMD:
+            def->type = EVISUM_UI_WIDGET_EXEL_ITEM_CELL_CMD;
+            def->key = "cmd";
+            def->aux_key = "icon";
+            def->align_x = 0.0;
+            def->boxed = EINA_FALSE;
+            def->spacer = ELM_SCALE_SIZE(4);
+            def->icon_size = 16;
+            return EINA_TRUE;
+        case PROC_FIELD_UID: def->key = "uid"; def->align_x = 0.0; return EINA_TRUE;
+        case PROC_FIELD_PID: def->key = "pid"; return EINA_TRUE;
+        case PROC_FIELD_THREADS: def->key = "thr"; return EINA_TRUE;
+        case PROC_FIELD_CPU: def->key = "cpu"; return EINA_TRUE;
+        case PROC_FIELD_PRI: def->key = "prio"; return EINA_TRUE;
+        case PROC_FIELD_NICE: def->key = "nice"; return EINA_TRUE;
+        case PROC_FIELD_FILES: def->key = "files"; return EINA_TRUE;
+        case PROC_FIELD_NET_IN: def->key = "net_in"; return EINA_TRUE;
+        case PROC_FIELD_NET_OUT: def->key = "net_out"; return EINA_TRUE;
+        case PROC_FIELD_SIZE: def->key = "size"; return EINA_TRUE;
+        case PROC_FIELD_VIRT: def->key = "virt"; return EINA_TRUE;
+        case PROC_FIELD_RSS: def->key = "rss"; return EINA_TRUE;
+        case PROC_FIELD_SHARED: def->key = "share"; return EINA_TRUE;
+        case PROC_FIELD_STATE: def->key = "state"; return EINA_TRUE;
+        case PROC_FIELD_TIME: def->key = "time"; return EINA_TRUE;
+        case PROC_FIELD_CPU_USAGE:
+            def->type = EVISUM_UI_WIDGET_EXEL_ITEM_CELL_PROGRESS;
+            def->key = "cpu_u";
+            def->unit_format = "%1.1f %%";
+            return EINA_TRUE;
+        default: return EINA_FALSE;
+    }
+}
+
 static void
 _evisum_ui_process_list_field_proportions_apply(Evisum_Ui_Process_List_View *view) {
     evisum_ui_widget_exel_field_proportions_apply(view->widget_exel);
@@ -233,27 +274,22 @@ _evisum_ui_process_list_fields_resize_done_cb(void *data) {
 
 static void
 _evisum_ui_process_list_fields_init(Evisum_Ui_Process_List_View *view) {
-    Evisum_Ui_Widget_Exel_Params p = {
-        .win = view->win,
-        .parent = view->win,
-        .field_first = PROC_FIELD_CMD,
-        .field_max = PROC_FIELD_MAX,
-        .resize_hit_width = PROC_COL_RESIZE_HIT_WIDTH,
-        .fields_mask = &view->ui->proc.fields,
-        .field_widths = view->ui->proc.field_widths,
-        .reference_mask_get_cb = _evisum_ui_process_list_fields_reference_mask_get_cb,
-        .fields_changed_cb = _evisum_ui_process_list_fields_changed_cb,
-        .fields_applied_cb = _evisum_ui_process_list_fields_applied_cb,
-        .resize_live_cb = _evisum_ui_process_list_fields_resize_live_cb,
-        .resize_done_cb = _evisum_ui_process_list_fields_resize_done_cb,
-        .data = ""
-    };
+    view->widget_exel = evisum_ui_widget_exel_create(view->win);
+    if (!view->widget_exel) return;
 
-    view->widget_exel = evisum_ui_widget_exel_add(&p);
+    evisum_ui_widget_exel_field_bounds_set(view->widget_exel, PROC_FIELD_CMD, PROC_FIELD_MAX);
+    evisum_ui_widget_exel_resize_hit_width_set(view->widget_exel, PROC_COL_RESIZE_HIT_WIDTH);
+    evisum_ui_widget_exel_state_bind(view->widget_exel, &view->ui->proc.fields, view->ui->proc.field_widths);
+    evisum_ui_widget_exel_callbacks_set(view->widget_exel, _evisum_ui_process_list_fields_reference_mask_get_cb,
+                                        _evisum_ui_process_list_fields_changed_cb,
+                                        _evisum_ui_process_list_fields_applied_cb,
+                                        _evisum_ui_process_list_fields_resize_live_cb,
+                                        _evisum_ui_process_list_fields_resize_done_cb, view);
 
     for (int i = PROC_FIELD_CMD; i < PROC_FIELD_MAX; i++) {
         Proc_Sort type;
         Evas_Object *btn;
+        Evisum_Ui_Widget_Exel_Item_Cell_Def row_def;
         const Proc_Field_Info *meta;
         const char *name, *desc;
 
@@ -271,6 +307,9 @@ _evisum_ui_process_list_fields_init(Evisum_Ui_Process_List_View *view) {
         evisum_ui_widget_exel_field_register(view->widget_exel, i, btn, desc,
                                              _evisum_ui_process_list_field_default_width_get(i),
                                              _evisum_ui_process_list_field_min_width_get(i), i == PROC_FIELD_CMD);
+        if (_evisum_ui_process_list_field_row_def_get(i, &row_def)) {
+            evisum_ui_widget_exel_field_row_def_set(view->widget_exel, i, &row_def);
+        }
         evisum_ui_widget_exel_field_resize_attach(view->widget_exel, btn, i);
         evisum_ui_widget_exel_field_width_apply(view->widget_exel, i);
         evas_object_event_callback_add(btn, EVAS_CALLBACK_MOUSE_UP, _evisum_ui_process_list_fields_mouse_up_cb, view);
@@ -299,66 +338,6 @@ _evisum_ui_process_list_item_del(void *data, Evas_Object *obj EINA_UNUSED) {
     proc_info_free(proc);
 }
 
-static Evas_Object *
-_evisum_ui_process_list_item_create(Evas_Object *obj) {
-    typedef struct {
-        Proc_Field type;
-        const char *key;
-        Evisum_Ui_Widget_Exel_Item_Cell_Type cell_type;
-        double align_x;
-    } Proc_List_Row_Field;
-    static const Proc_List_Row_Field fields[] = {
-        { PROC_FIELD_UID,       "uid",     EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,     0.0 },
-        { PROC_FIELD_PID,       "pid",     EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,     1.0 },
-        { PROC_FIELD_THREADS,   "thr",     EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,     1.0 },
-        { PROC_FIELD_CPU,       "cpu",     EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,     1.0 },
-        { PROC_FIELD_PRI,       "prio",    EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,     1.0 },
-        { PROC_FIELD_NICE,      "nice",    EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,     1.0 },
-        { PROC_FIELD_FILES,     "files",   EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,     1.0 },
-        { PROC_FIELD_NET_IN,    "net_in",  EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,     1.0 },
-        { PROC_FIELD_NET_OUT,   "net_out", EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,     1.0 },
-        { PROC_FIELD_SIZE,      "size",    EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,     1.0 },
-        { PROC_FIELD_VIRT,      "virt",    EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,     1.0 },
-        { PROC_FIELD_RSS,       "rss",     EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,     1.0 },
-        { PROC_FIELD_SHARED,    "share",   EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,     1.0 },
-        { PROC_FIELD_STATE,     "state",   EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,     1.0 },
-        { PROC_FIELD_TIME,      "time",    EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,     1.0 },
-        { PROC_FIELD_CPU_USAGE, "cpu_u",   EVISUM_UI_WIDGET_EXEL_ITEM_CELL_PROGRESS, 1.0 },
-    };
-    Evisum_Ui_Widget_Exel_Item_Cell_Def defs[1 + (sizeof(fields) / sizeof(fields[0]))];
-    unsigned int n = 0;
-    Evisum_Ui_Process_List_View *view = evas_object_data_get(obj, "process_list_view");
-
-    defs[n++] = (Evisum_Ui_Widget_Exel_Item_Cell_Def) {
-        .type = EVISUM_UI_WIDGET_EXEL_ITEM_CELL_CMD,
-        .key = "cmd",
-        .aux_key = "icon",
-        .align_x = 0.0,
-        .weight_x = EXPAND,
-        .boxed = 0,
-        .spacer = ELM_SCALE_SIZE(4),
-        .icon_size = 16,
-    };
-
-    for (unsigned int i = 0; i < (sizeof(fields) / sizeof(fields[0])); i++) {
-        if (!_evisum_ui_process_list_fields_enabled(view, fields[i].type)) continue;
-
-        defs[n++] = (Evisum_Ui_Widget_Exel_Item_Cell_Def) {
-            .type = fields[i].cell_type,
-            .key = fields[i].key,
-            .aux_key = NULL,
-            .unit_format = (fields[i].type == PROC_FIELD_CPU_USAGE) ? "%1.1f %%" : NULL,
-            .align_x = fields[i].align_x,
-            .weight_x = EXPAND,
-            .boxed = 1,
-            .spacer = ELM_SCALE_SIZE(6),
-            .icon_size = 0,
-        };
-    }
-
-    return evisum_ui_widget_exel_item_row_add(obj, defs, n);
-}
-
 static void
 _evisum_ui_process_list_run_time_set(char *buf, size_t n, int64_t secs) {
     int rem;
@@ -403,7 +382,7 @@ _evisum_ui_process_list_content_get(void *data, Evas_Object *obj, const char *so
     Evisum_Ui_Process_List_View *view;
     const char *icon_name, *icon_old, *icon_new;
 
-    view = evas_object_data_get(obj, "process_list_view");
+    view = evas_object_data_get(obj, "widget_exel_data");
     if (!view) return NULL;
     ui = view->ui;
     proc = (void *) data;
@@ -1143,22 +1122,6 @@ static Evas_Object *
 _evisum_ui_process_list_content_add(Evisum_Ui_Process_List_View *view, Evas_Object *parent) {
     Evas_Object *tb, *btn, *glist;
     Evas_Object *fr, *hbx;
-    Evisum_Ui_Widget_Exel_Genlist_Params gp = {
-        .homogeneous = 1,
-        .focus_allow = 1,
-        .multi_select = 0,
-        .bounce_h = 0,
-        .bounce_v = 0,
-        .select_mode = ELM_OBJECT_SELECT_MODE_DEFAULT,
-        .policy_h = ELM_SCROLLER_POLICY_AUTO,
-        .policy_v = ELM_SCROLLER_POLICY_AUTO,
-        .weight_x = EXPAND,
-        .weight_y = EXPAND,
-        .align_x = FILL,
-        .align_y = FILL,
-        .data_key = "process_list_view",
-        .data = ""
-    };
 
     tb = elm_table_add(parent);
     evas_object_size_hint_weight_set(tb, EXPAND, EXPAND);
@@ -1170,7 +1133,9 @@ _evisum_ui_process_list_content_add(Evisum_Ui_Process_List_View *view, Evas_Obje
     evas_object_show(btn);
 
     _evisum_ui_process_list_fields_init(view);
-    evisum_ui_widget_exel_genlist_add(view->widget_exel, parent, &gp);
+    if (!view->widget_exel) return tb;
+
+    evisum_ui_widget_exel_genlist_add(view->widget_exel, parent);
     glist = evisum_ui_widget_exel_genlist_obj_get(view->widget_exel);
 
     view->itc.item_style = "full";
@@ -1599,7 +1564,6 @@ evisum_ui_process_list_win_add(Evisum_Ui *ui) {
     elm_win_resize_object_add(win, tb);
     elm_object_content_set(win, tb);
 
-    evisum_ui_widget_exel_item_cache_configure(view->widget_exel, _evisum_ui_process_list_item_create, 30);
     view->icon_cache = evisum_icon_cache_new();
     view->proc_usage_cache = eina_hash_int64_new(_evisum_ui_process_list_usage_cache_free_cb);
 
@@ -1611,7 +1575,6 @@ evisum_ui_process_list_win_add(Evisum_Ui *ui) {
 
     _evisum_ui_process_list_search_add(view);
     _evisum_ui_process_list_effects_add(view, win);
-    evisum_ui_widget_exel_genlist_unrealized_release_enable(view->widget_exel, EINA_TRUE);
     _evisum_ui_process_list_content_reset(view);
 
     _evisum_ui_process_list_win_resize_cb(view, NULL, win, NULL);
diff --git a/src/bin/ui/evisum_ui_process_view.c b/src/bin/ui/evisum_ui_process_view.c
index a7fc20f..f60b7df 100644
--- a/src/bin/ui/evisum_ui_process_view.c
+++ b/src/bin/ui/evisum_ui_process_view.c
@@ -175,47 +175,6 @@ _evisum_ui_process_view_hash_free_cb(void *data) {
     free(inf);
 }
 
-static Evas_Object *
-_evisum_ui_process_view_item_column_add(Evas_Object *tb, const char *text, int col) {
-    Evisum_Ui_Widget_Exel_Column_Params params = {
-        .boxed = 0,
-        .boxed_spacer = 0,
-        .align_x = 0.0,
-        .align_y = FILL,
-        .weight_x = 0,
-        .weight_y = EXPAND,
-    };
-
-    return evisum_ui_widget_exel_item_column_add(tb, text, col, &params);
-}
-
-static Evas_Object *
-_evisum_ui_process_view_item_create(Evas_Object *parent) {
-    Evas_Object *tb, *lb, *pb;
-
-    tb = elm_table_add(parent);
-    evas_object_size_hint_weight_set(tb, EXPAND, EXPAND);
-    evas_object_size_hint_align_set(tb, FILL, FILL);
-    evas_object_show(tb);
-
-    lb = _evisum_ui_process_view_item_column_add(tb, "tid", 0);
-    evas_object_size_hint_align_set(lb, 0.5, FILL);
-    _evisum_ui_process_view_item_column_add(tb, "name", 1);
-    lb = _evisum_ui_process_view_item_column_add(tb, "state", 2);
-    evas_object_size_hint_align_set(lb, 0.0, FILL);
-    lb = _evisum_ui_process_view_item_column_add(tb, "cpu_id", 3);
-    evas_object_size_hint_align_set(lb, 0.5, FILL);
-
-    pb = elm_progressbar_add(parent);
-    evas_object_size_hint_align_set(pb, FILL, FILL);
-    evas_object_size_hint_weight_set(pb, EXPAND, EXPAND);
-    elm_progressbar_unit_format_set(pb, "%1.0f %%");
-    evas_object_data_set(tb, "cpu_usage", pb);
-    elm_table_pack(tb, pb, 4, 0, 1, 1);
-
-    return tb;
-}
-
 static Evas_Object *
 _evisum_ui_process_view_content_get(void *data, Evas_Object *obj, const char *source) {
     Evisum_Ui_Process_View *view;
@@ -227,7 +186,7 @@ _evisum_ui_process_view_content_get(void *data, Evas_Object *obj, const char *so
     th = data;
     if (!th) return NULL;
 
-    view = evas_object_data_get(obj, "ui");
+    view = evas_object_data_get(obj, "widget_exel_data");
     if (!view) return NULL;
 
     row = evisum_ui_widget_exel_item_cache_object_get(view->threads.widget_exel);
@@ -432,7 +391,7 @@ _evisum_ui_process_view_children_icon_get(void *data, Evas_Object *obj, const ch
     Evas_Object *ic = elm_icon_add(obj);
 
     proc = data;
-    view = evas_object_data_get(obj, "windata");
+    view = evas_object_data_get(obj, "widget_exel_data");
 
     if (!strcmp(part, "elm.swallow.icon")) {
         evisum_ui_icon_set(ic, evisum_icon_cache_find(view->icon_cache, proc));
@@ -1193,36 +1152,28 @@ static Evas_Object *
 _evisum_ui_process_view_threads_tab_add(Evas_Object *parent, Evisum_Ui_Process_View *view) {
     Evas_Object *fr, *bx, *bx2, *tb, *rec, *btn, *glist;
     Evas_Object *graph;
-    Evisum_Ui_Widget_Exel_Genlist_Params gp = {
-        .homogeneous = 1,
-        .focus_allow = 0,
-        .multi_select = 0,
-        .bounce_h = 0,
-        .bounce_v = 0,
-        .select_mode = ELM_OBJECT_SELECT_MODE_NONE,
-        .policy_h = ELM_SCROLLER_POLICY_OFF,
-        .policy_v = ELM_SCROLLER_POLICY_AUTO,
-        .weight_x = EXPAND,
-        .weight_y = EXPAND,
-        .align_x = FILL,
-        .align_y = FILL,
-        .data_key = "ui",
-        .data = ""
-    };
     struct {
         const char *label;
         Thread_Sort_Type sort;
         double weight;
         double align;
         int field_id;
+        const char *key;
+        Evisum_Ui_Widget_Exel_Item_Cell_Type type;
+        const char *unit_format;
         const char *field_desc;
         Eina_Bool min_width_btn;
     } cols[] = {
-        { _("id"),     THREAD_SORT_TID,       EXPAND, FILL, 0, "Thread ID",        0 },
-        { _("name"),   THREAD_SORT_NAME,      EXPAND, FILL, 1, "Thread Name",      0 },
-        { _("state"),  THREAD_SORT_STATE,     EXPAND, FILL, 2, "Thread State",     0 },
-        { _("cpu id"), THREAD_SORT_CPU_ID,    0,      FILL, 3, "Thread CPU ID",    1 },
-        { _("cpu %"),  THREAD_SORT_CPU_USAGE, EXPAND, FILL, 4, "Thread CPU Usage", 0 },
+        { _("id"),     THREAD_SORT_TID,       EXPAND, FILL, 0, "tid",      EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,
+          NULL, "Thread ID",        0 },
+        { _("name"),   THREAD_SORT_NAME,      EXPAND, FILL, 1, "name",     EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,
+          NULL, "Thread Name",      0 },
+        { _("state"),  THREAD_SORT_STATE,     EXPAND, FILL, 2, "state",    EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,
+          NULL, "Thread State",     0 },
+        { _("cpu id"), THREAD_SORT_CPU_ID,    0,      FILL, 3, "cpu_id",   EVISUM_UI_WIDGET_EXEL_ITEM_CELL_TEXT,
+          NULL, "Thread CPU ID",    1 },
+        { _("cpu %"),  THREAD_SORT_CPU_USAGE, EXPAND, FILL, 4, "cpu_usage",
+          EVISUM_UI_WIDGET_EXEL_ITEM_CELL_PROGRESS, "%1.0f %%", "Thread CPU Usage", 0 },
     };
     Evas_Smart_Cb sort_clicked_cb = _evisum_ui_process_view_btn_threads_sort_clicked_cb;
     int i = 0;
@@ -1264,6 +1215,18 @@ _evisum_ui_process_view_threads_tab_add(Evas_Object *parent, Evisum_Ui_Process_V
         evas_object_data_set(btn, "thread_sort_type", (void *) (intptr_t) cols[c].sort);
         evisum_ui_widget_exel_field_register(view->threads.widget_exel, cols[c].field_id, btn, cols[c].field_desc,
                                              ELM_SCALE_SIZE(BTN_WIDTH), ELM_SCALE_SIZE(BTN_WIDTH), EINA_TRUE);
+        evisum_ui_widget_exel_field_row_def_set(
+                view->threads.widget_exel, cols[c].field_id,
+                &(Evisum_Ui_Widget_Exel_Item_Cell_Def) {
+                    .type = cols[c].type,
+                    .key = cols[c].key,
+                    .unit_format = cols[c].unit_format,
+                    .align_x = cols[c].align,
+                    .weight_x = cols[c].weight,
+                    .boxed = EINA_FALSE,
+                    .spacer = 0,
+                    .icon_size = 0,
+                });
         evisum_ui_widget_exel_field_width_apply(view->threads.widget_exel, cols[c].field_id);
         if (cols[c].min_width_btn) {
             rec = evas_object_rectangle_add(evas_object_evas_get(tb));
@@ -1274,7 +1237,7 @@ _evisum_ui_process_view_threads_tab_add(Evas_Object *parent, Evisum_Ui_Process_V
         evas_object_show(btn);
     }
 
-    glist = evisum_ui_widget_exel_genlist_add(view->threads.widget_exel, parent, &gp);
+    glist = evisum_ui_widget_exel_genlist_add(view->threads.widget_exel, parent);
     elm_box_pack_end(bx2, glist);
     elm_box_pack_end(bx, bx2);
 
@@ -1284,22 +1247,6 @@ _evisum_ui_process_view_threads_tab_add(Evas_Object *parent, Evisum_Ui_Process_V
 static Evas_Object *
 _evisum_ui_process_view_children_tab_add(Evas_Object *parent, Evisum_Ui_Process_View *view) {
     Evas_Object *fr, *bx, *glist;
-    Evisum_Ui_Widget_Exel_Genlist_Params gp = {
-        .homogeneous = 1,
-        .focus_allow = 1,
-        .multi_select = 0,
-        .bounce_h = 1,
-        .bounce_v = 1,
-        .select_mode = ELM_OBJECT_SELECT_MODE_DEFAULT,
-        .policy_h = ELM_SCROLLER_POLICY_AUTO,
-        .policy_v = ELM_SCROLLER_POLICY_AUTO,
-        .weight_x = EXPAND,
-        .weight_y = EXPAND,
-        .align_x = FILL,
-        .align_y = FILL,
-        .data_key = "windata",
-        .data = ""
-    };
 
     fr = elm_frame_add(parent);
     evas_object_size_hint_weight_set(fr, EXPAND, EXPAND);
@@ -1312,7 +1259,7 @@ _evisum_ui_process_view_children_tab_add(Evas_Object *parent, Evisum_Ui_Process_
     evas_object_show(bx);
     elm_object_content_set(fr, bx);
 
-    glist = evisum_ui_widget_exel_genlist_add(view->children.widget_exel, parent, &gp);
+    glist = evisum_ui_widget_exel_genlist_add(view->children.widget_exel, parent);
     evas_object_smart_callback_add(glist, "selected", _evisum_ui_process_view_item_children_clicked_cb, view);
     elm_box_pack_end(bx, glist);
 
@@ -1552,7 +1499,6 @@ evisum_ui_process_view_win_add(int pid, Evisum_Proc_Action action) {
     Proc_Info *proc;
 
     Evisum_Ui_Process_View *view = calloc(1, sizeof(Evisum_Ui_Process_View));
-    Evisum_Ui_Widget_Exel_Params wx_params;
     view->selected_pid = pid;
     view->poll_delay = 1;
     view->threads.widget_exel = NULL;
@@ -1581,34 +1527,26 @@ evisum_ui_process_view_win_add(int pid, Evisum_Proc_Action action) {
 
     elm_win_title_set(view->win, eina_slstr_printf("%s (%i)", view->selected_cmd, view->selected_pid));
 
-    wx_params = (Evisum_Ui_Widget_Exel_Params) {
-        .win = view->win,
-        .parent = view->win,
-        .field_first = 0,
-        .field_max = 1,
-        .resize_hit_width = 0,
-        .fields_mask = &view->threads.fields_mask,
-        .field_widths = view->threads.field_widths,
-        .reference_mask_get_cb = NULL,
-        .fields_changed_cb = NULL,
-        .fields_applied_cb = NULL,
-        .resize_live_cb = NULL,
-        .resize_done_cb = NULL,
-        .data = ""
-    };
-    view->threads.widget_exel = evisum_ui_widget_exel_add(&wx_params);
+    view->threads.widget_exel = evisum_ui_widget_exel_create(view->win);
     if (!view->threads.widget_exel) {
         evas_object_del(view->win);
         return;
     }
+    evisum_ui_widget_exel_field_bounds_set(view->threads.widget_exel, 0, 5);
+    evisum_ui_widget_exel_resize_hit_width_set(view->threads.widget_exel, 0);
+    evisum_ui_widget_exel_state_bind(view->threads.widget_exel, &view->threads.fields_mask, view->threads.field_widths);
+    evisum_ui_widget_exel_callbacks_set(view->threads.widget_exel, NULL, NULL, NULL, NULL, NULL, view);
 
-    wx_params.fields_mask = &view->children.fields_mask;
-    wx_params.field_widths = view->children.field_widths;
-    view->children.widget_exel = evisum_ui_widget_exel_add(&wx_params);
+    view->children.widget_exel = evisum_ui_widget_exel_create(view->win);
     if (!view->children.widget_exel) {
         evas_object_del(view->win);
         return;
     }
+    evisum_ui_widget_exel_field_bounds_set(view->children.widget_exel, 0, 1);
+    evisum_ui_widget_exel_resize_hit_width_set(view->children.widget_exel, 0);
+    evisum_ui_widget_exel_state_bind(view->children.widget_exel, &view->children.fields_mask,
+                                     view->children.field_widths);
+    evisum_ui_widget_exel_callbacks_set(view->children.widget_exel, NULL, NULL, NULL, NULL, NULL, view);
 
     tabs = _evisum_ui_process_view_tabs_add(win, view);
 
@@ -1649,9 +1587,6 @@ evisum_ui_process_view_win_add(int pid, Evisum_Proc_Action action) {
     view->kthreads_has_rss = 1;
 #endif
 
-    evisum_ui_widget_exel_item_cache_configure(view->threads.widget_exel, _evisum_ui_process_view_item_create, 10);
-    evisum_ui_widget_exel_genlist_unrealized_release_enable(view->threads.widget_exel, EINA_FALSE);
-
     view->thread = ecore_thread_feedback_run(_evisum_ui_process_view_proc_info_main,
                                              _evisum_ui_process_view_proc_info_feedback_cb, NULL, NULL, view, 0);
 }
diff --git a/src/bin/ui/evisum_ui_widget_exel.c b/src/bin/ui/evisum_ui_widget_exel.c
index ef5849a..5b145fa 100644
--- a/src/bin/ui/evisum_ui_widget_exel.c
+++ b/src/bin/ui/evisum_ui_widget_exel.c
@@ -8,17 +8,36 @@
 #define EVISUM_UI_WIDGET_EXEL_DEFAULT_FIELD_FIRST 0
 #define EVISUM_UI_WIDGET_EXEL_DEFAULT_FIELD_MAX   32
 #define EVISUM_UI_WIDGET_EXEL_DEFAULT_HIT_WIDTH   8
+#define EVISUM_UI_WIDGET_EXEL_DEFAULT_CACHE_SIZE  30
 
 typedef struct {
     int id;
     Evas_Object *btn;
     const char *desc;
+    Evisum_Ui_Widget_Exel_Item_Cell_Def row_def;
     int default_width;
     int min_width;
     Eina_Bool always_visible;
     Eina_Bool enabled;
+    Eina_Bool row_def_set;
 } Exel_Field;
 
+typedef struct {
+    Evas_Object *win;
+    Evas_Object *parent;
+    int field_first;
+    int field_max;
+    int resize_hit_width;
+    unsigned int *fields_mask;
+    int *field_widths;
+    Evisum_Ui_Widget_Exel_Reference_Mask_Get_Cb reference_mask_get_cb;
+    Evisum_Ui_Widget_Exel_Fields_Changed_Cb fields_changed_cb;
+    Evisum_Ui_Widget_Exel_Fields_Applied_Cb fields_applied_cb;
+    Evisum_Ui_Widget_Exel_Resize_Live_Cb resize_live_cb;
+    Evisum_Ui_Widget_Exel_Resize_Done_Cb resize_done_cb;
+    void *data;
+} Evisum_Ui_Widget_Exel_Params;
+
 struct _Evisum_Ui_Widget_Exel {
     Evisum_Ui_Widget_Exel_Params p;
     unsigned int fields_mask_state;
@@ -373,6 +392,7 @@ evisum_ui_widget_exel_object_get(const Evisum_Ui_Widget_Exel *wx) {
 void
 evisum_ui_widget_exel_field_add(Evisum_Ui_Widget_Exel *wx, const Evisum_Ui_Widget_Exel_Field_Params *params) {
     Evas_Object *btn;
+    Evisum_Ui_Widget_Exel_Item_Cell_Def def;
 
     if (!wx || !params || !wx->header_tb) return;
 
@@ -382,6 +402,18 @@ evisum_ui_widget_exel_field_add(Evisum_Ui_Widget_Exel *wx, const Evisum_Ui_Widge
 
     evisum_ui_widget_exel_field_register(wx, params->id, btn, params->desc, params->default_width, params->min_width,
                                          params->always_visible);
+    def = (Evisum_Ui_Widget_Exel_Item_Cell_Def) {
+        .type = params->type,
+        .key = params->key,
+        .aux_key = params->aux_key,
+        .unit_format = params->unit_format,
+        .align_x = params->align_x,
+        .weight_x = params->weight_x,
+        .boxed = params->boxed,
+        .spacer = params->spacer,
+        .icon_size = params->icon_size,
+    };
+    evisum_ui_widget_exel_field_row_def_set(wx, params->id, &def);
     evisum_ui_widget_exel_field_resize_attach(wx, btn, params->id);
     evas_object_event_callback_add(btn, EVAS_CALLBACK_MOUSE_UP, _evisum_ui_widget_exel_field_header_mouse_up_cb, wx);
 }
@@ -400,19 +432,6 @@ evisum_ui_widget_exel_fields_apply(Evisum_Ui_Widget_Exel *wx) {
     evisum_ui_widget_exel_fields_pack_visible(wx, wx->header_tb, 0);
 }
 
-Evas_Object *
-evisum_ui_widget_exel_genlist_attach(Evisum_Ui_Widget_Exel *wx, const Evisum_Ui_Widget_Exel_Genlist_Params *params) {
-    Evas_Object *glist;
-
-    if (!wx || !wx->root) return NULL;
-
-    glist = evisum_ui_widget_exel_genlist_add(wx, wx->root, params);
-    if (!glist) return NULL;
-
-    elm_box_pack_end(wx->root, glist);
-    return glist;
-}
-
 unsigned int
 evisum_ui_widget_exel_fields_mask_get(const Evisum_Ui_Widget_Exel *wx) {
     if (!wx || !wx->p.fields_mask) return 0;
@@ -426,23 +445,67 @@ evisum_ui_widget_exel_field_width_state_get(const Evisum_Ui_Widget_Exel *wx, int
     return wx->p.field_widths[id];
 }
 
-Evisum_Ui_Widget_Exel *
-evisum_ui_widget_exel_add(const Evisum_Ui_Widget_Exel_Params *params) {
-    Evisum_Ui_Widget_Exel *wx;
+void
+evisum_ui_widget_exel_state_bind(Evisum_Ui_Widget_Exel *wx, unsigned int *fields_mask, int *field_widths) {
+    int i;
 
-    if (!params) return NULL;
-    if (!params->field_widths || !params->fields_mask) return NULL;
+    if (!wx) return;
 
-    wx = calloc(1, sizeof(Evisum_Ui_Widget_Exel));
-    if (!wx) return NULL;
-
-    wx->p = *params;
-    if (wx->p.win) {
-        evas_object_event_callback_add(wx->p.win, EVAS_CALLBACK_MOUSE_MOVE, _evisum_ui_widget_exel_win_mouse_move_cb,
-                                       wx);
-        wx->win_mouse_move_registered = EINA_TRUE;
+    if (fields_mask) {
+        wx->p.fields_mask = fields_mask;
+        wx->owns_state = EINA_FALSE;
+    } else {
+        wx->p.fields_mask = &wx->fields_mask_state;
+        wx->owns_state = EINA_TRUE;
     }
-    return wx;
+
+    if (field_widths) {
+        wx->p.field_widths = field_widths;
+    } else {
+        for (i = wx->p.field_first; i < wx->p.field_max; i++) {
+            wx->field_widths_state[i] = 0;
+        }
+        wx->p.field_widths = wx->field_widths_state;
+        if (!fields_mask) wx->owns_state = EINA_TRUE;
+    }
+
+    _evisum_ui_widget_exel_fields_sync(wx);
+}
+
+void
+evisum_ui_widget_exel_field_bounds_set(Evisum_Ui_Widget_Exel *wx, int field_first, int field_max) {
+    if (!wx) return;
+    if (field_first < 0) field_first = 0;
+    if (field_first >= EVISUM_UI_WIDGET_EXEL_FIELDS_MAX) field_first = EVISUM_UI_WIDGET_EXEL_FIELDS_MAX - 1;
+    if (field_max <= field_first) field_max = field_first + 1;
+    if (field_max > EVISUM_UI_WIDGET_EXEL_FIELDS_MAX) field_max = EVISUM_UI_WIDGET_EXEL_FIELDS_MAX;
+
+    wx->p.field_first = field_first;
+    wx->p.field_max = field_max;
+    _evisum_ui_widget_exel_fields_sync(wx);
+}
+
+void
+evisum_ui_widget_exel_resize_hit_width_set(Evisum_Ui_Widget_Exel *wx, int hit_width) {
+    if (!wx) return;
+    if (hit_width < 0) hit_width = 0;
+    wx->p.resize_hit_width = hit_width;
+}
+
+void
+evisum_ui_widget_exel_callbacks_set(Evisum_Ui_Widget_Exel *wx,
+                                    Evisum_Ui_Widget_Exel_Reference_Mask_Get_Cb reference_mask_get_cb,
+                                    Evisum_Ui_Widget_Exel_Fields_Changed_Cb fields_changed_cb,
+                                    Evisum_Ui_Widget_Exel_Fields_Applied_Cb fields_applied_cb,
+                                    Evisum_Ui_Widget_Exel_Resize_Live_Cb resize_live_cb,
+                                    Evisum_Ui_Widget_Exel_Resize_Done_Cb resize_done_cb, void *data) {
+    if (!wx) return;
+    wx->p.reference_mask_get_cb = reference_mask_get_cb;
+    wx->p.fields_changed_cb = fields_changed_cb;
+    wx->p.fields_applied_cb = fields_applied_cb;
+    wx->p.resize_live_cb = resize_live_cb;
+    wx->p.resize_done_cb = resize_done_cb;
+    wx->p.data = ""
 }
 
 void
@@ -483,6 +546,20 @@ evisum_ui_widget_exel_field_register(Evisum_Ui_Widget_Exel *wx, int id, Evas_Obj
     _evisum_ui_widget_exel_fields_sync(wx);
 }
 
+void
+evisum_ui_widget_exel_field_row_def_set(Evisum_Ui_Widget_Exel *wx, int id,
+                                        const Evisum_Ui_Widget_Exel_Item_Cell_Def *def) {
+    Exel_Field *f;
+
+    if (!wx || !def) return;
+    if (id < 0 || id >= EVISUM_UI_WIDGET_EXEL_FIELDS_MAX) return;
+
+    f = &wx->fields[id];
+    if (f->id != id) return;
+    f->row_def = *def;
+    f->row_def_set = EINA_TRUE;
+}
+
 Eina_Bool
 evisum_ui_widget_exel_field_enabled_get(const Evisum_Ui_Widget_Exel *wx, int id) {
     Exel_Field *f = _evisum_ui_widget_exel_field_get(wx, id);
@@ -981,8 +1058,8 @@ evisum_ui_widget_exel_item_column_width_apply(Evas_Object *obj, Evas_Coord width
     }
 }
 
-void
-evisum_ui_widget_exel_glist_ensure_n_items(Evas_Object *glist, unsigned int items, Elm_Genlist_Item_Class *itc) {
+static void
+_evisum_ui_widget_exel_glist_ensure_n_items(Evas_Object *glist, unsigned int items, Elm_Genlist_Item_Class *itc) {
     Elm_Object_Item *it;
     unsigned int i, existing = elm_genlist_items_count(glist);
 
@@ -1092,11 +1169,25 @@ _evisum_ui_widget_exel_item_cache_add(Evisum_Ui_Widget_Exel *wx, Evas_Object *pa
     wx->cache = evisum_ui_item_cache_new(parent, create_cb, size);
 }
 
-void
-evisum_ui_widget_exel_item_cache_configure(Evisum_Ui_Widget_Exel *wx, Evas_Object *(*create_cb)(Evas_Object *),
-                                           int size) {
-    if (!wx || !wx->glist) return;
-    _evisum_ui_widget_exel_item_cache_add(wx, wx->glist, create_cb, size);
+static Evas_Object *
+_evisum_ui_widget_exel_item_create_from_fields(Evas_Object *parent) {
+    Evisum_Ui_Widget_Exel *wx = evas_object_data_get(parent, "widget_exel");
+    Evisum_Ui_Widget_Exel_Item_Cell_Def defs[EVISUM_UI_WIDGET_EXEL_FIELDS_MAX];
+    unsigned int n = 0;
+    int i;
+
+    if (!wx) return NULL;
+
+    _evisum_ui_widget_exel_fields_sync(wx);
+
+    for (i = wx->p.field_first; i < wx->p.field_max; i++) {
+        Exel_Field *f = _evisum_ui_widget_exel_field_get(wx, i);
+        if (!f || !f->row_def_set || !f->enabled) continue;
+        defs[n++] = f->row_def;
+    }
+
+    if (!n) return NULL;
+    return evisum_ui_widget_exel_item_row_add(parent, defs, n);
 }
 
 static Eina_Bool
@@ -1109,7 +1200,12 @@ Evas_Object *
 evisum_ui_widget_exel_item_cache_object_get(Evisum_Ui_Widget_Exel *wx) {
     Item_Cache *it;
 
-    if (!wx || !wx->cache) return NULL;
+    if (!wx) return NULL;
+    if (!wx->cache && wx->glist) {
+        _evisum_ui_widget_exel_item_cache_add(wx, wx->glist, _evisum_ui_widget_exel_item_create_from_fields,
+                                              EVISUM_UI_WIDGET_EXEL_DEFAULT_CACHE_SIZE);
+    }
+    if (!wx->cache) return NULL;
     it = evisum_ui_item_cache_item_get(wx->cache);
     if (!it) return NULL;
 
@@ -1133,26 +1229,30 @@ evisum_ui_widget_exel_item_cache_active_count_get(const Evisum_Ui_Widget_Exel *w
     return eina_list_count(wx->cache->active);
 }
 
+static void
+_evisum_ui_widget_exel_genlist_unrealized_release_enable(Evisum_Ui_Widget_Exel *wx, Eina_Bool delete_unhandled);
+
 Evas_Object *
-evisum_ui_widget_exel_genlist_add(Evisum_Ui_Widget_Exel *wx, Evas_Object *parent,
-                                  const Evisum_Ui_Widget_Exel_Genlist_Params *params) {
+evisum_ui_widget_exel_genlist_add(Evisum_Ui_Widget_Exel *wx, Evas_Object *parent) {
     Evas_Object *glist;
 
-    if (!wx || !parent || !params) return NULL;
+    if (!wx || !parent) return NULL;
 
     glist = elm_genlist_add(parent);
-    elm_genlist_homogeneous_set(glist, params->homogeneous);
-    elm_scroller_bounce_set(glist, params->bounce_h, params->bounce_v);
-    elm_object_focus_allow_set(glist, params->focus_allow);
-    elm_scroller_policy_set(glist, params->policy_h, params->policy_v);
-    elm_genlist_multi_select_set(glist, params->multi_select);
-    elm_genlist_select_mode_set(glist, params->select_mode);
-    evas_object_size_hint_weight_set(glist, params->weight_x, params->weight_y);
-    evas_object_size_hint_align_set(glist, params->align_x, params->align_y);
-    if (params->data_key) evas_object_data_set(glist, params->data_key, (void *) params->data);
+    elm_genlist_homogeneous_set(glist, EINA_TRUE);
+    elm_scroller_bounce_set(glist, EINA_FALSE, EINA_FALSE);
+    elm_object_focus_allow_set(glist, EINA_TRUE);
+    elm_scroller_policy_set(glist, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_AUTO);
+    elm_genlist_multi_select_set(glist, EINA_FALSE);
+    elm_genlist_select_mode_set(glist, ELM_OBJECT_SELECT_MODE_DEFAULT);
+    evas_object_size_hint_weight_set(glist, EXPAND, EXPAND);
+    evas_object_size_hint_align_set(glist, FILL, FILL);
+    evas_object_data_set(glist, "widget_exel", wx);
+    if (wx->p.data) evas_object_data_set(glist, "widget_exel_data", wx->p.data);
     evas_object_show(glist);
 
     wx->glist = glist;
+    _evisum_ui_widget_exel_genlist_unrealized_release_enable(wx, EINA_TRUE);
     return glist;
 }
 
@@ -1178,7 +1278,7 @@ evisum_ui_widget_exel_genlist_clear(Evisum_Ui_Widget_Exel *wx) {
 void
 evisum_ui_widget_exel_genlist_items_ensure(Evisum_Ui_Widget_Exel *wx, unsigned int items, Elm_Genlist_Item_Class *itc) {
     if (!wx || !wx->glist) return;
-    evisum_ui_widget_exel_glist_ensure_n_items(wx->glist, items, itc);
+    _evisum_ui_widget_exel_glist_ensure_n_items(wx->glist, items, itc);
 }
 
 Elm_Object_Item *
@@ -1271,8 +1371,8 @@ _evisum_ui_widget_exel_genlist_unrealized_cb(void *data, Evas_Object *obj EINA_U
     _evisum_ui_widget_exel_genlist_item_contents_release(wx, event_info, wx->unrealized_delete_unhandled);
 }
 
-void
-evisum_ui_widget_exel_genlist_unrealized_release_enable(Evisum_Ui_Widget_Exel *wx, Eina_Bool delete_unhandled) {
+static void
+_evisum_ui_widget_exel_genlist_unrealized_release_enable(Evisum_Ui_Widget_Exel *wx, Eina_Bool delete_unhandled) {
     if (!wx || !wx->glist) return;
 
     if (!wx->unrealized_release_enabled) {
diff --git a/src/bin/ui/evisum_ui_widget_exel.h b/src/bin/ui/evisum_ui_widget_exel.h
index 373e57c..fe73d82 100644
--- a/src/bin/ui/evisum_ui_widget_exel.h
+++ b/src/bin/ui/evisum_ui_widget_exel.h
@@ -45,6 +45,15 @@ typedef struct {
     int id;
     const char *title;
     const char *desc;
+    const char *key;
+    const char *aux_key;
+    const char *unit_format;
+    Evisum_Ui_Widget_Exel_Item_Cell_Type type;
+    double align_x;
+    double weight_x;
+    Eina_Bool boxed;
+    int spacer;
+    int icon_size;
     int default_width;
     int min_width;
     Eina_Bool always_visible;
@@ -53,40 +62,6 @@ typedef struct {
     const void *clicked_data;
 } Evisum_Ui_Widget_Exel_Field_Params;
 
-typedef struct {
-    Evas_Object *win;
-    Evas_Object *parent;
-    int field_first;
-    int field_max;
-    int resize_hit_width;
-    unsigned int *fields_mask;
-    int *field_widths;
-
-    Evisum_Ui_Widget_Exel_Reference_Mask_Get_Cb reference_mask_get_cb;
-    Evisum_Ui_Widget_Exel_Fields_Changed_Cb fields_changed_cb;
-    Evisum_Ui_Widget_Exel_Fields_Applied_Cb fields_applied_cb;
-    Evisum_Ui_Widget_Exel_Resize_Live_Cb resize_live_cb;
-    Evisum_Ui_Widget_Exel_Resize_Done_Cb resize_done_cb;
-    void *data;
-} Evisum_Ui_Widget_Exel_Params;
-
-typedef struct {
-    Eina_Bool homogeneous;
-    Eina_Bool focus_allow;
-    Eina_Bool multi_select;
-    Eina_Bool bounce_h;
-    Eina_Bool bounce_v;
-    Elm_Object_Select_Mode select_mode;
-    Elm_Scroller_Policy policy_h;
-    Elm_Scroller_Policy policy_v;
-    double weight_x;
-    double weight_y;
-    double align_x;
-    double align_y;
-    const char *data_key;
-    const void *data;
-} Evisum_Ui_Widget_Exel_Genlist_Params;
-
 /* Create a full exel view with internal root/header objects and owned field state.
  * This API avoids exposing internal params arrays or requiring caller-managed header containers. */
 Evisum_Ui_Widget_Exel *evisum_ui_widget_exel_create(Evas_Object *parent);
@@ -103,11 +78,6 @@ void evisum_ui_widget_exel_field_add(Evisum_Ui_Widget_Exel *wx, const Evisum_Ui_
  * Call once after field registration and whenever field visibility changes are applied. */
 void evisum_ui_widget_exel_fields_apply(Evisum_Ui_Widget_Exel *wx);
 
-/* Create the widget-owned genlist under the widget root and pack it automatically.
- * This avoids passing container boxes from callers. */
-Evas_Object *evisum_ui_widget_exel_genlist_attach(Evisum_Ui_Widget_Exel *wx,
-                                                  const Evisum_Ui_Widget_Exel_Genlist_Params *params);
-
 /* Return the current field visibility mask tracked by the widget.
  * Use this when persisting user field selection without direct access to internal params. */
 unsigned int evisum_ui_widget_exel_fields_mask_get(const Evisum_Ui_Widget_Exel *wx);
@@ -116,9 +86,25 @@ unsigned int evisum_ui_widget_exel_fields_mask_get(const Evisum_Ui_Widget_Exel *
  * Use this when persisting column sizing without touching internal arrays. */
 int evisum_ui_widget_exel_field_width_state_get(const Evisum_Ui_Widget_Exel *wx, int id);
 
-/* Create and initialize the exel widget controller with field masks, widths, and callbacks.
- * Use this once per view before registering fields so resize/menu behavior is managed centrally. */
-Evisum_Ui_Widget_Exel *evisum_ui_widget_exel_add(const Evisum_Ui_Widget_Exel_Params *params);
+/* Bind an external fields mask/widths state to the widget.
+ * Pass NULL pointers to keep/create widget-owned state. */
+void evisum_ui_widget_exel_state_bind(Evisum_Ui_Widget_Exel *wx, unsigned int *fields_mask, int *field_widths);
+
+/* Configure the active field id range used by the widget.
+ * Must be called before registering fields when using non-default ranges. */
+void evisum_ui_widget_exel_field_bounds_set(Evisum_Ui_Widget_Exel *wx, int field_first, int field_max);
+
+/* Set header-resize hit width in pixels for edge drag detection.
+ * Keep zero to disable resize hit-testing. */
+void evisum_ui_widget_exel_resize_hit_width_set(Evisum_Ui_Widget_Exel *wx, int hit_width);
+
+/* Configure optional callbacks and callback context for field/menu/resize state changes. */
+void evisum_ui_widget_exel_callbacks_set(Evisum_Ui_Widget_Exel *wx,
+                                         Evisum_Ui_Widget_Exel_Reference_Mask_Get_Cb reference_mask_get_cb,
+                                         Evisum_Ui_Widget_Exel_Fields_Changed_Cb fields_changed_cb,
+                                         Evisum_Ui_Widget_Exel_Fields_Applied_Cb fields_applied_cb,
+                                         Evisum_Ui_Widget_Exel_Resize_Live_Cb resize_live_cb,
+                                         Evisum_Ui_Widget_Exel_Resize_Done_Cb resize_done_cb, void *data);
 
 /* Release the exel widget controller and any menu state it owns.
  * Call this during view teardown to avoid leaked UI objects and stale pointers. */
@@ -129,6 +115,11 @@ void evisum_ui_widget_exel_free(Evisum_Ui_Widget_Exel *wx);
 void evisum_ui_widget_exel_field_register(Evisum_Ui_Widget_Exel *wx, int id, Evas_Object *btn, const char *desc,
                                           int default_width, int min_width, Eina_Bool always_visible);
 
+/* Set row-cell metadata for a registered field so the widget can build row objects internally.
+ * Call this for every field that should appear in cached rows. */
+void evisum_ui_widget_exel_field_row_def_set(Evisum_Ui_Widget_Exel *wx, int id,
+                                             const Evisum_Ui_Widget_Exel_Item_Cell_Def *def);
+
 /* Query whether a field is currently enabled and should be visible in the active layout.
  * Use this when building row content or packing headers so hidden fields stay consistent. */
 Eina_Bool evisum_ui_widget_exel_field_enabled_get(const Evisum_Ui_Widget_Exel *wx, int id);
@@ -237,10 +228,6 @@ Eina_Bool evisum_ui_widget_exel_item_field_progress_set(Evisum_Ui_Widget_Exel *w
  * Pass `is_last` for trailing columns that should stretch and all others will be fixed to header width. */
 void evisum_ui_widget_exel_item_column_width_apply(Evas_Object *obj, Evas_Coord width, Eina_Bool is_last);
 
-/* Ensure a genlist has exactly the requested item count using a shared item class.
- * Use this before setting item data so add/remove behavior stays uniform across views. */
-void evisum_ui_widget_exel_glist_ensure_n_items(Evas_Object *glist, unsigned int items, Elm_Genlist_Item_Class *itc);
-
 /* Add a menu item with optional themed icon and fallback icon behavior.
  * This keeps process menus consistent and avoids repeated icon-part compatibility code. */
 Elm_Object_Item *evisum_ui_widget_exel_menu_item_add(Evas_Object *menu, Elm_Object_Item *parent, const char *icon,
@@ -262,11 +249,6 @@ Evas_Object *evisum_ui_widget_exel_icon_button_add(Evas_Object *parent, const ch
                                                    double weight_x, double align_x, Evas_Smart_Cb clicked_cb,
                                                    const void *data);
 
-/* Configure an item cache for the widget-owned genlist.
- * Use this when row content objects are pooled and should be owned by the widget lifecycle. */
-void evisum_ui_widget_exel_item_cache_configure(Evisum_Ui_Widget_Exel *wx, Evas_Object *(*create_cb)(Evas_Object *),
-                                                int size);
-
 /* Return one cached row object from the widget-owned item cache.
  * Use this in content callbacks to avoid exposing `Item_Cache` internals in consumers. */
 Evas_Object *evisum_ui_widget_exel_item_cache_object_get(Evisum_Ui_Widget_Exel *wx);
@@ -283,10 +265,9 @@ void evisum_ui_widget_exel_item_cache_steal(Evisum_Ui_Widget_Exel *wx, Eina_List
  * This is useful for deciding when to compact cache state after feedback updates. */
 unsigned int evisum_ui_widget_exel_item_cache_active_count_get(const Evisum_Ui_Widget_Exel *wx);
 
-/* Create and own a genlist configured from one parameter block and return the created object.
+/* Create and own a genlist with API-defined defaults and return the created object.
  * Use this so exel consumers do not manually construct genlists and keep list setup centralized. */
-Evas_Object *evisum_ui_widget_exel_genlist_add(Evisum_Ui_Widget_Exel *wx, Evas_Object *parent,
-                                               const Evisum_Ui_Widget_Exel_Genlist_Params *params);
+Evas_Object *evisum_ui_widget_exel_genlist_add(Evisum_Ui_Widget_Exel *wx, Evas_Object *parent);
 
 /* Return the widget-owned genlist object, or NULL if none was created yet.
  * Use this only when another container API requires the object for packing. */
@@ -353,11 +334,6 @@ void evisum_ui_widget_exel_genlist_item_selected_set(Elm_Object_Item *it, Eina_B
  * Use this after swapping row data on an existing item. */
 void evisum_ui_widget_exel_genlist_item_update(Elm_Object_Item *it);
 
-/* Enable/disable automatic unrealized-item content release through the widget item cache.
- * When enabled, all genlist unrealized contents are released internally without consumer callbacks. */
-void evisum_ui_widget_exel_genlist_unrealized_release_enable(Evisum_Ui_Widget_Exel *wx,
-                                                             Eina_Bool delete_unhandled);
-
 /* Append a new item to the widget-owned genlist using Elm-style append parameters.
  * Pass `func`/`func_data` when per-item selection callbacks are needed, or NULL to match existing behavior. */
 Elm_Object_Item *evisum_ui_widget_exel_genlist_item_append(Evisum_Ui_Widget_Exel *wx, Elm_Genlist_Item_Class *itc,

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to