ui/gtk/list.c

changeset 633
4c6ba81d319e
parent 632
8cce45a85942
child 637
6a2c744fe042
equal deleted inserted replaced
632:8cce45a85942 633:4c6ba81d319e
46 46
47 void* ui_strmodel_getvalue(void *elm, int column) { 47 void* ui_strmodel_getvalue(void *elm, int column) {
48 return column == 0 ? elm : NULL; 48 return column == 0 ? elm : NULL;
49 } 49 }
50 50
51 static void* model_getvalue(UiModel *model, UiList *list, void *elm, int row, int col) {
52 if(model->getvalue2) {
53 return model->getvalue2(list, elm, row, col, model->getvalue2data);
54 } else if(model->getvalue) {
55 return model->getvalue(elm, col);
56 }
57 return NULL;
58 }
59
51 /* 60 /*
52 static GtkTargetEntry targetentries[] = 61 static GtkTargetEntry targetentries[] =
53 { 62 {
54 { "STRING", 0, 0 }, 63 { "STRING", 0, 0 },
55 { "text/plain", 0, 1 }, 64 { "text/plain", 0, 1 },
71 /* BEGIN GObject wrapper for generic pointers */ 80 /* BEGIN GObject wrapper for generic pointers */
72 81
73 typedef struct _ObjWrapper { 82 typedef struct _ObjWrapper {
74 GObject parent_instance; 83 GObject parent_instance;
75 void *data; 84 void *data;
85 int i;
76 } ObjWrapper; 86 } ObjWrapper;
77 87
78 typedef struct _ObjWrapperClass { 88 typedef struct _ObjWrapperClass {
79 GObjectClass parent_class; 89 GObjectClass parent_class;
80 } ObjWrapperClass; 90 } ObjWrapperClass;
87 97
88 static void obj_wrapper_init(ObjWrapper *self) { 98 static void obj_wrapper_init(ObjWrapper *self) {
89 self->data = NULL; 99 self->data = NULL;
90 } 100 }
91 101
92 ObjWrapper* obj_wrapper_new(void* data) { 102 ObjWrapper* obj_wrapper_new(void* data, int i) {
93 ObjWrapper *obj = g_object_new(obj_wrapper_get_type(), NULL); 103 ObjWrapper *obj = g_object_new(obj_wrapper_get_type(), NULL);
94 obj->data = data; 104 obj->data = data;
105 obj->i = i;
95 return obj; 106 return obj;
96 } 107 }
97 108
98 /* END GObject wrapper for generic pointers */ 109 /* END GObject wrapper for generic pointers */
99 110
120 } 131 }
121 } 132 }
122 133
123 static void column_factory_bind( GtkListItemFactory *factory, GtkListItem *item, gpointer userdata) { 134 static void column_factory_bind( GtkListItemFactory *factory, GtkListItem *item, gpointer userdata) {
124 UiColData *col = userdata; 135 UiColData *col = userdata;
136 UiList *list = col->listview->var->value;
125 137
126 ObjWrapper *obj = gtk_list_item_get_item(item); 138 ObjWrapper *obj = gtk_list_item_get_item(item);
127 UiModel *model = col->listview->model; 139 UiModel *model = col->listview->model;
128 UiModelType type = model->types[col->model_column]; 140 UiModelType type = model->types[col->model_column];
129 141
130 void *data = model->getvalue(obj->data, col->data_column); 142 void *data = model_getvalue(model, list, obj->data, obj->i, col->data_column);
131 GtkWidget *child = gtk_list_item_get_child(item); 143 GtkWidget *child = gtk_list_item_get_child(item);
132 144
133 bool freevalue = TRUE; 145 bool freevalue = TRUE;
134 switch(type) { 146 switch(type) {
135 case UI_STRING: { 147 case UI_STRING: {
158 } 170 }
159 case UI_ICON_TEXT: { 171 case UI_ICON_TEXT: {
160 freevalue = FALSE; 172 freevalue = FALSE;
161 } 173 }
162 case UI_ICON_TEXT_FREE: { 174 case UI_ICON_TEXT_FREE: {
163 void *data2 = model->getvalue(obj->data, col->data_column+1); 175 void *data2 = model_getvalue(model, list, obj->data, obj->i, col->data_column+1);
164 GtkWidget *image = g_object_get_data(G_OBJECT(child), "image"); 176 GtkWidget *image = g_object_get_data(G_OBJECT(child), "image");
165 GtkWidget *label = g_object_get_data(G_OBJECT(child), "label"); 177 GtkWidget *label = g_object_get_data(G_OBJECT(child), "label");
166 if(data && image) { 178 if(data && image) {
167 UiIcon *icon = data; 179 UiIcon *icon = data;
168 gtk_image_set_from_paintable(GTK_IMAGE(image), GDK_PAINTABLE(icon->info)); 180 gtk_image_set_from_paintable(GTK_IMAGE(image), GDK_PAINTABLE(icon->info));
213 UiObject* current = uic_current_obj(obj); 225 UiObject* current = uic_current_obj(obj);
214 226
215 // to simplify things and share code with ui_table_create, we also 227 // to simplify things and share code with ui_table_create, we also
216 // use a UiModel for the listview 228 // use a UiModel for the listview
217 UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1); 229 UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1);
218 model->getvalue = args->getvalue ? args->getvalue : ui_strmodel_getvalue; 230 if(args->getvalue2) {
231 model->getvalue2 = args->getvalue2;
232 } else if(args->getvalue) {
233 model->getvalue = args->getvalue;
234 } else {
235 model->getvalue = ui_strmodel_getvalue;
236 }
219 args->model = model; 237 args->model = model;
220 238
221 GListStore *ls = g_list_store_new(G_TYPE_OBJECT); 239 GListStore *ls = g_list_store_new(G_TYPE_OBJECT);
222 UiListView *listview = create_listview(obj, args); 240 UiListView *listview = create_listview(obj, args);
223 241
296 UiObject* current = uic_current_obj(obj); 314 UiObject* current = uic_current_obj(obj);
297 315
298 // to simplify things and share code with ui_tableview_create, we also 316 // to simplify things and share code with ui_tableview_create, we also
299 // use a UiModel for the listview 317 // use a UiModel for the listview
300 UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1); 318 UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1);
301 model->getvalue = args->getvalue ? args->getvalue : ui_strmodel_getvalue; 319 if(args->getvalue2) {
320 model->getvalue2 = args->getvalue2;
321 } else if(args->getvalue) {
322 model->getvalue = args->getvalue;
323 } else {
324 model->getvalue = ui_strmodel_getvalue;
325 }
302 args->model = model; 326 args->model = model;
303 327
304 GListStore *ls = g_list_store_new(G_TYPE_OBJECT); 328 GListStore *ls = g_list_store_new(G_TYPE_OBJECT);
305 UiListView *listview = create_listview(obj, args); 329 UiListView *listview = create_listview(obj, args);
306 330
567 } 591 }
568 } 592 }
569 593
570 void ui_update_liststore(GListStore *liststore, UiList *list) { 594 void ui_update_liststore(GListStore *liststore, UiList *list) {
571 g_list_store_remove_all(liststore); 595 g_list_store_remove_all(liststore);
596 int i = 0;
572 void *elm = list->first(list); 597 void *elm = list->first(list);
573 while(elm) { 598 while(elm) {
574 ObjWrapper *obj = obj_wrapper_new(elm); 599 ObjWrapper *obj = obj_wrapper_new(elm, i++);
575 g_list_store_append(liststore, obj); 600 g_list_store_append(liststore, obj);
576 elm = list->next(list); 601 elm = list->next(list);
577 } 602 }
578 } 603 }
579 604
580 void ui_update_liststore_static(GListStore *liststore, char **elm, size_t nelm) { 605 void ui_update_liststore_static(GListStore *liststore, char **elm, size_t nelm) {
581 g_list_store_remove_all(liststore); 606 g_list_store_remove_all(liststore);
582 for(int i=0;i<nelm;i++) { 607 for(int i=0;i<nelm;i++) {
583 ObjWrapper *obj = obj_wrapper_new(elm[i]); 608 ObjWrapper *obj = obj_wrapper_new(elm[i], i);
584 g_list_store_append(liststore, obj); 609 g_list_store_append(liststore, obj);
585 } 610 }
586 } 611 }
587 612
588 void ui_listview_update2(UiList *list, int i) { 613 void ui_listview_update2(UiList *list, int i) {
590 if(i < 0) { 615 if(i < 0) {
591 ui_update_liststore(view->liststore, list); 616 ui_update_liststore(view->liststore, list);
592 } else { 617 } else {
593 void *value = list->get(list, i); 618 void *value = list->get(list, i);
594 if(value) { 619 if(value) {
595 ObjWrapper *obj = obj_wrapper_new(value); 620 ObjWrapper *obj = obj_wrapper_new(value, i);
596 // TODO: if index i is selected, the selection is lost 621 // TODO: if index i is selected, the selection is lost
597 // is it possible to update the item without removing it? 622 // is it possible to update the item without removing it?
598 int count = g_list_model_get_n_items(G_LIST_MODEL(view->liststore)); 623 int count = g_list_model_get_n_items(G_LIST_MODEL(view->liststore));
599 if(count <= i) { 624 if(count <= i) {
600 g_list_store_splice(view->liststore, i, 0, (void **)&obj, 1); 625 g_list_store_splice(view->liststore, i, 0, (void **)&obj, 1);
660 ui_setop_enable(FALSE); 685 ui_setop_enable(FALSE);
661 } 686 }
662 687
663 #else 688 #else
664 689
665 static void update_list_row(GtkListStore *store, GtkTreeIter *iter, UiModel *model, void *elm) { 690 static void update_list_row(GtkListStore *store, GtkTreeIter *iter, UiModel *model, UiList *list, void *elm, int row) {
666 // set column values 691 // set column values
667 int c = 0; 692 int c = 0;
668 for(int i=0;i<model->columns;i++,c++) { 693 for(int i=0;i<model->columns;i++,c++) {
669 void *data = model->getvalue(elm, c); 694 void *data = model_getvalue(model, list, elm, row, c);
670 695
671 GValue value = G_VALUE_INIT; 696 GValue value = G_VALUE_INIT;
672 switch(model->types[i]) { 697 switch(model->types[i]) {
673 case UI_STRING: 698 case UI_STRING:
674 case UI_STRING_FREE: { 699 case UI_STRING_FREE: {
726 gtk_list_store_set_value(store, iter, c, &pixbufvalue); 751 gtk_list_store_set_value(store, iter, c, &pixbufvalue);
727 } 752 }
728 #endif 753 #endif
729 c++; 754 c++;
730 755
731 char *str = model->getvalue(elm, c); 756 char *str = model_getvalue(model, list, elm, row, c);
732 g_value_init(&value, G_TYPE_STRING); 757 g_value_init(&value, G_TYPE_STRING);
733 g_value_set_string(&value, str); 758 g_value_set_string(&value, str);
734 if(model->types[i] == UI_ICON_TEXT_FREE) { 759 if(model->types[i] == UI_ICON_TEXT_FREE) {
735 free(str); 760 free(str);
736 } 761 }
762 787
763 GtkListStore *store = gtk_list_store_newv(c, types); 788 GtkListStore *store = gtk_list_store_newv(c, types);
764 789
765 if(list) { 790 if(list) {
766 void *elm = list->first(list); 791 void *elm = list->first(list);
792 int i = 0;
767 while(elm) { 793 while(elm) {
768 // insert new row 794 // insert new row
769 GtkTreeIter iter; 795 GtkTreeIter iter;
770 gtk_list_store_insert (store, &iter, -1); 796 gtk_list_store_insert (store, &iter, -1);
771 797
772 update_list_row(store, &iter, model, elm); 798 update_list_row(store, &iter, model, list, elm, i++);
773 799
774 // next row 800 // next row
775 elm = list->next(list); 801 elm = list->next(list);
776 } 802 }
777 } 803 }
801 #else 827 #else
802 // TODO: implement for gtk2 828 // TODO: implement for gtk2
803 #endif 829 #endif
804 830
805 UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1); 831 UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1);
806 model->getvalue = args->getvalue ? args->getvalue : ui_strmodel_getvalue; 832 if(args->getvalue2) {
833 model->getvalue2 = args->getvalue2;
834 } else if(args->getvalue) {
835 model->getvalue = args->getvalue;
836 } else {
837 model->getvalue = ui_strmodel_getvalue;
838 }
807 839
808 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST); 840 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST);
809 841
810 UiList *list = var ? var->value : NULL; 842 UiList *list = var ? var->value : NULL;
811 GtkListStore *listmodel = create_list_store(list, model); 843 GtkListStore *listmodel = create_list_store(list, model);
1073 } else { 1105 } else {
1074 void *elm = list->get(list, i); 1106 void *elm = list->get(list, i);
1075 GtkTreeModel *store = gtk_tree_view_get_model(GTK_TREE_VIEW(view->widget)); 1107 GtkTreeModel *store = gtk_tree_view_get_model(GTK_TREE_VIEW(view->widget));
1076 GtkTreeIter iter; 1108 GtkTreeIter iter;
1077 if(gtk_tree_model_iter_nth_child(store, &iter, NULL, i)) { 1109 if(gtk_tree_model_iter_nth_child(store, &iter, NULL, i)) {
1078 update_list_row(GTK_LIST_STORE(store), &iter, view->model, elm); 1110 update_list_row(GTK_LIST_STORE(store), &iter, view->model, list, elm, i);
1079 } 1111 }
1080 } 1112 }
1081 } 1113 }
1082 1114
1083 UiListSelection ui_listview_getselection(UiList *list) { 1115 UiListSelection ui_listview_getselection(UiList *list) {
1104 1136
1105 UIWIDGET ui_combobox_create(UiObject *obj, UiListArgs *args) { 1137 UIWIDGET ui_combobox_create(UiObject *obj, UiListArgs *args) {
1106 UiObject* current = uic_current_obj(obj); 1138 UiObject* current = uic_current_obj(obj);
1107 1139
1108 UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1); 1140 UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1);
1109 model->getvalue = args->getvalue ? args->getvalue : ui_strmodel_getvalue; 1141 if(args->getvalue2) {
1142 model->getvalue2 = args->getvalue2;
1143 } else if(args->getvalue) {
1144 model->getvalue = args->getvalue;
1145 } else {
1146 model->getvalue = ui_strmodel_getvalue;
1147 }
1110 1148
1111 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST); 1149 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST);
1112 1150
1113 GtkWidget *combobox = ui_create_combobox(obj, model, var, args->static_elements, args->static_nelm, args->onactivate, args->onactivatedata); 1151 GtkWidget *combobox = ui_create_combobox(obj, model, var, args->static_elements, args->static_nelm, args->onactivate, args->onactivatedata);
1114 ui_set_name_and_style(combobox, args->name, args->style_class); 1152 ui_set_name_and_style(combobox, args->name, args->style_class);

mercurial