]>
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 ( wxDrag_AllowMove
)  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.