1 | #include <gtk/gtk.h> |
2 | |
3 | typedef GtkListStore MyModel; |
4 | typedef GtkListStoreClass MyModelClass; |
5 | |
6 | static void my_model_drag_source_init (GtkTreeDragSourceIface *iface); |
7 | |
8 | static GType my_model_get_type (void); |
9 | G_DEFINE_TYPE_WITH_CODE (MyModel, my_model, GTK_TYPE_LIST_STORE, |
10 | G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE, |
11 | my_model_drag_source_init)) |
12 | |
13 | static void |
14 | my_model_class_init (MyModelClass *class) |
15 | { |
16 | } |
17 | |
18 | static void |
19 | my_model_init (MyModel *object) |
20 | { |
21 | GType types[1] = { G_TYPE_STRING }; |
22 | |
23 | gtk_list_store_set_column_types (GTK_LIST_STORE (object), G_N_ELEMENTS (types), types); |
24 | } |
25 | |
26 | static GdkContentProvider * |
27 | my_model_drag_data_get (GtkTreeDragSource *source, |
28 | GtkTreePath *path) |
29 | { |
30 | GdkContentProvider *content; |
31 | GtkTreeIter iter; |
32 | char *text; |
33 | |
34 | gtk_tree_model_get_iter (GTK_TREE_MODEL (source), iter: &iter, path); |
35 | gtk_tree_model_get (GTK_TREE_MODEL (source), iter: &iter, 0, &text, -1); |
36 | content = gdk_content_provider_new_typed (G_TYPE_STRING, text); |
37 | g_free (mem: text); |
38 | |
39 | return content; |
40 | } |
41 | |
42 | static void |
43 | my_model_drag_source_init (GtkTreeDragSourceIface *iface) |
44 | { |
45 | static GtkTreeDragSourceIface *parent; |
46 | |
47 | parent = g_type_interface_peek_parent (g_iface: iface); |
48 | |
49 | iface->row_draggable = parent->row_draggable; |
50 | iface->drag_data_delete = parent->drag_data_delete; |
51 | iface->drag_data_get = my_model_drag_data_get; |
52 | } |
53 | |
54 | static GtkTreeModel * |
55 | get_model (void) |
56 | { |
57 | MyModel *model; |
58 | |
59 | model = g_object_new (object_type: my_model_get_type (), NULL); |
60 | gtk_list_store_insert_with_values (GTK_LIST_STORE (model), NULL, position: -1, 0, "Item 1" , -1); |
61 | gtk_list_store_insert_with_values (GTK_LIST_STORE (model), NULL, position: -1, 0, "Item 2" , -1); |
62 | gtk_list_store_insert_with_values (GTK_LIST_STORE (model), NULL, position: -1, 0, "Item 3" , -1); |
63 | |
64 | return GTK_TREE_MODEL (model); |
65 | } |
66 | |
67 | static GtkWidget * |
68 | get_dragsource (void) |
69 | { |
70 | GtkTreeView *tv; |
71 | GtkCellRenderer *renderer; |
72 | GtkTreeViewColumn *column; |
73 | GdkContentFormats *targets; |
74 | |
75 | tv = (GtkTreeView*) gtk_tree_view_new (); |
76 | renderer = gtk_cell_renderer_text_new (); |
77 | column = gtk_tree_view_column_new_with_attributes (title: "Text" , cell: renderer, "text" , 0, NULL); |
78 | gtk_tree_view_append_column (tree_view: tv, column); |
79 | |
80 | gtk_tree_view_set_model (tree_view: tv, model: get_model ()); |
81 | targets = gdk_content_formats_new_for_gtype (G_TYPE_STRING); |
82 | gtk_tree_view_enable_model_drag_source (tree_view: tv, start_button_mask: GDK_BUTTON1_MASK, formats: targets, actions: GDK_ACTION_COPY); |
83 | gdk_content_formats_unref (formats: targets); |
84 | |
85 | return GTK_WIDGET (tv); |
86 | } |
87 | |
88 | static void |
89 | drag_drop (GtkDropTarget *dest, |
90 | const GValue *value, |
91 | int x, |
92 | int y, |
93 | gpointer dada) |
94 | { |
95 | GtkWidget *widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest)); |
96 | |
97 | gtk_label_set_label (GTK_LABEL (widget), str: g_value_get_string (value)); |
98 | } |
99 | |
100 | static GtkWidget * |
101 | get_droptarget (void) |
102 | { |
103 | GtkWidget *label; |
104 | GtkDropTarget *dest; |
105 | |
106 | label = gtk_label_new (str: "Drop here" ); |
107 | dest = gtk_drop_target_new (G_TYPE_STRING, actions: GDK_ACTION_COPY); |
108 | g_signal_connect (dest, "drop" , G_CALLBACK (drag_drop), NULL); |
109 | gtk_widget_add_controller (widget: label, GTK_EVENT_CONTROLLER (dest)); |
110 | |
111 | return label; |
112 | } |
113 | |
114 | int |
115 | main (int argc, char *argv[]) |
116 | { |
117 | GtkWidget *window; |
118 | GtkWidget *box; |
119 | |
120 | gtk_init (); |
121 | |
122 | window = gtk_window_new (); |
123 | |
124 | box = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0); |
125 | gtk_window_set_child (GTK_WINDOW (window), child: box); |
126 | gtk_box_append (GTK_BOX (box), child: get_dragsource ()); |
127 | gtk_box_append (GTK_BOX (box), child: get_droptarget ()); |
128 | |
129 | gtk_widget_show (widget: window); |
130 | |
131 | while (TRUE) |
132 | g_main_context_iteration (NULL, TRUE); |
133 | |
134 | return 0; |
135 | } |
136 | |