]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/demo/CustomDragAndDrop.py
5 #----------------------------------------------------------------------
8 class DoodlePad(wx
.Window
):
9 def __init__(self
, parent
, log
):
10 wx
.Window
.__init
__(self
, parent
, -1, style
=wx
.SUNKEN_BORDER
)
12 self
.SetBackgroundColour(wx
.WHITE
)
17 self
.Bind(wx
.EVT_LEFT_DOWN
, self
.OnLeftDown
)
18 self
.Bind(wx
.EVT_LEFT_UP
, self
.OnLeftUp
)
19 self
.Bind(wx
.EVT_RIGHT_UP
, self
.OnRightUp
)
20 self
.Bind(wx
.EVT_MOTION
, self
.OnMotion
)
21 self
.Bind(wx
.EVT_PAINT
, self
.OnPaint
)
24 def SetMode(self
, mode
):
26 if self
.mode
== "Draw":
27 self
.SetCursor(wx
.StockCursor(wx
.CURSOR_PENCIL
))
29 self
.SetCursor(wx
.STANDARD_CURSOR
)
32 def OnPaint(self
, event
):
34 self
.DrawSavedLines(dc
)
36 def DrawSavedLines(self
, dc
):
38 dc
.SetPen(wx
.Pen(wx
.BLUE
, 3))
39 for line
in self
.lines
:
45 def OnLeftDown(self
, event
):
46 if self
.mode
== "Drag":
47 self
.StartDragOpperation()
48 elif self
.mode
== "Draw":
50 self
.x
, self
.y
= event
.GetPositionTuple()
54 self
.log
.write("unknown mode!\n")
57 def OnLeftUp(self
, event
):
59 self
.lines
.append(self
.curLine
)
63 def OnRightUp(self
, event
):
67 def OnMotion(self
, event
):
68 if self
.HasCapture() and event
.Dragging() and not self
.mode
== "Drag":
69 dc
= wx
.ClientDC(self
)
71 dc
.SetPen(wx
.Pen(wx
.BLUE
, 3))
72 coords
= (self
.x
, self
.y
) + event
.GetPositionTuple()
73 self
.curLine
.append(coords
)
75 self
.x
, self
.y
= event
.GetPositionTuple()
79 def StartDragOpperation(self
):
80 # pickle the lines list
81 linesdata
= cPickle
.dumps(self
.lines
, 1)
83 # create our own data format and use it in a
85 ldata
= wx
.CustomDataObject("DoodleLines")
86 ldata
.SetData(linesdata
)
88 # Also create a Bitmap version of the drawing
90 bmp
= wx
.EmptyBitmap(size
.width
, size
.height
)
93 dc
.SetBackground(wx
.WHITE_BRUSH
)
95 self
.DrawSavedLines(dc
)
96 dc
.SelectObject(wx
.NullBitmap
)
98 # Now make a data object for the bitmap and also a composite
99 # data object holding both of the others.
100 bdata
= wx
.BitmapDataObject(bmp
)
101 data
= wx
.DataObjectComposite()
105 # And finally, create the drop source and begin the drag
106 # and drop opperation
107 dropSource
= wx
.DropSource(self
)
108 dropSource
.SetData(data
)
109 self
.log
.WriteText("Begining DragDrop\n")
110 result
= dropSource
.DoDragDrop(wx
.Drag_AllowMove
)
111 self
.log
.WriteText("DragDrop completed: %d\n" % result
)
113 if result
== wx
.DragMove
:
118 #----------------------------------------------------------------------
121 class DoodleDropTarget(wx
.PyDropTarget
):
122 def __init__(self
, window
, log
):
123 wx
.PyDropTarget
.__init
__(self
)
127 # specify the type of data we will accept
128 self
.data
= wx
.CustomDataObject("DoodleLines")
129 self
.SetDataObject(self
.data
)
132 # some virtual methods that track the progress of the drag
133 def OnEnter(self
, x
, y
, d
):
134 self
.log
.WriteText("OnEnter: %d, %d, %d\n" % (x
, y
, d
))
138 self
.log
.WriteText("OnLeave\n")
140 def OnDrop(self
, x
, y
):
141 self
.log
.WriteText("OnDrop: %d %d\n" % (x
, y
))
144 def OnDragOver(self
, x
, y
, d
):
145 #self.log.WriteText("OnDragOver: %d, %d, %d\n" % (x, y, d))
147 # The value returned here tells the source what kind of visual
148 # feedback to give. For example, if wxDragCopy is returned then
149 # only the copy cursor will be shown, even if the source allows
150 # moves. You can use the passed in (x,y) to determine what kind
151 # of feedback to give. In this case we return the suggested value
152 # which is based on whether the Ctrl key is pressed.
157 # Called when OnDrop returns True. We need to get the data and
158 # do something with it.
159 def OnData(self
, x
, y
, d
):
160 self
.log
.WriteText("OnData: %d, %d, %d\n" % (x
, y
, d
))
162 # copy the data from the drag source to our data object
164 # convert it back to a list of lines and give it to the viewer
165 linesdata
= self
.data
.GetData()
166 lines
= cPickle
.loads(linesdata
)
167 self
.dv
.SetLines(lines
)
169 # what is returned signals the source what to do
170 # with the original data (move, copy, etc.) In this
171 # case we just return the suggested value given to us.
176 class DoodleViewer(wx
.Window
):
177 def __init__(self
, parent
, log
):
178 wx
.Window
.__init
__(self
, parent
, -1, style
=wx
.SUNKEN_BORDER
)
180 self
.SetBackgroundColour(wx
.WHITE
)
183 dt
= DoodleDropTarget(self
, log
)
184 self
.SetDropTarget(dt
)
185 self
.Bind(wx
.EVT_PAINT
, self
.OnPaint
)
188 def SetLines(self
, lines
):
192 def OnPaint(self
, event
):
193 dc
= wx
.PaintDC(self
)
194 self
.DrawSavedLines(dc
)
196 def DrawSavedLines(self
, dc
):
198 dc
.SetPen(wx
.Pen(wx
.RED
, 3))
200 for line
in self
.lines
:
205 #----------------------------------------------------------------------
207 class CustomDnDPanel(wx
.Panel
):
208 def __init__(self
, parent
, log
):
209 wx
.Panel
.__init
__(self
, parent
, -1)
211 self
.SetFont(wx
.Font(10, wx
.SWISS
, wx
.NORMAL
, wx
.BOLD
, False))
214 text1
= wx
.StaticText(self
, -1,
215 "Draw a little picture in this window\n"
216 "then switch the mode below and drag the\n"
217 "picture to the lower window or to another\n"
218 "application that accepts Bitmaps as a\n"
222 rb1
= wx
.RadioButton(self
, -1, "Draw", style
=wx
.RB_GROUP
)
224 rb2
= wx
.RadioButton(self
, -1, "Drag")
227 text2
= wx
.StaticText(self
, -1,
228 "The lower window is accepting a\n"
229 "custom data type that is a pickled\n"
230 "Python list of lines data.")
232 self
.pad
= DoodlePad(self
, log
)
233 view
= DoodleViewer(self
, log
)
236 sizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
237 box
= wx
.BoxSizer(wx
.VERTICAL
)
238 rbox
= wx
.BoxSizer(wx
.HORIZONTAL
)
242 box
.Add(text1
, 0, wx
.ALL
, 10)
243 box
.Add(rbox
, 0, wx
.ALIGN_CENTER
)
245 box
.Add(text2
, 0, wx
.ALL
, 10)
249 dndsizer
= wx
.BoxSizer(wx
.VERTICAL
)
250 dndsizer
.Add(self
.pad
, 1, wx
.EXPAND|wx
.ALL
, 5)
251 dndsizer
.Add(view
, 1, wx
.EXPAND|wx
.ALL
, 5)
253 sizer
.Add(dndsizer
, 1, wx
.EXPAND
)
255 self
.SetAutoLayout(True)
259 self
.Bind(wx
.EVT_RADIOBUTTON
, self
.OnRadioButton
, rb1
)
260 self
.Bind(wx
.EVT_RADIOBUTTON
, self
.OnRadioButton
, rb2
)
263 def OnRadioButton(self
, evt
):
264 rb
= self
.FindWindowById(evt
.GetId())
265 self
.pad
.SetMode(rb
.GetLabel())
268 #----------------------------------------------------------------------
269 #----------------------------------------------------------------------
271 class TestPanel(wx
.Panel
):
272 def __init__(self
, parent
, log
):
273 wx
.Panel
.__init
__(self
, parent
, -1)
275 self
.SetAutoLayout(True)
276 sizer
= wx
.BoxSizer(wx
.VERTICAL
)
278 msg
= "Custom Drag-And-Drop"
279 text
= wx
.StaticText(self
, -1, "", style
=wx
.ALIGN_CENTRE
)
280 text
.SetFont(wx
.Font(24, wx
.SWISS
, wx
.NORMAL
, wx
.BOLD
, False))
282 w
,h
= text
.GetTextExtent(msg
)
283 text
.SetSize(wx
.Size(w
,h
+1))
284 text
.SetForegroundColour(wx
.BLUE
)
285 sizer
.Add(text
, 0, wx
.EXPAND|wx
.ALL
, 5)
286 sizer
.Add(wx
.StaticLine(self
, -1), 0, wx
.EXPAND
)
288 sizer
.Add(CustomDnDPanel(self
, log
), 1, wx
.EXPAND
)
293 #----------------------------------------------------------------------
295 def runTest(frame
, nb
, log
):
296 #win = TestPanel(nb, log)
297 win
= CustomDnDPanel(nb
, log
)
301 if __name__
== '__main__':
305 def WriteText(self
, text
):
306 sys
.stdout
.write(text
)
308 class TestApp(wx
.App
):
310 wx
.InitAllImageHandlers()
314 def MakeFrame(self
, event
=None):
315 frame
= wx
.Frame(None, -1, "Custom Drag and Drop", size
=(550,400))
317 item
= menu
.Append(-1, "Window")
319 mb
.Append(menu
, "New")
321 frame
.Bind(wx
.EVT_MENU
, self
.MakeFrame
, item
)
322 panel
= TestPanel(frame
, DummyLog())
324 self
.SetTopWindow(frame
)
326 #----------------------------------------------------------------------
331 #----------------------------------------------------------------------
334 overview
= """<html><body>
335 This demo shows Drag and Drop using a custom data type and a custom
336 data object. A type called "DoodleLines" is created and a Python
337 Pickle of a list is actually transfered in the drag and drop
340 A second data object is also created containing a bitmap of the image
341 and is made available to any drop target that accepts bitmaps, such as
344 The two data objects are combined in a wx.DataObjectComposite and the
345 rest is handled by the framework.