| 115 tableview->getvaluedata = args->getvalue2data; |
115 tableview->getvaluedata = args->getvalue2data; |
| 116 } else if(args->getvalue) { |
116 } else if(args->getvalue) { |
| 117 tableview->getvalue = getvalue_wrapper; |
117 tableview->getvalue = getvalue_wrapper; |
| 118 tableview->getvaluedata = (void*)args->getvalue; |
118 tableview->getvaluedata = (void*)args->getvalue; |
| 119 } else { |
119 } else { |
| 120 tableview->getvalue = null_getvalue; |
120 tableview->getvalue = ui_null_getvalue; |
| 121 } |
121 } |
| 122 |
122 |
| 123 return tableview; |
123 return tableview; |
| 124 } |
124 } |
| 125 |
125 |
| |
126 static UiListView* create_treeview(UiObject *obj, UiTreeArgs *args) { |
| |
127 UiListView *treeview = malloc(sizeof(UiListView)); |
| |
128 memset(treeview, 0, sizeof(UiListView)); |
| |
129 treeview->obj = obj; |
| |
130 treeview->model = args->model; |
| |
131 treeview->multiselection = args->multiselection; |
| |
132 treeview->onactivate = args->onactivate; |
| |
133 treeview->onactivatedata = args->onactivatedata; |
| |
134 treeview->onactivate_action = args->onactivate_action ? strdup(args->onactivate_action) : NULL; |
| |
135 treeview->onselection = args->onselection; |
| |
136 treeview->onselectiondata = args->onselectiondata; |
| |
137 treeview->onselection_action = args->onselection_action ? strdup(args->onselection_action) : NULL; |
| |
138 treeview->ondragstart = args->ondragstart; |
| |
139 treeview->ondragstartdata = args->ondragstartdata; |
| |
140 treeview->ondragstart_action = args->ondragstart_action ? strdup(args->ondragstart_action) : NULL; |
| |
141 treeview->ondragcomplete = args->ondragcomplete; |
| |
142 treeview->ondragcompletedata = args->ondragcompletedata; |
| |
143 treeview->ondragcomplete_action = args->ondragcomplete_action ? strdup(args->ondragcomplete_action) : NULL; |
| |
144 treeview->ondrop = args->ondrop; |
| |
145 treeview->ondropdata = args->ondropdata; |
| |
146 treeview->ondrop_action = args->ondrop_action ? strdup(args->ondrop_action) : NULL; |
| |
147 treeview->selection.count = 0; |
| |
148 treeview->selection.rows = NULL; |
| |
149 treeview->current_row = -1; |
| |
150 |
| |
151 #if GTK_CHECK_VERSION(4, 0, 0) |
| |
152 treeview->coldata.listview = treeview; |
| |
153 treeview->coldata.column = 0; |
| |
154 #endif |
| |
155 |
| |
156 if(args->getvalue != NULL) { |
| |
157 treeview->getvalue = args->getvalue; |
| |
158 treeview->getvaluedata = args->getvaluedata; |
| |
159 } else { |
| |
160 args->getvalue = ui_null_getvalue; |
| |
161 } |
| |
162 |
| |
163 treeview->istreeview = TRUE; |
| |
164 treeview->getdepth = args->getdepth; |
| |
165 treeview->getdepthdata = args->getdepthdata; |
| |
166 |
| |
167 return treeview; |
| |
168 } |
| |
169 |
| 126 #if GTK_CHECK_VERSION(4, 10, 0) |
170 #if GTK_CHECK_VERSION(4, 10, 0) |
| 127 |
171 |
| 128 |
172 |
| 129 /* BEGIN GObject wrapper for generic pointers */ |
173 /* BEGIN GObject wrapper for generic pointers */ |
| 130 |
|
| 131 typedef struct _ObjWrapper { |
|
| 132 GObject parent_instance; |
|
| 133 void *data; |
|
| 134 int i; |
|
| 135 } ObjWrapper; |
|
| 136 |
174 |
| 137 typedef struct _ObjWrapperClass { |
175 typedef struct _ObjWrapperClass { |
| 138 GObjectClass parent_class; |
176 GObjectClass parent_class; |
| 139 } ObjWrapperClass; |
177 } ObjWrapperClass; |
| 140 |
178 |
| 758 ct->add(ct, scroll_area, &layout); |
796 ct->add(ct, scroll_area, &layout); |
| 759 |
797 |
| 760 return scroll_area; |
798 return scroll_area; |
| 761 } |
799 } |
| 762 |
800 |
| |
801 |
| |
802 |
| |
803 UIWIDGET ui_treeview_create(UiObject *obj, UiTreeArgs *args) { |
| |
804 GListStore *ls = g_list_store_new(G_TYPE_OBJECT); |
| |
805 //g_list_store_append(ls, v1); |
| |
806 |
| |
807 // create obj to store all relevant data we need for handling events |
| |
808 // and list updates |
| |
809 UiListView *tableview = create_treeview(obj, args); |
| |
810 |
| |
811 GtkSelectionModel *selection_model = create_selection_model(tableview, ls, args->multiselection); |
| |
812 GtkWidget *view = gtk_column_view_new(GTK_SELECTION_MODEL(selection_model)); |
| |
813 if(!args->show_header) { |
| |
814 gtk_widget_set_visible(gtk_widget_get_first_child(view), FALSE); |
| |
815 } |
| |
816 |
| |
817 UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->list, args->varname, UI_VAR_LIST); |
| |
818 |
| |
819 // init tableview |
| |
820 tableview->widget = view; |
| |
821 tableview->var = var; |
| |
822 tableview->liststore = ls; |
| |
823 tableview->selectionmodel = selection_model; |
| |
824 g_signal_connect( |
| |
825 view, |
| |
826 "destroy", |
| |
827 G_CALLBACK(ui_listview_destroy), |
| |
828 tableview); |
| |
829 |
| |
830 |
| |
831 // create columns from UiModel |
| |
832 UiModel *model = args->model; |
| |
833 int columns = 0; |
| |
834 if(model) { |
| |
835 columns = model->columns; |
| |
836 ui_model_add_observer(model, ui_listview_update_model, tableview); |
| |
837 } |
| |
838 |
| |
839 tableview->columns = calloc(columns, sizeof(int)); |
| |
840 tableview->numcolumns = columns; |
| |
841 |
| |
842 tableview->bound_rows = cxHashMapCreate(NULL, CX_STORE_POINTERS, 128); |
| |
843 tableview->bound_rows->collection.simple_destructor = (cx_destructor_func)free; |
| |
844 |
| |
845 int addi = 0; |
| |
846 for(int i=0;i<columns;i++) { |
| |
847 tableview->columns[i] = i+addi; |
| |
848 |
| |
849 if(model->types[i] == UI_ICON_TEXT || model->types[i] == UI_ICON_TEXT_FREE) { |
| |
850 // icon+text has 2 data columns |
| |
851 addi++; |
| |
852 } |
| |
853 |
| |
854 add_column(tableview, i); |
| |
855 } |
| |
856 |
| |
857 // bind listview to list |
| |
858 if(var && var->value) { |
| |
859 UiList *list = var->value; |
| |
860 |
| |
861 list->obj = tableview; |
| |
862 list->update = ui_listview_update2; |
| |
863 list->getselection = ui_listview_getselection2; |
| |
864 list->setselection = ui_listview_setselection2; |
| |
865 |
| |
866 ui_update_liststore(ls, list); |
| |
867 } |
| |
868 |
| |
869 // event handling |
| |
870 if(args->onactivate || args->onactivate_action) { |
| |
871 g_signal_connect(view, "activate", G_CALLBACK(ui_columnview_activate), tableview); |
| |
872 } |
| |
873 if(args->contextmenu) { |
| |
874 UIMENU menu = ui_contextmenu_create(args->contextmenu, obj, view); |
| |
875 ui_widget_set_contextmenu(view, menu); |
| |
876 } |
| |
877 |
| |
878 // add widget to parent |
| |
879 GtkWidget *scroll_area = SCROLLEDWINDOW_NEW(); |
| |
880 gtk_scrolled_window_set_policy( |
| |
881 GTK_SCROLLED_WINDOW(scroll_area), |
| |
882 GTK_POLICY_AUTOMATIC, |
| |
883 GTK_POLICY_AUTOMATIC); // GTK_POLICY_ALWAYS |
| |
884 SCROLLEDWINDOW_SET_CHILD(scroll_area, view); |
| |
885 |
| |
886 if(args->width > 0 || args->height > 0) { |
| |
887 int width = args->width; |
| |
888 int height = args->height; |
| |
889 if(width == 0) { |
| |
890 width = -1; |
| |
891 } |
| |
892 if(height == 0) { |
| |
893 height = -1; |
| |
894 } |
| |
895 gtk_widget_set_size_request(scroll_area, width, height); |
| |
896 } |
| |
897 |
| |
898 UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; |
| |
899 UiLayout layout = UI_ARGS2LAYOUT(args); |
| |
900 ct->add(ct, scroll_area, &layout); |
| |
901 |
| |
902 return scroll_area; |
| |
903 } |
| |
904 |
| 763 void ui_listview_update_model(UiModel *model, void *userdata, int insert_index, int delete_index) { |
905 void ui_listview_update_model(UiModel *model, void *userdata, int insert_index, int delete_index) { |
| 764 UiListView *listview = userdata; |
906 UiListView *listview = userdata; |
| 765 if(insert_index >= listview->numcolumns) { |
907 if(insert_index >= listview->numcolumns) { |
| 766 listview->numcolumns = insert_index+1; |
908 listview->numcolumns = insert_index+1; |
| 767 listview->columns = realloc(listview->columns, listview->numcolumns * sizeof(UiColData)); |
909 listview->columns = realloc(listview->columns, listview->numcolumns * sizeof(UiColData)); |
| 916 void ui_update_liststore(GListStore *liststore, UiList *list) { |
1058 void ui_update_liststore(GListStore *liststore, UiList *list) { |
| 917 g_list_store_remove_all(liststore); |
1059 g_list_store_remove_all(liststore); |
| 918 int i = 0; |
1060 int i = 0; |
| 919 void *elm = list->first(list); |
1061 void *elm = list->first(list); |
| 920 while(elm) { |
1062 while(elm) { |
| 921 ObjWrapper *obj = obj_wrapper_new(elm, i++); |
1063 ObjWrapper *obj = ui_gobj_wrapper_new(elm, i++); |
| 922 g_list_store_append(liststore, obj); |
1064 g_list_store_append(liststore, obj); |
| 923 elm = list->next(list); |
1065 elm = list->next(list); |
| 924 } |
1066 } |
| 925 } |
1067 } |
| 926 |
1068 |
| 927 void ui_update_liststore_static(GListStore *liststore, char **elm, size_t nelm) { |
1069 void ui_update_liststore_static(GListStore *liststore, char **elm, size_t nelm) { |
| 928 g_list_store_remove_all(liststore); |
1070 g_list_store_remove_all(liststore); |
| 929 for(int i=0;i<nelm;i++) { |
1071 for(int i=0;i<nelm;i++) { |
| 930 ObjWrapper *obj = obj_wrapper_new(elm[i], i); |
1072 ObjWrapper *obj = ui_gobj_wrapper_new(elm[i], i); |
| 931 g_list_store_append(liststore, obj); |
1073 g_list_store_append(liststore, obj); |
| 932 } |
1074 } |
| 933 } |
1075 } |
| 934 |
1076 |
| 935 void ui_listview_update2(UiList *list, int i) { |
1077 void ui_listview_update2(UiList *list, int i) { |