ui/gtk/list.c

changeset 722
6466b4f16e5e
parent 701
6fdec085c385
child 723
e513086eadbb
equal deleted inserted replaced
721:e9f655afc7ed 722:6466b4f16e5e
43 #include "icon.h" 43 #include "icon.h"
44 #include "menu.h" 44 #include "menu.h"
45 #include "dnd.h" 45 #include "dnd.h"
46 46
47 47
48 void* ui_strmodel_getvalue(void *elm, int column) { 48 static void* getvalue_wrapper(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult) {
49 return column == 0 ? elm : NULL; 49 ui_getvaluefunc getvalue = (ui_getvaluefunc)userdata;
50 } 50 return getvalue(elm, col);
51 51 }
52 static void* model_getvalue(UiModel *model, UiList *list, void *elm, int row, int col, UiBool *freeResult) { 52
53 if(model->getvalue2) { 53 static void* str_getvalue(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult) {
54 return model->getvalue2(list, elm, row, col, model->getvalue2data, freeResult); 54 return elm;
55 } else if(model->getvalue) { 55 }
56 return model->getvalue(elm, col); 56
57 } 57 static void* null_getvalue(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult) {
58 return NULL; 58 return NULL;
59 } 59 }
60 60
61 /* 61 /*
62 static GtkTargetEntry targetentries[] = 62 static GtkTargetEntry targetentries[] =
71 listview->elements = calloc(nelm, sizeof(char*)); 71 listview->elements = calloc(nelm, sizeof(char*));
72 listview->nelm = nelm; 72 listview->nelm = nelm;
73 for(int i=0;i<nelm;i++) { 73 for(int i=0;i<nelm;i++) {
74 listview->elements[i] = strdup(elm[i]); 74 listview->elements[i] = strdup(elm[i]);
75 } 75 }
76 }
77
78 static UiListView* create_listview(UiObject *obj, UiListArgs *args) {
79 UiListView *tableview = malloc(sizeof(UiListView));
80 memset(tableview, 0, sizeof(UiListView));
81 tableview->obj = obj;
82 tableview->model = args->model;
83 tableview->onactivate = args->onactivate;
84 tableview->onactivatedata = args->onactivatedata;
85 tableview->onselection = args->onselection;
86 tableview->onselectiondata = args->onselectiondata;
87 tableview->ondragstart = args->ondragstart;
88 tableview->ondragstartdata = args->ondragstartdata;
89 tableview->ondragcomplete = args->ondragcomplete;
90 tableview->ondragcompletedata = args->ondragcompletedata;
91 tableview->ondrop = args->ondrop;
92 tableview->ondropdata = args->ondropdata;
93 tableview->selection.count = 0;
94 tableview->selection.rows = NULL;
95
96 if(args->getvalue2) {
97 tableview->getvalue = args->getvalue2;
98 tableview->getvaluedata = args->getvalue2data;
99 } else if(args->getvalue) {
100 tableview->getvalue = getvalue_wrapper;
101 tableview->getvaluedata = (void*)args->getvalue;
102 } else {
103 tableview->getvalue = null_getvalue;
104 }
105
106 return tableview;
76 } 107 }
77 108
78 #if GTK_CHECK_VERSION(4, 10, 0) 109 #if GTK_CHECK_VERSION(4, 10, 0)
79 110
80 111
130 gtk_label_set_xalign(GTK_LABEL(label), 0); 161 gtk_label_set_xalign(GTK_LABEL(label), 0);
131 gtk_list_item_set_child(item, label); 162 gtk_list_item_set_child(item, label);
132 } 163 }
133 } 164 }
134 165
135 static void column_factory_bind( GtkListItemFactory *factory, GtkListItem *item, gpointer userdata) { 166 static void column_factory_bind(GtkListItemFactory *factory, GtkListItem *item, gpointer userdata) {
136 UiColData *col = userdata; 167 UiColData *col = userdata;
137 UiList *list = col->listview->var ? col->listview->var->value : NULL; 168 UiList *list = col->listview->var ? col->listview->var->value : NULL;
169 UiListView *listview = col->listview;
138 170
139 ObjWrapper *obj = gtk_list_item_get_item(item); 171 ObjWrapper *obj = gtk_list_item_get_item(item);
140 UiModel *model = col->listview->model; 172 UiModel *model = col->listview->model;
141 UiModelType type = model->types[col->model_column]; 173 UiModelType type = model->types[col->model_column];
142 174
143 UiBool freevalue = FALSE; 175 UiBool freevalue = FALSE;
144 void *data = model_getvalue(model, list, obj->data, obj->i, col->data_column, &freevalue); 176 void *data = listview->getvalue(list, obj->data, obj->i, col->data_column, listview->getvaluedata, &freevalue);
145 GtkWidget *child = gtk_list_item_get_child(item); 177 GtkWidget *child = gtk_list_item_get_child(item);
146 178
147 switch(type) { 179 switch(type) {
148 case UI_STRING_FREE: { 180 case UI_STRING_FREE: {
149 freevalue = TRUE; 181 freevalue = TRUE;
171 } 203 }
172 case UI_ICON_TEXT: { 204 case UI_ICON_TEXT: {
173 205
174 } 206 }
175 case UI_ICON_TEXT_FREE: { 207 case UI_ICON_TEXT_FREE: {
176 void *data2 = model_getvalue(model, list, obj->data, obj->i, col->data_column+1, &freevalue); 208 void *data2 = listview->getvalue(list, obj->data, obj->i, col->data_column+1, listview->getvaluedata, &freevalue);
177 if(type == UI_ICON_TEXT_FREE) { 209 if(type == UI_ICON_TEXT_FREE) {
178 freevalue = TRUE; 210 freevalue = TRUE;
179 } 211 }
180 GtkWidget *image = g_object_get_data(G_OBJECT(child), "image"); 212 GtkWidget *image = g_object_get_data(G_OBJECT(child), "image");
181 GtkWidget *label = g_object_get_data(G_OBJECT(child), "label"); 213 GtkWidget *label = g_object_get_data(G_OBJECT(child), "label");
205 } 237 }
206 g_signal_connect(selection_model, "selection-changed", G_CALLBACK(ui_listview_selection_changed), listview); 238 g_signal_connect(selection_model, "selection-changed", G_CALLBACK(ui_listview_selection_changed), listview);
207 return selection_model; 239 return selection_model;
208 } 240 }
209 241
210 static UiListView* create_listview(UiObject *obj, UiListArgs *args) {
211 UiListView *tableview = malloc(sizeof(UiListView));
212 memset(tableview, 0, sizeof(UiListView));
213 tableview->obj = obj;
214 tableview->model = args->model;
215 tableview->onactivate = args->onactivate;
216 tableview->onactivatedata = args->onactivatedata;
217 tableview->onselection = args->onselection;
218 tableview->onselectiondata = args->onselectiondata;
219 tableview->ondragstart = args->ondragstart;
220 tableview->ondragstartdata = args->ondragstartdata;
221 tableview->ondragcomplete = args->ondragcomplete;
222 tableview->ondragcompletedata = args->ondragcompletedata;
223 tableview->ondrop = args->ondrop;
224 tableview->ondropdata = args->ondropdata;
225 tableview->selection.count = 0;
226 tableview->selection.rows = NULL;
227 return tableview;
228 }
229
230 UIWIDGET ui_listview_create(UiObject *obj, UiListArgs *args) { 242 UIWIDGET ui_listview_create(UiObject *obj, UiListArgs *args) {
231 UiObject* current = uic_current_obj(obj); 243 UiObject* current = uic_current_obj(obj);
232 244
233 // to simplify things and share code with ui_table_create, we also 245 // to simplify things and share code with ui_table_create, we also
234 // use a UiModel for the listview 246 // use a UiModel for the listview
235 UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1); 247 UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1);
236 if(args->getvalue2) {
237 model->getvalue2 = args->getvalue2;
238 model->getvalue2data = args->getvalue2data;
239 } else if(args->getvalue) {
240 model->getvalue = args->getvalue;
241 } else {
242 model->getvalue = ui_strmodel_getvalue;
243 }
244 args->model = model; 248 args->model = model;
245 249
246 GListStore *ls = g_list_store_new(G_TYPE_OBJECT); 250 GListStore *ls = g_list_store_new(G_TYPE_OBJECT);
247 UiListView *listview = create_listview(obj, args); 251 UiListView *listview = create_listview(obj, args);
252 if(!args->getvalue && !args->getvalue2) {
253 listview->getvalue = str_getvalue;
254 }
248 255
249 listview->columns = malloc(sizeof(UiColData)); 256 listview->columns = malloc(sizeof(UiColData));
250 listview->columns->listview = listview; 257 listview->columns->listview = listview;
251 listview->columns->data_column = 0; 258 listview->columns->data_column = 0;
252 listview->columns->model_column = 0; 259 listview->columns->model_column = 0;
253 260
254 GtkListItemFactory *factory = gtk_signal_list_item_factory_new(); 261 GtkListItemFactory *factory = gtk_signal_list_item_factory_new();
255 g_signal_connect(factory, "setup", G_CALLBACK(column_factory_setup), listview->columns); 262 g_signal_connect(factory, "setup", G_CALLBACK(column_factory_setup), listview->columns);
256 g_signal_connect(factory, "bind", G_CALLBACK(column_factory_bind), listview->columns); 263 g_signal_connect(factory, "bind", G_CALLBACK(column_factory_bind), listview->columns);
257 264
258 GtkSelectionModel *selection_model = create_selection_model(listview, ls, args->multiselection); 265 GtkSelectionModel *selection_model = create_selection_model(listview, ls, args->multiselection);
281 list->setselection = ui_listview_setselection2; 288 list->setselection = ui_listview_setselection2;
282 289
283 ui_update_liststore(ls, list); 290 ui_update_liststore(ls, list);
284 } else if (args->static_elements && args->static_nelm > 0) { 291 } else if (args->static_elements && args->static_nelm > 0) {
285 listview_copy_static_elements(listview, args->static_elements, args->static_nelm); 292 listview_copy_static_elements(listview, args->static_elements, args->static_nelm);
286 listview->model->getvalue = ui_strmodel_getvalue; // force strmodel 293 listview->getvalue = str_getvalue; // force string values
287 ui_update_liststore_static(ls, listview->elements, listview->nelm); 294 ui_update_liststore_static(ls, listview->elements, listview->nelm);
288 } 295 }
289 296
290 // event handling 297 // event handling
291 if(args->onactivate) { 298 if(args->onactivate) {
321 UiObject* current = uic_current_obj(obj); 328 UiObject* current = uic_current_obj(obj);
322 329
323 // to simplify things and share code with ui_tableview_create, we also 330 // to simplify things and share code with ui_tableview_create, we also
324 // use a UiModel for the listview 331 // use a UiModel for the listview
325 UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1); 332 UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1);
326 if(args->getvalue2) {
327 model->getvalue2 = args->getvalue2;
328 model->getvalue2data = args->getvalue2data;
329 } else if(args->getvalue) {
330 model->getvalue = args->getvalue;
331 } else {
332 model->getvalue = ui_strmodel_getvalue;
333 }
334 args->model = model; 333 args->model = model;
335 334
336 GListStore *ls = g_list_store_new(G_TYPE_OBJECT); 335 GListStore *ls = g_list_store_new(G_TYPE_OBJECT);
337 UiListView *listview = create_listview(obj, args); 336 UiListView *listview = create_listview(obj, args);
337
338 if(!args->getvalue && !args->getvalue2) {
339 listview->getvalue = str_getvalue;
340 }
338 341
339 listview->columns = malloc(sizeof(UiColData)); 342 listview->columns = malloc(sizeof(UiColData));
340 listview->columns->listview = listview; 343 listview->columns->listview = listview;
341 listview->columns->data_column = 0; 344 listview->columns->data_column = 0;
342 listview->columns->model_column = 0; 345 listview->columns->model_column = 0;
371 list->setselection = ui_combobox_setselection; 374 list->setselection = ui_combobox_setselection;
372 375
373 ui_update_liststore(ls, list); 376 ui_update_liststore(ls, list);
374 } else if (args->static_elements && args->static_nelm > 0) { 377 } else if (args->static_elements && args->static_nelm > 0) {
375 listview_copy_static_elements(listview, args->static_elements, args->static_nelm); 378 listview_copy_static_elements(listview, args->static_elements, args->static_nelm);
376 listview->model->getvalue = ui_strmodel_getvalue; // force strmodel 379 listview->getvalue = str_getvalue; // force string values
377 ui_update_liststore_static(ls, listview->elements, listview->nelm); 380 ui_update_liststore_static(ls, listview->elements, listview->nelm);
378 } 381 }
379 382
380 // event handling 383 // event handling
381 if(args->onactivate) { 384 if(args->onactivate) {
702 ui_setop_enable(FALSE); 705 ui_setop_enable(FALSE);
703 } 706 }
704 707
705 #else 708 #else
706 709
707 static void update_list_row(GtkListStore *store, GtkTreeIter *iter, UiModel *model, UiList *list, void *elm, int row) { 710 static void update_list_row(UiListView *listview, GtkListStore *store, GtkTreeIter *iter, UiList *list, void *elm, int row) {
711 UiModel *model = listview->model;
708 // set column values 712 // set column values
709 int c = 0; 713 int c = 0;
710 for(int i=0;i<model->columns;i++,c++) { 714 for(int i=0;i<model->columns;i++,c++) {
711 UiBool freevalue = FALSE; 715 UiBool freevalue = FALSE;
712 void *data = model_getvalue(model, list, elm, row, c, &freevalue); 716 void *data = listview->getvalue(list, elm, row, c, listview->getvaluedata, &freevalue);
713 717
714 GValue value = G_VALUE_INIT; 718 GValue value = G_VALUE_INIT;
715 switch(model->types[i]) { 719 switch(model->types[i]) {
716 case UI_STRING_FREE: { 720 case UI_STRING_FREE: {
717 freevalue = TRUE; 721 freevalue = TRUE;
772 } 776 }
773 #endif 777 #endif
774 c++; 778 c++;
775 779
776 freevalue = FALSE; 780 freevalue = FALSE;
777 char *str = model_getvalue(model, list, elm, row, c, &freevalue); 781 char *str = listview->getvalue(list, elm, row, c, listview->getvaluedata, &freevalue);
778 g_value_init(&value, G_TYPE_STRING); 782 g_value_init(&value, G_TYPE_STRING);
779 g_value_set_string(&value, str); 783 g_value_set_string(&value, str);
780 if(model->types[i] == UI_ICON_TEXT_FREE || freevalue) { 784 if(model->types[i] == UI_ICON_TEXT_FREE || freevalue) {
781 free(str); 785 free(str);
782 } 786 }
786 790
787 gtk_list_store_set_value(store, iter, c, &value); 791 gtk_list_store_set_value(store, iter, c, &value);
788 } 792 }
789 } 793 }
790 794
791 static GtkListStore* create_list_store(UiList *list, UiModel *model) { 795 static GtkListStore* create_list_store(UiListView *listview, UiList *list) {
796 UiModel *model = listview->model;
792 int columns = model->columns; 797 int columns = model->columns;
793 GType types[2*columns]; 798 GType types[2*columns];
794 int c = 0; 799 int c = 0;
795 for(int i=0;i<columns;i++,c++) { 800 for(int i=0;i<columns;i++,c++) {
796 switch(model->types[i]) { 801 switch(model->types[i]) {
814 while(elm) { 819 while(elm) {
815 // insert new row 820 // insert new row
816 GtkTreeIter iter; 821 GtkTreeIter iter;
817 gtk_list_store_insert (store, &iter, -1); 822 gtk_list_store_insert (store, &iter, -1);
818 823
819 update_list_row(store, &iter, model, list, elm, i++); 824 update_list_row(listview, store, &iter, list, elm, i++);
820 825
821 // next row 826 // next row
822 elm = list->next(list); 827 elm = list->next(list);
823 } 828 }
824 } 829 }
848 #else 853 #else
849 // TODO: implement for gtk2 854 // TODO: implement for gtk2
850 #endif 855 #endif
851 856
852 UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1); 857 UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1);
853 if(args->getvalue2) { 858
854 model->getvalue2 = args->getvalue2; 859 UiListView *listview = create_listview(obj, args);
855 model->getvalue2data = args->getvalue2data; 860 if(!args->getvalue && !args->getvalue2) {
856 } else if(args->getvalue) { 861 listview->getvalue = str_getvalue;
857 model->getvalue = args->getvalue; 862 }
858 } else {
859 model->getvalue = ui_strmodel_getvalue;
860 }
861
862 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST);
863
864 UiList *list = var ? var->value : NULL;
865 GtkListStore *listmodel = create_list_store(list, model);
866 gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(listmodel));
867 g_object_unref(listmodel);
868
869 UiListView *listview = malloc(sizeof(UiListView));
870 memset(listview, 0, sizeof(UiListView));
871 listview->obj = obj;
872 listview->widget = view;
873 listview->var = var;
874 listview->model = model; 863 listview->model = model;
875 listview->selection.count = 0;
876 listview->selection.rows = NULL;
877 g_signal_connect( 864 g_signal_connect(
878 view, 865 view,
879 "destroy", 866 "destroy",
880 G_CALLBACK(ui_listview_destroy), 867 G_CALLBACK(ui_listview_destroy),
881 listview); 868 listview);
869
870 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST);
871
872 // init listview
873 listview->widget = view;
874 listview->var = var;
875
876 UiList *list = var ? var->value : NULL;
877 GtkListStore *listmodel = create_list_store(listview, list);
878 gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(listmodel));
879 g_object_unref(listmodel);
882 880
883 // bind var 881 // bind var
884 list->update = ui_listview_update; 882 list->update = ui_listview_update;
885 list->getselection = ui_listview_getselection; 883 list->getselection = ui_listview_getselection;
886 list->setselection = ui_listview_setselection; 884 list->setselection = ui_listview_setselection;
1013 1011
1014 #endif 1012 #endif
1015 1013
1016 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST); 1014 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST);
1017 1015
1018 UiList *list = var ? var->value : NULL;
1019 GtkListStore *listmodel = create_list_store(list, model);
1020 gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(listmodel));
1021 g_object_unref(listmodel);
1022
1023 //g_signal_connect(view, "drag-begin", G_CALLBACK(drag_begin), NULL); 1016 //g_signal_connect(view, "drag-begin", G_CALLBACK(drag_begin), NULL);
1024 //g_signal_connect(view, "drag-end", G_CALLBACK(drag_end), NULL); 1017 //g_signal_connect(view, "drag-end", G_CALLBACK(drag_end), NULL);
1025 1018
1026 // add TreeView as observer to the UiList to update the TreeView if the 1019 // add TreeView as observer to the UiList to update the TreeView if the
1027 // data changes 1020 // data changes
1028 UiListView *tableview = malloc(sizeof(UiListView)); 1021 UiListView *tableview = create_listview(obj, args);
1029 memset(tableview, 0, sizeof(UiListView));
1030 tableview->obj = obj;
1031 tableview->widget = view;
1032 tableview->var = var;
1033 tableview->model = model;
1034 tableview->ondragstart = args->ondragstart;
1035 tableview->ondragstartdata = args->ondragstartdata;
1036 tableview->ondragcomplete = args->ondragcomplete;
1037 tableview->ondragcompletedata = args->ondragcompletedata;
1038 tableview->ondrop = args->ondrop;
1039 tableview->ondropdata = args->ondropdata;
1040 tableview->selection.count = 0;
1041 tableview->selection.rows = NULL;
1042 g_signal_connect( 1022 g_signal_connect(
1043 view, 1023 view,
1044 "destroy", 1024 "destroy",
1045 G_CALLBACK(ui_listview_destroy), 1025 G_CALLBACK(ui_listview_destroy),
1046 tableview); 1026 tableview);
1027
1028 UiList *list = var ? var->value : NULL;
1029 GtkListStore *listmodel = create_list_store(tableview, list);
1030 gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(listmodel));
1031 g_object_unref(listmodel);
1047 1032
1048 // bind var 1033 // bind var
1049 list->update = ui_listview_update; 1034 list->update = ui_listview_update;
1050 list->getselection = ui_listview_getselection; 1035 list->getselection = ui_listview_getselection;
1051 list->setselection = ui_listview_setselection; 1036 list->setselection = ui_listview_setselection;
1119 1104
1120 1105
1121 void ui_listview_update(UiList *list, int i) { 1106 void ui_listview_update(UiList *list, int i) {
1122 UiListView *view = list->obj; 1107 UiListView *view = list->obj;
1123 if(i < 0) { 1108 if(i < 0) {
1124 GtkListStore *store = create_list_store(list, view->model); 1109 GtkListStore *store = create_list_store(view, list);
1125 gtk_tree_view_set_model(GTK_TREE_VIEW(view->widget), GTK_TREE_MODEL(store)); 1110 gtk_tree_view_set_model(GTK_TREE_VIEW(view->widget), GTK_TREE_MODEL(store));
1126 g_object_unref(G_OBJECT(store)); 1111 g_object_unref(G_OBJECT(store));
1127 } else { 1112 } else {
1128 void *elm = list->get(list, i); 1113 void *elm = list->get(list, i);
1129 GtkTreeModel *store = gtk_tree_view_get_model(GTK_TREE_VIEW(view->widget)); 1114 GtkTreeModel *store = gtk_tree_view_get_model(GTK_TREE_VIEW(view->widget));
1130 GtkTreeIter iter; 1115 GtkTreeIter iter;
1131 if(gtk_tree_model_iter_nth_child(store, &iter, NULL, i)) { 1116 if(gtk_tree_model_iter_nth_child(store, &iter, NULL, i)) {
1132 update_list_row(GTK_LIST_STORE(store), &iter, view->model, list, elm, i); 1117 update_list_row(view, GTK_LIST_STORE(store), &iter, list, elm, i);
1133 } 1118 }
1134 } 1119 }
1135 } 1120 }
1136 1121
1137 UiListSelection ui_listview_getselection(UiList *list) { 1122 UiListSelection ui_listview_getselection(UiList *list) {
1157 /* --------------------------- ComboBox --------------------------- */ 1142 /* --------------------------- ComboBox --------------------------- */
1158 1143
1159 UIWIDGET ui_combobox_create(UiObject *obj, UiListArgs *args) { 1144 UIWIDGET ui_combobox_create(UiObject *obj, UiListArgs *args) {
1160 UiObject* current = uic_current_obj(obj); 1145 UiObject* current = uic_current_obj(obj);
1161 1146
1162 UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1); 1147 //GtkWidget *combobox = ui_create_combobox(obj, model, var, args->static_elements, args->static_nelm, args->onactivate, args->onactivatedata);
1163 if(args->getvalue2) { 1148
1164 model->getvalue2 = args->getvalue2; 1149 GtkWidget *combobox = gtk_combo_box_new();
1165 model->getvalue2data = args->getvalue2data; 1150
1166 } else if(args->getvalue) {
1167 model->getvalue = args->getvalue;
1168 } else {
1169 model->getvalue = ui_strmodel_getvalue;
1170 }
1171
1172 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST);
1173
1174 GtkWidget *combobox = ui_create_combobox(obj, model, var, args->static_elements, args->static_nelm, args->onactivate, args->onactivatedata);
1175 ui_set_name_and_style(combobox, args->name, args->style_class); 1151 ui_set_name_and_style(combobox, args->name, args->style_class);
1176 ui_set_widget_groups(obj->ctx, combobox, args->groups); 1152 ui_set_widget_groups(obj->ctx, combobox, args->groups);
1177 UI_APPLY_LAYOUT2(current, args); 1153 UI_APPLY_LAYOUT2(current, args);
1178 current->container->add(current->container, combobox); 1154 current->container->add(current->container, combobox);
1179 current->container->current = combobox; 1155 current->container->current = combobox;
1180 return combobox; 1156
1181 } 1157 UiListView *listview = create_listview(obj, args);
1182 1158 listview->widget = combobox;
1183 GtkWidget* ui_create_combobox(UiObject *obj, UiModel *model, UiVar *var, char **elm, size_t nelm, ui_callback f, void *udata) { 1159 listview->model = ui_model(obj->ctx, UI_STRING, "", -1);
1184 GtkWidget *combobox = gtk_combo_box_new(); 1160 g_signal_connect(
1185 1161 combobox,
1186 UiListView *uicbox = malloc(sizeof(UiListView)); 1162 "destroy",
1187 memset(uicbox, 0, sizeof(UiListView)); 1163 G_CALLBACK(ui_listview_destroy),
1188 uicbox->obj = obj; 1164 listview);
1189 uicbox->widget = combobox; 1165
1190 1166 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST);
1191 UiList *list = var ? var->value : NULL; 1167 UiList *list = var ? var->value : NULL;
1192 GtkListStore *listmodel = create_list_store(list, model); 1168 GtkListStore *listmodel = create_list_store(listview, list);
1193 1169 if(var) {
1194 if(!list && elm && nelm > 0) { 1170 listview->var = var;
1195 listview_copy_static_elements(uicbox, elm, nelm); 1171 list->update = ui_combobox_modelupdate;
1196 for(int i=0;i<nelm;i++) { 1172 list->getselection = ui_combobox_getselection;
1173 list->setselection = ui_combobox_setselection;
1174 list->obj = listview;
1175 list->update(list, -1);
1176 } else if(args->static_nelm > 0) {
1177 listview_copy_static_elements(listview, args->static_elements, args->static_nelm);
1178 for(int i=0;i<args->static_nelm;i++) {
1197 GtkTreeIter iter; 1179 GtkTreeIter iter;
1198 GValue value = G_VALUE_INIT; 1180 GValue value = G_VALUE_INIT;
1199 gtk_list_store_insert(listmodel, &iter, -1); 1181 gtk_list_store_insert(listmodel, &iter, -1);
1200 g_value_init(&value, G_TYPE_STRING); 1182 g_value_init(&value, G_TYPE_STRING);
1201 g_value_set_string(&value, uicbox->elements[i]); 1183 g_value_set_string(&value, listview->elements[i]);
1202 gtk_list_store_set_value(listmodel, &iter, 0, &value); 1184 gtk_list_store_set_value(listmodel, &iter, 0, &value);
1203 } 1185 }
1204 } 1186 }
1205 1187
1206 if(listmodel) { 1188 if(listmodel) {
1207 gtk_combo_box_set_model(GTK_COMBO_BOX(combobox), GTK_TREE_MODEL(listmodel)); 1189 gtk_combo_box_set_model(GTK_COMBO_BOX(combobox), GTK_TREE_MODEL(listmodel));
1208 g_object_unref(listmodel); 1190 g_object_unref(listmodel);
1209 }
1210
1211 uicbox->var = var;
1212 uicbox->model = model;
1213
1214 g_signal_connect(
1215 combobox,
1216 "destroy",
1217 G_CALLBACK(ui_combobox_destroy),
1218 uicbox);
1219
1220 // bind var
1221 if(list) {
1222 list->update = ui_combobox_modelupdate;
1223 list->getselection = ui_combobox_getselection;
1224 list->setselection = ui_combobox_setselection;
1225 list->obj = uicbox;
1226 } 1191 }
1227 1192
1228 GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); 1193 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
1229 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox), renderer, TRUE); 1194 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox), renderer, TRUE);
1230 gtk_cell_layout_set_attributes( 1195 gtk_cell_layout_set_attributes(
1234 0, 1199 0,
1235 NULL); 1200 NULL);
1236 gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), 0); 1201 gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), 0);
1237 1202
1238 // add callback 1203 // add callback
1239 if(f) { 1204 if(args->onactivate) {
1240 UiEventData *event = ui_malloc(obj->ctx, sizeof(UiEventData)); 1205 UiEventData *event = ui_malloc(obj->ctx, sizeof(UiEventData));
1241 event->obj = obj; 1206 event->obj = obj;
1242 event->userdata = udata; 1207 event->userdata = args->onactivatedata;
1243 event->callback = f; 1208 event->callback = args->onactivate;
1244 event->value = 0; 1209 event->value = 0;
1245 event->customdata = uicbox; 1210 event->customdata = listview;
1246 1211
1247 g_signal_connect( 1212 g_signal_connect(
1248 combobox, 1213 combobox,
1249 "changed", 1214 "changed",
1250 G_CALLBACK(ui_combobox_change_event), 1215 G_CALLBACK(ui_combobox_change_event),
1275 e->callback(&event, e->userdata); 1240 e->callback(&event, e->userdata);
1276 } 1241 }
1277 1242
1278 void ui_combobox_modelupdate(UiList *list, int i) { 1243 void ui_combobox_modelupdate(UiList *list, int i) {
1279 UiListView *view = list->obj; 1244 UiListView *view = list->obj;
1280 GtkListStore *store = create_list_store(view->var->value, view->model); 1245 GtkListStore *store = create_list_store(view, list);
1281 gtk_combo_box_set_model(GTK_COMBO_BOX(view->widget), GTK_TREE_MODEL(store)); 1246 gtk_combo_box_set_model(GTK_COMBO_BOX(view->widget), GTK_TREE_MODEL(store));
1282 g_object_unref(store); 1247 g_object_unref(store);
1283 } 1248 }
1284 1249
1285 UiListSelection ui_combobox_getselection(UiList *list) { 1250 UiListSelection ui_combobox_getselection(UiList *list) {
1716 #endif 1681 #endif
1717 free(v->selection.rows); 1682 free(v->selection.rows);
1718 free(v); 1683 free(v);
1719 } 1684 }
1720 1685
1721 void ui_combobox_destroy(GtkWidget *w, UiListView *v) {
1722 if(v->var) {
1723 ui_destroy_boundvar(v->obj->ctx, v->var);
1724 }
1725 if(v->elements) {
1726 for(int i=0;i<v->nelm;i++) {
1727 free(v->elements[i]);
1728 }
1729 free(v->elements);
1730 }
1731 free(v);
1732 }
1733
1734 1686
1735 /* ------------------------------ Source List ------------------------------ */ 1687 /* ------------------------------ Source List ------------------------------ */
1736 1688
1737 static void ui_destroy_sourcelist(GtkWidget *w, UiListBox *v) { 1689 static void ui_destroy_sourcelist(GtkWidget *w, UiListBox *v) {
1738 cxListFree(v->sublists); 1690 cxListFree(v->sublists);

mercurial