| 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); |