2 from wxPython
.wx
import *
6 #----------------------------------------------------------------------
9 class DoodlePad(wxWindow
):
10 def __init__(self
, parent
, log
):
11 wxWindow
.__init
__(self
, parent
, -1, style
=wxSUNKEN_BORDER
)
13 self
.SetBackgroundColour(wxWHITE
)
16 self
.SetCursor(wxStockCursor(wxCURSOR_PENCIL
))
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 EVT_PAINT(self
, self
.OnPaint
)
25 def OnPaint(self
, event
):
27 self
.DrawSavedLines(dc
)
29 def DrawSavedLines(self
, dc
):
31 dc
.SetPen(wxPen(wxBLUE
, 3))
32 for line
in self
.lines
:
34 apply(dc
.DrawLine
, coords
)
38 def OnLeftDown(self
, event
):
39 if event
.ControlDown():
40 self
.StartDragOpperation()
43 self
.x
, self
.y
= event
.GetPositionTuple()
47 def OnLeftUp(self
, event
):
48 self
.lines
.append(self
.curLine
)
52 def OnRightUp(self
, event
):
56 def OnMotion(self
, event
):
57 if event
.Dragging() and not event
.ControlDown():
60 dc
.SetPen(wxPen(wxBLUE
, 3))
61 coords
= (self
.x
, self
.y
) + event
.GetPositionTuple()
62 self
.curLine
.append(coords
)
63 apply(dc
.DrawLine
, coords
)
64 self
.x
, self
.y
= event
.GetPositionTuple()
68 def StartDragOpperation(self
):
69 # pickle the lines list
70 linesdata
= cPickle
.dumps(self
.lines
, 1)
72 # create our own data format and use it in a
74 ldata
= wxCustomDataObject(wxCustomDataFormat("DoodleLines"))
75 ldata
.SetData(linesdata
)
77 # Also create a Bitmap version of the drawing
79 bmp
= wxEmptyBitmap(size
.width
, size
.height
)
82 dc
.SetBackground(wxWHITE_BRUSH
)
84 self
.DrawSavedLines(dc
)
85 dc
.SelectObject(wxNullBitmap
)
87 # Now make a data object for the bitmap and also a composite
88 # data object holding both of the others.
89 bdata
= wxBitmapDataObject(bmp
)
90 data
= wxDataObjectComposite()
94 # And finally, create the drop source and begin the drag
96 dropSource
= wxDropSource(self
)
97 dropSource
.SetData(data
)
98 self
.log
.WriteText("Begining DragDrop\n")
99 result
= dropSource
.DoDragDrop()
100 self
.log
.WriteText("DragDrop completed: %d\n" % result
)
104 #----------------------------------------------------------------------
107 class DoodleDropTarget(wxPyDropTarget
):
108 def __init__(self
, window
, log
):
109 wxPyDropTarget
.__init
__(self
)
113 # specify the type of data we will accept
114 self
.data
= wxCustomDataObject(wxCustomDataFormat("DoodleLines"))
115 self
.SetDataObject(self
.data
)
118 # some virtual methods that track the progress of the drag
119 def OnEnter(self
, x
, y
, d
):
120 self
.log
.WriteText("OnEnter: %d, %d, %d\n" % (x
, y
, d
))
123 self
.log
.WriteText("OnLeave\n")
124 def OnDrop(self
, x
, y
):
125 self
.log
.WriteText("OnDrop: %d %d\n" % (x
, y
))
127 #def OnDragOver(self, x, y, d):
128 # self.log.WriteText("OnDragOver: %d, %d, %d\n" % (x, y, d))
132 # Called when OnDrop returns true. We need to get the data and
133 # do something with it.
134 def OnData(self
, x
, y
, d
):
135 self
.log
.WriteText("OnData: %d, %d, %d\n" % (x
, y
, d
))
137 # copy the data from the drag source to out data object
139 # convert it back to a list of lines and give it to the viewer
140 linesdata
= self
.data
.GetData()
141 lines
= cPickle
.loads(linesdata
)
142 self
.dv
.SetLines(lines
)
148 class DoodleViewer(wxWindow
):
149 def __init__(self
, parent
, log
):
150 wxWindow
.__init
__(self
, parent
, -1, style
=wxSUNKEN_BORDER
)
152 self
.SetBackgroundColour(wxWHITE
)
155 dt
= DoodleDropTarget(self
, log
)
156 self
.SetDropTarget(dt
)
157 EVT_PAINT(self
, self
.OnPaint
)
159 def SetLines(self
, lines
):
163 def OnPaint(self
, event
):
165 self
.DrawSavedLines(dc
)
167 def DrawSavedLines(self
, dc
):
169 dc
.SetPen(wxPen(wxRED
, 3))
170 for line
in self
.lines
:
172 apply(dc
.DrawLine
, coords
)
175 #----------------------------------------------------------------------
177 class CustomDnDPanel(wxPanel
):
178 def __init__(self
, parent
, log
):
179 wxPanel
.__init
__(self
, parent
, -1)
181 self
.SetFont(wxFont(10, wxSWISS
, wxNORMAL
, wxBOLD
, false
))
183 sizer
= wxBoxSizer(wxHORIZONTAL
)
184 text
= wxStaticText(self
, -1,
185 "Draw a little picture in this window\n"
186 "then Ctrl-Drag it to the lower \n"
187 "window or to another application\n"
188 "that accepts BMP's as a drop target.\n\n"
189 "The lower window is accepting a\n"
190 "custom data type that is a pickled\n"
191 "Python list of lines data.")
192 sizer
.Add(text
, 1, wxALL
, 10)
194 insizer
= wxBoxSizer(wxVERTICAL
)
195 insizer
.Add(DoodlePad(self
, log
), 1, wxEXPAND|wxALL
, 5)
196 insizer
.Add(DoodleViewer(self
, log
), 1, wxEXPAND|wxALL
, 5)
198 sizer
.Add(insizer
, 1, wxEXPAND
)
199 self
.SetAutoLayout(true
)
205 #----------------------------------------------------------------------
206 #----------------------------------------------------------------------
208 class TestPanel(wxPanel
):
209 def __init__(self
, parent
, log
):
210 wxPanel
.__init
__(self
, parent
, -1)
212 self
.SetAutoLayout(true
)
213 sizer
= wxBoxSizer(wxVERTICAL
)
215 msg
= "Custom Drag-And-Drop"
216 text
= wxStaticText(self
, -1, "", style
=wxALIGN_CENTRE
)
217 text
.SetFont(wxFont(24, wxSWISS
, wxNORMAL
, wxBOLD
, false
))
219 w
,h
= text
.GetTextExtent(msg
)
220 text
.SetSize(wxSize(w
,h
+1))
221 text
.SetForegroundColour(wxBLUE
)
222 sizer
.Add(text
, 0, wxEXPAND|wxALL
, 5)
223 sizer
.Add(wxStaticLine(self
, -1), 0, wxEXPAND
)
225 sizer
.Add(CustomDnDPanel(self
, log
), 1, wxEXPAND
)
230 #----------------------------------------------------------------------
232 def runTest(frame
, nb
, log
):
233 win
= TestPanel(nb
, log
)
237 if __name__
== '__main__':
240 def WriteText(self
, text
):
241 sys
.stdout
.write(text
)
243 class TestApp(wxApp
):
248 def MakeFrame(self
, event
=None):
249 frame
= wxFrame(None, -1, "Custom Drag and Drop", size
=(550,400))
251 menu
.Append(6543, "Window")
253 mb
.Append(menu
, "New")
255 EVT_MENU(frame
, 6543, self
.MakeFrame
)
256 panel
= TestPanel(frame
, DummyLog())
258 self
.SetTopWindow(frame
)
265 #----------------------------------------------------------------------
279 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.
281 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.
283 The two data objects are combined in a wxDataObjectComposite and the rest is handled by the framework.