]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/demo/CustomDragAndDrop.py
1 # 11/5/2003 - Modified by grimmtooth@softhome.net (Jeff Grimmett)
3 # o Updated for wx namespace
5 # 11/24/2003 - Modified by grimmtooth@softhome.net (Jeff Grimmett)
7 # o Issues around line 167. I'm stuck.
13 #----------------------------------------------------------------------
16 class DoodlePad(wx
.Window
):
17 def __init__(self
, parent
, log
):
18 wx
.Window
.__init
__(self
, parent
, -1, style
=wx
.SUNKEN_BORDER
)
20 self
.SetBackgroundColour(wx
.WHITE
)
25 wx
.EVT_LEFT_DOWN(self
, self
.OnLeftDown
)
26 wx
.EVT_LEFT_UP(self
, self
.OnLeftUp
)
27 wx
.EVT_RIGHT_UP(self
, self
.OnRightUp
)
28 wx
.EVT_MOTION(self
, self
.OnMotion
)
29 wx
.EVT_PAINT(self
, self
.OnPaint
)
32 def SetMode(self
, mode
):
34 if self
.mode
== "Draw":
35 self
.SetCursor(wx
.StockCursor(wx
.CURSOR_PENCIL
))
37 self
.SetCursor(wx
.STANDARD_CURSOR
)
40 def OnPaint(self
, event
):
42 self
.DrawSavedLines(dc
)
44 def DrawSavedLines(self
, dc
):
46 dc
.SetPen(wx
.Pen(wx
.BLUE
, 3))
47 for line
in self
.lines
:
49 dc
.DrawLineXY(*coords
)
53 def OnLeftDown(self
, event
):
54 if self
.mode
== "Drag":
55 self
.StartDragOpperation()
56 elif self
.mode
== "Draw":
58 self
.x
, self
.y
= event
.GetPositionTuple()
62 self
.log
.write("unknown mode!\n")
65 def OnLeftUp(self
, event
):
66 self
.lines
.append(self
.curLine
)
70 def OnRightUp(self
, event
):
74 def OnMotion(self
, event
):
75 if event
.Dragging() and not self
.mode
== "Drag":
76 dc
= wx
.ClientDC(self
)
78 dc
.SetPen(wx
.Pen(wx
.BLUE
, 3))
79 coords
= ((self
.x
, self
.y
), event
.GetPosition())
80 self
.curLine
.append(coords
)
81 dc
.DrawLineXY(*coords
)
82 self
.x
, self
.y
= event
.GetPositionTuple()
86 def StartDragOpperation(self
):
87 # pickle the lines list
88 linesdata
= cPickle
.dumps(self
.lines
, 1)
90 # create our own data format and use it in a
92 ldata
= wx
.CustomDataObject(wx
.CustomDataFormat("DoodleLines"))
93 ldata
.SetData(linesdata
)
95 # Also create a Bitmap version of the drawing
97 bmp
= wx
.EmptyBitmap(size
.width
, size
.height
)
100 dc
.SetBackground(wx
.WHITE_BRUSH
)
102 self
.DrawSavedLines(dc
)
103 dc
.SelectObject(wx
.NullBitmap
)
105 # Now make a data object for the bitmap and also a composite
106 # data object holding both of the others.
107 bdata
= wx
.BitmapDataObject(bmp
)
108 data
= wx
.DataObjectComposite()
112 # And finally, create the drop source and begin the drag
113 # and drop opperation
114 dropSource
= wx
.DropSource(self
)
115 dropSource
.SetData(data
)
116 self
.log
.WriteText("Begining DragDrop\n")
117 result
= dropSource
.DoDragDrop(wx
.Drag_AllowMove
)
118 self
.log
.WriteText("DragDrop completed: %d\n" % result
)
120 if result
== wx
.DragMove
:
125 #----------------------------------------------------------------------
128 class DoodleDropTarget(wx
.PyDropTarget
):
129 def __init__(self
, window
, log
):
130 wx
.PyDropTarget
.__init
__(self
)
134 # specify the type of data we will accept
135 self
.df
= wx
.CustomDataFormat("DoodleLines")
136 self
.data
= wx
.CustomDataObject(self
.df
)
137 self
.SetDataObject(self
.data
)
140 # some virtual methods that track the progress of the drag
141 def OnEnter(self
, x
, y
, d
):
142 self
.log
.WriteText("OnEnter: %d, %d, %d\n" % (x
, y
, d
))
146 self
.log
.WriteText("OnLeave\n")
148 def OnDrop(self
, x
, y
):
149 self
.log
.WriteText("OnDrop: %d %d\n" % (x
, y
))
152 def OnDragOver(self
, x
, y
, d
):
153 #self.log.WriteText("OnDragOver: %d, %d, %d\n" % (x, y, d))
155 # The value returned here tells the source what kind of visual
156 # feedback to give. For example, if wxDragCopy is returned then
157 # only the copy cursor will be shown, even if the source allows
158 # moves. You can use the passed in (x,y) to determine what kind
159 # of feedback to give. In this case we return the suggested value
160 # which is based on whether the Ctrl key is pressed.
165 # Called when OnDrop returns True. We need to get the data and
166 # do something with it.
167 def OnData(self
, x
, y
, d
):
168 self
.log
.WriteText("OnData: %d, %d, %d\n" % (x
, y
, d
))
170 # copy the data from the drag source to our data object
172 # convert it back to a list of lines and give it to the viewer
173 linesdata
= self
.data
.GetData()
174 lines
= wx
.InputStream(cPickle
.loads(linesdata
))
175 self
.dv
.SetLines(lines
)
177 # what is returned signals the source what to do
178 # with the original data (move, copy, etc.) In this
179 # case we just return the suggested value given to us.
184 class DoodleViewer(wx
.Window
):
185 def __init__(self
, parent
, log
):
186 wx
.Window
.__init
__(self
, parent
, -1, style
=wx
.SUNKEN_BORDER
)
188 self
.SetBackgroundColour(wx
.WHITE
)
191 dt
= DoodleDropTarget(self
, log
)
192 self
.SetDropTarget(dt
)
193 wx
.EVT_PAINT(self
, self
.OnPaint
)
196 def SetLines(self
, lines
):
200 def OnPaint(self
, event
):
201 dc
= wx
.PaintDC(self
)
202 self
.DrawSavedLines(dc
)
204 def DrawSavedLines(self
, dc
):
206 dc
.SetPen(wx
.Pen(wx
.RED
, 3))
208 for line
in self
.lines
:
210 dc
.DrawLineXY(*coords
)
213 #----------------------------------------------------------------------
215 class CustomDnDPanel(wx
.Panel
):
216 def __init__(self
, parent
, log
):
217 wx
.Panel
.__init
__(self
, parent
, -1)
219 self
.SetFont(wx
.Font(10, wx
.SWISS
, wx
.NORMAL
, wx
.BOLD
, False))
222 text1
= wx
.StaticText(self
, -1,
223 "Draw a little picture in this window\n"
224 "then switch the mode below and drag the\n"
225 "picture to the lower window or to another\n"
226 "application that accepts BMP's as a drop\n"
230 rb1
= wx
.RadioButton(self
, -1, "Draw", style
=wx
.RB_GROUP
)
232 rb2
= wx
.RadioButton(self
, -1, "Drag")
235 text2
= wx
.StaticText(self
, -1,
236 "The lower window is accepting a\n"
237 "custom data type that is a pickled\n"
238 "Python list of lines data.")
240 self
.pad
= DoodlePad(self
, log
)
241 view
= DoodleViewer(self
, log
)
244 sizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
245 box
= wx
.BoxSizer(wx
.VERTICAL
)
246 rbox
= wx
.BoxSizer(wx
.HORIZONTAL
)
250 box
.Add(text1
, 0, wx
.ALL
, 10)
251 box
.Add(rbox
, 0, wx
.ALIGN_CENTER
)
253 box
.Add(text2
, 0, wx
.ALL
, 10)
257 dndsizer
= wx
.BoxSizer(wx
.VERTICAL
)
258 dndsizer
.Add(self
.pad
, 1, wx
.EXPAND|wx
.ALL
, 5)
259 dndsizer
.Add(view
, 1, wx
.EXPAND|wx
.ALL
, 5)
261 sizer
.Add(dndsizer
, 1, wx
.EXPAND
)
263 self
.SetAutoLayout(True)
267 wx
.EVT_RADIOBUTTON(self
, rb1
.GetId(), self
.OnRadioButton
)
268 wx
.EVT_RADIOBUTTON(self
, rb2
.GetId(), self
.OnRadioButton
)
271 def OnRadioButton(self
, evt
):
272 rb
= self
.FindWindowById(evt
.GetId())
273 self
.pad
.SetMode(rb
.GetLabel())
276 #----------------------------------------------------------------------
277 #----------------------------------------------------------------------
279 class TestPanel(wx
.Panel
):
280 def __init__(self
, parent
, log
):
281 wx
.Panel
.__init
__(self
, parent
, -1)
283 self
.SetAutoLayout(True)
284 sizer
= wx
.BoxSizer(wx
.VERTICAL
)
286 msg
= "Custom Drag-And-Drop"
287 text
= wx
.StaticText(self
, -1, "", style
=wx
.ALIGN_CENTRE
)
288 text
.SetFont(wx
.Font(24, wx
.SWISS
, wx
.NORMAL
, wx
.BOLD
, False))
290 w
,h
= text
.GetTextExtent(msg
)
291 text
.SetSize(wx
.Size(w
,h
+1))
292 text
.SetForegroundColour(wx
.BLUE
)
293 sizer
.Add(text
, 0, wx
.EXPAND|wx
.ALL
, 5)
294 sizer
.Add(wx
.StaticLine(self
, -1), 0, wx
.EXPAND
)
296 sizer
.Add(CustomDnDPanel(self
, log
), 1, wx
.EXPAND
)
301 #----------------------------------------------------------------------
303 def runTest(frame
, nb
, log
):
304 #win = TestPanel(nb, log)
305 win
= CustomDnDPanel(nb
, log
)
309 if __name__
== '__main__':
313 def WriteText(self
, text
):
314 sys
.stdout
.write(text
)
316 class TestApp(wx
.App
):
318 wx
.InitAllImageHandlers()
322 def MakeFrame(self
, event
=None):
323 frame
= wx
.Frame(None, -1, "Custom Drag and Drop", size
=(550,400))
325 menu
.Append(6543, "Window")
327 mb
.Append(menu
, "New")
329 wx
.EVT_MENU(frame
, 6543, self
.MakeFrame
)
330 panel
= TestPanel(frame
, DummyLog())
332 self
.SetTopWindow(frame
)
334 #----------------------------------------------------------------------
339 #----------------------------------------------------------------------
342 overview
= """<html><body>
343 This demo shows Drag and Drop using a custom data type and a custom
344 data object. A type called "DoodleLines" is created and a Python
345 Pickle of a list is actually transfered in the drag and drop
348 A second data object is also created containing a bitmap of the image
349 and is made available to any drop target that accepts bitmaps, such as
352 The two data objects are combined in a wx.DataObjectComposite and the
353 rest is handled by the framework.