]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/demo/DragImage.py
5 #----------------------------------------------------------------------
8 def __init__(self
, bmp
):
13 self
.fullscreen
= False
15 def HitTest(self
, pt
):
17 return rect
.InsideXY(pt
.x
, pt
.y
)
20 return wx
.Rect(self
.pos
[0], self
.pos
[1],
21 self
.bmp
.GetWidth(), self
.bmp
.GetHeight())
23 def Draw(self
, dc
, op
= wx
.COPY
):
26 memDC
.SelectObject(self
.bmp
)
28 dc
.Blit(self
.pos
[0], self
.pos
[1],
29 self
.bmp
.GetWidth(), self
.bmp
.GetHeight(),
30 memDC
, 0, 0, op
, True)
38 #----------------------------------------------------------------------
40 class DragCanvas(wx
.ScrolledWindow
):
41 def __init__(self
, parent
, ID
):
42 wx
.ScrolledWindow
.__init
__(self
, parent
, ID
)
46 self
.hiliteShape
= None
48 self
.SetCursor(wx
.StockCursor(wx
.CURSOR_ARROW
))
49 self
.bg_bmp
= images
.getBackgroundBitmap()
50 self
.SetBackgroundStyle(wx
.BG_STYLE_CUSTOM
)
52 # Make a shape from an image and mask. This one will demo
53 # dragging outside the window
54 bmp
= images
.getTestStarBitmap()
55 #bmp = wx.Bitmap('bitmaps/toucan.png')
56 shape
= DragShape(bmp
)
58 shape
.fullscreen
= True
59 self
.shapes
.append(shape
)
61 # Make a shape from some text
63 bg_colour
= wx
.Colour(57, 115, 57) # matches the bg image
64 font
= wx
.Font(15, wx
.ROMAN
, wx
.NORMAL
, wx
.BOLD
)
65 textExtent
= self
.GetFullTextExtent(text
, font
)
67 # create a bitmap the same size as our text
68 bmp
= wx
.EmptyBitmap(textExtent
[0], textExtent
[1])
70 # 'draw' the text onto the bitmap
73 dc
.SetBackground(wx
.Brush(bg_colour
, wx
.SOLID
))
75 dc
.SetTextForeground(wx
.RED
)
77 dc
.DrawText(text
, 0, 0)
78 dc
.SelectObject(wx
.NullBitmap
)
79 mask
= wx
.Mask(bmp
, bg_colour
)
81 shape
= DragShape(bmp
)
83 shape
.text
= "Some dragging text"
84 self
.shapes
.append(shape
)
87 bmp
= images
.getTheKidBitmap()
88 shape
= DragShape(bmp
)
90 self
.shapes
.append(shape
)
92 self
.Bind(wx
.EVT_ERASE_BACKGROUND
, self
.OnEraseBackground
)
93 self
.Bind(wx
.EVT_PAINT
, self
.OnPaint
)
94 self
.Bind(wx
.EVT_LEFT_DOWN
, self
.OnLeftDown
)
95 self
.Bind(wx
.EVT_LEFT_UP
, self
.OnLeftUp
)
96 self
.Bind(wx
.EVT_MOTION
, self
.OnMotion
)
97 self
.Bind(wx
.EVT_LEAVE_WINDOW
, self
.OnLeaveWindow
)
100 # We're not doing anything here, but you might have reason to.
101 # for example, if you were dragging something, you might elect to
102 # 'drop it' when the cursor left the window.
103 def OnLeaveWindow(self
, evt
):
107 # tile the background bitmap
108 def TileBackground(self
, dc
):
109 sz
= self
.GetClientSize()
110 w
= self
.bg_bmp
.GetWidth()
111 h
= self
.bg_bmp
.GetHeight()
119 dc
.DrawBitmap(self
.bg_bmp
, x
, y
)
125 # Go through our list of shapes and draw them in whatever place they are.
126 def DrawShapes(self
, dc
):
127 for shape
in self
.shapes
:
131 # This is actually a sophisticated 'hit test', but in this
132 # case we're also determining which shape, if any, was 'hit'.
133 def FindShape(self
, pt
):
134 for shape
in self
.shapes
:
135 if shape
.HitTest(pt
):
139 # Remove a shape from the display
140 def EraseShape(self
, shape
, dc
):
142 dc
.SetClippingRect(r
)
143 self
.TileBackground(dc
)
145 dc
.DestroyClippingRegion()
147 # Clears the background, then redraws it. If the DC is passed, then
148 # we only do so in the area so designated. Otherwise, it's the whole thing.
149 def OnEraseBackground(self
, evt
):
153 dc
= wx
.ClientDC(self
)
154 rect
= self
.GetUpdateRegion().GetBox()
155 dc
.SetClippingRect(rect
)
156 self
.TileBackground(dc
)
158 # Fired whenever a paint event occurs
159 def OnPaint(self
, evt
):
160 dc
= wx
.PaintDC(self
)
164 # Left mouse button is down.
165 def OnLeftDown(self
, evt
):
166 # Did the mouse go down on one of our shapes?
167 shape
= self
.FindShape(evt
.GetPosition())
169 # If a shape was 'hit', then set that as the shape we're going to
170 # drag around. Get our start position. Dragging has not yet started.
171 # That will happen once the mouse moves, OR the mouse is released.
173 self
.dragShape
= shape
174 self
.dragStartPos
= evt
.GetPosition()
176 # Left mouse button up.
177 def OnLeftUp(self
, evt
):
178 if not self
.dragImage
or not self
.dragShape
:
179 self
.dragImage
= None
180 self
.dragShape
= None
183 # Hide the image, end dragging, and nuke out the drag image.
184 self
.dragImage
.Hide()
185 self
.dragImage
.EndDrag()
186 self
.dragImage
= None
189 self
.RefreshRect(self
.hiliteShape
.GetRect())
190 self
.hiliteShape
= None
192 # reposition and draw the shape
194 # Note by jmg 11/28/03
195 # Here's the original:
197 # self.dragShape.pos = self.dragShape.pos + evt.GetPosition() - self.dragStartPos
199 # So if there are any problems associated with this, use that as
200 # a starting place in your investigation. I've tried to simulate the
201 # wx.Point __add__ method here -- it won't work for tuples as we
202 # have now from the various methods
204 # There must be a better way to do this :-)
207 self
.dragShape
.pos
= (
208 self
.dragShape
.pos
[0] + evt
.GetPosition()[0] - self
.dragStartPos
[0],
209 self
.dragShape
.pos
[1] + evt
.GetPosition()[1] - self
.dragStartPos
[1]
212 self
.dragShape
.shown
= True
213 self
.RefreshRect(self
.dragShape
.GetRect())
214 self
.dragShape
= None
217 # The mouse is moving
218 def OnMotion(self
, evt
):
219 # Ignore mouse movement if we're not dragging.
220 if not self
.dragShape
or not evt
.Dragging() or not evt
.LeftIsDown():
223 # if we have a shape, but haven't started dragging yet
224 if self
.dragShape
and not self
.dragImage
:
226 # only start the drag after having moved a couple pixels
228 pt
= evt
.GetPosition()
229 dx
= abs(pt
.x
- self
.dragStartPos
.x
)
230 dy
= abs(pt
.y
- self
.dragStartPos
.y
)
231 if dx
<= tolerance
and dy
<= tolerance
:
234 # erase the shape since it will be drawn independently now
235 dc
= wx
.ClientDC(self
)
236 self
.dragShape
.shown
= False
237 self
.EraseShape(self
.dragShape
, dc
)
240 if self
.dragShape
.text
:
241 self
.dragImage
= wx
.DragString(self
.dragShape
.text
,
242 wx
.StockCursor(wx
.CURSOR_HAND
))
244 self
.dragImage
= wx
.DragImage(self
.dragShape
.bmp
,
245 wx
.StockCursor(wx
.CURSOR_HAND
))
247 hotspot
= self
.dragStartPos
- self
.dragShape
.pos
248 self
.dragImage
.BeginDrag(hotspot
, self
, self
.dragShape
.fullscreen
)
250 self
.dragImage
.Move(pt
)
251 self
.dragImage
.Show()
254 # if we have shape and image then move it, posibly highlighting another shape.
255 elif self
.dragShape
and self
.dragImage
:
256 onShape
= self
.FindShape(evt
.GetPosition())
260 # figure out what to hilite and what to unhilite
262 if onShape
is None or self
.hiliteShape
is not onShape
:
265 if onShape
and onShape
is not self
.hiliteShape
and onShape
.shown
:
268 # if needed, hide the drag image so we can update the window
269 if unhiliteOld
or hiliteNew
:
270 self
.dragImage
.Hide()
273 dc
= wx
.ClientDC(self
)
274 self
.hiliteShape
.Draw(dc
)
275 self
.hiliteShape
= None
278 dc
= wx
.ClientDC(self
)
279 self
.hiliteShape
= onShape
280 self
.hiliteShape
.Draw(dc
, wx
.INVERT
)
282 # now move it and show it again if needed
283 self
.dragImage
.Move(evt
.GetPosition())
284 if unhiliteOld
or hiliteNew
:
285 self
.dragImage
.Show()
288 #----------------------------------------------------------------------
290 def runTest(frame
, nb
, log
):
292 win
= wx
.Panel(nb
, -1)
293 canvas
= DragCanvas(win
, -1)
295 def onSize(evt
, panel
=win
, canvas
=canvas
):
296 canvas
.SetSize(panel
.GetSize())
298 win
.Bind(wx
.EVT_SIZE
, onSize
)
301 #----------------------------------------------------------------------
306 DragImage is used when you wish to drag an object on the screen, and a simple
307 cursor is not enough.
309 On Windows, the WIN32 API is used to do achieve smooth dragging. On other
310 platforms, <code>GenericDragImage</code> is used. Applications may also prefer to use
311 <code>GenericDragImage</code> on Windows, too.
313 <b>wxPython note</b>: wxPython uses <code>GenericDragImage</code> on all
314 platforms, but uses the <code>DragImage</code> name.
316 To use this class, when you wish to start dragging an image, create a
317 <code>DragImage</code> object and store it somewhere you can access it as the
318 drag progresses. Call BeginDrag to start, and EndDrag to stop the drag. To move
319 the image, initially call Show and then Move. If you wish to update the screen
320 contents during the drag (for example, highlight an item as in the example), first
321 call Hide, update the screen, call Move, and then call Show.
323 You can drag within one window, or you can use full-screen dragging either across
324 the whole screen, or just restricted to one area of the screen to save resources.
325 If you want the user to drag between two windows, then you will need to use
326 full-screen dragging.
331 if __name__
== '__main__':
334 run
.main(['', os
.path
.basename(sys
.argv
[0])] + sys
.argv
[1:])