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