]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/lib/gridmovers.py
Added FindById
[wxWidgets.git] / wxPython / wx / lib / gridmovers.py
1 #----------------------------------------------------------------------------
2 # Name: GridColMover.py
3 # Purpose: Grid Column Mover Extension
4 #
5 # Author: Gerrit van Dyk (email: gerritvd@decillion.net)
6 #
7 # Version 0.1
8 # Date: Nov 19, 2002
9 # RCS-ID: $Id$
10 # Licence: wxWindows license
11 #----------------------------------------------------------------------------
12 # 12/07/2003 - Jeff Grimmett (grimmtooth@softhome.net)
13 #
14 # o 2.5 Compatability changes
15 #
16
17 import wx
18 import wx.grid
19
20 #----------------------------------------------------------------------------
21 # event class and macros
22 #
23 # New style 12/7/03
24 #
25
26 wxEVT_COMMAND_GRID_COL_MOVE = wx.NewEventType()
27 wxEVT_COMMAND_GRID_ROW_MOVE = wx.NewEventType()
28
29 EVT_GRID_COL_MOVE = wx.PyEventBinder(wxEVT_COMMAND_GRID_COL_MOVE, 1)
30 EVT_GRID_ROW_MOVE = wx.PyEventBinder(wxEVT_COMMAND_GRID_ROW_MOVE, 1)
31
32 #----------------------------------------------------------------------------
33
34 class wxGridColMoveEvent(wx.PyCommandEvent):
35 def __init__(self, id, dCol, bCol):
36 wx.PyCommandEvent.__init__(self, id = id)
37 self.SetEventType(wxEVT_COMMAND_GRID_COL_MOVE)
38 self.moveColumn = dCol
39 self.beforeColumn = bCol
40
41 def GetMoveColumn(self):
42 return self.moveColumn
43
44 def GetBeforeColumn(self):
45 return self.beforeColumn
46
47
48 class wxGridRowMoveEvent(wx.PyCommandEvent):
49 def __init__(self, id, dRow, bRow):
50 wx.PyCommandEvent.__init__(self,id = id)
51 self.SetEventType(wxEVT_COMMAND_GRID_ROW_MOVE)
52 self.moveRow = dRow
53 self.beforeRow = bRow
54
55 def GetMoveRow(self):
56 return self.moveRow
57
58 def GetBeforeRow(self):
59 return self.beforeRow
60
61
62 #----------------------------------------------------------------------------
63 # graft new methods into the wxGrid class
64
65 def _ColToRect(self,col):
66 if self.GetNumberRows() > 0:
67 rect = self.CellToRect(0,col)
68 else:
69 rect = wxRect()
70 rect.height = self.GetColLabelSize()
71 rect.width = self.GetColSize(col)
72
73 for cCol in range(0,col):
74 rect.x += self.GetColSize(cCol)
75
76 rect.y = self.GetGridColLabelWindow().GetPosition()[1]
77 return rect
78
79 wx.grid.Grid.ColToRect = _ColToRect
80
81
82 def _RowToRect(self,row):
83 if self.GetNumberCols() > 0:
84 rect = self.CellToRect(row,0)
85 else:
86 rect = wxRect()
87 rect.width = self.GetRowLabelSize()
88 rect.height = self.GetRowSize(row)
89
90 for cRow in range(0,row):
91 rect.y += self.GetRowSize(cRow)
92
93 rect.x = self.GetGridRowLabelWindow().GetPosition()[0]
94 return rect
95
96 wx.grid.Grid.RowToRect = _RowToRect
97
98
99 #----------------------------------------------------------------------------
100
101 class ColDragWindow(wx.Window):
102 def __init__(self,parent,image,dragCol):
103 wx.Window.__init__(self,parent,-1, style=wx.SIMPLE_BORDER)
104 self.image = image
105 self.SetSize((self.image.GetWidth(),self.image.GetHeight()))
106 self.ux = parent.GetScrollPixelsPerUnit()[0]
107 self.moveColumn = dragCol
108
109 self.Bind(wx.EVT_PAINT, self.OnPaint)
110
111 def DisplayAt(self,pos,y):
112 x = self.GetPositionTuple()[0]
113 if x == pos:
114 self.Refresh() # Need to display insertion point
115 else:
116 self.MoveXY(pos,y)
117
118 def GetMoveColumn(self):
119 return self.moveColumn
120
121 def _GetInsertionInfo(self):
122 parent = self.GetParent()
123 sx = parent.GetViewStart()[0] * self.ux
124 sx -= parent._rlSize
125 x = self.GetPosition()[0]
126 w = self.GetSize()[0]
127 sCol = parent.XToCol(x + sx)
128 eCol = parent.XToCol(x + w + sx)
129 iPos = xPos = xCol = 99999
130 centerPos = x + sx + (w / 2)
131
132 for col in range(sCol,eCol + 1):
133 cx = parent.ColToRect(col)[0]
134
135 if abs(cx - centerPos) < iPos:
136 iPos = abs(cx - centerPos)
137 xCol = col
138 xPos = cx
139
140 if xCol < 0 or xCol > parent.GetNumberCols():
141 xCol = parent.GetNumberCols()
142
143 return (xPos - sx - x,xCol)
144
145 def GetInsertionColumn(self):
146 return self._GetInsertionInfo()[1]
147
148 def GetInsertionPos(self):
149 return self._GetInsertionInfo()[0]
150
151 def OnPaint(self,evt):
152 dc = wx.PaintDC(self)
153 w,h = self.GetSize()
154 dc.DrawBitmap(self.image, (0,0))
155 dc.SetPen(wx.Pen(wx.BLACK,1,wx.SOLID))
156 dc.SetBrush(wx.TRANSPARENT_BRUSH)
157 dc.DrawRectangle((0,0), (w,h))
158 iPos = self.GetInsertionPos()
159 dc.DrawLine((iPos,h - 10), (iPos,h))
160
161
162
163
164 class RowDragWindow(wx.Window):
165 def __init__(self,parent,image,dragRow):
166 wx.Window.__init__(self,parent,-1, style=wx.SIMPLE_BORDER)
167 self.image = image
168 self.SetSize((self.image.GetWidth(),self.image.GetHeight()))
169 self.uy = parent.GetScrollPixelsPerUnit()[1]
170 self.moveRow = dragRow
171
172 self.Bind(wx.EVT_PAINT, self.OnPaint)
173
174 def DisplayAt(self,x,pos):
175 y = self.GetPosition()[1]
176 if y == pos:
177 self.Refresh() # Need to display insertion point
178 else:
179 self.MoveXY(x,pos)
180
181 def GetMoveRow(self):
182 return self.moveRow
183
184 def _GetInsertionInfo(self):
185 parent = self.GetParent()
186 sy = parent.GetViewStart()[1] * self.uy
187 sy -= parent._clSize
188 y = self.GetPosition()[1]
189 h = self.GetSize()[1]
190 sRow = parent.YToRow(y + sy)
191 eRow = parent.YToRow(y + h + sy)
192 iPos = yPos = yRow = 99999
193 centerPos = y + sy + (h / 2)
194
195 for row in range(sRow,eRow + 1):
196 cy = parent.RowToRect(row)[1]
197
198 if abs(cy - centerPos) < iPos:
199 iPos = abs(cy - centerPos)
200 yRow = row
201 yPos = cy
202
203 if yRow < 0 or yRow > parent.GetNumberRows():
204 yRow = parent.GetNumberRows()
205
206 return (yPos - sy - y,yRow)
207
208 def GetInsertionRow(self):
209 return self._GetInsertionInfo()[1]
210
211 def GetInsertionPos(self):
212 return self._GetInsertionInfo()[0]
213
214 def OnPaint(self,evt):
215 dc = wx.PaintDC(self)
216 w,h = self.GetSize()
217 dc.DrawBitmap(self.image, (0,0))
218 dc.SetPen(wx.Pen(wx.BLACK,1,wx.SOLID))
219 dc.SetBrush(wx.TRANSPARENT_BRUSH)
220 dc.DrawRectangle((0,0), (w,h))
221 iPos = self.GetInsertionPos()
222 dc.DrawLine((w - 10,iPos), (w,iPos))
223
224 #----------------------------------------------------------------------------
225
226 class wxGridColMover(wx.EvtHandler):
227 def __init__(self,grid):
228 wx.EvtHandler.__init__(self)
229
230 self.grid = grid
231 self.grid._rlSize = self.grid.GetRowLabelSize()
232 self.lwin = grid.GetGridColLabelWindow()
233 self.lwin.PushEventHandler(self)
234 self.colWin = None
235 self.ux = self.grid.GetScrollPixelsPerUnit()[0]
236 self.startX = -10
237 self.cellX = 0
238 self.didMove = False
239 self.isDragging = False
240
241 self.Bind(wx.EVT_MOTION, self.OnMouseMove)
242 self.Bind(wx.EVT_LEFT_DOWN, self.OnPress)
243 self.Bind(wx.EVT_LEFT_UP, self.OnRelease)
244
245 def OnMouseMove(self,evt):
246 if self.isDragging:
247 if abs(self.startX - evt.m_x) >= 3:
248 self.didMove = True
249 sx,y = self.grid.GetViewStart()
250 w,h = self.lwin.GetClientSize()
251 x = sx * self.ux
252
253 if (evt.m_x + x) < x:
254 x = evt.m_x + x
255 elif evt.m_x > w:
256 x += evt.m_x - w
257
258 if x < 1: x = 0
259 else: x /= self.ux
260
261 if x != sx:
262 if wx.Platform == '__WXMSW__':
263 self.colWin.Show(False)
264
265 self.grid.Scroll(x,y)
266
267 x,y = self.lwin.ClientToScreenXY(evt.m_x,0)
268 x,y = self.grid.ScreenToClientXY(x,y)
269
270 if not self.colWin.IsShown():
271 self.colWin.Show(True)
272
273 px = x - self.cellX
274
275 if px < 0 + self.grid._rlSize: px = 0 + self.grid._rlSize
276
277 if px > w - self.colWin.GetSize()[0] + self.grid._rlSize:
278 px = w - self.colWin.GetSize()[0] + self.grid._rlSize
279
280 self.colWin.DisplayAt(px,y)
281 return
282
283 evt.Skip()
284
285 def OnPress(self,evt):
286 self.startX = evt.m_x
287 sx = self.grid.GetViewStart()[0] * self.ux
288 sx -= self.grid._rlSize
289 px,py = self.lwin.ClientToScreenXY(evt.m_x,evt.m_y)
290 px,py = self.grid.ScreenToClientXY(px,py)
291
292 if self.grid.XToEdgeOfCol(px + sx) != wx.NOT_FOUND:
293 evt.Skip()
294 return
295
296 self.isDragging = True
297 self.didMove = False
298 col = self.grid.XToCol(px + sx)
299 rect = self.grid.ColToRect(col)
300 self.cellX = px + sx - rect.x
301 size = self.lwin.GetSize()
302 rect.y = 0
303 rect.x -= sx + self.grid._rlSize
304 rect.height = size[1]
305 colImg = self._CaptureImage(rect)
306 self.colWin = ColDragWindow(self.grid,colImg,col)
307 self.colWin.Show(False)
308 self.lwin.CaptureMouse()
309
310 def OnRelease(self,evt):
311 if self.isDragging:
312 self.lwin.ReleaseMouse()
313 self.colWin.Show(False)
314 self.isDragging = False
315
316 if not self.didMove:
317 px = self.lwin.ClientToScreenXY(self.startX,0)[0]
318 px = self.grid.ScreenToClientXY(px,0)[0]
319 sx = self.grid.GetViewStart()[0] * self.ux
320 sx -= self.grid._rlSize
321 col = self.grid.XToCol(px+sx)
322
323 if col != wx.NOT_FOUND:
324 self.grid.SelectCol(col,evt.m_controlDown)
325
326 return
327 else:
328 bCol = self.colWin.GetInsertionColumn()
329 dCol = self.colWin.GetMoveColumn()
330 wx.PostEvent(self,
331 wxGridColMoveEvent(self.grid.GetId(), dCol, bCol))
332
333 self.colWin.Destroy()
334 evt.Skip()
335
336 def _CaptureImage(self,rect):
337 bmp = wx.EmptyBitmap(rect.width,rect.height)
338 memdc = wx.MemoryDC()
339 memdc.SelectObject(bmp)
340 dc = wx.WindowDC(self.lwin)
341 memdc.Blit((0,0), rect.GetSize(), dc, rect.GetPosition())
342 memdc.SelectObject(wx.NullBitmap)
343 return bmp
344
345
346 class wxGridRowMover(wx.EvtHandler):
347 def __init__(self,grid):
348 wx.EvtHandler.__init__(self)
349
350 self.grid = grid
351 self.grid._clSize = self.grid.GetColLabelSize()
352 self.lwin = grid.GetGridRowLabelWindow()
353 self.lwin.PushEventHandler(self)
354 self.rowWin = None
355 self.uy = self.grid.GetScrollPixelsPerUnit()[1]
356 self.startY = -10
357 self.cellY = 0
358 self.didMove = False
359 self.isDragging = False
360
361 self.Bind(wx.EVT_MOTION, self.OnMouseMove)
362 self.Bind(wx.EVT_LEFT_DOWN, self.OnPress)
363 self.Bind(wx.EVT_LEFT_UP, self.OnRelease)
364
365 def OnMouseMove(self,evt):
366 if self.isDragging:
367 if abs(self.startY - evt.m_y) >= 3:
368 self.didMove = True
369 x,sy = self.grid.GetViewStart()
370 w,h = self.lwin.GetClientSizeTuple()
371 y = sy * self.uy
372
373 if (evt.m_y + y) < y:
374 y = evt.m_y + y
375 elif evt.m_y > h:
376 y += evt.m_y - h
377
378 if y < 1:
379 y = 0
380 else:
381 y /= self.uy
382
383 if y != sy:
384 if wx.Platform == '__WXMSW__':
385 self.rowWin.Show(False)
386
387 self.grid.Scroll(x,y)
388
389 x,y = self.lwin.ClientToScreenXY(0,evt.m_y)
390 x,y = self.grid.ScreenToClientXY(x,y)
391
392 if not self.rowWin.IsShown():
393 self.rowWin.Show(True)
394
395 py = y - self.cellY
396
397 if py < 0 + self.grid._clSize:
398 py = 0 + self.grid._clSize
399
400 if py > h - self.rowWin.GetSize()[1] + self.grid._clSize:
401 py = h - self.rowWin.GetSize()[1] + self.grid._clSize
402
403 self.rowWin.DisplayAt(x,py)
404 return
405
406 evt.Skip()
407
408 def OnPress(self,evt):
409 self.startY = evt.m_y
410 sy = self.grid.GetViewStart()[1] * self.uy
411 sy -= self.grid._clSize
412 px,py = self.lwin.ClientToScreenXY(evt.m_x,evt.m_y)
413 px,py = self.grid.ScreenToClientXY(px,py)
414
415 if self.grid.YToEdgeOfRow(py + sy) != wx.NOT_FOUND:
416 evt.Skip()
417 return
418
419 self.isDragging = True
420 self.didMove = False
421 row = self.grid.YToRow(py + sy)
422 rect = self.grid.RowToRect(row)
423 self.cellY = py + sy - rect.y
424 size = self.lwin.GetSize()
425 rect.x = 0
426 rect.y -= sy + self.grid._clSize
427 rect.width = size[0]
428 rowImg = self._CaptureImage(rect)
429 self.rowWin = RowDragWindow(self.grid,rowImg,row)
430 self.rowWin.Show(False)
431 self.lwin.CaptureMouse()
432
433 def OnRelease(self,evt):
434 if self.isDragging:
435 self.lwin.ReleaseMouse()
436 self.rowWin.Show(False)
437 self.isDragging = False
438
439 if not self.didMove:
440 py = self.lwin.ClientToScreenXY(0,self.startY)[1]
441 py = self.grid.ScreenToClientXY(0,py)[1]
442 sy = self.grid.GetViewStart()[1] * self.uy
443 sy -= self.grid._clSize
444 row = self.grid.YToRow(py + sy)
445
446 if row != wx.NOT_FOUND:
447 self.grid.SelectRow(row,evt.m_controlDown)
448 return
449 else:
450 bRow = self.rowWin.GetInsertionRow()
451 dRow = self.rowWin.GetMoveRow()
452
453 wx.PostEvent(self,
454 wxGridRowMoveEvent(self.grid.GetId(), dRow, bRow))
455
456 self.rowWin.Destroy()
457 evt.Skip()
458
459 def _CaptureImage(self,rect):
460 bmp = wx.EmptyBitmap(rect.width,rect.height)
461 memdc = wx.MemoryDC()
462 memdc.SelectObject(bmp)
463 dc = wx.WindowDC(self.lwin)
464 memdc.Blit((0,0), rect.GetSize(), dc, rect.GetPosition())
465 memdc.SelectObject(wx.NullBitmap)
466 return bmp
467
468
469 #----------------------------------------------------------------------------