ui/gtk/list.c

changeset 1244
a29b53f97d1a
parent 1192
96858abf075a
equal deleted inserted replaced
1243:59d97ac069f0 1244:a29b53f97d1a
53 53
54 static void* str_getvalue(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult) { 54 static void* str_getvalue(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult) {
55 return elm; 55 return elm;
56 } 56 }
57 57
58 static void* null_getvalue(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult) { 58 void* ui_null_getvalue(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult) {
59 return NULL; 59 return NULL;
60 } 60 }
61 61
62 /* 62 /*
63 static GtkTargetEntry targetentries[] = 63 static GtkTargetEntry targetentries[] =
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
146 184
147 static void obj_wrapper_init(ObjWrapper *self) { 185 static void obj_wrapper_init(ObjWrapper *self) {
148 self->data = NULL; 186 self->data = NULL;
149 } 187 }
150 188
151 ObjWrapper* obj_wrapper_new(void* data, int i) { 189 ObjWrapper* ui_gobj_wrapper_new(void* data, int i) {
152 ObjWrapper *obj = g_object_new(obj_wrapper_get_type(), NULL); 190 ObjWrapper *obj = g_object_new(obj_wrapper_get_type(), NULL);
153 obj->data = data; 191 obj->data = data;
154 obj->i = i; 192 obj->i = i;
155 return obj; 193 return obj;
156 } 194 }
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) {
2121 } 2263 }
2122 2264
2123 #endif 2265 #endif
2124 2266
2125 2267
2126 GtkWidget* ui_get_tree_widget(UIWIDGET widget) {
2127 return SCROLLEDWINDOW_GET_CHILD(widget);
2128 }
2129
2130 static char** targets2array(char *target0, va_list ap, int *nelm) { 2268 static char** targets2array(char *target0, va_list ap, int *nelm) {
2131 int al = 16; 2269 int al = 16;
2132 char **targets = calloc(16, sizeof(char*)); 2270 char **targets = calloc(16, sizeof(char*));
2133 targets[0] = target0; 2271 targets[0] = target0;
2134 2272

mercurial