ui/gtk/list.c

changeset 90
f501f0efc9a8
parent 88
e27526429d85
child 98
16e84fac48bd
equal deleted inserted replaced
89:2fbb3cac05a5 90:f501f0efc9a8
33 33
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 <cx/array_list.h>
39
38 #include "list.h" 40 #include "list.h"
39 #include "icon.h" 41 #include "icon.h"
40 #include "menu.h" 42 #include "menu.h"
43 #include "dnd.h"
41 44
42 45
43 void* ui_strmodel_getvalue(void *elm, int column) { 46 void* ui_strmodel_getvalue(void *elm, int column) {
44 return column == 0 ? elm : NULL; 47 return column == 0 ? elm : NULL;
45 } 48 }
364 UiListView *tableview = malloc(sizeof(UiListView)); 367 UiListView *tableview = malloc(sizeof(UiListView));
365 tableview->obj = obj; 368 tableview->obj = obj;
366 tableview->widget = view; 369 tableview->widget = view;
367 tableview->var = var; 370 tableview->var = var;
368 tableview->model = model; 371 tableview->model = model;
372 tableview->ondragstart = args.ondragstart;
373 tableview->ondragstartdata = args.ondragstartdata;
374 tableview->ondragcomplete = args.ondragcomplete;
375 tableview->ondragcompletedata = args.ondragcompletedata;
376 tableview->ondrop = args.ondrop;
377 tableview->ondropdata = args.ondropsdata;
369 g_signal_connect( 378 g_signal_connect(
370 view, 379 view,
371 "destroy", 380 "destroy",
372 G_CALLBACK(ui_listview_destroy), 381 G_CALLBACK(ui_listview_destroy),
373 tableview); 382 tableview);
401 G_CALLBACK(ui_listview_selection_event), 410 G_CALLBACK(ui_listview_selection_event),
402 event); 411 event);
403 } 412 }
404 // TODO: destroy callback 413 // TODO: destroy callback
405 414
415
416 if(args.ondragstart) {
417 ui_listview_add_dnd(tableview, &args);
418 }
419 if(args.ondrop) {
420 ui_listview_enable_drop(tableview, &args);
421 }
406 422
407 GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(view)); 423 GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(view));
408 if(args.multiselection) { 424 if(args.multiselection) {
409 gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); 425 gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
410 } 426 }
429 // to add a context menu 445 // to add a context menu
430 current->container->current = view; 446 current->container->current = view;
431 447
432 return scroll_area; 448 return scroll_area;
433 } 449 }
450
451 #if GTK_MAJOR_VERSION >= 4
452
453 static GdkContentProvider *ui_listview_dnd_prepare(GtkDragSource *source, double x, double y, void *data) {
454 //printf("drag prepare\n");
455 UiListView *listview = data;
456
457 UiDnD *dnd = ui_create_dnd();
458 GdkContentProvider *provider = NULL;
459
460
461 if(listview->ondragstart) {
462 UiEvent event;
463 event.obj = listview->obj;
464 event.window = event.obj->window;
465 event.document = event.obj->ctx->document;
466 event.eventdata = dnd;
467 event.intval = 0;
468 listview->ondragstart(&event, listview->ondragstartdata);
469 }
470
471 size_t numproviders = cxListSize(dnd->providers);
472 if(numproviders > 0) {
473 GdkContentProvider **providers = (GdkContentProvider**)cxListAt(dnd->providers, 0);
474 provider = gdk_content_provider_new_union(providers, numproviders);
475 }
476 ui_dnd_free(dnd);
477
478 return provider;
479 }
480
481 static void ui_listview_drag_begin(GtkDragSource *self, GdkDrag *drag, gpointer userdata) {
482 //printf("drag begin\n");
483 }
484
485 static void ui_listview_drag_end(GtkDragSource *self, GdkDrag *drag, gboolean delete_data, gpointer user_data) {
486 //printf("drag end\n");
487 UiListView *listview = user_data;
488 if(listview->ondragcomplete) {
489 UiDnD dnd;
490 dnd.target = NULL;
491 dnd.value = NULL;
492 dnd.providers = NULL;
493 dnd.selected_action = gdk_drag_get_selected_action(drag);
494 dnd.delete = delete_data;
495 dnd.accept = FALSE;
496
497 UiEvent event;
498 event.obj = listview->obj;
499 event.window = event.obj->window;
500 event.document = event.obj->ctx->document;
501 event.eventdata = &dnd;
502 event.intval = 0;
503 listview->ondragcomplete(&event, listview->ondragcompletedata);
504 }
505 }
506
507 static gboolean ui_listview_drop(
508 GtkDropTarget *target,
509 const GValue* value,
510 gdouble x,
511 gdouble y,
512 gpointer user_data)
513 {
514 UiListView *listview = user_data;
515 UiDnD dnd;
516 dnd.providers = NULL;
517 dnd.target = target;
518 dnd.value = value;
519 dnd.selected_action = 0;
520 dnd.delete = FALSE;
521 dnd.accept = FALSE;
522
523 if(listview->ondrop) {
524 dnd.accept = TRUE;
525 UiEvent event;
526 event.obj = listview->obj;
527 event.window = event.obj->window;
528 event.document = event.obj->ctx->document;
529 event.eventdata = &dnd;
530 event.intval = 0;
531 listview->ondrop(&event, listview->ondropdata);
532 }
533
534 return dnd.accept;
535 }
536
537 void ui_listview_add_dnd(UiListView *listview, UiListArgs *args) {
538 GtkDragSource *dragsource = gtk_drag_source_new();
539 gtk_widget_add_controller(listview->widget, GTK_EVENT_CONTROLLER(dragsource));
540 g_signal_connect (dragsource, "prepare", G_CALLBACK (ui_listview_dnd_prepare), listview);
541 g_signal_connect(
542 dragsource,
543 "drag-begin",
544 G_CALLBACK(ui_listview_drag_begin),
545 listview);
546 g_signal_connect(
547 dragsource,
548 "drag-end",
549 G_CALLBACK(ui_listview_drag_end),
550 listview);
551 }
552
553 void ui_listview_enable_drop(UiListView *listview, UiListArgs *args) {
554 GtkDropTarget *target = gtk_drop_target_new(G_TYPE_INVALID, GDK_ACTION_COPY);
555 gtk_widget_add_controller(listview->widget, GTK_EVENT_CONTROLLER(target));
556 GType default_types[2] = { GDK_TYPE_FILE_LIST, G_TYPE_STRING };
557 gtk_drop_target_set_gtypes(target, default_types, 2);
558 g_signal_connect(target, "drop", G_CALLBACK(ui_listview_drop), listview);
559 }
560
561 #else
562
563 static GtkTargetEntry targetentries[] =
564 {
565 { "STRING", 0, 0 },
566 { "text/plain", 0, 1 },
567 { "text/uri-list", 0, 2 },
568 };
569
570 static void ui_listview_drag_getdata(
571 GtkWidget* self,
572 GdkDragContext* context,
573 GtkSelectionData* data,
574 guint info,
575 guint time,
576 gpointer user_data)
577 {
578 UiListView *listview = user_data;
579 UiDnD dnd;
580 dnd.context = context;
581 dnd.data = data;
582 dnd.selected_action = 0;
583 dnd.delete = FALSE;
584 dnd.accept = FALSE;
585
586 if(listview->ondragstart) {
587 UiEvent event;
588 event.obj = listview->obj;
589 event.window = event.obj->window;
590 event.document = event.obj->ctx->document;
591 event.eventdata = &dnd;
592 event.intval = 0;
593 listview->ondragstart(&event, listview->ondragstartdata);
594 }
595 }
596
597 static void ui_listview_drag_end(
598 GtkWidget *widget,
599 GdkDragContext *context,
600 guint time,
601 gpointer user_data)
602 {
603 UiListView *listview = user_data;
604 UiDnD dnd;
605 dnd.context = context;
606 dnd.data = NULL;
607 dnd.selected_action = gdk_drag_context_get_selected_action(context);
608 dnd.delete = dnd.selected_action == UI_DND_ACTION_MOVE ? TRUE : FALSE;
609 dnd.accept = FALSE;
610 if(listview->ondragcomplete) {
611 UiEvent event;
612 event.obj = listview->obj;
613 event.window = event.obj->window;
614 event.document = event.obj->ctx->document;
615 event.eventdata = &dnd;
616 event.intval = 0;
617 listview->ondragcomplete(&event, listview->ondragcompletedata);
618 }
619 }
620
621 void ui_listview_add_dnd(UiListView *listview, UiListArgs *args) {
622 gtk_tree_view_enable_model_drag_source(
623 GTK_TREE_VIEW(listview->widget),
624 GDK_BUTTON1_MASK,
625 targetentries,
626 2,
627 GDK_ACTION_COPY);
628
629 g_signal_connect(listview->widget, "drag-data-get", G_CALLBACK(ui_listview_drag_getdata), listview);
630 g_signal_connect(listview->widget, "drag-end", G_CALLBACK(ui_listview_drag_end), listview);
631 }
632
633
634
635
636 static void ui_listview_drag_data_received(
637 GtkWidget *self,
638 GdkDragContext *context,
639 gint x,
640 gint y,
641 GtkSelectionData *data,
642 guint info,
643 guint time,
644 gpointer user_data)
645 {
646 UiListView *listview = user_data;
647 UiDnD dnd;
648 dnd.context = context;
649 dnd.data = data;
650 dnd.selected_action = 0;
651 dnd.delete = FALSE;
652 dnd.accept = FALSE;
653
654 if(listview->ondrop) {
655 dnd.accept = TRUE;
656 UiEvent event;
657 event.obj = listview->obj;
658 event.window = event.obj->window;
659 event.document = event.obj->ctx->document;
660 event.eventdata = &dnd;
661 event.intval = 0;
662 listview->ondrop(&event, listview->ondropdata);
663 }
664 }
665
666 void ui_listview_enable_drop(UiListView *listview, UiListArgs *args) {
667 gtk_tree_view_enable_model_drag_dest(
668 GTK_TREE_VIEW(listview->widget),
669 targetentries,
670 3,
671 GDK_ACTION_COPY);
672 if(listview->ondrop) {
673 g_signal_connect(listview->widget, "drag_data_received", G_CALLBACK(ui_listview_drag_data_received), listview);
674 }
675 }
676
677 #endif
434 678
435 679
436 GtkWidget* ui_get_tree_widget(UIWIDGET widget) { 680 GtkWidget* ui_get_tree_widget(UIWIDGET widget) {
437 return SCROLLEDWINDOW_GET_CHILD(widget); 681 return SCROLLEDWINDOW_GET_CHILD(widget);
438 } 682 }

mercurial