1 | /* testdnd.c |
2 | * Copyright (C) 1998 Red Hat, Inc. |
3 | * Author: Owen Taylor |
4 | * |
5 | * This library is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU Library General Public |
7 | * License as published by the Free Software Foundation; either |
8 | * version 2 of the License, or (at your option) any later version. |
9 | * |
10 | * This library is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | * Library General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU Library General Public |
16 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
17 | */ |
18 | |
19 | #include "config.h" |
20 | #include "gtk/gtk.h" |
21 | |
22 | /* Target side drag signals */ |
23 | |
24 | /* XPM */ |
25 | static const char * drag_icon_xpm[] = { |
26 | "36 48 9 1" , |
27 | " c None" , |
28 | ". c #020204" , |
29 | "+ c #8F8F90" , |
30 | "@ c #D3D3D2" , |
31 | "# c #AEAEAC" , |
32 | "$ c #ECECEC" , |
33 | "% c #A2A2A4" , |
34 | "& c #FEFEFC" , |
35 | "* c #BEBEBC" , |
36 | " ....................." , |
37 | " ..&&&&&&&&&&&&&&&&&&&." , |
38 | " ...&&&&&&&&&&&&&&&&&&&." , |
39 | " ..&.&&&&&&&&&&&&&&&&&&&." , |
40 | " ..&&.&&&&&&&&&&&&&&&&&&&." , |
41 | " ..&&&.&&&&&&&&&&&&&&&&&&&." , |
42 | " ..&&&&.&&&&&&&&&&&&&&&&&&&." , |
43 | " ..&&&&&.&&&@&&&&&&&&&&&&&&&." , |
44 | " ..&&&&&&.*$%$+$&&&&&&&&&&&&&." , |
45 | " ..&&&&&&&.%$%$+&&&&&&&&&&&&&&." , |
46 | " ..&&&&&&&&.#&#@$&&&&&&&&&&&&&&." , |
47 | " ..&&&&&&&&&.#$**#$&&&&&&&&&&&&&." , |
48 | " ..&&&&&&&&&&.&@%&%$&&&&&&&&&&&&&." , |
49 | " ..&&&&&&&&&&&.&&&&&&&&&&&&&&&&&&&." , |
50 | " ..&&&&&&&&&&&&.&&&&&&&&&&&&&&&&&&&." , |
51 | "................&$@&&&@&&&&&&&&&&&&." , |
52 | ".&&&&&&&+&&#@%#+@#@*$%$+$&&&&&&&&&&." , |
53 | ".&&&&&&&+&&#@#@&&@*%$%$+&&&&&&&&&&&." , |
54 | ".&&&&&&&+&$%&#@&#@@#&#@$&&&&&&&&&&&." , |
55 | ".&&&&&&@#@@$&*@&@#@#$**#$&&&&&&&&&&." , |
56 | ".&&&&&&&&&&&&&&&&&&&@%&%$&&&&&&&&&&." , |
57 | ".&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&." , |
58 | ".&&&&&&&&$#@@$&&&&&&&&&&&&&&&&&&&&&." , |
59 | ".&&&&&&&&&+&$+&$&@&$@&&$@&&&&&&&&&&." , |
60 | ".&&&&&&&&&+&&#@%#+@#@*$%&+$&&&&&&&&." , |
61 | ".&&&&&&&&&+&&#@#@&&@*%$%$+&&&&&&&&&." , |
62 | ".&&&&&&&&&+&$%&#@&#@@#&#@$&&&&&&&&&." , |
63 | ".&&&&&&&&@#@@$&*@&@#@#$#*#$&&&&&&&&." , |
64 | ".&&&&&&&&&&&&&&&&&&&&&$%&%$&&&&&&&&." , |
65 | ".&&&&&&&&&&$#@@$&&&&&&&&&&&&&&&&&&&." , |
66 | ".&&&&&&&&&&&+&$%&$$@&$@&&$@&&&&&&&&." , |
67 | ".&&&&&&&&&&&+&&#@%#+@#@*$%$+$&&&&&&." , |
68 | ".&&&&&&&&&&&+&&#@#@&&@*#$%$+&&&&&&&." , |
69 | ".&&&&&&&&&&&+&$+&*@&#@@#&#@$&&&&&&&." , |
70 | ".&&&&&&&&&&$%@@&&*@&@#@#$#*#&&&&&&&." , |
71 | ".&&&&&&&&&&&&&&&&&&&&&&&$%&%$&&&&&&." , |
72 | ".&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&." , |
73 | ".&&&&&&&&&&&&&&$#@@$&&&&&&&&&&&&&&&." , |
74 | ".&&&&&&&&&&&&&&&+&$%&$$@&$@&&$@&&&&." , |
75 | ".&&&&&&&&&&&&&&&+&&#@%#+@#@*$%$+$&&." , |
76 | ".&&&&&&&&&&&&&&&+&&#@#@&&@*#$%$+&&&." , |
77 | ".&&&&&&&&&&&&&&&+&$+&*@&#@@#&#@$&&&." , |
78 | ".&&&&&&&&&&&&&&$%@@&&*@&@#@#$#*#&&&." , |
79 | ".&&&&&&&&&&&&&&&&&&&&&&&&&&&$%&%$&&." , |
80 | ".&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&." , |
81 | ".&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&." , |
82 | ".&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&." , |
83 | "...................................." }; |
84 | |
85 | /* XPM */ |
86 | static const char * trashcan_closed_xpm[] = { |
87 | "64 80 17 1" , |
88 | " c None" , |
89 | ". c #030304" , |
90 | "+ c #5A5A5C" , |
91 | "@ c #323231" , |
92 | "# c #888888" , |
93 | "$ c #1E1E1F" , |
94 | "% c #767677" , |
95 | "& c #494949" , |
96 | "* c #9E9E9C" , |
97 | "= c #111111" , |
98 | "- c #3C3C3D" , |
99 | "; c #6B6B6B" , |
100 | "> c #949494" , |
101 | ", c #282828" , |
102 | "' c #808080" , |
103 | ") c #545454" , |
104 | "! c #AEAEAC" , |
105 | " " , |
106 | " " , |
107 | " " , |
108 | " " , |
109 | " " , |
110 | " " , |
111 | " " , |
112 | " " , |
113 | " " , |
114 | " " , |
115 | " " , |
116 | " " , |
117 | " " , |
118 | " " , |
119 | " " , |
120 | " " , |
121 | " " , |
122 | " " , |
123 | " " , |
124 | " " , |
125 | " " , |
126 | " " , |
127 | " ==......=$$...=== " , |
128 | " ..$------)+++++++++++++@$$... " , |
129 | " ..=@@-------&+++++++++++++++++++-.... " , |
130 | " =.$$@@@-&&)++++)-,$$$$=@@&+++++++++++++,..$ " , |
131 | " .$$$$@@&+++++++&$$$@@@@-&,$,-++++++++++;;;&.. " , |
132 | " $$$$,@--&++++++&$$)++++++++-,$&++++++;%%'%%;;$@ " , |
133 | " .-@@-@-&++++++++-@++++++++++++,-++++++;''%;;;%*-$ " , |
134 | " +------++++++++++++++++++++++++++++++;;%%%;;##*!. " , |
135 | " =+----+++++++++++++++++++++++;;;;;;;;;;;;%'>>). " , |
136 | " .=)&+++++++++++++++++;;;;;;;;;;;;;;%''>>#>#@. " , |
137 | " =..=&++++++++++++;;;;;;;;;;;;;%###>>###+%== " , |
138 | " .&....=-+++++%;;####''''''''''##'%%%)..#. " , |
139 | " .+-++@....=,+%#####'%%%%%%%%%;@$-@-@*++!. " , |
140 | " .+-++-+++-&-@$$=$=......$,,,@;&)+!++!++!. " , |
141 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
142 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
143 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
144 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
145 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
146 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
147 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
148 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
149 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
150 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
151 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
152 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
153 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
154 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
155 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
156 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
157 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
158 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
159 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
160 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
161 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
162 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
163 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
164 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
165 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
166 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
167 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
168 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
169 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
170 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
171 | " =+-++-+++-+++++++++!++++!++++!+++!++!+++= " , |
172 | " $.++-+++-+++++++++!++++!++++!+++!++!+.$ " , |
173 | " =.++++++++++++++!++++!++++!+++!++.= " , |
174 | " $..+++++++++++++++!++++++...$ " , |
175 | " $$=.............=$$ " , |
176 | " " , |
177 | " " , |
178 | " " , |
179 | " " , |
180 | " " , |
181 | " " , |
182 | " " , |
183 | " " , |
184 | " " }; |
185 | |
186 | /* XPM */ |
187 | static const char * trashcan_open_xpm[] = { |
188 | "64 80 17 1" , |
189 | " c None" , |
190 | ". c #030304" , |
191 | "+ c #5A5A5C" , |
192 | "@ c #323231" , |
193 | "# c #888888" , |
194 | "$ c #1E1E1F" , |
195 | "% c #767677" , |
196 | "& c #494949" , |
197 | "* c #9E9E9C" , |
198 | "= c #111111" , |
199 | "- c #3C3C3D" , |
200 | "; c #6B6B6B" , |
201 | "> c #949494" , |
202 | ", c #282828" , |
203 | "' c #808080" , |
204 | ") c #545454" , |
205 | "! c #AEAEAC" , |
206 | " " , |
207 | " " , |
208 | " " , |
209 | " " , |
210 | " " , |
211 | " " , |
212 | " .=.==.,@ " , |
213 | " ==.,@-&&&)-= " , |
214 | " .$@,&++;;;%>*- " , |
215 | " $,-+)+++%%;;'#+. " , |
216 | " =---+++++;%%%;%##@. " , |
217 | " @)++++++++;%%%%'#%$ " , |
218 | " $&++++++++++;%%;%##@= " , |
219 | " ,-++++)+++++++;;;'#%) " , |
220 | " @+++&&--&)++++;;%'#'-. " , |
221 | " ,&++-@@,,,,-)++;;;'>'+, " , |
222 | " =-++&@$@&&&&-&+;;;%##%+@ " , |
223 | " =,)+)-,@@&+++++;;;;%##%&@ " , |
224 | " @--&&,,@&)++++++;;;;'#)@ " , |
225 | " ---&)-,@)+++++++;;;%''+, " , |
226 | " $--&)+&$-+++++++;;;%%'';- " , |
227 | " .,-&+++-$&++++++;;;%''%&= " , |
228 | " $,-&)++)-@++++++;;%''%), " , |
229 | " =,@&)++++&&+++++;%'''+$@&++++++ " , |
230 | " .$@-++++++++++++;'#';,........=$@&++++ " , |
231 | " =$@@&)+++++++++++'##-.................=&++ " , |
232 | " .$$@-&)+++++++++;%#+$.....................=)+ " , |
233 | " $$,@-)+++++++++;%;@=........................,+ " , |
234 | " .$$@@-++++++++)-)@=............................ " , |
235 | " $,@---)++++&)@===............................,. " , |
236 | " $-@---&)))-$$=..............................=)!. " , |
237 | " --&-&&,,$=,==...........................=&+++!. " , |
238 | " =,=$..=$+)+++++&@$=.............=$@&+++++!++!. " , |
239 | " .)-++-+++++++++++++++++++++++++++!++!++!. " , |
240 | " .+-++-+++++++++++++++++++++++!+++!++!++!. " , |
241 | " .+-++-+++-+++++++++!+++!!++++!+++!++!++!. " , |
242 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
243 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
244 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
245 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
246 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
247 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
248 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
249 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
250 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
251 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
252 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
253 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
254 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
255 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
256 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
257 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
258 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
259 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
260 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
261 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
262 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
263 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
264 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
265 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
266 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
267 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
268 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
269 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
270 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
271 | " .+-++-+++-+++++++++!++++!++++!+++!++!++!. " , |
272 | " =+-++-+++-+++++++++!++++!++++!+++!++!+++= " , |
273 | " $.++-+++-+++++++++!++++!++++!+++!++!+.$ " , |
274 | " =.++++++++++++++!++++!++++!+++!++.= " , |
275 | " $..+++++++++++++++!++++++...$ " , |
276 | " $$==...........==$$ " , |
277 | " " , |
278 | " " , |
279 | " " , |
280 | " " , |
281 | " " , |
282 | " " , |
283 | " " , |
284 | " " , |
285 | " " }; |
286 | |
287 | GdkPixbuf *trashcan_open; |
288 | GdkPixbuf *trashcan_closed; |
289 | |
290 | |
291 | static GdkDragAction |
292 | action_make_unique (GdkDragAction action) |
293 | { |
294 | if (gdk_drag_action_is_unique (action)) |
295 | return action; |
296 | |
297 | if (action & GDK_ACTION_COPY) |
298 | return GDK_ACTION_COPY; |
299 | |
300 | if (action & GDK_ACTION_MOVE) |
301 | return GDK_ACTION_MOVE; |
302 | |
303 | if (action & GDK_ACTION_LINK) |
304 | return GDK_ACTION_LINK; |
305 | |
306 | g_assert_not_reached (); |
307 | return 0; |
308 | } |
309 | |
310 | static GdkDragAction |
311 | trash_drag_enter (GtkDropTarget *dest, |
312 | GdkDrop *drop, |
313 | double x, |
314 | double y, |
315 | GtkWidget *widget) |
316 | { |
317 | char *s; |
318 | |
319 | gtk_image_set_from_pixbuf (GTK_IMAGE (widget), pixbuf: trashcan_open); |
320 | |
321 | s = gdk_content_formats_to_string (formats: gdk_drop_get_formats (self: drop)); |
322 | g_print (format: "trash enter: %s\n" , s); |
323 | g_free (mem: s); |
324 | |
325 | return action_make_unique (action: gdk_drop_get_actions (self: drop));; |
326 | } |
327 | |
328 | static GdkDragAction |
329 | trash_drag_leave (GtkDropTarget *dest, |
330 | GdkDrop *drop, |
331 | GtkWidget *widget) |
332 | { |
333 | char *s; |
334 | |
335 | gtk_image_set_from_pixbuf (GTK_IMAGE (widget), pixbuf: trashcan_closed); |
336 | |
337 | s = gdk_content_formats_to_string (formats: gdk_drop_get_formats (self: drop)); |
338 | g_print (format: "trash leave: %s\n" , s); |
339 | g_free (mem: s); |
340 | |
341 | return action_make_unique (action: gdk_drop_get_actions (self: drop)); |
342 | } |
343 | |
344 | static gboolean |
345 | trash_drag_drop (GtkDropTarget *dest, |
346 | GdkDrop *drop, |
347 | double x, |
348 | double y, |
349 | GtkWidget *widget) |
350 | { |
351 | char *s; |
352 | |
353 | s = gdk_content_formats_to_string (formats: gdk_drop_get_formats (self: drop)); |
354 | g_print (format: "trash drop: %s\n" , s); |
355 | g_free (mem: s); |
356 | |
357 | gdk_drop_finish (self: drop, action: action_make_unique (action: gdk_drop_get_actions (self: drop))); |
358 | |
359 | return TRUE; |
360 | } |
361 | |
362 | static gboolean |
363 | label_drag_drop (GtkDropTarget *dest, |
364 | const GValue *value, |
365 | int x, |
366 | int y, |
367 | GtkWidget *widget) |
368 | { |
369 | g_print (format: "Received \"%s\" in label\n" , g_value_get_string (value)); |
370 | return TRUE; |
371 | } |
372 | |
373 | /* The following is a rather elaborate example demonstrating/testing |
374 | * changing of the window hierarchy during a drag - in this case, |
375 | * via a "spring-loaded" popup window. |
376 | */ |
377 | static GtkWidget * = NULL; |
378 | |
379 | static gboolean popped_up = FALSE; |
380 | static gboolean = FALSE; |
381 | static guint popdown_timer = 0; |
382 | static guint = 0; |
383 | |
384 | static int |
385 | popdown_cb (gpointer data) |
386 | { |
387 | popdown_timer = 0; |
388 | |
389 | gtk_widget_hide (widget: popup_window); |
390 | popped_up = FALSE; |
391 | |
392 | return FALSE; |
393 | } |
394 | |
395 | static void |
396 | (GtkDropTarget *dest) |
397 | { |
398 | g_print (format: "popup enter\n" ); |
399 | if (!in_popup) |
400 | { |
401 | in_popup = TRUE; |
402 | if (popdown_timer) |
403 | { |
404 | g_print (format: "removed popdown\n" ); |
405 | g_source_remove (tag: popdown_timer); |
406 | popdown_timer = 0; |
407 | } |
408 | } |
409 | } |
410 | |
411 | static void |
412 | (GtkDropTarget *dest) |
413 | { |
414 | g_print (format: "popup leave\n" ); |
415 | if (in_popup) |
416 | { |
417 | in_popup = FALSE; |
418 | if (!popdown_timer) |
419 | { |
420 | g_print (format: "added popdown\n" ); |
421 | popdown_timer = g_timeout_add (interval: 500, function: popdown_cb, NULL); |
422 | } |
423 | } |
424 | } |
425 | |
426 | static gboolean |
427 | (GtkDropTarget *dest) |
428 | { |
429 | popdown_cb (NULL); |
430 | return TRUE; |
431 | } |
432 | |
433 | static gboolean |
434 | (gpointer data) |
435 | { |
436 | if (!popped_up) |
437 | { |
438 | if (!popup_window) |
439 | { |
440 | GtkWidget *button; |
441 | GtkWidget *grid; |
442 | int i, j; |
443 | |
444 | popup_window = gtk_window_new (); |
445 | |
446 | grid = gtk_grid_new (); |
447 | |
448 | for (i=0; i<3; i++) |
449 | for (j=0; j<3; j++) |
450 | { |
451 | char buffer[128]; |
452 | GtkDropTarget *dest; |
453 | |
454 | g_snprintf(string: buffer, n: sizeof(buffer), format: "%d,%d" , i, j); |
455 | button = gtk_button_new_with_label (label: buffer); |
456 | gtk_widget_set_hexpand (widget: button, TRUE); |
457 | gtk_widget_set_vexpand (widget: button, TRUE); |
458 | gtk_grid_attach (GTK_GRID (grid), child: button, column: i, row: j, width: 1, height: 1); |
459 | |
460 | dest = gtk_drop_target_new (G_TYPE_STRING, actions: GDK_ACTION_COPY | GDK_ACTION_MOVE); |
461 | g_signal_connect (dest, "enter" , G_CALLBACK (popup_enter), NULL); |
462 | g_signal_connect (dest, "leave" , G_CALLBACK (popup_leave), NULL); |
463 | g_signal_connect (dest, "drop" , G_CALLBACK (popup_drop), NULL); |
464 | gtk_widget_add_controller (widget: button, GTK_EVENT_CONTROLLER (dest)); |
465 | } |
466 | gtk_window_set_child (GTK_WINDOW (popup_window), child: grid); |
467 | } |
468 | gtk_widget_show (widget: popup_window); |
469 | popped_up = TRUE; |
470 | } |
471 | |
472 | popup_timer = FALSE; |
473 | |
474 | return FALSE; |
475 | } |
476 | |
477 | static void |
478 | popsite_enter (GtkDropControllerMotion *motion) |
479 | { |
480 | g_print (format: "popsite enter\n" ); |
481 | if (!popup_timer) |
482 | popup_timer = g_timeout_add (interval: 500, function: popup_cb, NULL); |
483 | } |
484 | |
485 | static void |
486 | popsite_leave (GtkDropControllerMotion *motion) |
487 | { |
488 | g_print (format: "popsite leave\n" ); |
489 | if (popup_timer) |
490 | { |
491 | g_source_remove (tag: popup_timer); |
492 | popup_timer = 0; |
493 | } |
494 | } |
495 | |
496 | static void |
497 | quit_cb (GtkWidget *widget, |
498 | gpointer data) |
499 | { |
500 | gboolean *done = data; |
501 | |
502 | *done = TRUE; |
503 | |
504 | g_main_context_wakeup (NULL); |
505 | } |
506 | |
507 | int |
508 | main (int argc, char **argv) |
509 | { |
510 | GtkWidget *window; |
511 | GtkWidget *grid; |
512 | GtkWidget *label; |
513 | GtkWidget *pixmap; |
514 | GtkWidget *button; |
515 | GdkPixbuf *drag_icon; |
516 | GdkTexture *texture; |
517 | GdkContentProvider *content; |
518 | GtkDragSource *source; |
519 | GtkDropTarget *dest; |
520 | GtkDropTargetAsync *async; |
521 | GtkEventController *controller; |
522 | gboolean done = FALSE; |
523 | |
524 | gtk_init (); |
525 | |
526 | window = gtk_window_new (); |
527 | g_signal_connect (window, "destroy" , |
528 | G_CALLBACK (quit_cb), &done); |
529 | |
530 | |
531 | grid = gtk_grid_new (); |
532 | gtk_window_set_child (GTK_WINDOW (window), child: grid); |
533 | |
534 | drag_icon = gdk_pixbuf_new_from_xpm_data (data: drag_icon_xpm); |
535 | texture = gdk_texture_new_for_pixbuf (pixbuf: drag_icon); |
536 | g_object_unref (object: drag_icon); |
537 | trashcan_open = gdk_pixbuf_new_from_xpm_data (data: trashcan_open_xpm); |
538 | trashcan_closed = gdk_pixbuf_new_from_xpm_data (data: trashcan_closed_xpm); |
539 | |
540 | label = gtk_label_new (str: "Drop Here\n" ); |
541 | |
542 | dest = gtk_drop_target_new (G_TYPE_STRING, actions: GDK_ACTION_COPY | GDK_ACTION_MOVE); |
543 | g_signal_connect (dest, "drop" , G_CALLBACK (label_drag_drop), NULL); |
544 | gtk_widget_add_controller (widget: label, GTK_EVENT_CONTROLLER (dest)); |
545 | |
546 | gtk_widget_set_hexpand (widget: label, TRUE); |
547 | gtk_widget_set_vexpand (widget: label, TRUE); |
548 | gtk_grid_attach (GTK_GRID (grid), child: label, column: 0, row: 0, width: 1, height: 1); |
549 | |
550 | label = gtk_label_new (str: "Popup\n" ); |
551 | |
552 | controller = gtk_drop_controller_motion_new (); |
553 | g_signal_connect (controller, "enter" , G_CALLBACK (popsite_enter), NULL); |
554 | g_signal_connect (controller, "leave" , G_CALLBACK (popsite_leave), NULL); |
555 | gtk_widget_add_controller (widget: label, controller); |
556 | |
557 | gtk_widget_set_hexpand (widget: label, TRUE); |
558 | gtk_widget_set_vexpand (widget: label, TRUE); |
559 | gtk_grid_attach (GTK_GRID (grid), child: label, column: 1, row: 1, width: 1, height: 1); |
560 | |
561 | pixmap = gtk_image_new_from_pixbuf (pixbuf: trashcan_closed); |
562 | async = gtk_drop_target_async_new (NULL, GDK_ACTION_ALL); |
563 | g_signal_connect (async, "drag-enter" , G_CALLBACK (trash_drag_enter), pixmap); |
564 | g_signal_connect (async, "drag-leave" , G_CALLBACK (trash_drag_leave), pixmap); |
565 | g_signal_connect (async, "drop" , G_CALLBACK (trash_drag_drop), pixmap); |
566 | gtk_widget_add_controller (widget: pixmap, GTK_EVENT_CONTROLLER (async)); |
567 | |
568 | gtk_widget_set_hexpand (widget: pixmap, TRUE); |
569 | gtk_widget_set_vexpand (widget: pixmap, TRUE); |
570 | gtk_grid_attach (GTK_GRID (grid), child: pixmap, column: 1, row: 0, width: 1, height: 1); |
571 | |
572 | |
573 | /* Drag site */ |
574 | |
575 | button = gtk_label_new (str: "Drag Here\n" ); |
576 | |
577 | source = gtk_drag_source_new (); |
578 | content = gdk_content_provider_new_typed (G_TYPE_STRING, "I'm data!" ); |
579 | gtk_drag_source_set_content (source, content); |
580 | g_object_unref (object: content); |
581 | gtk_drag_source_set_actions (source, actions: GDK_ACTION_COPY|GDK_ACTION_MOVE); |
582 | gtk_widget_add_controller (widget: button, GTK_EVENT_CONTROLLER (source)); |
583 | gtk_drag_source_set_icon (source, paintable: GDK_PAINTABLE (ptr: texture), hot_x: 0, hot_y: 0); |
584 | |
585 | g_object_unref (object: texture); |
586 | |
587 | gtk_widget_set_hexpand (widget: button, TRUE); |
588 | gtk_widget_set_vexpand (widget: button, TRUE); |
589 | gtk_grid_attach (GTK_GRID (grid), child: button, column: 0, row: 1, width: 1, height: 1); |
590 | |
591 | gtk_widget_show (widget: window); |
592 | |
593 | while (!done) |
594 | g_main_context_iteration (NULL, TRUE); |
595 | |
596 | return 0; |
597 | } |
598 | |