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 4fbba3327862f7b8458d8c23000185383a6371d7
Author: Alastair Poole <[email protected]>
AuthorDate: Fri Mar 27 22:46:34 2026 +0000

    API: Simplify
---
 src/bin/evisum_ui_widget_example.c  | 253 ++++++++++------------------
 src/bin/ui/evisum_ui_process_list.c | 106 ++----------
 src/bin/ui/evisum_ui_process_view.c |  56 +------
 src/bin/ui/evisum_ui_widget_exel.c  | 325 ++++++++++++++++++++++++++----------
 src/bin/ui/evisum_ui_widget_exel.h  |  60 +++----
 5 files changed, 363 insertions(+), 437 deletions(-)

diff --git a/src/bin/evisum_ui_widget_example.c b/src/bin/evisum_ui_widget_example.c
index 463d0f5..00f19ca 100644
--- a/src/bin/evisum_ui_widget_example.c
+++ b/src/bin/evisum_ui_widget_example.c
@@ -14,15 +14,34 @@ typedef struct {
     double cpu_usage;
 } Example_Row;
 
-typedef struct {
-    Evas_Object *win;
-    Evas_Object *header_tb;
-    Evisum_Ui_Widget_Exel *wx;
-    Elm_Genlist_Item_Class itc;
-    Ecore_Timer *timer;
-    unsigned int fields_mask;
-    int field_widths[EX_FIELD_MAX];
-} Example_App;
+static const Evisum_Ui_Widget_Exel_Item_Cell_Def _row_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 },
+};
+
+static Evisum_Ui_Widget_Exel *wx;
+static Elm_Genlist_Item_Class itc;
+static Ecore_Timer *timer;
 
 static Example_Row *
 _row_new(const char *cmd, unsigned long long mem_kib, double cpu_usage) {
@@ -46,59 +65,25 @@ _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(NULL, parent, defs, 3);
-}
-
 static Evas_Object *
 _content_get(void *data, Evas_Object *obj, const char *source) {
     Example_Row *row = data;
-    Example_App *app;
     Evas_Object *item;
     char buf[64];
 
     if (strcmp(source, "elm.swallow.content")) return NULL;
     if (!row) return NULL;
 
-    app = evas_object_data_get(obj, "app");
-    if (!app) return NULL;
-
-    item = evisum_ui_widget_exel_item_cache_object_get(app->wx);
+    item = evisum_ui_widget_exel_item_cache_object_get(wx);
     if (!item) return NULL;
 
-    evisum_ui_widget_exel_item_field_text_set(app->wx, item, EX_FIELD_CMD, "cmd", row->cmd);
+    evisum_ui_widget_exel_item_field_text_set(wx, item, EX_FIELD_CMD, "cmd", row->cmd);
 
     snprintf(buf, sizeof(buf), "%llu MiB", row->mem_size_kib / 1024ULL);
-    evisum_ui_widget_exel_item_field_text_set(app->wx, item, EX_FIELD_MEM_SIZE, "mem_size", buf);
+    evisum_ui_widget_exel_item_field_text_set(wx, item, EX_FIELD_MEM_SIZE, "mem_size", buf);
 
     snprintf(buf, sizeof(buf), "%1.1f %%", row->cpu_usage);
-    evisum_ui_widget_exel_item_field_progress_set(app->wx, item, EX_FIELD_CPU_USAGE, "cpu_usage",
+    evisum_ui_widget_exel_item_field_progress_set(wx, item, EX_FIELD_CPU_USAGE, "cpu_usage",
                                                   row->cpu_usage / 100.0, buf);
 
     return item;
@@ -106,176 +91,113 @@ _content_get(void *data, Evas_Object *obj, const char *source) {
 
 static void
 _unrealized_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info) {
-    Example_App *app = data;
-    Eina_List *contents = NULL;
-    Evas_Object *content;
-
-    evisum_ui_widget_exel_genlist_item_all_contents_unset(app->wx, event_info, &contents);
-
-    EINA_LIST_FREE(contents, content) {
-        if (!evisum_ui_widget_exel_item_cache_item_release(app->wx, content)) evas_object_del(content);
-    }
+    (void) data;
+    evisum_ui_widget_exel_genlist_item_unrealized_handle(wx, event_info);
 }
 
-static unsigned int
-_reference_mask_get_cb(void *data) {
-    Example_App *app = data;
-    return app->fields_mask;
-}
-
-static void
-_fields_changed_cb(void *data EINA_UNUSED, Eina_Bool changed EINA_UNUSED) {}
-
-static void
-_fields_applied_cb(void *data, Eina_Bool changed) {
-    Example_App *app = data;
-    if (!changed) return;
-    evisum_ui_widget_exel_item_cache_reset(app->wx, NULL, NULL);
-}
-
-static void
-_resize_live_cb(void *data) {
-    Example_App *app = data;
-    evisum_ui_widget_exel_genlist_realized_items_update(app->wx);
-}
-
-static void
-_resize_done_cb(void *data EINA_UNUSED) {}
-
 static Eina_Bool
 _update_timer_cb(void *data) {
-    Example_App *app = data;
-    Elm_Object_Item *it = evisum_ui_widget_exel_genlist_first_item_get(app->wx);
+    Elm_Object_Item *it = evisum_ui_widget_exel_genlist_first_item_get(wx);
+    (void) data;
 
     while (it) {
-        Example_Row *row = evisum_ui_widget_exel_object_item_data_get(app->wx, it);
+        Example_Row *row = evisum_ui_widget_exel_object_item_data_get(wx, it);
         if (row) {
             row->cpu_usage += (rand() % 11) - 5;
             if (row->cpu_usage < 0.0) row->cpu_usage = 0.0;
             if (row->cpu_usage > 100.0) row->cpu_usage = 100.0;
             row->mem_size_kib += (rand() % 1024);
         }
-        evisum_ui_widget_exel_genlist_item_update(app->wx, it);
-        it = evisum_ui_widget_exel_genlist_item_next_get(app->wx, it);
+        evisum_ui_widget_exel_genlist_item_update(wx, it);
+        it = evisum_ui_widget_exel_genlist_item_next_get(wx, it);
     }
 
     return ECORE_CALLBACK_RENEW;
 }
 
 static void
-_fill_demo_rows(Example_App *app) {
+_fill_demo_rows(void) {
     Example_Row *rows[3];
     Elm_Object_Item *it;
 
-    evisum_ui_widget_exel_genlist_items_ensure(app->wx, 3, &app->itc);
-    it = evisum_ui_widget_exel_genlist_first_item_get(app->wx);
+    evisum_ui_widget_exel_genlist_items_ensure(wx, 3, &itc);
+    it = evisum_ui_widget_exel_genlist_first_item_get(wx);
 
     rows[0] = _row_new("evisum", 512000, 24.3);
     rows[1] = _row_new("clang", 342000, 8.1);
     rows[2] = _row_new("python", 768000, 57.8);
 
     for (int i = 0; i < 3 && it; i++) {
-        Example_Row *old = evisum_ui_widget_exel_object_item_data_get(app->wx, it);
+        Example_Row *old = evisum_ui_widget_exel_object_item_data_get(wx, it);
         if (old) _row_free(old);
-        evisum_ui_widget_exel_object_item_data_set(app->wx, it, rows[i]);
-        evisum_ui_widget_exel_genlist_item_update(app->wx, it);
-        it = evisum_ui_widget_exel_genlist_item_next_get(app->wx, it);
+        evisum_ui_widget_exel_object_item_data_set(wx, it, rows[i]);
+        evisum_ui_widget_exel_genlist_item_update(wx, it);
+        it = evisum_ui_widget_exel_genlist_item_next_get(wx, it);
     }
 }
 
 static void
 _win_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) {
-    Example_App *app = data;
+    (void) data;
 
-    if (app->timer) ecore_timer_del(app->timer);
+    if (timer) ecore_timer_del(timer);
+    timer = NULL;
 
-    evisum_ui_widget_exel_genlist_clear(app->wx);
-    evisum_ui_widget_exel_free(app->wx);
-    free(app);
+    evisum_ui_widget_exel_genlist_clear(wx);
+    evisum_ui_widget_exel_free(wx);
+    wx = NULL;
     elm_exit();
 }
 
 EAPI_MAIN int
 elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED) {
-    Example_App *app = calloc(1, sizeof(Example_App));
+    Evas_Object *win;
     Evas_Object *root;
     Evas_Object *glist;
     Evisum_Ui_Widget_Exel_Params wp;
     Evisum_Ui_Widget_Exel_Genlist_Params gp;
-
-    if (!app) return EXIT_FAILURE;
+    unsigned int fields_mask;
 
     /* App state */
     srand((unsigned int) time(NULL));
-    app->fields_mask = (1u << EX_FIELD_CMD) | (1u << EX_FIELD_MEM_SIZE) | (1u << EX_FIELD_CPU_USAGE);
-    app->field_widths[EX_FIELD_CMD] = 160;
-    app->field_widths[EX_FIELD_MEM_SIZE] = 120;
-    app->field_widths[EX_FIELD_CPU_USAGE] = 150;
+    fields_mask = (1u << EX_FIELD_CMD) | (1u << EX_FIELD_MEM_SIZE) | (1u << EX_FIELD_CPU_USAGE);
 
     /* Window and layout */
-    app->win = elm_win_util_standard_add("evisum_test", "Widget Example");
-    elm_win_autodel_set(app->win, EINA_TRUE);
+    win = elm_win_util_standard_add("evisum_test", "Widget Example");
+    elm_win_autodel_set(win, EINA_TRUE);
 
-    root = elm_box_add(app->win);
+    root = elm_box_add(win);
     evas_object_size_hint_weight_set(root, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
     evas_object_size_hint_align_set(root, EVAS_HINT_FILL, EVAS_HINT_FILL);
     evas_object_show(root);
-    elm_win_resize_object_add(app->win, root);
-
-    app->header_tb = elm_table_add(root);
-    evas_object_size_hint_weight_set(app->header_tb, EVAS_HINT_EXPAND, 0.0);
-    evas_object_size_hint_align_set(app->header_tb, EVAS_HINT_FILL, EVAS_HINT_FILL);
-    evas_object_show(app->header_tb);
-    elm_box_pack_end(root, app->header_tb);
+    elm_win_resize_object_add(win, root);
 
     /* Exel API setup */
-    wp.win = app->win;
-    wp.parent = app->win;
-    wp.field_first = EX_FIELD_CMD;
-    wp.field_max = EX_FIELD_MAX;
-    wp.resize_hit_width = 8;
-    wp.fields_mask = &app->fields_mask;
-    wp.field_widths = app->field_widths;
-    wp.reference_mask_get_cb = _reference_mask_get_cb;
-    wp.fields_changed_cb = _fields_changed_cb;
-    wp.fields_applied_cb = _fields_applied_cb;
-    wp.resize_live_cb = _resize_live_cb;
-    wp.resize_done_cb = _resize_done_cb;
+    wp.win = win;
+    wp.parent = win;
+    wp.resize_live_cb = NULL;
+    wp.resize_done_cb = NULL;
     wp.field_clicked_cb = NULL;
-    wp.data = ""
+    wp.data = ""
 
-    app->wx = evisum_ui_widget_exel_add(&wp);
-    if (!app->wx) {
-        evas_object_del(app->win);
-        free(app);
+    wx = evisum_ui_widget_exel_add(&wp);
+    if (!wx) {
+        evas_object_del(win);
         return EXIT_FAILURE;
     }
+    evisum_ui_widget_exel_resize_hit_width_set(wx, 8);
+    evisum_ui_widget_exel_fields_mask_set(wx, fields_mask);
 
-    evisum_ui_widget_exel_field_register(app->wx, EX_FIELD_CMD, "command", "Command", 160, 90, EINA_TRUE, 1.0,
+    evisum_ui_widget_exel_field_register(wx, EX_FIELD_CMD, "command", "Command", 160, 90, EINA_TRUE, 1.0,
                                          EVAS_HINT_FILL);
-    evisum_ui_widget_exel_field_register(app->wx, EX_FIELD_MEM_SIZE, "mem size", "Memory Size", 120, 80, EINA_FALSE,
+    evisum_ui_widget_exel_field_register(wx, EX_FIELD_MEM_SIZE, "mem size", "Memory Size", 120, 80, EINA_FALSE,
                                          1.0, EVAS_HINT_FILL);
-    evisum_ui_widget_exel_field_register(app->wx, EX_FIELD_CPU_USAGE, "cpu %", "CPU Usage", 150, 90, EINA_FALSE, 1.0,
+    evisum_ui_widget_exel_field_register(wx, EX_FIELD_CPU_USAGE, "cpu %", "CPU Usage", 150, 90, EINA_FALSE, 1.0,
                                          EVAS_HINT_FILL);
 
-    for (Example_Field field = EX_FIELD_CMD, col = 0; field < EX_FIELD_MAX; field++) {
-        Evas_Object *btn = evisum_ui_widget_exel_field_header_get(app->wx, field);
-
-        if (!btn) continue;
-        if (!evisum_ui_widget_exel_field_enabled_get(app->wx, field)) {
-            evas_object_hide(btn);
-            continue;
-        }
-
-        elm_table_pack(app->header_tb, btn, col++, 0, 1, 1);
-        evas_object_show(btn);
-    }
-
+    memset(&gp, 0, sizeof(Evisum_Ui_Widget_Exel_Genlist_Params));
     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;
@@ -283,28 +205,27 @@ elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED) {
     gp.weight_y = EVAS_HINT_EXPAND;
     gp.align_x = EVAS_HINT_FILL;
     gp.align_y = EVAS_HINT_FILL;
-    gp.data_key = "app";
-    gp.data = ""
 
-    glist = evisum_ui_widget_exel_genlist_add(app->wx, &gp);
+    glist = evisum_ui_widget_exel_genlist_add(wx, &gp);
     elm_box_pack_end(root, glist);
-    evisum_ui_widget_exel_genlist_callback_add(app->wx, "unrealized", _unrealized_cb, app);
-    evisum_ui_widget_exel_item_cache_attach(app->wx, _item_factory, 16);
+    evisum_ui_widget_exel_genlist_callback_add(wx, "unrealized", _unrealized_cb, NULL);
+    evisum_ui_widget_exel_item_template_set(wx, _row_defs, sizeof(_row_defs) / sizeof(_row_defs[0]));
+    evisum_ui_widget_exel_item_cache_attach_template(wx, 16);
 
     /* Data model hooks */
-    app->itc.item_style = "full";
-    app->itc.func.text_get = NULL;
-    app->itc.func.content_get = _content_get;
-    app->itc.func.filter_get = NULL;
-    app->itc.func.del = _item_del;
+    itc.item_style = "full";
+    itc.func.text_get = NULL;
+    itc.func.content_get = _content_get;
+    itc.func.filter_get = NULL;
+    itc.func.del = _item_del;
 
-    _fill_demo_rows(app);
-    app->timer = ecore_timer_add(1.0, _update_timer_cb, app);
+    _fill_demo_rows();
+    timer = ecore_timer_add(1.0, _update_timer_cb, NULL);
 
     /* Window callbacks and run */
-    evas_object_event_callback_add(app->win, EVAS_CALLBACK_DEL, _win_del_cb, app);
-    evas_object_resize(app->win, 680, 360);
-    evas_object_show(app->win);
+    evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _win_del_cb, NULL);
+    evas_object_resize(win, 680, 360);
+    evas_object_show(win);
     elm_run();
 
     return EXIT_SUCCESS;
diff --git a/src/bin/ui/evisum_ui_process_list.c b/src/bin/ui/evisum_ui_process_list.c
index 48f4956..ccd228b 100644
--- a/src/bin/ui/evisum_ui_process_list.c
+++ b/src/bin/ui/evisum_ui_process_list.c
@@ -53,6 +53,7 @@ typedef struct {
     } search;
 
     Evas_Object *tb_main;
+    Evas_Object *exel_panel;
 
     Elm_Genlist_Item_Class itc;
 
@@ -158,57 +159,10 @@ _evisum_ui_process_list_cmd_width_sync(Evisum_Ui_Process_List_View *view, Evas_C
     _evisum_ui_process_list_content_update_all(view);
 }
 
-static void
-_evisum_ui_process_list_fields_update_deferred_cb(void *data) {
-    Evisum_Ui_Process_List_View *view = data;
-    view->skip_wait = 1;
-    view->skip_update = 0;
-}
-
-static void
-_evisum_ui_process_list_fields_cache_reset_done_cb(void *data) {
-    Evisum_Ui_Process_List_View *view = data;
-
-    evisum_ui_widget_exel_deferred_call_schedule(view->widget_exel, 1.0,
-                                                 _evisum_ui_process_list_fields_update_deferred_cb, view);
-}
-
-static unsigned int
-_evisum_ui_process_list_fields_reference_mask_get_cb(void *data) {
-    (void) data;
-    return config()->proc.fields;
-}
-
-static void
-_evisum_ui_process_list_fields_changed_cb(void *data, Eina_Bool changed) {
-    Evisum_Ui_Process_List_View *view = data;
-
-    view->skip_update = 1;
-    (void) changed;
-    evisum_ui_config_save(view->ui);
-}
-
-static void
-_evisum_ui_process_list_fields_applied_cb(void *data, Eina_Bool changed) {
-    Evisum_Ui_Process_List_View *view = data;
-
-    if (!changed) return;
-
-    if (evisum_ui_effects_enabled_get(view->ui))
-        elm_object_signal_emit(view->indicator, "fields,change", "evisum/indicator");
-
-    _evisum_ui_process_list_content_reset(view);
-}
-
-static void
-_evisum_ui_process_list_fields_resize_live_cb(void *data) {
-    Evisum_Ui_Process_List_View *view = data;
-    evisum_ui_widget_exel_genlist_realized_items_update(view->widget_exel);
-}
-
 static void
 _evisum_ui_process_list_fields_resize_done_cb(void *data) {
     Evisum_Ui_Process_List_View *view = data;
+    view->ui->proc.fields = evisum_ui_widget_exel_fields_mask_get(view->widget_exel);
     evisum_ui_config_save(view->ui);
 }
 
@@ -217,21 +171,15 @@ _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_live_cb = NULL,
         .resize_done_cb = _evisum_ui_process_list_fields_resize_done_cb,
         .field_clicked_cb = _evisum_ui_process_list_field_clicked_cb,
         .data = ""
     };
 
     view->widget_exel = evisum_ui_widget_exel_add(&p);
+    evisum_ui_widget_exel_resize_hit_width_set(view->widget_exel, PROC_COL_RESIZE_HIT_WIDTH);
+    evisum_ui_widget_exel_fields_mask_set(view->widget_exel, view->ui->proc.fields);
 
     for (int i = PROC_FIELD_CMD; i < PROC_FIELD_MAX; i++) {
         const Proc_Field_Info *meta;
@@ -259,46 +207,20 @@ _evisum_ui_process_list_fields_init(Evisum_Ui_Process_List_View *view) {
 
 static void
 _evisum_ui_process_list_content_reset(Evisum_Ui_Process_List_View *view) {
-    int j = 0;
-
     elm_table_clear(view->tb_main, 0);
-    elm_table_pack(view->tb_main, view->btn_menu, j++, 0, 1, 1);
-
-    for (int i = PROC_FIELD_CMD; i < PROC_FIELD_MAX; i++) {
-        Evas_Object *btn = evisum_ui_widget_exel_field_header_get(view->widget_exel, i);
-
-        if (!btn) continue;
-        if (!evisum_ui_widget_exel_field_enabled_get(view->widget_exel, i)) {
-            evas_object_hide(btn);
-            continue;
-        }
-
-        elm_table_pack(view->tb_main, btn, j++, 0, 1, 1);
-        evas_object_show(btn);
-    }
-
-    elm_table_pack(view->tb_main, evisum_ui_widget_exel_genlist_obj_get(view->widget_exel), 0, 1, j, 1);
-    elm_table_pack(view->tb_main, view->summary.fr, 0, 2, j, 1);
+    elm_table_pack(view->tb_main, view->btn_menu, 0, 0, 1, 1);
+    elm_table_pack(view->tb_main, view->exel_panel, 0, 1, 1, 1);
+    elm_table_pack(view->tb_main, view->summary.fr, 0, 2, 1, 1);
     evas_object_show(view->summary.fr);
     evisum_ui_widget_exel_genlist_clear(view->widget_exel);
-    evisum_ui_widget_exel_item_cache_reset(view->widget_exel, _evisum_ui_process_list_fields_cache_reset_done_cb, view);
 }
 
 static void
 _evisum_ui_process_list_item_unrealized_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) {
-    Evas_Object *o;
     Evisum_Ui_Process_List_View *view;
-    Eina_List *contents = NULL;
 
     view = data;
-
-    evisum_ui_widget_exel_genlist_item_all_contents_unset(view->widget_exel, event_info, &contents);
-
-    EINA_LIST_FREE(contents, o) {
-        if (!evisum_ui_widget_exel_item_cache_item_release(view->widget_exel, o)) {
-            evas_object_del(o);
-        }
-    }
+    evisum_ui_widget_exel_genlist_item_unrealized_handle(view->widget_exel, event_info);
 }
 
 static void
@@ -406,7 +328,7 @@ _evisum_ui_process_list_content_get(void *data, Evas_Object *obj, const char *so
     struct passwd *pwd_entry;
     Evas_Object *cell, *o;
     char buf[128];
-    Evas_Coord w, ow, bw;
+    Evas_Coord w, ow;
     Evisum_Ui *ui;
     Evisum_Ui_Process_List_View *view;
     const char *icon_name, *icon_old, *icon_new;
@@ -425,15 +347,12 @@ _evisum_ui_process_list_content_get(void *data, Evas_Object *obj, const char *so
         exit(-1);
     }
 
-    evas_object_geometry_get(view->btn_menu, NULL, NULL, &bw, NULL);
     w = evisum_ui_widget_exel_field_width_get(view->widget_exel, PROC_FIELD_CMD);
-    w += bw;
 
     snprintf(buf, sizeof(buf), "%s", proc->command);
     cell = evisum_ui_widget_exel_item_object_get(view->widget_exel, row, "cmd");
     evisum_ui_widget_exel_item_text_object_if_changed_set(view->widget_exel, cell, buf);
     evas_object_geometry_get(cell, NULL, NULL, &ow, NULL);
-    ow += bw;
     _evisum_ui_process_list_cmd_width_sync(view, ow);
 
     icon_name = evisum_icon_cache_find(view->icon_cache, proc);
@@ -1137,7 +1056,7 @@ _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, &gp);
+    view->exel_panel = evisum_ui_widget_exel_genlist_add(view->widget_exel, &gp);
 
     view->itc.item_style = "full";
     view->itc.func.text_get = NULL;
@@ -1355,8 +1274,6 @@ _evisum_ui_process_list_win_resize_cb(void *data, Evas *e, Evas_Object *obj, voi
     view = data;
     ui = view->ui;
 
-    evisum_ui_widget_exel_genlist_realized_items_update(view->widget_exel);
-
     view->skip_wait = 1;
 
     if (view->resize_timer) ecore_timer_reset(view->resize_timer);
@@ -1463,6 +1380,7 @@ _evisum_ui_process_list_win_del_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED,
     view = data;
     ui = view->ui;
 
+    ui->proc.fields = evisum_ui_widget_exel_fields_mask_get(view->widget_exel);
     evisum_ui_config_save(ui);
 
     evisum_ui_widget_exel_deferred_call_cancel(view->widget_exel);
diff --git a/src/bin/ui/evisum_ui_process_view.c b/src/bin/ui/evisum_ui_process_view.c
index 86cf50f..85cf5c9 100644
--- a/src/bin/ui/evisum_ui_process_view.c
+++ b/src/bin/ui/evisum_ui_process_view.c
@@ -70,8 +70,6 @@ typedef struct {
 
     struct {
         Evisum_Ui_Widget_Exel *widget_exel;
-        unsigned int fields_mask;
-        int field_widths[1];
     } children;
 
     struct {
@@ -84,8 +82,6 @@ typedef struct {
 
         Eina_Hash *hash_cpu_times;
         Evisum_Ui_Widget_Exel *widget_exel;
-        unsigned int fields_mask;
-        int field_widths[5];
         int (*sort_cb)(const void *p1, const void *p2);
 
         Eina_Bool sort_reverse;
@@ -163,14 +159,9 @@ _evisum_ui_process_view_exe_response(const char *command) {
 static void
 _evisum_ui_process_view_item_unrealized_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) {
     Evisum_Ui_Process_View *view;
-    Evas_Object *o;
-    Eina_List *contents = NULL;
 
     view = data;
-
-    evisum_ui_widget_exel_genlist_item_all_contents_unset(view->threads.widget_exel, event_info, &contents);
-
-    EINA_LIST_FREE(contents, o) { evisum_ui_widget_exel_item_cache_item_release(view->threads.widget_exel, o); }
+    evisum_ui_widget_exel_genlist_item_unrealized_handle(view->threads.widget_exel, event_info);
 }
 
 static void
@@ -1202,7 +1193,7 @@ _evisum_ui_process_view_threads_field_clicked_cb(void *data, int field_id) {
 
 static Evas_Object *
 _evisum_ui_process_view_threads_tab_add(Evas_Object *parent, Evisum_Ui_Process_View *view) {
-    Evas_Object *fr, *bx, *bx2, *tb, *glist;
+    Evas_Object *fr, *bx, *bx2, *glist;
     Evas_Object *graph;
     Evisum_Ui_Widget_Exel_Genlist_Params gp = {
         .homogeneous = 1,
@@ -1255,15 +1246,7 @@ _evisum_ui_process_view_threads_tab_add(Evas_Object *parent, Evisum_Ui_Process_V
     evas_object_size_hint_align_set(bx2, FILL, FILL);
     evas_object_show(bx2);
 
-    tb = elm_table_add(bx2);
-    evas_object_size_hint_weight_set(tb, EXPAND, 0);
-    evas_object_size_hint_align_set(tb, FILL, FILL);
-    elm_box_pack_end(bx2, tb);
-    evas_object_show(tb);
-
     for (unsigned int c = 0; c < sizeof(cols) / sizeof(cols[0]); c++) {
-        Evas_Object *btn;
-
         evisum_ui_widget_exel_field_register(view->threads.widget_exel, cols[c].field_id, cols[c].label, cols[c].field_desc,
                                              ELM_SCALE_SIZE(BTN_WIDTH), ELM_SCALE_SIZE(BTN_WIDTH), EINA_TRUE,
                                              cols[c].weight, cols[c].align);
@@ -1271,15 +1254,6 @@ _evisum_ui_process_view_threads_tab_add(Evas_Object *parent, Evisum_Ui_Process_V
         if (_evisum_ui_process_view_thread_sort_cb_get(cols[c].sort) == view->threads.sort_cb)
             evisum_ui_widget_exel_field_sort_state_set(view->threads.widget_exel, cols[c].field_id,
                                                        view->threads.sort_reverse);
-
-        btn = evisum_ui_widget_exel_field_header_get(view->threads.widget_exel, cols[c].field_id);
-        if (!btn) continue;
-        if (!evisum_ui_widget_exel_field_enabled_get(view->threads.widget_exel, cols[c].field_id)) {
-            evas_object_hide(btn);
-            continue;
-        }
-        elm_table_pack(tb, btn, c, 0, 1, 1);
-        evas_object_show(btn);
     }
 
     glist = evisum_ui_widget_exel_genlist_add(view->threads.widget_exel, &gp);
@@ -1514,13 +1488,6 @@ _evisum_ui_process_view_win_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object
     free(view);
 }
 
-static void
-_evisum_ui_process_view_win_resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) {
-    Evisum_Ui_Process_View *view = data;
-
-    evisum_ui_widget_exel_genlist_realized_items_update(view->threads.widget_exel);
-}
-
 static void
 _evisum_ui_process_view_win_key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) {
     Evas_Event_Key_Down *ev;
@@ -1568,10 +1535,6 @@ evisum_ui_process_view_win_add(int pid, Evisum_Proc_Action action) {
     view->poll_delay = 1;
     view->threads.widget_exel = NULL;
     view->children.widget_exel = NULL;
-    view->children.fields_mask = 0;
-    view->children.field_widths[0] = 1;
-    view->threads.fields_mask = 0;
-    view->threads.field_widths[0] = 1;
     view->threads.sort_reverse = 1;
     view->threads.sort_cb = _evisum_ui_process_view_sort_by_cpu_usage;
     view->icon_cache = evisum_icon_cache_new();
@@ -1595,14 +1558,6 @@ evisum_ui_process_view_win_add(int pid, Evisum_Proc_Action action) {
     wx_params = (Evisum_Ui_Widget_Exel_Params) {
         .win = view->win,
         .parent = view->win,
-        .field_first = 0,
-        .field_max = (int) (sizeof(view->threads.field_widths) / sizeof(view->threads.field_widths[0])),
-        .resize_hit_width = 8,
-        .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,
         .field_clicked_cb = _evisum_ui_process_view_threads_field_clicked_cb,
@@ -1613,15 +1568,17 @@ evisum_ui_process_view_win_add(int pid, Evisum_Proc_Action action) {
         evas_object_del(view->win);
         return;
     }
+    evisum_ui_widget_exel_resize_hit_width_set(view->threads.widget_exel, 8);
+    evisum_ui_widget_exel_fields_mask_set(view->threads.widget_exel, ~0u);
 
-    wx_params.fields_mask = &view->children.fields_mask;
-    wx_params.field_widths = view->children.field_widths;
     wx_params.field_clicked_cb = NULL;
     view->children.widget_exel = evisum_ui_widget_exel_add(&wx_params);
     if (!view->children.widget_exel) {
         evas_object_del(view->win);
         return;
     }
+    evisum_ui_widget_exel_resize_hit_width_set(view->children.widget_exel, 8);
+    evisum_ui_widget_exel_fields_mask_set(view->children.widget_exel, ~0u);
 
     tabs = _evisum_ui_process_view_tabs_add(win, view);
 
@@ -1650,7 +1607,6 @@ evisum_ui_process_view_win_add(int pid, Evisum_Proc_Action action) {
     elm_object_content_set(win, bx);
 
     evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _evisum_ui_process_view_win_del_cb, view);
-    evas_object_event_callback_add(win, EVAS_CALLBACK_RESIZE, _evisum_ui_process_view_win_resize_cb, view);
     evas_object_event_callback_add(bx, EVAS_CALLBACK_KEY_DOWN, _evisum_ui_process_view_win_key_down_cb, view);
 
     evas_object_resize(win, ELM_SCALE_SIZE(460), 1);
diff --git a/src/bin/ui/evisum_ui_widget_exel.c b/src/bin/ui/evisum_ui_widget_exel.c
index e5792ba..814c7f3 100644
--- a/src/bin/ui/evisum_ui_widget_exel.c
+++ b/src/bin/ui/evisum_ui_widget_exel.c
@@ -19,14 +19,22 @@ typedef struct {
 struct _Evisum_Ui_Widget_Exel {
     Evisum_Ui_Widget_Exel_Params p;
     Exel_Field fields[EVISUM_UI_WIDGET_EXEL_FIELDS_MAX];
+    int field_widths[EVISUM_UI_WIDGET_EXEL_FIELDS_MAX];
+    int field_first;
+    int field_max;
+    int resize_hit_width;
+    unsigned int fields_mask;
+    unsigned int fields_mask_reference;
     Evisum_Ui_Cache *cache;
+    Evisum_Ui_Widget_Exel_Item_Cell_Def *cache_defs;
+    unsigned int cache_defs_count;
+    Evas_Object *container;
+    Evas_Object *header_tb;
     Evas_Object *glist;
 
     Evas_Object *fields_menu;
     Evas_Object *resize_btn;
     Ecore_Timer *deferred_timer;
-    void (*deferred_cb)(void *data);
-    void *deferred_data;
 
     int resize_field;
     Evas_Coord resize_start_x;
@@ -40,6 +48,59 @@ struct _Evisum_Ui_Widget_Exel {
     int last_visible_field;
 };
 
+#define EVISUM_UI_WIDGET_EXEL_WX_DATA_KEY "__evisum_ui_widget_exel_wx"
+
+static void
+_evisum_ui_widget_exel_cache_defs_free(Evisum_Ui_Widget_Exel *wx) {
+    unsigned int i;
+
+    if (!wx || !wx->cache_defs) return;
+
+    for (i = 0; i < wx->cache_defs_count; i++) {
+        eina_stringshare_del(wx->cache_defs[i].key);
+        eina_stringshare_del(wx->cache_defs[i].aux_key);
+        eina_stringshare_del(wx->cache_defs[i].unit_format);
+    }
+    free(wx->cache_defs);
+    wx->cache_defs = NULL;
+    wx->cache_defs_count = 0;
+}
+
+static Eina_Bool
+_evisum_ui_widget_exel_cache_defs_set(Evisum_Ui_Widget_Exel *wx, const Evisum_Ui_Widget_Exel_Item_Cell_Def *defs,
+                                      unsigned int count) {
+    unsigned int i;
+    Evisum_Ui_Widget_Exel_Item_Cell_Def *copy;
+
+    if (!wx || !defs || !count) return 0;
+
+    copy = calloc(count, sizeof(Evisum_Ui_Widget_Exel_Item_Cell_Def));
+    if (!copy) return 0;
+
+    for (i = 0; i < count; i++) {
+        copy[i] = defs[i];
+        copy[i].key = defs[i].key ? eina_stringshare_add(defs[i].key) : NULL;
+        copy[i].aux_key = defs[i].aux_key ? eina_stringshare_add(defs[i].aux_key) : NULL;
+        copy[i].unit_format = defs[i].unit_format ? eina_stringshare_add(defs[i].unit_format) : NULL;
+    }
+
+    _evisum_ui_widget_exel_cache_defs_free(wx);
+    wx->cache_defs = copy;
+    wx->cache_defs_count = count;
+    return 1;
+}
+
+static Evas_Object *
+_evisum_ui_widget_exel_item_cache_row_create(Evas_Object *parent) {
+    Evisum_Ui_Widget_Exel *wx;
+
+    if (!parent) return NULL;
+    wx = evas_object_data_get(parent, EVISUM_UI_WIDGET_EXEL_WX_DATA_KEY);
+    if (!wx || !wx->cache_defs || !wx->cache_defs_count) return NULL;
+
+    return evisum_ui_widget_exel_item_row_add(wx, parent, wx->cache_defs, wx->cache_defs_count);
+}
+
 static Exel_Field *
 _evisum_ui_widget_exel_field_get(const Evisum_Ui_Widget_Exel *wx, int id) {
     if (!wx) return NULL;
@@ -52,7 +113,7 @@ static int
 _evisum_ui_widget_exel_field_prev_visible_get(const Evisum_Ui_Widget_Exel *wx, int id) {
     int i;
 
-    for (i = id - 1; i >= wx->p.field_first; i--) {
+    for (i = id - 1; i >= wx->field_first; i--) {
         Exel_Field *f = _evisum_ui_widget_exel_field_get(wx, i);
         if (f && f->enabled) return i;
     }
@@ -79,15 +140,16 @@ _evisum_ui_widget_exel_fields_sync(Evisum_Ui_Widget_Exel *wx) {
     int i;
     unsigned int mask;
 
-    if (!wx || !wx->p.fields_mask) return;
+    if (!wx) return;
+    if (wx->field_max <= wx->field_first) return;
 
-    mask = *(wx->p.fields_mask);
+    mask = wx->fields_mask;
     if (wx->fields_mask_snapshot == mask) return;
 
     wx->fields_mask_snapshot = mask;
-    wx->last_visible_field = wx->p.field_first;
+    wx->last_visible_field = wx->field_first;
 
-    for (i = wx->p.field_first; i < wx->p.field_max; i++) {
+    for (i = wx->field_first; i < wx->field_max; i++) {
         Exel_Field *f = _evisum_ui_widget_exel_field_get(wx, i);
         if (!f) continue;
 
@@ -109,39 +171,22 @@ _evisum_ui_widget_exel_sort_ignore_consume(Evisum_Ui_Widget_Exel *wx);
 static Eina_Bool
 _evisum_ui_widget_exel_fields_menu_visible_get(const Evisum_Ui_Widget_Exel *wx);
 
-static Eina_Bool
-_evisum_ui_widget_exel_deferred_timer_cb(void *data) {
-    Evisum_Ui_Widget_Exel *wx = data;
-    void (*cb)(void *data);
-    void *cb_data;
+static void
+_evisum_ui_widget_exel_header_repack(Evisum_Ui_Widget_Exel *wx);
 
-    if (!wx) return ECORE_CALLBACK_CANCEL;
-
-    cb = wx->deferred_cb;
-    cb_data = wx->deferred_data;
-    wx->deferred_timer = NULL;
-    wx->deferred_cb = NULL;
-    wx->deferred_data = NULL;
-
-    if (cb) cb(cb_data);
-
-    return ECORE_CALLBACK_CANCEL;
-}
+static void
+_evisum_ui_widget_exel_panel_resize_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
+                                       void *event_info EINA_UNUSED);
 
 static Eina_Bool
 _evisum_ui_widget_exel_dirty_get(Evisum_Ui_Widget_Exel *wx) {
-    unsigned int ref;
-
-    if (!wx->p.reference_mask_get_cb) return wx->fields_changed;
-
-    ref = wx->p.reference_mask_get_cb(wx->p.data);
-    return ref != *(wx->p.fields_mask);
+    if (!wx) return 0;
+    return wx->fields_mask_reference != wx->fields_mask;
 }
 
 static void
 _evisum_ui_widget_exel_fields_changed_notify(Evisum_Ui_Widget_Exel *wx) {
     wx->fields_changed = _evisum_ui_widget_exel_dirty_get(wx);
-    if (wx->p.fields_changed_cb) wx->p.fields_changed_cb(wx->p.data, wx->fields_changed);
 }
 
 static void
@@ -171,8 +216,11 @@ _evisum_ui_widget_exel_fields_menu_apply_clicked_cb(void *data, Evas_Object *obj
 
     changed = wx->fields_changed;
     evisum_ui_widget_exel_fields_menu_dismiss(wx);
+    if (!changed) return;
+    wx->fields_mask_reference = wx->fields_mask;
 
-    if (wx->p.fields_applied_cb) wx->p.fields_applied_cb(wx->p.data, changed);
+    if (wx->glist) elm_genlist_clear(wx->glist);
+    if (wx->cache) evisum_ui_item_cache_reset(wx->cache, NULL, NULL);
 }
 
 static void
@@ -184,8 +232,9 @@ _evisum_ui_widget_exel_fields_menu_check_changed_cb(void *data, Evas_Object *obj
     wx = evas_object_data_get(obj, "wx");
     if (!wx || !f) return;
 
-    *(wx->p.fields_mask) ^= (1U << f->id);
+    wx->fields_mask ^= (1U << f->id);
     _evisum_ui_widget_exel_fields_sync(wx);
+    _evisum_ui_widget_exel_header_repack(wx);
     _evisum_ui_widget_exel_fields_changed_notify(wx);
 
     ic = evas_object_data_get(obj, "apply_icon");
@@ -239,7 +288,7 @@ _evisum_ui_widget_exel_fields_menu_create(Evisum_Ui_Widget_Exel *wx) {
     elm_box_pack_end(bx, hbx);
     evas_object_show(hbx);
 
-    for (i = wx->p.field_first + 1; i < wx->p.field_max; i++) {
+    for (i = wx->field_first + 1; i < wx->field_max; i++) {
         Exel_Field *f = _evisum_ui_widget_exel_field_get(wx, i);
         if (!f || !f->btn || !f->desc) continue;
 
@@ -278,9 +327,9 @@ _evisum_ui_widget_exel_field_header_mouse_down_cb(void *data, Evas *e EINA_UNUSE
 
     evas_object_geometry_get(obj, &x, NULL, &w, NULL);
     field = (int) (intptr_t) evas_object_data_get(obj, "field_id");
-    if (field < wx->p.field_first || field >= wx->p.field_max) return;
+    if (field < wx->field_first || field >= wx->field_max) return;
 
-    if (ev->canvas.x >= (x + w - ELM_SCALE_SIZE(wx->p.resize_hit_width))) {
+    if (ev->canvas.x >= (x + w - ELM_SCALE_SIZE(wx->resize_hit_width))) {
         wx->resizing = 1;
         wx->resize_btn = obj;
         wx->resize_field = field;
@@ -290,7 +339,7 @@ _evisum_ui_widget_exel_field_header_mouse_down_cb(void *data, Evas *e EINA_UNUSE
         return;
     }
 
-    if (ev->canvas.x <= (x + ELM_SCALE_SIZE(wx->p.resize_hit_width))) {
+    if (ev->canvas.x <= (x + ELM_SCALE_SIZE(wx->resize_hit_width))) {
         prev = _evisum_ui_widget_exel_field_prev_visible_get(wx, field);
         if (!prev) return;
 
@@ -332,8 +381,9 @@ _evisum_ui_widget_exel_field_resize_mouse_move(Evisum_Ui_Widget_Exel *wx, Evas_E
         width = _evisum_ui_widget_exel_field_min_width_get(wx, wx->resize_field);
 
     evas_object_size_hint_min_set(wx->resize_btn, width, 1);
-    wx->p.field_widths[wx->resize_field] = width;
+    wx->field_widths[wx->resize_field] = width;
     _evisum_ui_widget_exel_field_proportions_apply(wx);
+    if (wx->glist) elm_genlist_realized_items_update(wx->glist);
 
     if (wx->p.resize_live_cb) wx->p.resize_live_cb(wx->p.data);
 }
@@ -347,8 +397,9 @@ _evisum_ui_widget_exel_field_resize_mouse_up(Evisum_Ui_Widget_Exel *wx, Evas_Eve
     if (!wx->resizing || !wx->resize_btn) return;
 
     evas_object_geometry_get(wx->resize_btn, NULL, NULL, &w, NULL);
-    wx->p.field_widths[wx->resize_field] = w;
+    wx->field_widths[wx->resize_field] = w;
     _evisum_ui_widget_exel_field_proportions_apply(wx);
+    if (wx->glist) elm_genlist_realized_items_update(wx->glist);
 
     wx->resizing = 0;
     wx->resize_btn = NULL;
@@ -401,11 +452,43 @@ _evisum_ui_widget_exel_field_header_clicked_cb(void *data, Evas_Object *obj, voi
     }
 
     field = (int) (intptr_t) evas_object_data_get(obj, "field_id");
-    if (field < wx->p.field_first || field >= wx->p.field_max) return;
+    if (field < wx->field_first || field >= wx->field_max) return;
 
     if (wx->p.field_clicked_cb) wx->p.field_clicked_cb(wx->p.data, field);
 }
 
+static void
+_evisum_ui_widget_exel_header_repack(Evisum_Ui_Widget_Exel *wx) {
+    int i, col = 0;
+
+    if (!wx || !wx->header_tb) return;
+
+    _evisum_ui_widget_exel_fields_sync(wx);
+    _evisum_ui_widget_exel_field_proportions_apply(wx);
+    elm_table_clear(wx->header_tb, 0);
+
+    for (i = wx->field_first; i < wx->field_max; i++) {
+        Exel_Field *f = _evisum_ui_widget_exel_field_get(wx, i);
+        if (!f || !f->btn) continue;
+
+        if (!f->enabled) {
+            evas_object_hide(f->btn);
+            continue;
+        }
+
+        elm_table_pack(wx->header_tb, f->btn, col++, 0, 1, 1);
+        evas_object_show(f->btn);
+    }
+}
+
+static void
+_evisum_ui_widget_exel_panel_resize_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
+                                       void *event_info EINA_UNUSED) {
+    Evisum_Ui_Widget_Exel *wx = data;
+    if (!wx || !wx->glist) return;
+    elm_genlist_realized_items_update(wx->glist);
+}
+
 static void
 _evisum_ui_widget_exel_win_mouse_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
                                          void *event_info) {
@@ -436,14 +519,17 @@ evisum_ui_widget_exel_add(const Evisum_Ui_Widget_Exel_Params *params) {
     Evisum_Ui_Widget_Exel *wx;
 
     if (!params) return NULL;
-    if (!params->field_widths || !params->fields_mask) return NULL;
-
     wx = calloc(1, sizeof(Evisum_Ui_Widget_Exel));
     if (!wx) return NULL;
 
     wx->p = *params;
+    wx->field_first = EVISUM_UI_WIDGET_EXEL_FIELDS_MAX;
+    wx->field_max = 0;
+    wx->resize_hit_width = 8;
+    wx->fields_mask = UINT_MAX;
+    wx->last_visible_field = 0;
+    wx->fields_mask_reference = wx->fields_mask;
     wx->fields_mask_snapshot = UINT_MAX;
-    wx->last_visible_field = wx->p.field_first;
     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);
@@ -455,6 +541,9 @@ evisum_ui_widget_exel_add(const Evisum_Ui_Widget_Exel_Params *params) {
 void
 evisum_ui_widget_exel_free(Evisum_Ui_Widget_Exel *wx) {
     if (!wx) return;
+    if (wx->container)
+        evas_object_event_callback_del_full(wx->container, EVAS_CALLBACK_RESIZE, _evisum_ui_widget_exel_panel_resize_cb,
+                                            wx);
     if (wx->p.win) {
         evas_object_event_callback_del_full(wx->p.win, EVAS_CALLBACK_MOUSE_MOVE, _evisum_ui_widget_exel_win_mouse_move_cb,
                                             wx);
@@ -463,7 +552,10 @@ evisum_ui_widget_exel_free(Evisum_Ui_Widget_Exel *wx) {
     }
     evisum_ui_widget_exel_fields_menu_dismiss(wx);
     evisum_ui_widget_exel_deferred_call_cancel(wx);
+    _evisum_ui_widget_exel_cache_defs_free(wx);
     if (wx->cache) evisum_ui_item_cache_free(wx->cache);
+    wx->container = NULL;
+    wx->header_tb = NULL;
     wx->glist = NULL;
     free(wx);
 }
@@ -474,12 +566,21 @@ evisum_ui_widget_exel_field_register(Evisum_Ui_Widget_Exel *wx, int id, const ch
                                      double align_x) {
     Exel_Field *f;
     Evas_Object *btn;
+    Evas_Object *parent;
 
     if (!wx) return;
     if (id < 0 || id >= EVISUM_UI_WIDGET_EXEL_FIELDS_MAX) return;
     if (!wx->p.parent) return;
 
-    btn = elm_button_add(wx->p.parent);
+    if (!wx->header_tb) {
+        wx->header_tb = elm_table_add(wx->p.parent);
+        evas_object_size_hint_weight_set(wx->header_tb, EXPAND, 0.0);
+        evas_object_size_hint_align_set(wx->header_tb, FILL, FILL);
+        evas_object_show(wx->header_tb);
+    }
+    parent = wx->header_tb ? wx->header_tb : wx->p.parent;
+
+    btn = elm_button_add(parent);
     evas_object_size_hint_weight_set(btn, weight_x, EXPAND);
     evas_object_size_hint_align_set(btn, align_x, FILL);
     elm_object_text_set(btn, title ? title : "");
@@ -497,25 +598,39 @@ evisum_ui_widget_exel_field_register(Evisum_Ui_Widget_Exel *wx, int id, const ch
     f->default_width = default_width;
     f->min_width = min_width;
     f->always_visible = always_visible;
+    if (id < wx->field_first) wx->field_first = id;
+    if ((id + 1) > wx->field_max) wx->field_max = id + 1;
+    if (wx->last_visible_field < wx->field_first) wx->last_visible_field = wx->field_first;
 
     wx->fields_mask_snapshot = UINT_MAX;
     _evisum_ui_widget_exel_fields_sync(wx);
     _evisum_ui_widget_exel_field_width_apply(wx, id);
+    _evisum_ui_widget_exel_header_repack(wx);
 }
 
-Evas_Object *
-evisum_ui_widget_exel_field_header_get(const Evisum_Ui_Widget_Exel *wx, int id) {
-    Exel_Field *f;
+void
+evisum_ui_widget_exel_fields_mask_set(Evisum_Ui_Widget_Exel *wx, unsigned int mask) {
+    if (!wx) return;
 
-    if (!wx) return NULL;
-    if (id < 0 || id >= EVISUM_UI_WIDGET_EXEL_FIELDS_MAX) return NULL;
+    wx->fields_mask = mask;
+    wx->fields_mask_reference = mask;
+    wx->fields_mask_snapshot = UINT_MAX;
+    _evisum_ui_widget_exel_fields_sync(wx);
+    _evisum_ui_widget_exel_header_repack(wx);
+    if (wx->glist) elm_genlist_realized_items_update(wx->glist);
+}
 
-    _evisum_ui_widget_exel_fields_sync((Evisum_Ui_Widget_Exel *) wx);
-    _evisum_ui_widget_exel_field_proportions_apply((Evisum_Ui_Widget_Exel *) wx);
+unsigned int
+evisum_ui_widget_exel_fields_mask_get(const Evisum_Ui_Widget_Exel *wx) {
+    if (!wx) return 0;
+    return wx->fields_mask;
+}
 
-    f = _evisum_ui_widget_exel_field_get(wx, id);
-    if (!f) return NULL;
-    return f->btn;
+void
+evisum_ui_widget_exel_resize_hit_width_set(Evisum_Ui_Widget_Exel *wx, int width) {
+    if (!wx) return;
+    if (width < 1) width = 1;
+    wx->resize_hit_width = width;
 }
 
 Eina_Bool
@@ -543,7 +658,7 @@ Evas_Coord
 evisum_ui_widget_exel_field_width_get(const Evisum_Ui_Widget_Exel *wx, int id) {
     if (!wx) return 0;
     if (id < 0 || id >= EVISUM_UI_WIDGET_EXEL_FIELDS_MAX) return 0;
-    return wx->p.field_widths[id];
+    return wx->field_widths[id];
 }
 
 void
@@ -556,8 +671,8 @@ evisum_ui_widget_exel_field_min_width_set(Evisum_Ui_Widget_Exel *wx, int id, Eva
     if (!f || !f->btn) return;
 
     evas_object_size_hint_min_set(f->btn, width, 1);
-    if (id >= wx->p.field_first && id < wx->p.field_max && wx->p.field_widths[id] < width)
-        wx->p.field_widths[id] = width;
+    if (id >= wx->field_first && id < wx->field_max && wx->field_widths[id] < width)
+        wx->field_widths[id] = width;
 }
 
 static void
@@ -573,11 +688,11 @@ _evisum_ui_widget_exel_field_width_apply(Evisum_Ui_Widget_Exel *wx, int id) {
     }
     if (!btn) return;
 
-    width = wx->p.field_widths[id];
+    width = wx->field_widths[id];
     if (width < _evisum_ui_widget_exel_field_min_width_get(wx, id))
         width = _evisum_ui_widget_exel_field_default_width_get(wx, id);
 
-    wx->p.field_widths[id] = width;
+    wx->field_widths[id] = width;
     evas_object_size_hint_min_set(btn, width, 1);
 }
 
@@ -590,21 +705,21 @@ _evisum_ui_widget_exel_field_proportions_apply(Evisum_Ui_Widget_Exel *wx) {
 
     _evisum_ui_widget_exel_fields_sync(wx);
 
-    for (i = wx->p.field_first; i < wx->p.field_max; i++) {
+    for (i = wx->field_first; i < wx->field_max; i++) {
         Exel_Field *f = _evisum_ui_widget_exel_field_get(wx, i);
         if (!f || !f->enabled) continue;
-        if (!wx->p.field_widths[i]) wx->p.field_widths[i] = _evisum_ui_widget_exel_field_default_width_get(wx, i);
-        total += wx->p.field_widths[i];
+        if (!wx->field_widths[i]) wx->field_widths[i] = _evisum_ui_widget_exel_field_default_width_get(wx, i);
+        total += wx->field_widths[i];
     }
 
     if (total <= 0.0) total = 1.0;
 
-    for (i = wx->p.field_first; i < wx->p.field_max; i++) {
+    for (i = wx->field_first; i < wx->field_max; i++) {
         Exel_Field *f = _evisum_ui_widget_exel_field_get(wx, i);
         Evas_Object *btn = f ? f->btn : NULL;
         if (!btn) continue;
 
-        if (f->enabled) evas_object_size_hint_weight_set(btn, wx->p.field_widths[i] / total, 0.0);
+        if (f->enabled) evas_object_size_hint_weight_set(btn, wx->field_widths[i] / total, 0.0);
         else evas_object_size_hint_weight_set(btn, 0.0, 0.0);
     }
 }
@@ -618,9 +733,9 @@ evisum_ui_widget_exel_cmd_width_sync(Evisum_Ui_Widget_Exel *wx, int field_cmd_id
     minw = _evisum_ui_widget_exel_field_min_width_get(wx, field_cmd_id);
     if (width < minw) width = minw;
 
-    if (wx->p.field_widths[field_cmd_id] >= width) return;
+    if (wx->field_widths[field_cmd_id] >= width) return;
 
-    wx->p.field_widths[field_cmd_id] = width;
+    wx->field_widths[field_cmd_id] = width;
     _evisum_ui_widget_exel_field_width_apply(wx, field_cmd_id);
     _evisum_ui_widget_exel_field_proportions_apply(wx);
 }
@@ -1016,9 +1131,24 @@ evisum_ui_widget_exel_item_cache_add(Evisum_Ui_Widget_Exel *wx, Evas_Object *par
 void
 evisum_ui_widget_exel_item_cache_attach(Evisum_Ui_Widget_Exel *wx, Evas_Object *(*create_cb)(Evas_Object *), int size) {
     if (!wx || !wx->glist) return;
+    _evisum_ui_widget_exel_cache_defs_free(wx);
     evisum_ui_widget_exel_item_cache_add(wx, wx->glist, create_cb, size);
 }
 
+Eina_Bool
+evisum_ui_widget_exel_item_template_set(Evisum_Ui_Widget_Exel *wx,
+                                        const Evisum_Ui_Widget_Exel_Item_Cell_Def *defs,
+                                        unsigned int count) {
+    if (!wx || !defs || !count) return 0;
+    return _evisum_ui_widget_exel_cache_defs_set(wx, defs, count);
+}
+
+void
+evisum_ui_widget_exel_item_cache_attach_template(Evisum_Ui_Widget_Exel *wx, int size) {
+    if (!wx || !wx->glist || !wx->cache_defs || !wx->cache_defs_count || size <= 0) return;
+    evisum_ui_widget_exel_item_cache_add(wx, wx->glist, _evisum_ui_widget_exel_item_cache_row_create, size);
+}
+
 Evas_Object *
 evisum_ui_widget_exel_item_cache_object_get(Evisum_Ui_Widget_Exel *wx) {
     Item_Cache *it;
@@ -1030,18 +1160,12 @@ evisum_ui_widget_exel_item_cache_object_get(Evisum_Ui_Widget_Exel *wx) {
     return it->obj;
 }
 
-Eina_Bool
-evisum_ui_widget_exel_item_cache_item_release(Evisum_Ui_Widget_Exel *wx, Evas_Object *obj) {
+static Eina_Bool
+_evisum_ui_widget_exel_item_cache_item_release(Evisum_Ui_Widget_Exel *wx, Evas_Object *obj) {
     if (!wx || !wx->cache) return 0;
     return evisum_ui_item_cache_item_release(wx->cache, obj);
 }
 
-void
-evisum_ui_widget_exel_item_cache_reset(Evisum_Ui_Widget_Exel *wx, void (*done_cb)(void *data), void *data) {
-    if (!wx || !wx->cache) return;
-    evisum_ui_item_cache_reset(wx->cache, done_cb, data);
-}
-
 void
 evisum_ui_widget_exel_item_cache_steal(Evisum_Ui_Widget_Exel *wx, Eina_List *objs) {
     if (!wx || !wx->cache) return;
@@ -1063,6 +1187,20 @@ evisum_ui_widget_exel_genlist_add(Evisum_Ui_Widget_Exel *wx, const Evisum_Ui_Wid
     parent = wx->p.parent;
     if (!parent) return NULL;
 
+    if (!wx->container) {
+        wx->container = elm_table_add(parent);
+        evas_object_size_hint_weight_set(wx->container, EXPAND, EXPAND);
+        evas_object_size_hint_align_set(wx->container, FILL, FILL);
+        evas_object_event_callback_add(wx->container, EVAS_CALLBACK_RESIZE, _evisum_ui_widget_exel_panel_resize_cb, wx);
+        evas_object_show(wx->container);
+    }
+    if (!wx->header_tb) {
+        wx->header_tb = elm_table_add(parent);
+        evas_object_size_hint_weight_set(wx->header_tb, EXPAND, 0.0);
+        evas_object_size_hint_align_set(wx->header_tb, FILL, FILL);
+        evas_object_show(wx->header_tb);
+    }
+
     glist = elm_genlist_add(parent);
     elm_genlist_homogeneous_set(glist, params->homogeneous);
     elm_scroller_bounce_set(glist, params->bounce_h, params->bounce_v);
@@ -1077,7 +1215,12 @@ evisum_ui_widget_exel_genlist_add(Evisum_Ui_Widget_Exel *wx, const Evisum_Ui_Wid
 
     if (wx->glist) evas_object_del(wx->glist);
     wx->glist = glist;
-    return glist;
+    evas_object_data_set(wx->glist, EVISUM_UI_WIDGET_EXEL_WX_DATA_KEY, wx);
+
+    elm_table_pack(wx->container, wx->header_tb, 0, 0, 1, 1);
+    elm_table_pack(wx->container, wx->glist, 0, 1, 1, 1);
+    _evisum_ui_widget_exel_header_repack(wx);
+    return wx->container;
 }
 
 Evas_Object *
@@ -1182,13 +1325,25 @@ evisum_ui_widget_exel_genlist_item_update(Evisum_Ui_Widget_Exel *wx EINA_UNUSED,
     elm_genlist_item_update(it);
 }
 
-void
-evisum_ui_widget_exel_genlist_item_all_contents_unset(Evisum_Ui_Widget_Exel *wx EINA_UNUSED, Elm_Object_Item *it,
-                                                      Eina_List **contents) {
+static void
+_evisum_ui_widget_exel_genlist_item_all_contents_unset(Elm_Object_Item *it, Eina_List **contents) {
     if (!it) return;
     elm_genlist_item_all_contents_unset(it, contents);
 }
 
+void
+evisum_ui_widget_exel_genlist_item_unrealized_handle(Evisum_Ui_Widget_Exel *wx, Elm_Object_Item *it) {
+    Eina_List *contents = NULL;
+    Evas_Object *o;
+
+    if (!wx || !it) return;
+
+    _evisum_ui_widget_exel_genlist_item_all_contents_unset(it, &contents);
+    EINA_LIST_FREE(contents, o) {
+        if (!_evisum_ui_widget_exel_item_cache_item_release(wx, o)) evas_object_del(o);
+    }
+}
+
 Elm_Object_Item *
 evisum_ui_widget_exel_genlist_item_append(Evisum_Ui_Widget_Exel *wx, Elm_Genlist_Item_Class *itc, const void *data,
                                           Elm_Object_Item *parent, Elm_Genlist_Item_Type type, Evas_Smart_Cb func,
@@ -1209,23 +1364,9 @@ evisum_ui_widget_exel_object_item_data_set(Evisum_Ui_Widget_Exel *wx EINA_UNUSED
     elm_object_item_data_set(it, data);
 }
 
-void
-evisum_ui_widget_exel_deferred_call_schedule(Evisum_Ui_Widget_Exel *wx, double delay_seconds, void (*cb)(void *data),
-                                             void *data) {
-    if (!wx || !cb) return;
-
-    if (wx->deferred_timer) ecore_timer_del(wx->deferred_timer);
-
-    wx->deferred_cb = cb;
-    wx->deferred_data = data;
-    wx->deferred_timer = ecore_timer_add(delay_seconds, _evisum_ui_widget_exel_deferred_timer_cb, wx);
-}
-
 void
 evisum_ui_widget_exel_deferred_call_cancel(Evisum_Ui_Widget_Exel *wx) {
     if (!wx) return;
     if (wx->deferred_timer) ecore_timer_del(wx->deferred_timer);
     wx->deferred_timer = NULL;
-    wx->deferred_cb = NULL;
-    wx->deferred_data = NULL;
 }
diff --git a/src/bin/ui/evisum_ui_widget_exel.h b/src/bin/ui/evisum_ui_widget_exel.h
index ddb67d6..634b1c8 100644
--- a/src/bin/ui/evisum_ui_widget_exel.h
+++ b/src/bin/ui/evisum_ui_widget_exel.h
@@ -35,9 +35,6 @@ typedef struct {
     int icon_size;
 } Evisum_Ui_Widget_Exel_Item_Cell_Def;
 
-typedef unsigned int (*Evisum_Ui_Widget_Exel_Reference_Mask_Get_Cb)(void *data);
-typedef void (*Evisum_Ui_Widget_Exel_Fields_Changed_Cb)(void *data, Eina_Bool changed);
-typedef void (*Evisum_Ui_Widget_Exel_Fields_Applied_Cb)(void *data, Eina_Bool changed);
 typedef void (*Evisum_Ui_Widget_Exel_Resize_Live_Cb)(void *data);
 typedef void (*Evisum_Ui_Widget_Exel_Resize_Done_Cb)(void *data);
 typedef void (*Evisum_Ui_Widget_Exel_Field_Clicked_Cb)(void *data, int field_id);
@@ -45,15 +42,7 @@ typedef void (*Evisum_Ui_Widget_Exel_Field_Clicked_Cb)(void *data, int field_id)
 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;
     Evisum_Ui_Widget_Exel_Field_Clicked_Cb field_clicked_cb;
@@ -77,7 +66,7 @@ typedef struct {
     const void *data;
 } Evisum_Ui_Widget_Exel_Genlist_Params;
 
-/* Create and initialize the exel widget controller with field masks, widths, and callbacks.
+/* Create and initialize the exel widget controller with behavior 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);
 
@@ -91,9 +80,15 @@ void evisum_ui_widget_exel_field_register(Evisum_Ui_Widget_Exel *wx, int id, con
                                           int default_width, int min_width, Eina_Bool always_visible, double weight_x,
                                           double align_x);
 
-/* Return the header button object for a registered field id.
- * Consumers can pack/show/hide header objects manually in their own layouts. */
-Evas_Object *evisum_ui_widget_exel_field_header_get(const Evisum_Ui_Widget_Exel *wx, int id);
+/* Set the enabled field bitmask managed by the widget.
+ * Bits map directly to field ids and are used for non-always-visible show/hide state. */
+void evisum_ui_widget_exel_fields_mask_set(Evisum_Ui_Widget_Exel *wx, unsigned int mask);
+
+/* Return the current field bitmask managed by the widget. */
+unsigned int evisum_ui_widget_exel_fields_mask_get(const Evisum_Ui_Widget_Exel *wx);
+
+/* Set header resize grab width in pixels for left/right edge hit-testing. */
+void evisum_ui_widget_exel_resize_hit_width_set(Evisum_Ui_Widget_Exel *wx, int width);
 
 /* 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. */
@@ -175,18 +170,19 @@ Evas_Object *evisum_ui_widget_exel_icon_button_add(Evisum_Ui_Widget_Exel *wx, co
 void evisum_ui_widget_exel_item_cache_attach(Evisum_Ui_Widget_Exel *wx, Evas_Object *(*create_cb)(Evas_Object *),
                                              int size);
 
+/* Set a reusable declarative row template for widget-owned cache object creation.
+ * This keeps row-factory details internal and lets callers define row layout once. */
+Eina_Bool evisum_ui_widget_exel_item_template_set(Evisum_Ui_Widget_Exel *wx,
+                                                  const Evisum_Ui_Widget_Exel_Item_Cell_Def *defs,
+                                                  unsigned int count);
+
+/* Attach item cache using the previously set row template. */
+void evisum_ui_widget_exel_item_cache_attach_template(Evisum_Ui_Widget_Exel *wx, 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);
 
-/* Release a realized row object back to the widget-owned cache.
- * Returns true when the object was found and handled by the cache. */
-Eina_Bool evisum_ui_widget_exel_item_cache_item_release(Evisum_Ui_Widget_Exel *wx, Evas_Object *obj);
-
-/* Reset and rebuild the widget-owned cache and invoke completion callback when cleanup completes.
- * Use this after column/field layout changes so row object structure is recreated safely. */
-void evisum_ui_widget_exel_item_cache_reset(Evisum_Ui_Widget_Exel *wx, void (*done_cb)(void *data), void *data);
-
 /* Steal non-realized cache objects using the provided realized object list.
  * Use this to cap cache growth under churn without leaking stale pooled objects. */
 void evisum_ui_widget_exel_item_cache_steal(Evisum_Ui_Widget_Exel *wx, Eina_List *objs);
@@ -195,8 +191,8 @@ 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/replace the widget-owned genlist configured from one parameter block and return it.
- * Callers may pack the returned object manually where needed. */
+/* Create/replace the widget-owned list panel and return the container object.
+ * The returned object contains the internally generated header table and genlist. */
 Evas_Object *evisum_ui_widget_exel_genlist_add(Evisum_Ui_Widget_Exel *wx,
                                                 const Evisum_Ui_Widget_Exel_Genlist_Params *params);
 
@@ -223,7 +219,7 @@ void 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);
 
-/* Return the first item in the widget-owned genlist.
+/* Return the first item in the widg:et-owned genlist.
  * Use this as the starting point when applying updated row data in order. */
 Elm_Object_Item *evisum_ui_widget_exel_genlist_first_item_get(const Evisum_Ui_Widget_Exel *wx);
 
@@ -271,10 +267,9 @@ void evisum_ui_widget_exel_genlist_item_selected_set(Evisum_Ui_Widget_Exel *wx,
  * Use this after swapping row data on an existing item. */
 void evisum_ui_widget_exel_genlist_item_update(Evisum_Ui_Widget_Exel *wx, Elm_Object_Item *it);
 
-/* Unset all realized content objects from a genlist item and return them in `contents`.
- * Use this in unrealize callbacks before returning objects to the shared item cache. */
-void evisum_ui_widget_exel_genlist_item_all_contents_unset(Evisum_Ui_Widget_Exel *wx, Elm_Object_Item *it,
-                                                           Eina_List **contents);
+/* Handle unrealize cleanup for one genlist item.
+ * This unsets row contents and returns cacheable objects to the internal cache. */
+void evisum_ui_widget_exel_genlist_item_unrealized_handle(Evisum_Ui_Widget_Exel *wx, Elm_Object_Item *it);
 
 /* 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. */
@@ -291,11 +286,6 @@ void *evisum_ui_widget_exel_object_item_data_get(Evisum_Ui_Widget_Exel *wx, Elm_
  * Use this when replacing payloads during periodic list updates in the same way as `elm_object_item_data_set`. */
 void evisum_ui_widget_exel_object_item_data_set(Evisum_Ui_Widget_Exel *wx, Elm_Object_Item *it, void *data);
 
-/* Schedule a one-shot deferred callback owned by the widget and replace any pending one.
- * Use this for field-layout settling timers so consumer files no longer manage timer objects directly. */
-void evisum_ui_widget_exel_deferred_call_schedule(Evisum_Ui_Widget_Exel *wx, double delay_seconds,
-                                                  void (*cb)(void *data), void *data);
-
 /* Cancel any pending widget-owned deferred callback.
  * Call this when abandoning pending UI work, though widget free also cancels it automatically. */
 void evisum_ui_widget_exel_deferred_call_cancel(Evisum_Ui_Widget_Exel *wx);

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

Reply via email to