]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/demo/CustomDragAndDrop.py
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
)
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 SetMode ( self
, mode
):
27 if self
. mode
== "Draw" :
28 self
. SetCursor ( wxStockCursor ( wxCURSOR_PENCIL
))
30 self
. SetCursor ( wxSTANDARD_CURSOR
)
33 def OnPaint ( self
, event
):
35 self
. DrawSavedLines ( dc
)
37 def DrawSavedLines ( self
, dc
):
39 dc
. SetPen ( wxPen ( wxBLUE
, 3 ))
40 for line
in self
. lines
:
42 apply ( dc
. DrawLine
, coords
)
46 def OnLeftDown ( self
, event
):
47 if self
. mode
== "Drag" :
48 self
. StartDragOpperation ()
49 elif self
. mode
== "Draw" :
51 self
. x
, self
. y
= event
. GetPositionTuple ()
55 self
. log
. write ( "unknown mode! \n " )
58 def OnLeftUp ( self
, event
):
59 self
. lines
. append ( self
. curLine
)
63 def OnRightUp ( self
, event
):
67 def OnMotion ( self
, event
):
68 if event
. Dragging () and not self
. mode
== "Drag" :
71 dc
. SetPen ( wxPen ( wxBLUE
, 3 ))
72 coords
= ( self
. x
, self
. y
) + event
. GetPositionTuple ()
73 self
. curLine
. append ( coords
)
74 apply ( dc
. DrawLine
, 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
= wxCustomDataObject ( wxCustomDataFormat ( "DoodleLines" ))
86 ldata
. SetData ( linesdata
)
88 # Also create a Bitmap version of the drawing
90 bmp
= wxEmptyBitmap ( size
. width
, size
. height
)
93 dc
. SetBackground ( wxWHITE_BRUSH
)
95 self
. DrawSavedLines ( dc
)
96 dc
. SelectObject ( wxNullBitmap
)
98 # Now make a data object for the bitmap and also a composite
99 # data object holding both of the others.
100 bdata
= wxBitmapDataObject ( bmp
)
101 data
= wxDataObjectComposite ()
105 # And finally, create the drop source and begin the drag
106 # and drop opperation
107 dropSource
= wxDropSource ( self
)
108 dropSource
. SetData ( data
)
109 self
. log
. WriteText ( "Begining DragDrop \n " )
110 result
= dropSource
. DoDragDrop ( true
)
111 self
. log
. WriteText ( "DragDrop completed: %d \n " % result
)
112 if result
== wxDragMove
:
117 #----------------------------------------------------------------------
120 class DoodleDropTarget ( wxPyDropTarget
):
121 def __init__ ( self
, window
, log
):
122 wxPyDropTarget
.__ init
__ ( self
)
126 # specify the type of data we will accept
127 self
. data
= wxCustomDataObject ( wxCustomDataFormat ( "DoodleLines" ))
128 self
. SetDataObject ( self
. data
)
131 # some virtual methods that track the progress of the drag
132 def OnEnter ( self
, x
, y
, d
):
133 self
. log
. WriteText ( "OnEnter: %d , %d , %d \n " % ( x
, y
, d
))
137 self
. log
. WriteText ( "OnLeave \n " )
139 def OnDrop ( self
, x
, y
):
140 self
. log
. WriteText ( "OnDrop: %d %d \n " % ( x
, y
))
143 def OnDragOver ( self
, x
, y
, d
):
144 #self.log.WriteText("OnDragOver: %d, %d, %d\n" % (x, y, d))
146 # The value returned here tells the source what kind of visual
147 # feedback to give. For example, if wxDragCopy is returned then
148 # only the copy cursor will be shown, even if the source allows
149 # moves. You can use the passed in (x,y) to determine what kind
150 # of feedback to give. In this case we return the suggested value
151 # which is based on whether the Ctrl key is pressed.
156 # Called when OnDrop returns true. We need to get the data and
157 # do something with it.
158 def OnData ( self
, x
, y
, d
):
159 self
. log
. WriteText ( "OnData: %d , %d , %d \n " % ( x
, y
, d
))
161 # copy the data from the drag source to our data object
163 # convert it back to a list of lines and give it to the viewer
164 linesdata
= self
. data
. GetData ()
165 lines
= cPickle
. loads ( linesdata
)
166 self
. dv
. SetLines ( lines
)
167 return d
# what is returned signals the source what to do
168 # with the original data (move, copy, etc.) In this
169 # case we just return the suggested value given to us.
174 class DoodleViewer ( wxWindow
):
175 def __init__ ( self
, parent
, log
):
176 wxWindow
.__ init
__ ( self
, parent
, - 1 , style
= wxSUNKEN_BORDER
)
178 self
. SetBackgroundColour ( wxWHITE
)
181 dt
= DoodleDropTarget ( self
, log
)
182 self
. SetDropTarget ( dt
)
183 EVT_PAINT ( self
, self
. OnPaint
)
186 def SetLines ( self
, lines
):
190 def OnPaint ( self
, event
):
192 self
. DrawSavedLines ( dc
)
194 def DrawSavedLines ( self
, dc
):
196 dc
. SetPen ( wxPen ( wxRED
, 3 ))
197 for line
in self
. lines
:
199 apply ( dc
. DrawLine
, coords
)
202 #----------------------------------------------------------------------
204 class CustomDnDPanel ( wxPanel
):
205 def __init__ ( self
, parent
, log
):
206 wxPanel
.__ init
__ ( self
, parent
, - 1 )
208 self
. SetFont ( wxFont ( 10 , wxSWISS
, wxNORMAL
, wxBOLD
, false
))
211 text1
= wxStaticText ( self
, - 1 ,
212 "Draw a little picture in this window \n "
213 "then switch the mode below and drag the \n "
214 "picture to the lower window or to another \n "
215 "application that accepts BMP's as a drop \n "
219 rb1
= wxRadioButton ( self
, - 1 , "Draw" , style
= wxRB_GROUP
)
221 rb2
= wxRadioButton ( self
, - 1 , "Drag" )
224 text2
= wxStaticText ( self
, - 1 ,
225 "The lower window is accepting a \n "
226 "custom data type that is a pickled \n "
227 "Python list of lines data." )
229 self
. pad
= DoodlePad ( self
, log
)
230 view
= DoodleViewer ( self
, log
)
233 sizer
= wxBoxSizer ( wxHORIZONTAL
)
234 box
= wxBoxSizer ( wxVERTICAL
)
235 rbox
= wxBoxSizer ( wxHORIZONTAL
)
239 box
. Add ( text1
, 0 , wxALL
, 10 )
240 box
. Add ( rbox
, 0 , wxALIGN_CENTER
)
242 box
. Add ( text2
, 0 , wxALL
, 10 )
246 dndsizer
= wxBoxSizer ( wxVERTICAL
)
247 dndsizer
. Add ( self
. pad
, 1 , wxEXPAND|wxALL
, 5 )
248 dndsizer
. Add ( view
, 1 , wxEXPAND|wxALL
, 5 )
250 sizer
. Add ( dndsizer
, 1 , wxEXPAND
)
252 self
. SetAutoLayout ( true
)
256 EVT_RADIOBUTTON ( self
, rb1
. GetId (), self
. OnRadioButton
)
257 EVT_RADIOBUTTON ( self
, rb2
. GetId (), self
. OnRadioButton
)
260 def OnRadioButton ( self
, evt
):
261 rb
= self
. FindWindowById ( evt
. GetId ())
262 self
. pad
. SetMode ( rb
. GetLabel ())
265 #----------------------------------------------------------------------
266 #----------------------------------------------------------------------
268 class TestPanel ( wxPanel
):
269 def __init__ ( self
, parent
, log
):
270 wxPanel
.__ init
__ ( self
, parent
, - 1 )
272 self
. SetAutoLayout ( true
)
273 sizer
= wxBoxSizer ( wxVERTICAL
)
275 msg
= "Custom Drag-And-Drop"
276 text
= wxStaticText ( self
, - 1 , "" , style
= wxALIGN_CENTRE
)
277 text
. SetFont ( wxFont ( 24 , wxSWISS
, wxNORMAL
, wxBOLD
, false
))
279 w
, h
= text
. GetTextExtent ( msg
)
280 text
. SetSize ( wxSize ( w
, h
+ 1 ))
281 text
. SetForegroundColour ( wxBLUE
)
282 sizer
. Add ( text
, 0 , wxEXPAND|wxALL
, 5 )
283 sizer
. Add ( wxStaticLine ( self
, - 1 ), 0 , wxEXPAND
)
285 sizer
. Add ( CustomDnDPanel ( self
, log
), 1 , wxEXPAND
)
290 #----------------------------------------------------------------------
292 def runTest ( frame
, nb
, log
):
293 #win = TestPanel(nb, log)
294 win
= CustomDnDPanel ( nb
, log
)
298 if __name__
== '__main__' :
301 def WriteText ( self
, text
):
302 sys
. stdout
. write ( text
)
304 class TestApp ( wxApp
):
309 def MakeFrame ( self
, event
= None ):
310 frame
= wxFrame ( None , - 1 , "Custom Drag and Drop" , size
=( 550 , 400 ))
312 menu
. Append ( 6543 , "Window" )
314 mb
. Append ( menu
, "New" )
316 EVT_MENU ( frame
, 6543 , self
. MakeFrame
)
317 panel
= TestPanel ( frame
, DummyLog ())
319 self
. SetTopWindow ( frame
)
326 #----------------------------------------------------------------------
340 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.
342 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.
344 The two data objects are combined in a wxDataObjectComposite and the rest is handled by the framework.