| 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 |
| 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 } |
| 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; |
| 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) { |
| 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 } |