summaryrefslogtreecommitdiff
path: root/examples/pygtk-demo/demos/dnd.py
blob: b1f386bb5f077845a733f6ac285b56a1dba6ed6c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#!/usr/bin/env python
'''Drag and Drop Test

This is a test of the drag and drop capabilities of gtk.  It is a
fairly straight forward port of the example distributed with gtk.

FIXME: there are still a few things missing since I converted the
GdkDragContext wrapper to being a GObject.'''

description = 'Drag and Drop'

import gtk
from dndpixmap import *

trashcan_open = None
trashcan_open_mask = None
trashcan_closed = None
trashcan_closed_mask = None

have_drag = gtk.FALSE
popped_up = gtk.FALSE
in_popup = gtk.FALSE
popup_timer = 0
popdown_timer = 0
popup_win = None


TARGET_STRING = 0
TARGET_ROOTWIN = 1

target = [
    ('STRING', 0, TARGET_STRING),
    ('text/plain', 0, TARGET_STRING),
    ('application/x-rootwin-drop', 0, TARGET_ROOTWIN)]

def target_drag_leave(w, context, time):
    global trashcan_closed, trashcan_closed_mask
    global have_drag
    print 'leave'
    have_drag = gtk.FALSE
    w.set_from_pixmap(trashcan_closed, trashcan_closed_mask)
    
def target_drag_motion(w, context, x, y, time):
    global trashcan_open, trashcan_open_mask
    global have_drag
    if not have_drag:
	have_drag = gtk.TRUE
	w.set_from_pixmap(trashcan_open, trashcan_open_mask)
    source_widget = context.get_source_widget()
    print 'motion, source ',
    if source_widget:
	print source_widget.__class__.__name__
    else:
	print 'unknown'
    context.drag_status(context.suggested_action, time)
    return gtk.TRUE

def target_drag_drop(w, context, x, y, time):
    global trashcan_closed, trashcan_closed_mask
    global have_drag
    print 'drop'
    have_drag = gtk.FALSE
    w.set_from_pixmap(trashcan_closed, trashcan_closed_mask)
    if context.targets:
	w.drag_get_data(context, context.targets[0], time)
	return gtk.TRUE
    return gtk.FALSE

def target_drag_data_received(w, context, x, y, data, info, time):
    if data.format == 8:
	print 'Received "%s" in trashcan' % data.data
	context.finish(gtk.TRUE, gtk.FALSE, time)
    else:
	context.finish(gtk.FALSE, gtk.FALSE, time)
        
def label_drag_data_received(w, context, x, y, data, info, time):
    if data and data.format == 8:
	print 'Received "%s" in label' % data.data
	context.finish(gtk.TRUE, gtk.FALSE, time)
    else:
	context.finish(gtk.FALSE, gtk.FALSE, time)
        
def source_drag_data_get(w, context, selection_data, info, time):
    if info == TARGET_ROOTWIN:
	print 'I was dropped on the rootwin'
    else:
	selection_data.set(selection_data.target, 8, "I'm Data!")	

def popdown_cb():
    global popdown_timer, popped_up
    global popup_win
    popdown_timer = 0	
    popup_win.hide()
    popped_up = gtk.FALSE
    return gtk.FALSE

def popup_motion(w, context, x, y, time):
    global in_popup, popdown_timer
    if not in_popup:
	in_popup = gtk.TRUE
	if popdown_timer:
	    print 'removed popdown'
	    gtk.timeout_remove(popdown_timer)
	    popdown_timer = 0
    return gtk.TRUE

def popup_leave(w, context, time):
    global in_popup, popdown_timer
    print 'popup_leave'
    if in_popup:
	in_popup = gtk.FALSE
	if not popdown_timer:
	    print 'added popdown'
	    popdown_timer = gtk.timeout_add(500, popdown_cb)
            
