]> git.saurik.com Git - wxWidgets.git/blob - utils/wxPython/demo/CustomDragAndDrop.py
Fixed bug in DnD. wxDragSource will now delete itself when done.
[wxWidgets.git] / utils / wxPython / demo / CustomDragAndDrop.py
1
2 from wxPython.wx import *
3
4 import cPickle
5
6 #----------------------------------------------------------------------
7
8
9 class DoodlePad(wxWindow):
10 def __init__(self, parent, log):
11 wxWindow.__init__(self, parent, -1, style=wxSUNKEN_BORDER)
12 self.log = log
13 self.SetBackgroundColour(wxWHITE)
14 self.lines = []
15 self.x = self.y = 0
16 self.SetCursor(wxStockCursor(wxCURSOR_PENCIL))
17
18 EVT_LEFT_DOWN(self, self.OnLeftDown)
19 EVT_LEFT_UP(self, self.OnLeftUp)
20 EVT_RIGHT_UP(self, self.OnRightUp)
21 EVT_MOTION(self, self.OnMotion)
22
23
24 def OnPaint(self, event):
25 dc = wxPaintDC(self)
26 self.DrawSavedLines(dc)
27
28 def DrawSavedLines(self, dc):
29 dc.BeginDrawing()
30 dc.SetPen(wxPen(wxBLUE, 3))
31 for line in self.lines:
32 for coords in line:
33 apply(dc.DrawLine, coords)
34 dc.EndDrawing()
35
36
37 def OnLeftDown(self, event):
38 if event.ControlDown():
39 self.StartDragOpperation()
40 else:
41 self.curLine = []
42 self.x, self.y = event.GetPositionTuple()
43 self.CaptureMouse()
44
45
46 def OnLeftUp(self, event):
47 self.lines.append(self.curLine)
48 self.curLine = []
49 self.ReleaseMouse()
50
51 def OnRightUp(self, event):
52 self.lines = []
53 self.Refresh()
54
55 def OnMotion(self, event):
56 if event.Dragging() and not event.ControlDown():
57 dc = wxClientDC(self)
58 dc.BeginDrawing()
59 dc.SetPen(wxPen(wxBLUE, 3))
60 coords = (self.x, self.y) + event.GetPositionTuple()
61 self.curLine.append(coords)
62 apply(dc.DrawLine, coords)
63 self.x, self.y = event.GetPositionTuple()
64 dc.EndDrawing()
65
66
67 def StartDragOpperation(self):
68 # pickle the lines list
69 linesdata = cPickle.dumps(self.lines, 1)
70
71 # create our own data format and use it in a
72 # custom data object
73 ldata = wxCustomDataObject(wxCustomDataFormat("DoodleLines"))
74 ldata.SetData(linesdata)
75
76 # Also create a Bitmap version of the drawing
77 size = self.GetSize()
78 bmp = wxEmptyBitmap(size.width, size.height)
79 dc = wxMemoryDC()
80 dc.SelectObject(bmp)
81 dc.SetBackground(wxWHITE_BRUSH)
82 dc.Clear()
83 self.DrawSavedLines(dc)
84 dc.SelectObject(wxNullBitmap)
85
86 # Now make a data object for the bitmap and also a composite
87 # data object holding both of the others.
88 bdata = wxBitmapDataObject(bmp)
89 data = wxDataObjectComposite()
90 data.Add(ldata)
91 data.Add(bdata)
92
93 # And finally, create the drop source and begin the drag
94 # and drop opperation
95 dropSource = wxDropSource(self)
96 dropSource.SetData(data)
97 self.log.WriteText("Begining DragDrop\n")
98 result = dropSource.DoDragDrop()
99 self.log.WriteText("DragDrop completed: %d\n" % result)
100
101 #----------------------------------------------------------------------
102
103
104 class DoodleDropTarget(wxPyDropTarget):
105 def __init__(self, window, log):
106 wxPyDropTarget.__init__(self)
107 self.log = log
108 self.dv = window
109 self.data = wxCustomDataObject(wxCustomDataFormat("DoodleLines"))
110 self.SetDataObject(self.data)
111
112 def OnEnter(self, x, y, d):
113 self.log.WriteText("OnEnter: %d, %d, %d\n" % (x, y, d))
114 return wxDragCopy
115
116 def OnLeave(self):
117 self.log.WriteText("OnLeave\n")
118
119 def OnDrop(self, x, y):
120 self.log.WriteText("OnDrop: %d %d\n" % (x, y))
121 return true
122
123 def OnData(self, x, y, d):
124 self.log.WriteText("OnData: %d, %d, %d\n" % (x, y, d))
125 if self.GetData():
126 linesdata = self.data.GetData()
127 lines = cPickle.loads(linesdata)
128 self.dv.SetLines(lines)
129 return d
130
131 #def OnDragOver(self, x, y, d):
132 # self.log.WriteText("OnDragOver: %d, %d, %d\n" % (x, y, d))
133 # return wxDragCopy
134
135
136
137 class DoodleViewer(wxWindow):
138 def __init__(self, parent, log):
139 wxWindow.__init__(self, parent, -1, style=wxSUNKEN_BORDER)
140 self.log = log
141 self.SetBackgroundColour(wxWHITE)
142 self.lines = []
143 self.x = self.y = 0
144 dt = DoodleDropTarget(self, log)
145 self.SetDropTarget(dt)
146
147 def SetLines(self, lines):
148 self.lines = lines
149 self.Refresh()
150
151 def OnPaint(self, event):
152 dc = wxPaintDC(self)
153 self.DrawSavedLines(dc)
154
155 def DrawSavedLines(self, dc):
156 dc.BeginDrawing()
157 dc.SetPen(wxPen(wxRED, 3))
158 for line in self.lines:
159 for coords in line:
160 apply(dc.DrawLine, coords)
161 dc.EndDrawing()
162
163 #----------------------------------------------------------------------
164
165 class CustomDnDPanel(wxPanel):
166 def __init__(self, parent, log):
167 wxPanel.__init__(self, parent, -1)
168
169 self.SetFont(wxFont(10, wxSWISS, wxNORMAL, wxBOLD, false))
170
171 sizer = wxBoxSizer(wxHORIZONTAL)
172 sizer.Add(wxStaticText(self, -1,
173 "Draw a little picture in this window\n"
174 "then Ctrl-Drag it to the lower \n"
175 "window or to another application\n"
176 "that accepts BMP's as a drop target."),
177 1, wxEXPAND|wxALL, 10)
178
179 insizer = wxBoxSizer(wxVERTICAL)
180 insizer.Add(DoodlePad(self, log), 1, wxEXPAND|wxALL, 5)
181 insizer.Add(DoodleViewer(self, log), 1, wxEXPAND|wxALL, 5)
182
183 sizer.Add(insizer, 1, wxEXPAND)
184 self.SetAutoLayout(true)
185 self.SetSizer(sizer)
186
187
188
189
190 #----------------------------------------------------------------------
191 #----------------------------------------------------------------------
192
193 class TestPanel(wxPanel):
194 def __init__(self, parent, log):
195 wxPanel.__init__(self, parent, -1)
196
197 self.SetAutoLayout(true)
198 sizer = wxBoxSizer(wxVERTICAL)
199
200 msg = "Custom Drag-And-Drop"
201 text = wxStaticText(self, -1, "", style=wxALIGN_CENTRE)
202 text.SetFont(wxFont(24, wxSWISS, wxNORMAL, wxBOLD, false))
203 text.SetLabel(msg)
204 w,h = text.GetTextExtent(msg)
205 text.SetSize(wxSize(w,h+1))
206 text.SetForegroundColour(wxBLUE)
207 sizer.Add(text, 0, wxEXPAND|wxALL, 5)
208 sizer.Add(wxStaticLine(self, -1), 0, wxEXPAND)
209
210 sizer.Add(CustomDnDPanel(self, log), 1, wxEXPAND)
211
212 self.SetSizer(sizer)
213
214
215 #----------------------------------------------------------------------
216
217 def runTest(frame, nb, log):
218 win = TestPanel(nb, log)
219 return win
220
221 #----------------------------------------------------------------------
222
223
224
225
226
227
228
229
230
231
232
233
234 overview = """\
235 This demo shows Drag and Drop using a custom data type and a custom data object. A type called "DoodleLines" is created and a Python Pickle of a list is actually transfered in the drag and drop opperation.
236
237 A second data object is also created containing a bitmap of the image and is made available to any drop target that accepts bitmaps, such as MS Word.
238
239 The two data objects are combined in a wxDataObjectComposite and the rest is handled by the framework.
240 """