]> git.saurik.com Git - wxWidgets.git/blob - utils/wxPython/demo/CustomDragAndDrop.py
A bugfix in the wxTreeCtrl.GetItem wrapper
[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 text = 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.\n\n"
177 "The lower window is accepting a\n"
178 "custom data type that is a pickled\n"
179 "Python list of lines data.")
180 sizer.Add(text, 1, wxALL, 10)
181
182 insizer = wxBoxSizer(wxVERTICAL)
183 insizer.Add(DoodlePad(self, log), 1, wxEXPAND|wxALL, 5)
184 insizer.Add(DoodleViewer(self, log), 1, wxEXPAND|wxALL, 5)
185
186 sizer.Add(insizer, 1, wxEXPAND)
187 self.SetAutoLayout(true)
188 self.SetSizer(sizer)
189
190
191
192
193 #----------------------------------------------------------------------
194 #----------------------------------------------------------------------
195
196 class TestPanel(wxPanel):
197 def __init__(self, parent, log):
198 wxPanel.__init__(self, parent, -1)
199
200 self.SetAutoLayout(true)
201 sizer = wxBoxSizer(wxVERTICAL)
202
203 msg = "Custom Drag-And-Drop"
204 text = wxStaticText(self, -1, "", style=wxALIGN_CENTRE)
205 text.SetFont(wxFont(24, wxSWISS, wxNORMAL, wxBOLD, false))
206 text.SetLabel(msg)
207 w,h = text.GetTextExtent(msg)
208 text.SetSize(wxSize(w,h+1))
209 text.SetForegroundColour(wxBLUE)
210 sizer.Add(text, 0, wxEXPAND|wxALL, 5)
211 sizer.Add(wxStaticLine(self, -1), 0, wxEXPAND)
212
213 sizer.Add(CustomDnDPanel(self, log), 1, wxEXPAND)
214
215 self.SetSizer(sizer)
216
217
218 #----------------------------------------------------------------------
219
220 def runTest(frame, nb, log):
221 win = TestPanel(nb, log)
222 return win
223
224
225 if __name__ == '__main__':
226 import sys
227 class DummyLog:
228 def WriteText(self, text):
229 sys.stdout.write(text)
230
231 class TestApp(wxApp):
232 def OnInit(self):
233 self.MakeFrame()
234 return true
235
236 def MakeFrame(self, event=None):
237 frame = wxFrame(None, -1, "Custom Drag and Drop", size=(550,400))
238 menu = wxMenu()
239 menu.Append(6543, "Window")
240 mb = wxMenuBar()
241 mb.Append(menu, "New")
242 frame.SetMenuBar(mb)
243 EVT_MENU(frame, 6543, self.MakeFrame)
244 panel = TestPanel(frame, DummyLog())
245 frame.Show(true)
246 self.SetTopWindow(frame)
247
248
249
250 app = TestApp(0)
251 app.MainLoop()
252
253 #----------------------------------------------------------------------
254
255
256
257
258
259
260
261
262
263
264
265
266 overview = """\
267 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.
268
269 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.
270
271 The two data objects are combined in a wxDataObjectComposite and the rest is handled by the framework.
272 """
273