def popup_cb():
    global popped_up, popup_win
    global popup_timer, popdown_timer
    if not popped_up:
	if not popup_win:
	    popup_win = gtk.Window(gtk.WINDOW_POPUP)
	    popup_win.set_position(gtk.WIN_POS_MOUSE)
	    table = gtk.Table(3, 3)
	    for k in range(9):
		i, j = divmod(k, 3)
		b = gtk.Button("%d,%d" % (i,j))
		table.attach(b, i,i+1,j,j+1)
		b.drag_dest_set(gtk.DEST_DEFAULT_ALL, target, 
				gtk.gdk.ACTION_COPY | gtk.gdk.ACTION_MOVE)
		b.connect('drag_motion', popup_motion)
		b.connect('drag_leave', popup_leave)
	    table.show_all()
	    popup_win.add(table)
	popup_win.show()
	popped_up = gtk.TRUE
    popdown_timer = gtk.timeout_add(500, popdown_cb)
    print 'added popdown'
    popup_timer = 0
    return gtk.FALSE

def popsite_motion(w, context, x, y, time):
    global popup_timer
    if not popup_timer:
	popup_timer = gtk.timeout_add(500, popup_cb)
    return gtk.TRUE

def popsite_leave(w, context, time):
    global popup_timer
    if popup_timer:
	gtk.timeout_remove(popup_timer)
	popup_timer = 0
        
def source_drag_data_delete(w, context, data):
    print 'Delete the data!'
    
def create_pixmap(widget, xpm):
    return gtk.gdk.pixmap_colormap_create_from_xpm_d(None,
                                                     widget.get_colormap(),
                                                     None, xpm)

def main():
    global trashcan_open, trashcan_open_mask
    global trashcan_closed, trashcan_closed_mask
    global drag_icon, drag_mask
    win = gtk.Window()
    win.connect('destroy', lambda win: gtk.main_quit())
    table = gtk.Table(2,2)
    win.add(table)
    drag_icon, drag_mask = create_pixmap(win, drag_icon_xpm)
    trashcan_open, trashcan_open_mask = create_pixmap(win, trashcan_open_xpm)
    trashcan_closed, trashcan_closed_mask = create_pixmap(win, trashcan_closed_xpm)
    label = gtk.Label('Drop Here!\n')
    label.drag_dest_set(gtk.DEST_DEFAULT_ALL, target[:-1],
			gtk.gdk.ACTION_COPY | gtk.gdk.ACTION_MOVE)
    label.connect('drag_data_received', label_drag_data_received)
    table.attach(label, 0, 1, 0, 1)

    label = gtk.Label('Popup\n')
    label.drag_dest_set(gtk.DEST_DEFAULT_ALL, target[:-1],
			gtk.gdk.ACTION_COPY | gtk.gdk.ACTION_MOVE)
    table.attach(label, 1, 2, 1, 2)
    label.connect('drag_motion', popsite_motion)
    label.connect('drag_leave', popsite_leave)

    image = gtk.Image()
    image.set_from_pixmap(trashcan_closed, trashcan_closed_mask)
    image.drag_dest_set(0, [], 0)
    table.attach(image, 1, 2, 0, 1)
    image.connect('drag_leave', target_drag_leave)
    image.connect('drag_motion', target_drag_motion)
    image.connect('drag_drop', target_drag_drop)
    image.connect('drag_data_received', target_drag_data_received)

    b = gtk.Button('Drag Here\n')
    b.drag_source_set(gtk.gdk.BUTTON1_MASK | gtk.gdk.BUTTON3_MASK,
		      target, gtk.gdk.ACTION_COPY | gtk.gdk.ACTION_MOVE)
    b.drag_source_set_icon(win.get_colormap(), drag_icon, drag_mask)
    table.attach(b, 0, 1, 1, 2)
    b.connect('drag_data_get', source_drag_data_get)
    b.connect('drag_data_delete', source_drag_data_delete)
    win.show_all()
    gtk.main()
    
if __name__ == '__main__':
    main()