optimized selection callback (Motif)

Fri, 16 May 2014 19:20:17 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 16 May 2014 19:20:17 +0200
changeset 44
a1571777eff2
parent 43
157a21a914ac
child 45
cfeb2d5f1332

optimized selection callback (Motif)

ui/motif/tree.c file | annotate | diff | comparison | revisions
ui/motif/tree.h file | annotate | diff | comparison | revisions
--- a/ui/motif/tree.c	Fri May 16 17:39:45 2014 +0200
+++ b/ui/motif/tree.c	Fri May 16 19:20:17 2014 +0200
@@ -75,6 +75,7 @@
     event->activate = modelinfo->activate;
     event->selection = modelinfo->selection;
     event->userdata = modelinfo->userdata;
+    event->last_selection = NULL;
     if(modelinfo->selection) {
         XtAddCallback(
                 container,
@@ -185,14 +186,7 @@
         UiTreeEventData *event,
         XmContainerSelectCallbackStruct *sel)
 { 
-    UiListSelection *selection = malloc(sizeof(UiListSelection));
-    selection->count = sel->selected_item_count;
-    selection->rows = calloc(selection->count, sizeof(int));
-    for(int i=0;i<selection->count;i++) {
-        intptr_t index;
-        XtVaGetValues(sel->selected_items[i], XmNuserData, &index, NULL);
-        selection->rows[i] = index;
-    }
+    UiListSelection *selection = ui_list_selection(sel);
     
     UiEvent e;
     e.obj = event->obj;
@@ -202,7 +196,9 @@
     e.intval = selection->count > 0 ? selection->rows[0] : -1;
     event->activate(&e, event->userdata);
     
-    free(selection);
+    free(event->last_selection->rows);
+    free(event->last_selection);
+    event->last_selection = selection;
 }
 
 void ui_table_select_callback(
@@ -210,22 +206,46 @@
         UiTreeEventData *event,
         XmContainerSelectCallbackStruct *sel)
 { 
+    UiListSelection *selection = ui_list_selection(sel);
+    if(!ui_compare_list_selection(selection, event->last_selection)) {
+        UiEvent e;
+        e.obj = event->obj;
+        e.window = event->obj->window;
+        e.document = event->obj->document;
+        e.eventdata = selection;
+        e.intval = selection->count > 0 ? selection->rows[0] : -1;
+        event->selection(&e, event->userdata);
+    }
+    if(event->last_selection) {
+        free(event->last_selection->rows);
+        free(event->last_selection);
+    }
+    event->last_selection = selection;
+}
+
+UiListSelection* ui_list_selection(XmContainerSelectCallbackStruct *xs) {
     UiListSelection *selection = malloc(sizeof(UiListSelection));
-    selection->count = sel->selected_item_count;
+    selection->count = xs->selected_item_count;
     selection->rows = calloc(selection->count, sizeof(int));
     for(int i=0;i<selection->count;i++) {
         intptr_t index;
-        XtVaGetValues(sel->selected_items[i], XmNuserData, &index, NULL);
+        XtVaGetValues(xs->selected_items[i], XmNuserData, &index, NULL);
         selection->rows[i] = index;
     }
-    
-    UiEvent e;
-    e.obj = event->obj;
-    e.window = event->obj->window;
-    e.document = event->obj->document;
-    e.eventdata = selection;
-    e.intval = selection->count > 0 ? selection->rows[0] : -1;
-    event->selection(&e, event->userdata);
-    
-    free(selection);
+    return selection;
 }
+
+Boolean ui_compare_list_selection(UiListSelection *s1, UiListSelection *s2) {
+    if(!s1 || !s2) {
+        return FALSE;
+    } 
+    if(s1->count != s2->count) {
+        return FALSE;
+    }
+    for(int i=0;i<s1->count;i++) {
+        if(s1->rows[i] != s2->rows[i]) {
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
--- a/ui/motif/tree.h	Fri May 16 17:39:45 2014 +0200
+++ b/ui/motif/tree.h	Fri May 16 19:20:17 2014 +0200
@@ -36,10 +36,11 @@
 #endif
 
 typedef struct UiTreeEventData {
-    UiObject    *obj;
-    ui_callback activate;
-    ui_callback selection;
-    void        *userdata;
+    UiObject        *obj;
+    ui_callback     activate;
+    ui_callback     selection;
+    void            *userdata;
+    UiListSelection *last_selection;
 } UiTreeEventData;    
 
 void ui_add_icon_gadget(
@@ -58,6 +59,10 @@
         UiTreeEventData *event,
         XmContainerSelectCallbackStruct *sel);
 
+UiListSelection* ui_list_selection(XmContainerSelectCallbackStruct *xs);
+
+Boolean ui_compare_list_selection(UiListSelection *s1, UiListSelection *s2);
+
 
 #ifdef	__cplusplus
 }

mercurial