ui/gtk/list.c

changeset 103
6606616eca9f
parent 102
64ded9f6a6c6
child 108
77254bd6dccb
equal deleted inserted replaced
102:64ded9f6a6c6 103:6606616eca9f
55 { "text/plain", 0, 1 }, 55 { "text/plain", 0, 1 },
56 { "text/uri-list", 0, 2 }, 56 { "text/uri-list", 0, 2 },
57 }; 57 };
58 */ 58 */
59 59
60 static void listview_copy_static_elements(UiListView *listview, char **elm, size_t nelm) {
61 listview->elements = calloc(nelm, sizeof(char*));
62 listview->nelm = nelm;
63 for(int i=0;i<nelm;i++) {
64 listview->elements[i] = strdup(elm[i]);
65 }
66 }
67
60 #if GTK_CHECK_VERSION(4, 10, 0) 68 #if GTK_CHECK_VERSION(4, 10, 0)
61 69
62 70
63 /* BEGIN GObject wrapper for generic pointers */ 71 /* BEGIN GObject wrapper for generic pointers */
64 72
246 list->update = ui_listview_update2; 254 list->update = ui_listview_update2;
247 list->getselection = ui_listview_getselection2; 255 list->getselection = ui_listview_getselection2;
248 list->setselection = ui_listview_setselection2; 256 list->setselection = ui_listview_setselection2;
249 257
250 ui_update_liststore(ls, list); 258 ui_update_liststore(ls, list);
259 } else if (args.static_elements && args.static_nelm > 0) {
260 listview_copy_static_elements(listview, args.static_elements, args.static_nelm);
261 listview->model->getvalue = ui_strmodel_getvalue; // force strmodel
262 ui_update_liststore_static(ls, listview->elements, listview->nelm);
251 } 263 }
252 264
253 // event handling 265 // event handling
254 if(args.onactivate) { 266 if(args.onactivate) {
255 // columnview and listview can use the same callback function, because 267 // columnview and listview can use the same callback function, because
321 list->update = ui_listview_update2; 333 list->update = ui_listview_update2;
322 list->getselection = ui_combobox_getselection; 334 list->getselection = ui_combobox_getselection;
323 list->setselection = ui_combobox_setselection; 335 list->setselection = ui_combobox_setselection;
324 336
325 ui_update_liststore(ls, list); 337 ui_update_liststore(ls, list);
338 } else if (args.static_elements && args.static_nelm > 0) {
339 listview_copy_static_elements(listview, args.static_elements, args.static_nelm);
340 listview->model->getvalue = ui_strmodel_getvalue; // force strmodel
341 ui_update_liststore_static(ls, listview->elements, listview->nelm);
326 } 342 }
327 343
328 // event handling 344 // event handling
329 if(args.onactivate) { 345 if(args.onactivate) {
330 g_signal_connect(view, "activate", G_CALLBACK(ui_columnview_activate), listview); 346 g_signal_connect(view, "notify::selected", G_CALLBACK(ui_dropdown_notify), listview);
331 } 347 }
332 348
333 // add widget to parent 349 // add widget to parent
334 UI_APPLY_LAYOUT1(current, args); 350 UI_APPLY_LAYOUT1(current, args);
335 current->container->add(current->container, view, FALSE); 351 current->container->add(current->container, view, FALSE);
336 return view; 352 return view;
353 }
354
355 void ui_listview_select(UIWIDGET listview, int index) {
356 GtkSelectionModel *model = gtk_list_view_get_model(GTK_LIST_VIEW(listview));
357 gtk_selection_model_select_item(model, index, TRUE);
358 }
359
360 void ui_combobox_select(UIWIDGET dropdown, int index) {
361 gtk_drop_down_set_selected(GTK_DROP_DOWN(dropdown), index);
337 } 362 }
338 363
339 UIWIDGET ui_table_create(UiObject *obj, UiListArgs args) { 364 UIWIDGET ui_table_create(UiObject *obj, UiListArgs args) {
340 UiObject* current = uic_current_obj(obj); 365 UiObject* current = uic_current_obj(obj);
341 366
447 event.obj = view->obj; 472 event.obj = view->obj;
448 event.document = event.obj->ctx->document; 473 event.document = event.obj->ctx->document;
449 event.window = event.obj->window; 474 event.window = event.obj->window;
450 event.intval = view->selection.count; 475 event.intval = view->selection.count;
451 event.eventdata = &view->selection; 476 event.eventdata = &view->selection;
477 event.set = ui_get_setop();
452 if(cb) { 478 if(cb) {
453 cb(&event, cbdata); 479 cb(&event, cbdata);
454 } 480 }
455 } 481 }
456 482
476 view->selection.rows = newselection; 502 view->selection.rows = newselection;
477 } else { 503 } else {
478 free(newselection); 504 free(newselection);
479 } 505 }
480 } 506 }
507
508 void ui_dropdown_notify(GtkWidget *dropdown, GObject *pspec, gpointer userdata) {
509 UiListView *view = userdata;
510 guint index = gtk_drop_down_get_selected(GTK_DROP_DOWN(dropdown));
511 GObject *item = gtk_drop_down_get_selected_item(GTK_DROP_DOWN(dropdown));
512 if(item && view->onactivate) {
513 ObjWrapper *eventdata = (ObjWrapper*)item;
514 UiEvent event;
515 event.obj = view->obj;
516 event.document = event.obj->ctx->document;
517 event.window = event.obj->window;
518 event.intval = index;
519 event.eventdata = eventdata->data;
520 event.set = ui_get_setop();
521 view->onactivate(&event, view->onactivatedata);
522 }
523 }
524
481 525
482 void ui_columnview_activate(void *ignore, guint position, gpointer userdata) { 526 void ui_columnview_activate(void *ignore, guint position, gpointer userdata) {
483 UiListView *view = userdata; 527 UiListView *view = userdata;
484 if(view->selection.count == 0) { 528 if(view->selection.count == 0) {
485 listview_update_selection(view); 529 listview_update_selection(view);
508 event.obj = view->obj; 552 event.obj = view->obj;
509 event.document = event.obj->ctx->document; 553 event.document = event.obj->ctx->document;
510 event.window = event.obj->window; 554 event.window = event.obj->window;
511 event.intval = view->selection.count; 555 event.intval = view->selection.count;
512 event.eventdata = &view->selection; 556 event.eventdata = &view->selection;
557 event.set = ui_get_setop();
513 view->onactivate(&event, view->onactivatedata); 558 view->onactivate(&event, view->onactivatedata);
514 } 559 }
515 } 560 }
516 561
517 void ui_update_liststore(GListStore *liststore, UiList *list) { 562 void ui_update_liststore(GListStore *liststore, UiList *list) {
522 g_list_store_append(liststore, obj); 567 g_list_store_append(liststore, obj);
523 elm = list->next(list); 568 elm = list->next(list);
524 } 569 }
525 } 570 }
526 571
572 void ui_update_liststore_static(GListStore *liststore, char **elm, size_t nelm) {
573 g_list_store_remove_all(liststore);
574 for(int i=0;i<nelm;i++) {
575 ObjWrapper *obj = obj_wrapper_new(elm[i]);
576 g_list_store_append(liststore, obj);
577 }
578 }
579
527 void ui_listview_update2(UiList *list, int i) { 580 void ui_listview_update2(UiList *list, int i) {
528 UiListView *view = list->obj; 581 UiListView *view = list->obj;
529 ui_update_liststore(view->liststore, list); 582 if(i < 0) {
583 ui_update_liststore(view->liststore, list);
584 } else {
585 void *value = list->get(list, i);
586 if(value) {
587 ObjWrapper *obj = obj_wrapper_new(value);
588 // TODO: if index i is selected, the selection is lost
589 // is it possible to update the item without removing it?
590 g_list_store_splice(view->liststore, i, 1, (void **)&obj, 1);
591 }
592 }
530 } 593 }
531 594
532 UiListSelection ui_listview_getselection2(UiList *list) { 595 UiListSelection ui_listview_getselection2(UiList *list) {
533 UiListView *view = list->obj; 596 UiListView *view = list->obj;
534 UiListSelection selection; 597 UiListSelection selection;
537 memcpy(selection.rows, view->selection.rows, selection.count*sizeof(int)); 600 memcpy(selection.rows, view->selection.rows, selection.count*sizeof(int));
538 return selection; 601 return selection;
539 } 602 }
540 603
541 void ui_listview_setselection2(UiList *list, UiListSelection selection) { 604 void ui_listview_setselection2(UiList *list, UiListSelection selection) {
605 ui_setop_enable(TRUE);
542 UiListView *view = list->obj; 606 UiListView *view = list->obj;
543 UiListSelection newselection; 607 UiListSelection newselection;
544 newselection.count = view->selection.count; 608 newselection.count = view->selection.count;
545 if(selection.count > 0) { 609 if(selection.count > 0) {
546 newselection.rows = calloc(newselection.count, sizeof(int)); 610 newselection.rows = calloc(newselection.count, sizeof(int));
555 if(selection.count > 0) { 619 if(selection.count > 0) {
556 for(int i=0;i<selection.count;i++) { 620 for(int i=0;i<selection.count;i++) {
557 gtk_selection_model_select_item(view->selectionmodel, selection.rows[i], FALSE); 621 gtk_selection_model_select_item(view->selectionmodel, selection.rows[i], FALSE);
558 } 622 }
559 } 623 }
624 ui_setop_enable(FALSE);
560 } 625 }
561 626
562 UiListSelection ui_combobox_getselection(UiList *list) { 627 UiListSelection ui_combobox_getselection(UiList *list) {
563 UiListView *view = list->obj; 628 UiListView *view = list->obj;
564 guint selection = gtk_drop_down_get_selected(GTK_DROP_DOWN(view->widget)); 629 guint selection = gtk_drop_down_get_selected(GTK_DROP_DOWN(view->widget));
570 } 635 }
571 return sel; 636 return sel;
572 } 637 }
573 638
574 void ui_combobox_setselection(UiList *list, UiListSelection selection) { 639 void ui_combobox_setselection(UiList *list, UiListSelection selection) {
640 ui_setop_enable(TRUE);
575 UiListView *view = list->obj; 641 UiListView *view = list->obj;
576 if(selection.count > 0) { 642 if(selection.count > 0) {
577 gtk_drop_down_set_selected(GTK_DROP_DOWN(view->widget), selection.rows[0]); 643 gtk_drop_down_set_selected(GTK_DROP_DOWN(view->widget), selection.rows[0]);
578 } else { 644 } else {
579 gtk_drop_down_set_selected(GTK_DROP_DOWN(view->widget), GTK_INVALID_LIST_POSITION); 645 gtk_drop_down_set_selected(GTK_DROP_DOWN(view->widget), GTK_INVALID_LIST_POSITION);
580 } 646 }
647 ui_setop_enable(FALSE);
581 } 648 }
582 649
583 #else 650 #else
651
652 static void update_list_row(GtkListStore *store, GtkTreeIter *iter, UiModel *model, void *elm) {
653 // set column values
654 int c = 0;
655 for(int i=0;i<model->columns;i++,c++) {
656 void *data = model->getvalue(elm, c);
657
658 GValue value = G_VALUE_INIT;
659 switch(model->types[i]) {
660 case UI_STRING:
661 case UI_STRING_FREE: {
662 g_value_init(&value, G_TYPE_STRING);
663 g_value_set_string(&value, data);
664 if(model->types[i] == UI_STRING_FREE) {
665 free(data);
666 }
667 break;
668 }
669 case UI_INTEGER: {
670 g_value_init(&value, G_TYPE_INT);
671 intptr_t intptr = (intptr_t)data;
672 g_value_set_int(&value, (int)intptr);
673 break;
674 }
675 case UI_ICON: {
676 g_value_init(&value, G_TYPE_OBJECT);
677 UiIcon *icon = data;
678 #if GTK_MAJOR_VERSION >= 4
679 g_value_set_object(&value, icon->info); // TODO: does this work?
680 #else
681 if(!icon->pixbuf && icon->info) {
682 GError *error = NULL;
683 GdkPixbuf *pixbuf = gtk_icon_info_load_icon(icon->info, &error);
684 icon->pixbuf = pixbuf;
685 }
686
687 if(icon->pixbuf) {
688 g_value_set_object(&value, icon->pixbuf);
689 }
690 #endif
691 break;
692 }
693 case UI_ICON_TEXT:
694 case UI_ICON_TEXT_FREE: {
695 UiIcon *icon = data;
696 #if GTK_MAJOR_VERSION >= 4
697 if(icon) {
698 GValue iconvalue = G_VALUE_INIT;
699 g_value_init(&iconvalue, G_TYPE_OBJECT);
700 g_value_set_object(&iconvalue, ui_icon_pixbuf(icon));
701 gtk_list_store_set_value(store, &iter, c, &iconvalue);
702 }
703 #else
704 GValue pixbufvalue = G_VALUE_INIT;
705 if(icon) {
706 if(!icon->pixbuf && icon->info) {
707 GError *error = NULL;
708 GdkPixbuf *pixbuf = gtk_icon_info_load_icon(icon->info, &error);
709 icon->pixbuf = pixbuf;
710 }
711 g_value_init(&pixbufvalue, G_TYPE_OBJECT);
712 g_value_set_object(&pixbufvalue, icon->pixbuf);
713 gtk_list_store_set_value(store, iter, c, &pixbufvalue);
714 }
715 #endif
716 c++;
717
718 char *str = model->getvalue(elm, c);
719 g_value_init(&value, G_TYPE_STRING);
720 g_value_set_string(&value, str);
721 if(model->types[i] == UI_ICON_TEXT_FREE) {
722 free(str);
723 }
724 break;
725 }
726 }
727
728 gtk_list_store_set_value(store, iter, c, &value);
729 }
730 }
584 731
585 static GtkListStore* create_list_store(UiList *list, UiModel *model) { 732 static GtkListStore* create_list_store(UiList *list, UiModel *model) {
586 int columns = model->columns; 733 int columns = model->columns;
587 GType types[2*columns]; 734 GType types[2*columns];
588 int c = 0; 735 int c = 0;
607 while(elm) { 754 while(elm) {
608 // insert new row 755 // insert new row
609 GtkTreeIter iter; 756 GtkTreeIter iter;
610 gtk_list_store_insert (store, &iter, -1); 757 gtk_list_store_insert (store, &iter, -1);
611 758
612 // set column values 759 update_list_row(store, &iter, model, elm);
613 int c = 0;
614 for(int i=0;i<columns;i++,c++) {
615 void *data = model->getvalue(elm, c);
616
617 GValue value = G_VALUE_INIT;
618 switch(model->types[i]) {
619 case UI_STRING:
620 case UI_STRING_FREE: {
621 g_value_init(&value, G_TYPE_STRING);
622 g_value_set_string(&value, data);
623 if(model->types[i] == UI_STRING_FREE) {
624 free(data);
625 }
626 break;
627 }
628 case UI_INTEGER: {
629 g_value_init(&value, G_TYPE_INT);
630 intptr_t intptr = (intptr_t)data;
631 g_value_set_int(&value, (int)intptr);
632 break;
633 }
634 case UI_ICON: {
635 g_value_init(&value, G_TYPE_OBJECT);
636 UiIcon *icon = data;
637 #if GTK_MAJOR_VERSION >= 4
638 g_value_set_object(&value, icon->info); // TODO: does this work?
639 #else
640 if(!icon->pixbuf && icon->info) {
641 GError *error = NULL;
642 GdkPixbuf *pixbuf = gtk_icon_info_load_icon(icon->info, &error);
643 icon->pixbuf = pixbuf;
644 }
645
646 if(icon->pixbuf) {
647 g_value_set_object(&value, icon->pixbuf);
648 }
649 #endif
650 break;
651 }
652 case UI_ICON_TEXT:
653 case UI_ICON_TEXT_FREE: {
654 UiIcon *icon = data;
655 #if GTK_MAJOR_VERSION >= 4
656 if(icon) {
657 GValue iconvalue = G_VALUE_INIT;
658 g_value_init(&iconvalue, G_TYPE_OBJECT);
659 g_value_set_object(&iconvalue, ui_icon_pixbuf(icon));
660 gtk_list_store_set_value(store, &iter, c, &iconvalue);
661 }
662 #else
663 GValue pixbufvalue = G_VALUE_INIT;
664 if(icon) {
665 if(!icon->pixbuf && icon->info) {
666 GError *error = NULL;
667 GdkPixbuf *pixbuf = gtk_icon_info_load_icon(icon->info, &error);
668 icon->pixbuf = pixbuf;
669 }
670 g_value_init(&pixbufvalue, G_TYPE_OBJECT);
671 g_value_set_object(&pixbufvalue, icon->pixbuf);
672 gtk_list_store_set_value(store, &iter, c, &pixbufvalue);
673 }
674 #endif
675 c++;
676
677 char *str = model->getvalue(elm, c);
678 g_value_init(&value, G_TYPE_STRING);
679 g_value_set_string(&value, str);
680 if(model->types[i] == UI_ICON_TEXT_FREE) {
681 free(str);
682 }
683 break;
684 }
685 }
686
687 gtk_list_store_set_value(store, &iter, c, &value);
688 }
689 760
690 // next row 761 // next row
691 elm = list->next(list); 762 elm = list->next(list);
692 } 763 }
693 } 764 }
727 GtkListStore *listmodel = create_list_store(list, model); 798 GtkListStore *listmodel = create_list_store(list, model);
728 gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(listmodel)); 799 gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(listmodel));
729 g_object_unref(listmodel); 800 g_object_unref(listmodel);
730 801
731 UiListView *listview = malloc(sizeof(UiListView)); 802 UiListView *listview = malloc(sizeof(UiListView));
803 memset(listview, 0, sizeof(UiListView));
732 listview->obj = obj; 804 listview->obj = obj;
733 listview->widget = view; 805 listview->widget = view;
734 listview->var = var; 806 listview->var = var;
735 listview->model = model; 807 listview->model = model;
736 listview->selection.count = 0; 808 listview->selection.count = 0;
796 // ct->current should point to view, not scroll_area, to make it possible 868 // ct->current should point to view, not scroll_area, to make it possible
797 // to add a context menu 869 // to add a context menu
798 current->container->current = view; 870 current->container->current = view;
799 871
800 return scroll_area; 872 return scroll_area;
873 }
874
875 void ui_listview_select(UIWIDGET listview, int index) {
876 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(listview));
877 GtkTreePath *path = gtk_tree_path_new_from_indicesv(&index, 1);
878 gtk_tree_selection_select_path(sel, path);
879 //g_object_unref(path);
880 }
881
882 void ui_combobox_select(UIWIDGET dropdown, int index) {
883 gtk_combo_box_set_active(GTK_COMBO_BOX(dropdown), index);
801 } 884 }
802 885
803 UIWIDGET ui_table_create(UiObject *obj, UiListArgs args) { 886 UIWIDGET ui_table_create(UiObject *obj, UiListArgs args) {
804 UiObject* current = uic_current_obj(obj); 887 UiObject* current = uic_current_obj(obj);
805 888
874 //g_signal_connect(view, "drag-end", G_CALLBACK(drag_end), NULL); 957 //g_signal_connect(view, "drag-end", G_CALLBACK(drag_end), NULL);
875 958
876 // add TreeView as observer to the UiList to update the TreeView if the 959 // add TreeView as observer to the UiList to update the TreeView if the
877 // data changes 960 // data changes
878 UiListView *tableview = malloc(sizeof(UiListView)); 961 UiListView *tableview = malloc(sizeof(UiListView));
962 memset(tableview, 0, sizeof(UiListView));
879 tableview->obj = obj; 963 tableview->obj = obj;
880 tableview->widget = view; 964 tableview->widget = view;
881 tableview->var = var; 965 tableview->var = var;
882 tableview->model = model; 966 tableview->model = model;
883 tableview->ondragstart = args.ondragstart; 967 tableview->ondragstart = args.ondragstart;
967 1051
968 1052
969 1053
970 void ui_listview_update(UiList *list, int i) { 1054 void ui_listview_update(UiList *list, int i) {
971 UiListView *view = list->obj; 1055 UiListView *view = list->obj;
972 GtkListStore *store = create_list_store(list, view->model); 1056 if(i < 0) {
973 gtk_tree_view_set_model(GTK_TREE_VIEW(view->widget), GTK_TREE_MODEL(store)); 1057 GtkListStore *store = create_list_store(list, view->model);
974 g_object_unref(G_OBJECT(store)); 1058 gtk_tree_view_set_model(GTK_TREE_VIEW(view->widget), GTK_TREE_MODEL(store));
1059 g_object_unref(G_OBJECT(store));
1060 } else {
1061 void *elm = list->get(list, i);
1062 GtkTreeModel *store = gtk_tree_view_get_model(GTK_TREE_VIEW(view->widget));
1063 GtkTreeIter iter;
1064 if(gtk_tree_model_iter_nth_child(store, &iter, NULL, i)) {
1065 update_list_row(GTK_LIST_STORE(store), &iter, view->model, elm);
1066 }
1067 }
975 } 1068 }
976 1069
977 UiListSelection ui_listview_getselection(UiList *list) { 1070 UiListSelection ui_listview_getselection(UiList *list) {
978 UiListView *view = list->obj; 1071 UiListView *view = list->obj;
979 UiListSelection selection = ui_listview_selection( 1072 UiListSelection selection = ui_listview_selection(
981 NULL); 1074 NULL);
982 return selection; 1075 return selection;
983 } 1076 }
984 1077
985 void ui_listview_setselection(UiList *list, UiListSelection selection) { 1078 void ui_listview_setselection(UiList *list, UiListSelection selection) {
1079 ui_setop_enable(TRUE);
986 UiListView *view = list->obj; 1080 UiListView *view = list->obj;
987 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view->widget)); 1081 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view->widget));
988 GtkTreePath *path = gtk_tree_path_new_from_indicesv(selection.rows, selection.count); 1082 GtkTreePath *path = gtk_tree_path_new_from_indicesv(selection.rows, selection.count);
989 gtk_tree_selection_select_path(sel, path); 1083 gtk_tree_selection_select_path(sel, path);
990 //g_object_unref(path); 1084 //g_object_unref(path);
1085 ui_setop_enable(FALSE);
991 } 1086 }
992 1087
993 1088
994 1089
995 /* --------------------------- ComboBox --------------------------- */ 1090 /* --------------------------- ComboBox --------------------------- */
1000 UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1); 1095 UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1);
1001 model->getvalue = args.getvalue ? args.getvalue : ui_strmodel_getvalue; 1096 model->getvalue = args.getvalue ? args.getvalue : ui_strmodel_getvalue;
1002 1097
1003 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.list, args.varname, UI_VAR_LIST); 1098 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.list, args.varname, UI_VAR_LIST);
1004 1099
1005 GtkWidget *combobox = ui_create_combobox(obj, model, var, args.onactivate, args.onactivatedata); 1100 GtkWidget *combobox = ui_create_combobox(obj, model, var, args.static_elements, args.static_nelm, args.onactivate, args.onactivatedata);
1006 ui_set_name_and_style(combobox, args.name, args.style_class); 1101 ui_set_name_and_style(combobox, args.name, args.style_class);
1007 ui_set_widget_groups(obj->ctx, combobox, args.groups); 1102 ui_set_widget_groups(obj->ctx, combobox, args.groups);
1008 UI_APPLY_LAYOUT1(current, args); 1103 UI_APPLY_LAYOUT1(current, args);
1009 current->container->add(current->container, combobox, FALSE); 1104 current->container->add(current->container, combobox, FALSE);
1010 current->container->current = combobox; 1105 current->container->current = combobox;
1011 return combobox; 1106 return combobox;
1012 } 1107 }
1013 1108
1014 GtkWidget* ui_create_combobox(UiObject *obj, UiModel *model, UiVar *var, ui_callback f, void *udata) { 1109 GtkWidget* ui_create_combobox(UiObject *obj, UiModel *model, UiVar *var, char **elm, size_t nelm, ui_callback f, void *udata) {
1015 GtkWidget *combobox = gtk_combo_box_new(); 1110 GtkWidget *combobox = gtk_combo_box_new();
1016 1111
1017 UiListView *uicbox = malloc(sizeof(UiListView)); 1112 UiListView *uicbox = malloc(sizeof(UiListView));
1113 memset(uicbox, 0, sizeof(UiListView));
1018 uicbox->obj = obj; 1114 uicbox->obj = obj;
1019 uicbox->widget = combobox; 1115 uicbox->widget = combobox;
1020 1116
1021 UiList *list = var ? var->value : NULL; 1117 UiList *list = var ? var->value : NULL;
1022 GtkListStore *listmodel = create_list_store(list, model); 1118 GtkListStore *listmodel = create_list_store(list, model);
1119
1120 if(!list && elm && nelm > 0) {
1121 listview_copy_static_elements(uicbox, elm, nelm);
1122 for(int i=0;i<nelm;i++) {
1123 GtkTreeIter iter;
1124 GValue value = G_VALUE_INIT;
1125 gtk_list_store_insert(listmodel, &iter, -1);
1126 g_value_init(&value, G_TYPE_STRING);
1127 g_value_set_string(&value, uicbox->elements[i]);
1128 gtk_list_store_set_value(listmodel, &iter, 0, &value);
1129 }
1130 }
1023 1131
1024 if(listmodel) { 1132 if(listmodel) {
1025 gtk_combo_box_set_model(GTK_COMBO_BOX(combobox), GTK_TREE_MODEL(listmodel)); 1133 gtk_combo_box_set_model(GTK_COMBO_BOX(combobox), GTK_TREE_MODEL(listmodel));
1026 g_object_unref(listmodel); 1134 g_object_unref(listmodel);
1027 } 1135 }
1058 UiEventData *event = ui_malloc(obj->ctx, sizeof(UiEventData)); 1166 UiEventData *event = ui_malloc(obj->ctx, sizeof(UiEventData));
1059 event->obj = obj; 1167 event->obj = obj;
1060 event->userdata = udata; 1168 event->userdata = udata;
1061 event->callback = f; 1169 event->callback = f;
1062 event->value = 0; 1170 event->value = 0;
1063 event->customdata = NULL; 1171 event->customdata = uicbox;
1064 1172
1065 g_signal_connect( 1173 g_signal_connect(
1066 combobox, 1174 combobox,
1067 "changed", 1175 "changed",
1068 G_CALLBACK(ui_combobox_change_event), 1176 G_CALLBACK(ui_combobox_change_event),
1071 1179
1072 return combobox; 1180 return combobox;
1073 } 1181 }
1074 1182
1075 void ui_combobox_change_event(GtkComboBox *widget, UiEventData *e) { 1183 void ui_combobox_change_event(GtkComboBox *widget, UiEventData *e) {
1184 int index = gtk_combo_box_get_active(widget);
1185 UiListView *listview = e->customdata;
1186 void *eventdata = NULL;
1187 if(listview->var && listview->var->value) {
1188 UiList *list = listview->var->value;
1189 eventdata = ui_list_get(list, index);
1190 } else if(listview->elements && listview->nelm > index) {
1191 eventdata = listview->elements[index];
1192 }
1193
1076 UiEvent event; 1194 UiEvent event;
1077 event.obj = e->obj; 1195 event.obj = e->obj;
1078 event.window = event.obj->window; 1196 event.window = event.obj->window;
1079 event.document = event.obj->ctx->document; 1197 event.document = event.obj->ctx->document;
1080 event.eventdata = NULL; 1198 event.eventdata = eventdata;
1081 event.intval = gtk_combo_box_get_active(widget); 1199 event.intval = index;
1200 event.set = ui_get_setop();
1082 e->callback(&event, e->userdata); 1201 e->callback(&event, e->userdata);
1083 } 1202 }
1084 1203
1085 void ui_combobox_modelupdate(UiList *list, int i) { 1204 void ui_combobox_modelupdate(UiList *list, int i) {
1086 UiListView *view = list->obj; 1205 UiListView *view = list->obj;
1097 ret.rows[0] = gtk_combo_box_get_active(GTK_COMBO_BOX(combobox->widget)); 1216 ret.rows[0] = gtk_combo_box_get_active(GTK_COMBO_BOX(combobox->widget));
1098 return ret; 1217 return ret;
1099 } 1218 }
1100 1219
1101 void ui_combobox_setselection(UiList *list, UiListSelection selection) { 1220 void ui_combobox_setselection(UiList *list, UiListSelection selection) {
1221 ui_setop_enable(TRUE);
1102 UiListView *combobox = list->obj; 1222 UiListView *combobox = list->obj;
1103 if(selection.count > 0) { 1223 if(selection.count > 0) {
1104 gtk_combo_box_set_active(GTK_COMBO_BOX(combobox->widget), selection.rows[0]); 1224 gtk_combo_box_set_active(GTK_COMBO_BOX(combobox->widget), selection.rows[0]);
1105 } 1225 }
1226 ui_setop_enable(FALSE);
1106 } 1227 }
1107 1228
1108 1229
1109 1230
1110 1231
1122 e.obj = event->obj; 1243 e.obj = event->obj;
1123 e.window = event->obj->window; 1244 e.window = event->obj->window;
1124 e.document = event->obj->ctx->document; 1245 e.document = event->obj->ctx->document;
1125 e.eventdata = &selection; 1246 e.eventdata = &selection;
1126 e.intval = selection.count > 0 ? selection.rows[0] : -1; 1247 e.intval = selection.count > 0 ? selection.rows[0] : -1;
1248 e.set = ui_get_setop();
1127 event->activate(&e, event->activatedata); 1249 event->activate(&e, event->activatedata);
1128 1250
1129 if(selection.count > 0) { 1251 if(selection.count > 0) {
1130 free(selection.rows); 1252 free(selection.rows);
1131 } 1253 }
1141 e.obj = event->obj; 1263 e.obj = event->obj;
1142 e.window = event->obj->window; 1264 e.window = event->obj->window;
1143 e.document = event->obj->ctx->document; 1265 e.document = event->obj->ctx->document;
1144 e.eventdata = &selection; 1266 e.eventdata = &selection;
1145 e.intval = selection.count > 0 ? selection.rows[0] : -1; 1267 e.intval = selection.count > 0 ? selection.rows[0] : -1;
1268 e.set = ui_get_setop();
1146 event->selection(&e, event->selectiondata); 1269 event->selection(&e, event->selectiondata);
1147 1270
1148 if(selection.count > 0) { 1271 if(selection.count > 0) {
1149 free(selection.rows); 1272 free(selection.rows);
1150 } 1273 }
1199 event.obj = listview->obj; 1322 event.obj = listview->obj;
1200 event.window = event.obj->window; 1323 event.window = event.obj->window;
1201 event.document = event.obj->ctx->document; 1324 event.document = event.obj->ctx->document;
1202 event.eventdata = dnd; 1325 event.eventdata = dnd;
1203 event.intval = 0; 1326 event.intval = 0;
1327 event.set = ui_get_setop();
1204 listview->ondragstart(&event, listview->ondragstartdata); 1328 listview->ondragstart(&event, listview->ondragstartdata);
1205 } 1329 }
1206 1330
1207 size_t numproviders = cxListSize(dnd->providers); 1331 size_t numproviders = cxListSize(dnd->providers);
1208 if(numproviders > 0) { 1332 if(numproviders > 0) {
1234 event.obj = listview->obj; 1358 event.obj = listview->obj;
1235 event.window = event.obj->window; 1359 event.window = event.obj->window;
1236 event.document = event.obj->ctx->document; 1360 event.document = event.obj->ctx->document;
1237 event.eventdata = &dnd; 1361 event.eventdata = &dnd;
1238 event.intval = 0; 1362 event.intval = 0;
1363 event.set = ui_get_setop();
1239 listview->ondragcomplete(&event, listview->ondragcompletedata); 1364 listview->ondragcomplete(&event, listview->ondragcompletedata);
1240 } 1365 }
1241 } 1366 }
1242 1367
1243 static gboolean ui_listview_drop( 1368 static gboolean ui_listview_drop(
1262 event.obj = listview->obj; 1387 event.obj = listview->obj;
1263 event.window = event.obj->window; 1388 event.window = event.obj->window;
1264 event.document = event.obj->ctx->document; 1389 event.document = event.obj->ctx->document;
1265 event.eventdata = &dnd; 1390 event.eventdata = &dnd;
1266 event.intval = 0; 1391 event.intval = 0;
1392 event.set = ui_get_setop();
1267 listview->ondrop(&event, listview->ondropdata); 1393 listview->ondrop(&event, listview->ondropdata);
1268 } 1394 }
1269 1395
1270 return dnd.accept; 1396 return dnd.accept;
1271 } 1397 }
1324 event.obj = listview->obj; 1450 event.obj = listview->obj;
1325 event.window = event.obj->window; 1451 event.window = event.obj->window;
1326 event.document = event.obj->ctx->document; 1452 event.document = event.obj->ctx->document;
1327 event.eventdata = &dnd; 1453 event.eventdata = &dnd;
1328 event.intval = 0; 1454 event.intval = 0;
1455 event.set = ui_get_setop();
1329 listview->ondragstart(&event, listview->ondragstartdata); 1456 listview->ondragstart(&event, listview->ondragstartdata);
1330 } 1457 }
1331 } 1458 }
1332 1459
1333 static void ui_listview_drag_end( 1460 static void ui_listview_drag_end(
1348 event.obj = listview->obj; 1475 event.obj = listview->obj;
1349 event.window = event.obj->window; 1476 event.window = event.obj->window;
1350 event.document = event.obj->ctx->document; 1477 event.document = event.obj->ctx->document;
1351 event.eventdata = &dnd; 1478 event.eventdata = &dnd;
1352 event.intval = 0; 1479 event.intval = 0;
1480 event.set = ui_get_setop();
1353 listview->ondragcomplete(&event, listview->ondragcompletedata); 1481 listview->ondragcomplete(&event, listview->ondragcompletedata);
1354 } 1482 }
1355 } 1483 }
1356 1484
1357 void ui_listview_add_dnd(UiListView *listview, UiListArgs *args) { 1485 void ui_listview_add_dnd(UiListView *listview, UiListArgs *args) {
1393 event.obj = listview->obj; 1521 event.obj = listview->obj;
1394 event.window = event.obj->window; 1522 event.window = event.obj->window;
1395 event.document = event.obj->ctx->document; 1523 event.document = event.obj->ctx->document;
1396 event.eventdata = &dnd; 1524 event.eventdata = &dnd;
1397 event.intval = 0; 1525 event.intval = 0;
1526 event.set = ui_get_setop();
1398 listview->ondrop(&event, listview->ondropdata); 1527 listview->ondrop(&event, listview->ondropdata);
1399 } 1528 }
1400 } 1529 }
1401 1530
1402 void ui_listview_enable_drop(UiListView *listview, UiListArgs *args) { 1531 void ui_listview_enable_drop(UiListView *listview, UiListArgs *args) {
1494 } 1623 }
1495 */ 1624 */
1496 1625
1497 void ui_listview_destroy(GtkWidget *w, UiListView *v) { 1626 void ui_listview_destroy(GtkWidget *w, UiListView *v) {
1498 //gtk_tree_view_set_model(GTK_TREE_VIEW(w), NULL); 1627 //gtk_tree_view_set_model(GTK_TREE_VIEW(w), NULL);
1499 ui_destroy_boundvar(v->obj->ctx, v->var); 1628 if(v->var) {
1629 ui_destroy_boundvar(v->obj->ctx, v->var);
1630 }
1631 if(v->elements) {
1632 for(int i=0;i<v->nelm;i++) {
1633 free(v->elements[i]);
1634 }
1635 free(v->elements);
1636 }
1500 #if GTK_CHECK_VERSION(4, 10, 0) 1637 #if GTK_CHECK_VERSION(4, 10, 0)
1501 free(v->columns); 1638 free(v->columns);
1502 #endif 1639 #endif
1503 free(v->selection.rows); 1640 free(v->selection.rows);
1504 free(v); 1641 free(v);
1505 } 1642 }
1506 1643
1507 void ui_combobox_destroy(GtkWidget *w, UiListView *v) { 1644 void ui_combobox_destroy(GtkWidget *w, UiListView *v) {
1508 ui_destroy_boundvar(v->obj->ctx, v->var); 1645 if(v->var) {
1646 ui_destroy_boundvar(v->obj->ctx, v->var);
1647 }
1648 if(v->elements) {
1649 for(int i=0;i<v->nelm;i++) {
1650 free(v->elements[i]);
1651 }
1652 free(v->elements);
1653 }
1509 free(v); 1654 free(v);
1510 } 1655 }
1511 1656
1512 1657
1513 /* ------------------------------ Source List ------------------------------ */ 1658 /* ------------------------------ Source List ------------------------------ */
1849 event.obj = data->obj; 1994 event.obj = data->obj;
1850 event.window = event.obj->window; 1995 event.window = event.obj->window;
1851 event.document = event.obj->ctx->document; 1996 event.document = event.obj->ctx->document;
1852 event.eventdata = &eventdata; 1997 event.eventdata = &eventdata;
1853 event.intval = data->value0; 1998 event.intval = data->value0;
1999 event.set = ui_get_setop();
1854 2000
1855 if(data->callback) { 2001 if(data->callback) {
1856 data->callback(&event, data->userdata); 2002 data->callback(&event, data->userdata);
1857 } 2003 }
1858 } 2004 }

mercurial