]> git.saurik.com Git - wxWidgets.git/blob - wxPython/demo/wxDragImage.py
newevent helpers
[wxWidgets.git] / wxPython / demo / wxDragImage.py
1
2 from wxPython.wx import *
3
4 import images
5
6 #----------------------------------------------------------------------
7
8 class DragShape:
9 def __init__(self, bmp):
10 self.bmp = bmp
11 self.pos = wxPoint(0,0)
12 self.shown = True
13 self.text = None
14 self.fullscreen = False
15
16
17 def HitTest(self, pt):
18 rect = self.GetRect()
19 return rect.InsideXY(pt.x, pt.y)
20
21
22 def GetRect(self):
23 return wxRect(self.pos.x, self.pos.y,
24 self.bmp.GetWidth(), self.bmp.GetHeight())
25
26
27 def Draw(self, dc, op = wxCOPY):
28 if self.bmp.Ok():
29 memDC = wxMemoryDC()
30 memDC.SelectObject(self.bmp)
31
32 dc.Blit(self.pos.x, self.pos.y,
33 self.bmp.GetWidth(), self.bmp.GetHeight(),
34 memDC, 0, 0, op, True)
35
36 return True
37 else:
38 return False
39
40
41
42 #----------------------------------------------------------------------
43
44 class DragCanvas(wxScrolledWindow):
45 def __init__(self, parent, ID):
46 wxScrolledWindow.__init__(self, parent, ID)
47 self.shapes = []
48 self.dragImage = None
49 self.dragShape = None
50 self.hiliteShape = None
51
52 self.SetCursor(wxStockCursor(wxCURSOR_ARROW))
53 self.bg_bmp = images.getBackgroundBitmap()
54
55
56 # Make a shape from an image and mask. This one will demo
57 # dragging outside the window
58 bmp = images.getTestStarBitmap()
59 shape = DragShape(bmp)
60 shape.pos = wxPoint(5, 5)
61 shape.fullscreen = True
62 self.shapes.append(shape)
63
64
65 # Make a shape from some text
66 text = "Some Text"
67 bg_colour = wxColour(57, 115, 57) # matches the bg image
68 font = wxFont(15, wxROMAN, wxNORMAL, wxBOLD)
69 textExtent = self.GetFullTextExtent(text, font)
70 bmp = wxEmptyBitmap(textExtent[0], textExtent[1])
71 dc = wxMemoryDC()
72 dc.SelectObject(bmp)
73 dc.SetBackground(wxBrush(bg_colour, wxSOLID))
74 dc.Clear()
75 dc.SetTextForeground(wxRED)
76 dc.SetFont(font)
77 dc.DrawText(text, 0, 0)
78 dc.SelectObject(wxNullBitmap)
79 mask = wxMaskColour(bmp, bg_colour)
80 bmp.SetMask(mask)
81 shape = DragShape(bmp)
82 shape.pos = wxPoint(5, 100)
83 shape.text = "Some dragging text"
84 self.shapes.append(shape)
85
86
87 # Make some shapes from some playing card images.
88 x = 200
89 for card in ['_01c_', '_12h_', '_13d_', '_10s_']:
90 bmpFunc = getattr(images, "get%sBitmap" % card)
91 bmp = bmpFunc()
92 shape = DragShape(bmp)
93 shape.pos = wxPoint(x, 5)
94 self.shapes.append(shape)
95 x = x + 80
96
97
98 EVT_ERASE_BACKGROUND(self, self.OnEraseBackground)
99 EVT_PAINT(self, self.OnPaint)
100 EVT_LEFT_DOWN(self, self.OnLeftDown)
101 EVT_LEFT_UP(self, self.OnLeftUp)
102 EVT_MOTION(self, self.OnMotion)
103 EVT_LEAVE_WINDOW(self, self.OnLeaveWindow)
104
105
106 def OnLeaveWindow(self, evt):
107 pass
108
109
110 def TileBackground(self, dc):
111 # tile the background bitmap
112 sz = self.GetClientSize()
113 w = self.bg_bmp.GetWidth()
114 h = self.bg_bmp.GetHeight()
115
116 x = 0
117 while x < sz.width:
118 y = 0
119 while y < sz.height:
120 dc.DrawBitmap(self.bg_bmp, x, y)
121 y = y + h
122 x = x + w
123
124
125 def DrawShapes(self, dc):
126 for shape in self.shapes:
127 if shape.shown:
128 shape.Draw(dc)
129
130
131 def FindShape(self, pt):
132 for shape in self.shapes:
133 if shape.HitTest(pt):
134 return shape
135 return None
136
137
138 def EraseShape(self, shape, dc):
139 r = shape.GetRect()
140 dc.SetClippingRegion(r.x, r.y, r.width, r.height)
141 self.TileBackground(dc)
142 self.DrawShapes(dc)
143 dc.DestroyClippingRegion()
144
145
146 def OnEraseBackground(self, evt):
147 dc = evt.GetDC()
148 if not dc:
149 dc = wxClientDC(self)
150 rect = self.GetUpdateRegion().GetBox()
151 dc.SetClippingRegion(rect.x, rect.y, rect.width, rect.height)
152 self.TileBackground(dc)
153
154
155 def OnPaint(self, evt):
156 dc = wxPaintDC(self)
157 self.PrepareDC(dc)
158 self.DrawShapes(dc)
159
160
161 def OnLeftDown(self, evt):
162 shape = self.FindShape(evt.GetPosition())
163 if shape:
164 # get ready to start dragging, but wait for the user to
165 # move it a bit first
166 self.dragShape = shape
167 self.dragStartPos = evt.GetPosition()
168
169
170 def OnLeftUp(self, evt):
171 if not self.dragImage or not self.dragShape:
172 self.dragImage = None
173 self.dragShape = None
174 return
175
176 # end the dragging
177 self.dragImage.Hide()
178 self.dragImage.EndDrag()
179 self.dragImage = None
180
181 dc = wxClientDC(self)
182 if self.hiliteShape:
183 self.hiliteShape.Draw(dc)
184 self.hiliteShape = None
185
186 # reposition and draw the shape
187 self.dragShape.pos = self.dragShape.pos + evt.GetPosition() - self.dragStartPos
188 self.dragShape.shown = True
189 self.dragShape.Draw(dc)
190 self.dragShape = None
191
192
193 def OnMotion(self, evt):
194 if not self.dragShape or not evt.Dragging() or not evt.LeftIsDown():
195 return
196
197 # if we have a shape, but havn't started dragging yet
198 if self.dragShape and not self.dragImage:
199
200 # only start the drag after having moved a couple pixels
201 tolerance = 2
202 pt = evt.GetPosition()
203 dx = abs(pt.x - self.dragStartPos.x)
204 dy = abs(pt.y - self.dragStartPos.y)
205 if dx <= tolerance and dy <= tolerance:
206 return
207
208 # erase the shape since it will be drawn independently now
209 dc = wxClientDC(self)
210 self.dragShape.shown = False
211 self.EraseShape(self.dragShape, dc)
212
213
214 if self.dragShape.text:
215 self.dragImage = wxDragString(self.dragShape.text,
216 wxStockCursor(wxCURSOR_HAND))
217 else:
218 self.dragImage = wxDragImage(self.dragShape.bmp,
219 wxStockCursor(wxCURSOR_HAND))
220
221 hotspot = self.dragStartPos - self.dragShape.pos
222 self.dragImage.BeginDrag(hotspot, self, self.dragShape.fullscreen)
223
224 self.dragImage.Move(pt)
225 self.dragImage.Show()
226
227
228 # if we have shape and image then move it, posibly highlighting another shape.
229 elif self.dragShape and self.dragImage:
230 onShape = self.FindShape(evt.GetPosition())
231 unhiliteOld = False
232 hiliteNew = False
233
234 # figure out what to hilite and what to unhilite
235 if self.hiliteShape:
236 if onShape is None or self.hiliteShape is not onShape:
237 unhiliteOld = True
238
239 if onShape and onShape is not self.hiliteShape and onShape.shown:
240 hiliteNew = True
241
242 # if needed, hide the drag image so we can update the window
243 if unhiliteOld or hiliteNew:
244 self.dragImage.Hide()
245
246 if unhiliteOld:
247 dc = wxClientDC(self)
248 self.hiliteShape.Draw(dc)
249 self.hiliteShape = None
250
251 if hiliteNew:
252 dc = wxClientDC(self)
253 self.hiliteShape = onShape
254 self.hiliteShape.Draw(dc, wxINVERT)
255
256 # now move it and show it again if needed
257 self.dragImage.Move(evt.GetPosition())
258 if unhiliteOld or hiliteNew:
259 self.dragImage.Show()
260
261
262 #----------------------------------------------------------------------
263
264 def runTest(frame, nb, log):
265 win = wxPanel(nb, -1)
266 canvas = DragCanvas(win, -1)
267 def onSize(evt, panel=win, canvas=canvas): canvas.SetSize(panel.GetSize())
268 EVT_SIZE(win, onSize)
269 return win
270
271 #----------------------------------------------------------------------
272
273
274
275 overview = """\
276 """
277
278
279 if __name__ == '__main__':
280 import sys,os
281 import run
282 run.main(['', os.path.basename(sys.argv[0])])
283