]>
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 bmp
= images
.getTheKidBitmap()
62 shape
= DragShape(bmp
)
64 self
.shapes
.append(shape
)
66 # Make a shape from some text
68 bg_colour
= wx
.Colour(57, 115, 57) # matches the bg image
69 font
= wx
.Font(15, wx
.ROMAN
, wx
.NORMAL
, wx
.BOLD
)
70 textExtent
= self
.GetFullTextExtent(text
, font
)
72 # create a bitmap the same size as our text
73 bmp
= wx
.EmptyBitmap(textExtent
[0], textExtent
[1])
75 # 'draw' the text onto the bitmap
78 dc
.SetBackground(wx
.Brush(bg_colour
, wx
.SOLID
))
80 dc
.SetTextForeground(wx
.RED
)
82 dc
.DrawText(text
, 0, 0)
83 dc
.SelectObject(wx
.NullBitmap
)
84 mask
= wx
.Mask(bmp
, bg_colour
)
86 shape
= DragShape(bmp
)
88 shape
.text
= "Some dragging text"
89 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
):
140 # Clears the background, then redraws it. If the DC is passed, then
141 # we only do so in the area so designated. Otherwise, it's the whole thing.
142 def OnEraseBackground(self
, evt
):
145 dc
= wx
.ClientDC(self
)
146 rect
= self
.GetUpdateRegion().GetBox()
147 dc
.SetClippingRect(rect
)
148 self
.TileBackground(dc
)
150 # Fired whenever a paint event occurs
151 def OnPaint(self
, evt
):
152 dc
= wx
.PaintDC(self
)
156 # Left mouse button is down.
157 def OnLeftDown(self
, evt
):
158 # Did the mouse go down on one of our shapes?
159 shape
= self
.FindShape(evt
.GetPosition())
161 # If a shape was 'hit', then set that as the shape we're going to
162 # drag around. Get our start position. Dragging has not yet started.
163 # That will happen once the mouse moves, OR the mouse is released.
165 self
.dragShape
= shape
166 self
.dragStartPos
= evt
.GetPosition()
168 # Left mouse button up.
169 def OnLeftUp(self
, evt
):
170 if not self
.dragImage
or not self
.dragShape
:
171 self
.dragImage
= None
172 self
.dragShape
= None
175 # Hide the image, end dragging, and nuke out the drag image.
176 self
.dragImage
.Hide()
177 self
.dragImage
.EndDrag()
178 self
.dragImage
= None
181 self
.RefreshRect(self
.hiliteShape
.GetRect())
182 self
.hiliteShape
= None
184 # reposition and draw the shape
186 # Note by jmg 11/28/03
187 # Here's the original:
189 # self.dragShape.pos = self.dragShape.pos + evt.GetPosition() - self.dragStartPos
191 # So if there are any problems associated with this, use that as
192 # a starting place in your investigation. I've tried to simulate the
193 # wx.Point __add__ method here -- it won't work for tuples as we
194 # have now from the various methods
196 # There must be a better way to do this :-)
199 self
.dragShape
.pos
= (
200 self
.dragShape
.pos
[0] + evt
.GetPosition()[0] - self
.dragStartPos
[0],
201 self
.dragShape
.pos
[1] + evt
.GetPosition()[1] - self
.dragStartPos
[1]
204 self
.dragShape
.shown
= True
205 self
.RefreshRect(self
.dragShape
.GetRect())
206 self
.dragShape
= None
209 # The mouse is moving
210 def OnMotion(self
, evt
):
211 # Ignore mouse movement if we're not dragging.
212 if not self
.dragShape
or not evt
.Dragging() or not evt
.LeftIsDown():
215 # if we have a shape, but haven't started dragging yet
216 if self
.dragShape
and not self
.dragImage
:
218 # only start the drag after having moved a couple pixels
220 pt
= evt
.GetPosition()
221 dx
= abs(pt
.x
- self
.dragStartPos
.x
)
222 dy
= abs(pt
.y
- self
.dragStartPos
.y
)
223 if dx
<= tolerance
and dy
<= tolerance
:
226 # refresh the area of the window where the shape was so it
228 self
.dragShape
.shown
= False
229 self
.RefreshRect(self
.dragShape
.GetRect(), True)
232 if self
.dragShape
.text
:
233 self
.dragImage
= wx
.DragString(self
.dragShape
.text
,
234 wx
.StockCursor(wx
.CURSOR_HAND
))
236 self
.dragImage
= wx
.DragImage(self
.dragShape
.bmp
,
237 wx
.StockCursor(wx
.CURSOR_HAND
))
239 hotspot
= self
.dragStartPos
- self
.dragShape
.pos
240 self
.dragImage
.BeginDrag(hotspot
, self
, self
.dragShape
.fullscreen
)
242 self
.dragImage
.Move(pt
)
243 self
.dragImage
.Show()
246 # if we have shape and image then move it, posibly highlighting another shape.
247 elif self
.dragShape
and self
.dragImage
:
248 onShape
= self
.FindShape(evt
.GetPosition())
252 # figure out what to hilite and what to unhilite
254 if onShape
is None or self
.hiliteShape
is not onShape
:
257 if onShape
and onShape
is not self
.hiliteShape
and onShape
.shown
:
260 # if needed, hide the drag image so we can update the window
261 if unhiliteOld
or hiliteNew
:
262 self
.dragImage
.Hide()
265 dc
= wx
.ClientDC(self
)
266 self
.hiliteShape
.Draw(dc
)
267 self
.hiliteShape
= None
270 dc
= wx
.ClientDC(self
)
271 self
.hiliteShape
= onShape
272 self
.hiliteShape
.Draw(dc
, wx
.INVERT
)
274 # now move it and show it again if needed
275 self
.dragImage
.Move(evt
.GetPosition())
276 if unhiliteOld
or hiliteNew
:
277 self
.dragImage
.Show()
280 #----------------------------------------------------------------------
282 def runTest(frame
, nb
, log
):
284 win
= wx
.Panel(nb
, -1)
285 canvas
= DragCanvas(win
, -1)
287 def onSize(evt
, panel
=win
, canvas
=canvas
):
288 canvas
.SetSize(panel
.GetSize())
290 win
.Bind(wx
.EVT_SIZE
, onSize
)
293 #----------------------------------------------------------------------
298 DragImage is used when you wish to drag an object on the screen, and a simple
299 cursor is not enough.
301 On Windows, the WIN32 API is used to do achieve smooth dragging. On other
302 platforms, <code>GenericDragImage</code> is used. Applications may also prefer to use
303 <code>GenericDragImage</code> on Windows, too.
305 <b>wxPython note</b>: wxPython uses <code>GenericDragImage</code> on all
306 platforms, but uses the <code>DragImage</code> name.
308 To use this class, when you wish to start dragging an image, create a
309 <code>DragImage</code> object and store it somewhere you can access it as the
310 drag progresses. Call BeginDrag to start, and EndDrag to stop the drag. To move
311 the image, initially call Show and then Move. If you wish to update the screen
312 contents during the drag (for example, highlight an item as in the example), first
313 call Hide, update the screen, call Move, and then call Show.
315 You can drag within one window, or you can use full-screen dragging either across
316 the whole screen, or just restricted to one area of the screen to save resources.
317 If you want the user to drag between two windows, then you will need to use
318 full-screen dragging.
323 if __name__
== '__main__':
326 run
.main(['', os
.path
.basename(sys
.argv
[0])] + sys
.argv
[1:])