ui/gtk/tree.c

branch
newapi
changeset 268
1b321a0c624f
parent 253
087cc9216f28
child 269
3380100e20f5
equal deleted inserted replaced
267:79dd183dd4cb 268:1b321a0c624f
34 #include "../common/context.h" 34 #include "../common/context.h"
35 #include "../common/object.h" 35 #include "../common/object.h"
36 #include "container.h" 36 #include "container.h"
37 37
38 #include "tree.h" 38 #include "tree.h"
39 #include "image.h"
39 40
40 41
41 void* ui_strmodel_getvalue(void *elm, int column) { 42 void* ui_strmodel_getvalue(void *elm, int column) {
42 return column == 0 ? elm : NULL; 43 return column == 0 ? elm : NULL;
43 } 44 }
44 45
45 46 static GtkListStore* create_list_store(UiList *list, UiModel *model) {
47 int columns = model->columns;
48 GType types[2*columns];
49 int c = 0;
50 for(int i=0;i<columns;i++,c++) {
51 switch(model->types[i]) {
52 case UI_STRING:
53 case UI_STRING_FREE: types[c] = G_TYPE_STRING; break;
54 case UI_INTEGER: types[c] = G_TYPE_INT; break;
55 case UI_ICON: types[c] = G_TYPE_OBJECT; break;
56 case UI_ICON_TEXT:
57 case UI_ICON_TEXT_FREE: {
58 types[c] = G_TYPE_OBJECT;
59 types[++c] = G_TYPE_STRING;
60 }
61 }
62 }
63
64 GtkListStore *store = gtk_list_store_newv(c, types);
65
66 if(list) {
67 void *elm = list->first(list);
68 while(elm) {
69 // insert new row
70 GtkTreeIter iter;
71 gtk_list_store_insert (store, &iter, -1);
72
73 // set column values
74 int c = 0;
75 for(int i=0;i<columns;i++,c++) {
76 void *data = model->getvalue(elm, c);
77
78 GValue value = G_VALUE_INIT;
79 switch(model->types[i]) {
80 case UI_STRING:
81 case UI_STRING_FREE: {
82 g_value_init(&value, G_TYPE_STRING);
83 g_value_set_string(&value, data);
84 if(model->types[i] == UI_STRING_FREE) {
85 free(data);
86 }
87 break;
88 }
89 case UI_INTEGER: {
90 g_value_init(&value, G_TYPE_INT);
91 int *intptr = data;
92 g_value_set_int(&value, *intptr);
93 break;
94 }
95 case UI_ICON: {
96 g_value_init(&value, G_TYPE_OBJECT);
97 UiIcon *icon = data;
98 if(!icon->pixbuf && icon->info) {
99 GError *error = NULL;
100 GdkPixbuf *pixbuf = gtk_icon_info_load_icon(icon->info, &error);
101 icon->pixbuf = pixbuf;
102 }
103
104 if(icon->pixbuf) {
105 g_value_set_object(&value, icon->pixbuf);
106 }
107
108
109 break;
110 }
111 case UI_ICON_TEXT:
112 case UI_ICON_TEXT_FREE: {
113 GValue pixbufvalue = G_VALUE_INIT;
114 UiIcon *icon = data;
115 if(!icon->pixbuf && icon->info) {
116 GError *error = NULL;
117 GdkPixbuf *pixbuf = gtk_icon_info_load_icon(icon->info, &error);
118 icon->pixbuf = pixbuf;
119 }
120 g_value_init(&pixbufvalue, G_TYPE_OBJECT);
121 g_value_set_object(&pixbufvalue, icon->pixbuf);
122 gtk_list_store_set_value(store, &iter, c, &pixbufvalue);
123 c++;
124
125 char *str = model->getvalue(elm, c);
126 g_value_init(&value, G_TYPE_STRING);
127 g_value_set_string(&value, str);
128 if(model->types[i] == UI_ICON_TEXT_FREE) {
129 free(str);
130 }
131 break;
132 }
133 }
134
135 gtk_list_store_set_value(store, &iter, c, &value);
136 }
137
138 // next row
139 elm = list->next(list);
140 }
141 }
142
143 return store;
144 }
46 145
47 146
48 UIWIDGET ui_listview_var(UiObject *obj, UiVar *var, ui_getvaluefunc getvalue, ui_callback f, void *udata) { 147 UIWIDGET ui_listview_var(UiObject *obj, UiVar *var, ui_getvaluefunc getvalue, ui_callback f, void *udata) {
49 // create treeview 148 // create treeview
50 GtkWidget *view = gtk_tree_view_new(); 149 GtkWidget *view = gtk_tree_view_new();
64 #endif 163 #endif
65 164
66 UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1); 165 UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1);
67 model->getvalue = getvalue; 166 model->getvalue = getvalue;
68 UiList *list = var->value; 167 UiList *list = var->value;
69 UiListModel *listmodel = ui_list_model_new(obj, var, model); 168 GtkListStore *listmodel = create_list_store(list, model);
70 gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(listmodel)); 169 gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(listmodel));
71 170
72 UiListView *listview = malloc(sizeof(UiListView)); 171 UiListView *listview = malloc(sizeof(UiListView));
73 listview->obj = obj; 172 listview->obj = obj;
74 listview->widget = view; 173 listview->widget = view;
86 185
87 // add callback 186 // add callback
88 if(f) { 187 if(f) {
89 UiTreeEventData *event = ui_malloc(obj->ctx, sizeof(UiTreeEventData)); 188 UiTreeEventData *event = ui_malloc(obj->ctx, sizeof(UiTreeEventData));
90 event->obj = obj; 189 event->obj = obj;
91 event->userdata = udata; 190 event->activatedata = udata;
92 event->activate = f; 191 event->activate = f;
93 event->selection = NULL; 192 event->selection = NULL;
94 193
95 g_signal_connect( 194 g_signal_connect(
96 view, 195 view,
154 { "STRING", 0, 0 }, 253 { "STRING", 0, 0 },
155 { "text/plain", 0, 1 }, 254 { "text/plain", 0, 1 },
156 { "text/uri-list", 0, 2 }, 255 { "text/uri-list", 0, 2 },
157 }; 256 };
158 257
159 UIWIDGET ui_table_var(UiObject *obj, UiVar *var, UiModel *model, UiListCallbacks cb) { 258 UIWIDGET ui_table_create(UiObject *obj, UiListArgs args) {
259 UiObject* current = uic_current_obj(obj);
260
160 // create treeview 261 // create treeview
161 GtkWidget *view = gtk_tree_view_new(); 262 GtkWidget *view = gtk_tree_view_new();
162 263
264 UiModel *model = args.model;
265 int columns = model ? model->columns : 0;
266
163 int addi = 0; 267 int addi = 0;
164 for(int i=0;i<model->columns;i++) { 268 for(int i=0;i<columns;i++) {
165 GtkTreeViewColumn *column = NULL; 269 GtkTreeViewColumn *column = NULL;
166 if(model->types[i] == UI_ICON_TEXT) { 270 if(model->types[i] == UI_ICON_TEXT) {
167 column = gtk_tree_view_column_new(); 271 column = gtk_tree_view_column_new();
168 gtk_tree_view_column_set_title(column, model->titles[i]); 272 gtk_tree_view_column_set_title(column, model->titles[i]);
169 273
176 280
177 gtk_tree_view_column_add_attribute(column, iconrenderer, "pixbuf", i); 281 gtk_tree_view_column_add_attribute(column, iconrenderer, "pixbuf", i);
178 gtk_tree_view_column_add_attribute(column, textrenderer, "text", i+1); 282 gtk_tree_view_column_add_attribute(column, textrenderer, "text", i+1);
179 283
180 addi++; 284 addi++;
285 } else if (model->types[i] == UI_ICON) {
286 GtkCellRenderer *iconrenderer = gtk_cell_renderer_pixbuf_new();
287 column = gtk_tree_view_column_new_with_attributes(
288 model->titles[i],
289 iconrenderer,
290 "pixbuf",
291 i + addi,
292 NULL);
181 } else { 293 } else {
182 GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); 294 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
183 column = gtk_tree_view_column_new_with_attributes( 295 column = gtk_tree_view_column_new_with_attributes(
184 model->titles[i], 296 model->titles[i],
185 renderer, 297 renderer,
196 //gtk_tree_view_set_activate_on_single_click(GTK_TREE_VIEW(view), TRUE); 308 //gtk_tree_view_set_activate_on_single_click(GTK_TREE_VIEW(view), TRUE);
197 #else 309 #else
198 310
199 #endif 311 #endif
200 312
201 UiList *list = var->value; 313 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.list, args.varname, UI_VAR_LIST);
202 UiListModel *listmodel = ui_list_model_new(obj, var, model); 314
315 UiList *list = var ? var->value : NULL;
316 GtkListStore *listmodel = create_list_store(list, model);
203 gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(listmodel)); 317 gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(listmodel));
204 318
205 //g_signal_connect(view, "drag-begin", G_CALLBACK(drag_begin), NULL); 319 //g_signal_connect(view, "drag-begin", G_CALLBACK(drag_begin), NULL);
206 //g_signal_connect(view, "drag-end", G_CALLBACK(drag_end), NULL); 320 //g_signal_connect(view, "drag-end", G_CALLBACK(drag_end), NULL);
207 321
223 list->obj = tableview; 337 list->obj = tableview;
224 338
225 // add callback 339 // add callback
226 UiTreeEventData *event = ui_malloc(obj->ctx, sizeof(UiTreeEventData)); 340 UiTreeEventData *event = ui_malloc(obj->ctx, sizeof(UiTreeEventData));
227 event->obj = obj; 341 event->obj = obj;
228 event->activate = cb.activate; 342 event->activate = args.onactivate;
229 event->selection = cb.selection; 343 event->selection = args.onselection;
230 event->userdata = cb.userdata; 344 event->activatedata = args.onactivatedata;
231 if(cb.activate) { 345 event->selectiondata = args.onselectiondata;
346 if(args.onactivate) {
232 g_signal_connect( 347 g_signal_connect(
233 view, 348 view,
234 "row-activated", 349 "row-activated",
235 G_CALLBACK(ui_listview_activate_event), 350 G_CALLBACK(ui_listview_activate_event),
236 event); 351 event);
237 } 352 }
238 if(cb.selection) { 353 if(args.onselection) {
239 GtkTreeSelection *selection = gtk_tree_view_get_selection( 354 GtkTreeSelection *selection = gtk_tree_view_get_selection(
240 GTK_TREE_VIEW(view)); 355 GTK_TREE_VIEW(view));
241 g_signal_connect( 356 g_signal_connect(
242 selection, 357 selection,
243 "changed", 358 "changed",
256 GTK_SCROLLED_WINDOW(scroll_area), 371 GTK_SCROLLED_WINDOW(scroll_area),
257 GTK_POLICY_AUTOMATIC, 372 GTK_POLICY_AUTOMATIC,
258 GTK_POLICY_AUTOMATIC); // GTK_POLICY_ALWAYS 373 GTK_POLICY_AUTOMATIC); // GTK_POLICY_ALWAYS
259 gtk_container_add(GTK_CONTAINER(scroll_area), view); 374 gtk_container_add(GTK_CONTAINER(scroll_area), view);
260 375
261 UiContainer *ct = uic_get_current_container(obj); 376 UI_APPLY_LAYOUT1(current, args);
262 ct->add(ct, scroll_area, TRUE); 377 current->container->add(current->container, scroll_area, FALSE);
263 378
264 // ct->current should point to view, not scroll_area, to make it possible 379 // ct->current should point to view, not scroll_area, to make it possible
265 // to add a context menu 380 // to add a context menu
266 ct->current = view; 381 current->container->current = view;
267 382
268 return scroll_area; 383 return scroll_area;
269 } 384 }
270 385
271 UIWIDGET ui_table_deprecated(UiObject *obj, UiList *list, UiModel *model, UiListCallbacks cb) {
272 UiVar *var = malloc(sizeof(UiVar));
273 var->value = list;
274 var->type = UI_VAR_SPECIAL;
275 return ui_table_var(obj, var, model, cb);
276 }
277
278 UIWIDGET ui_table_nv(UiObject *obj, char *varname, UiModel *model, UiListCallbacks cb) {
279 UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_LIST);
280 if(var) {
281 return ui_table_var(obj, var, model, cb);
282 } else {
283 // TODO: error
284 }
285 return NULL;
286 }
287 386
288 GtkWidget* ui_get_tree_widget(UIWIDGET widget) { 387 GtkWidget* ui_get_tree_widget(UIWIDGET widget) {
289 GList *c = gtk_container_get_children(GTK_CONTAINER(widget)); 388 GList *c = gtk_container_get_children(GTK_CONTAINER(widget));
290 if(c) { 389 if(c) {
291 return c->data; 390 return c->data;
368 } 467 }
369 */ 468 */
370 469
371 void ui_listview_update(UiList *list, int i) { 470 void ui_listview_update(UiList *list, int i) {
372 UiListView *view = list->obj; 471 UiListView *view = list->obj;
373 UiListModel *model = ui_list_model_new(view->obj, view->var, view->model); 472 GtkListStore *store = create_list_store(list, view->model);
374 gtk_tree_view_set_model(GTK_TREE_VIEW(view->widget), GTK_TREE_MODEL(model)); 473 gtk_tree_view_set_model(GTK_TREE_VIEW(view->widget), GTK_TREE_MODEL(store));
375 g_object_unref(G_OBJECT(model)); 474 g_object_unref(G_OBJECT(store));
376 // TODO: free old model 475 // TODO: free old model
377 } 476 }
378 477
379 void ui_listview_destroy(GtkWidget *w, UiListView *v) { 478 void ui_listview_destroy(GtkWidget *w, UiListView *v) {
380 gtk_tree_view_set_model(GTK_TREE_VIEW(w), NULL); 479 gtk_tree_view_set_model(GTK_TREE_VIEW(w), NULL);
405 e.obj = event->obj; 504 e.obj = event->obj;
406 e.window = event->obj->window; 505 e.window = event->obj->window;
407 e.document = event->obj->ctx->document; 506 e.document = event->obj->ctx->document;
408 e.eventdata = selection; 507 e.eventdata = selection;
409 e.intval = selection->count > 0 ? selection->rows[0] : -1; 508 e.intval = selection->count > 0 ? selection->rows[0] : -1;
410 event->activate(&e, event->userdata); 509 event->activate(&e, event->activatedata);
411 510
412 if(selection->count > 0) { 511 if(selection->count > 0) {
413 free(selection->rows); 512 free(selection->rows);
414 } 513 }
415 free(selection); 514 free(selection);
425 e.obj = event->obj; 524 e.obj = event->obj;
426 e.window = event->obj->window; 525 e.window = event->obj->window;
427 e.document = event->obj->ctx->document; 526 e.document = event->obj->ctx->document;
428 e.eventdata = selection; 527 e.eventdata = selection;
429 e.intval = selection->count > 0 ? selection->rows[0] : -1; 528 e.intval = selection->count > 0 ? selection->rows[0] : -1;
430 event->selection(&e, event->userdata); 529 event->selection(&e, event->selectiondata);
431 530
432 if(selection->count > 0) { 531 if(selection->count > 0) {
433 free(selection->rows); 532 free(selection->rows);
434 } 533 }
435 free(selection); 534 free(selection);
484 } 583 }
485 return NULL; 584 return NULL;
486 } 585 }
487 586
488 UIWIDGET ui_combobox_var(UiObject *obj, UiVar *var, ui_getvaluefunc getvalue, ui_callback f, void *udata) { 587 UIWIDGET ui_combobox_var(UiObject *obj, UiVar *var, ui_getvaluefunc getvalue, ui_callback f, void *udata) {
588 /*
489 UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1); 589 UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1);
490 model->getvalue = getvalue; 590 model->getvalue = getvalue;
491 UiListModel *listmodel = ui_list_model_new(obj, var, model); 591 UiList *list = var ? var->value : NULL;
492 592 GtkListStore *store = create_list_store(list, model);
493 GtkWidget *combobox = ui_create_combobox(obj, listmodel, f, udata); 593
594 //GtkWidget *combobox = ui_create_combobox(obj, listmodel, f, udata);
494 UiContainer *ct = uic_get_current_container(obj); 595 UiContainer *ct = uic_get_current_container(obj);
495 ct->add(ct, combobox, FALSE); 596 ct->add(ct, combobox, FALSE);
496 return combobox; 597 return combobox;
497 } 598 */
498 599 return NULL;
499 GtkWidget* ui_create_combobox(UiObject *obj, UiListModel *model, ui_callback f, void *udata) { 600 }
500 GtkWidget *combobox = gtk_combo_box_new_with_model(GTK_TREE_MODEL(model)); 601
602 GtkWidget* ui_create_combobox(UiObject *obj, GtkListStore *store, ui_callback f, void *udata) {
603 GtkWidget *combobox = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
501 604
502 UiListView *uicbox = malloc(sizeof(UiListView)); 605 UiListView *uicbox = malloc(sizeof(UiListView));
503 uicbox->obj = obj; 606 uicbox->obj = obj;
504 uicbox->widget = combobox; 607 uicbox->widget = combobox;
505 uicbox->var = model->var; 608 // TODO
506 uicbox->model = model->model; 609 //uicbox->var = model->var;
610 //uicbox->model = model->model;
507 611
508 g_signal_connect( 612 g_signal_connect(
509 combobox, 613 combobox,
510 "destroy", 614 "destroy",
511 G_CALLBACK(ui_combobox_destroy), 615 G_CALLBACK(ui_combobox_destroy),
512 uicbox); 616 uicbox);
513 617
514 // bind var 618 // bind var
515 UiList *list = model->var->value; 619 //UiList *list = model->var->value;
516 list->update = ui_combobox_modelupdate; 620 //list->update = ui_combobox_modelupdate;
517 list->obj = uicbox; 621 //list->obj = uicbox;
518 622
519 GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); 623 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
520 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox), renderer, TRUE); 624 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox), renderer, TRUE);
521 gtk_cell_layout_set_attributes( 625 gtk_cell_layout_set_attributes(
522 GTK_CELL_LAYOUT(combobox), 626 GTK_CELL_LAYOUT(combobox),
554 e->callback(&event, e->userdata); 658 e->callback(&event, e->userdata);
555 } 659 }
556 660
557 void ui_combobox_modelupdate(UiList *list, int i) { 661 void ui_combobox_modelupdate(UiList *list, int i) {
558 UiListView *view = list->obj; 662 UiListView *view = list->obj;
559 UiListModel *model = ui_list_model_new(view->obj, view->var, view->model); 663 GtkListStore *store = create_list_store(view->var->value, view->model);
560 gtk_combo_box_set_model(GTK_COMBO_BOX(view->widget), GTK_TREE_MODEL(model)); 664 gtk_combo_box_set_model(GTK_COMBO_BOX(view->widget), GTK_TREE_MODEL(store));
561 } 665 }
562 666

mercurial