1 #----------------------------------------------------------------------------
2 # Name: GridColMover.py
3 # Purpose: Grid Column Mover Extension
5 # Author: Gerrit van Dyk (email: gerritvd@decillion.net)
10 # Licence: wxWindows license
11 #----------------------------------------------------------------------------
12 # 12/07/2003 - Jeff Grimmett (grimmtooth@softhome.net)
14 # o 2.5 Compatability changes
20 #----------------------------------------------------------------------------
21 # event class and macros
26 wxEVT_COMMAND_GRID_COL_MOVE
= wx
.NewEventType()
27 wxEVT_COMMAND_GRID_ROW_MOVE
= wx
.NewEventType()
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)
32 #----------------------------------------------------------------------------
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
41 def GetMoveColumn(self
):
42 return self
.moveColumn
44 def GetBeforeColumn(self
):
45 return self
.beforeColumn
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
)
58 def GetBeforeRow(self
):
62 #----------------------------------------------------------------------------
63 # graft new methods into the wxGrid class
65 def _ColToRect(self
,col
):
66 if self
.GetNumberRows() > 0:
67 rect
= self
.CellToRect(0,col
)
70 rect
.height
= self
.GetColLabelSize()
71 rect
.width
= self
.GetColSize(col
)
73 for cCol
in range(0,col
):
74 rect
.x
+= self
.GetColSize(cCol
)
76 rect
.y
= self
.GetGridColLabelWindow().GetPosition()[1]
79 wx
.grid
.Grid
.ColToRect
= _ColToRect
82 def _RowToRect(self
,row
):
83 if self
.GetNumberCols() > 0:
84 rect
= self
.CellToRect(row
,0)
87 rect
.width
= self
.GetRowLabelSize()
88 rect
.height
= self
.GetRowSize(row
)
90 for cRow
in range(0,row
):
91 rect
.y
+= self
.GetRowSize(cRow
)
93 rect
.x
= self
.GetGridRowLabelWindow().GetPosition()[0]
96 wx
.grid
.Grid
.RowToRect
= _RowToRect
99 #----------------------------------------------------------------------------
101 class ColDragWindow(wx
.Window
):
102 def __init__(self
,parent
,image
,dragCol
):
103 wx
.Window
.__init
__(self
,parent
,-1, style
=wx
.SIMPLE_BORDER
)
105 self
.SetSize((self
.image
.GetWidth(),self
.image
.GetHeight()))
106 self
.ux
= parent
.GetScrollPixelsPerUnit()[0]
107 self
.moveColumn
= dragCol
109 self
.Bind(wx
.EVT_PAINT
, self
.OnPaint
)
111 def DisplayAt(self
,pos
,y
):
112 x
= self
.GetPositionTuple()[0]
114 self
.Refresh() # Need to display insertion point
118 def GetMoveColumn(self
):
119 return self
.moveColumn
121 def _GetInsertionInfo(self
):
122 parent
= self
.GetParent()
123 sx
= parent
.GetViewStart()[0] * self
.ux
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)
132 for col
in range(sCol
,eCol
+ 1):
133 cx
= parent
.ColToRect(col
)[0]
135 if abs(cx
- centerPos
) < iPos
:
136 iPos
= abs(cx
- centerPos
)
140 if xCol
< 0 or xCol
> parent
.GetNumberCols():
141 xCol
= parent
.GetNumberCols()
143 return (xPos
- sx
- x
,xCol
)
145 def GetInsertionColumn(self
):
146 return self
._GetInsertionInfo
()[1]
148 def GetInsertionPos(self
):
149 return self
._GetInsertionInfo
()[0]
151 def OnPaint(self
,evt
):
152 dc
= wx
.PaintDC(self
)
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
))
164 class RowDragWindow(wx
.Window
):
165 def __init__(self
,parent
,image
,dragRow
):
166 wx
.Window
.__init
__(self
,parent
,-1, style
=wx
.SIMPLE_BORDER
)
168 self
.SetSize((self
.image
.GetWidth(),self
.image
.GetHeight()))
169 self
.uy
= parent
.GetScrollPixelsPerUnit()[1]
170 self
.moveRow
= dragRow
172 self
.Bind(wx
.EVT_PAINT
, self
.OnPaint
)
174 def DisplayAt(self
,x
,pos
):
175 y
= self
.GetPosition()[1]
177 self
.Refresh() # Need to display insertion point
181 def GetMoveRow(self
):
184 def _GetInsertionInfo(self
):
185 parent
= self
.GetParent()
186 sy
= parent
.GetViewStart()[1] * self
.uy
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)
195 for row
in range(sRow
,eRow
+ 1):
196 cy
= parent
.RowToRect(row
)[1]
198 if abs(cy
- centerPos
) < iPos
:
199 iPos
= abs(cy
- centerPos
)
203 if yRow
< 0 or yRow
> parent
.GetNumberRows():
204 yRow
= parent
.GetNumberRows()
206 return (yPos
- sy
- y
,yRow
)
208 def GetInsertionRow(self
):
209 return self
._GetInsertionInfo
()[1]
211 def GetInsertionPos(self
):
212 return self
._GetInsertionInfo
()[0]
214 def OnPaint(self
,evt
):
215 dc
= wx
.PaintDC(self
)
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
))
224 #----------------------------------------------------------------------------
226 class wxGridColMover(wx
.EvtHandler
):
227 def __init__(self
,grid
):
228 wx
.EvtHandler
.__init
__(self
)
231 self
.grid
._rlSize
= self
.grid
.GetRowLabelSize()
232 self
.lwin
= grid
.GetGridColLabelWindow()
233 self
.lwin
.PushEventHandler(self
)
235 self
.ux
= self
.grid
.GetScrollPixelsPerUnit()[0]
239 self
.isDragging
= False
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
)
245 def OnMouseMove(self
,evt
):
247 if abs(self
.startX
- evt
.m_x
) >= 3:
249 sx
,y
= self
.grid
.GetViewStart()
250 w
,h
= self
.lwin
.GetClientSize()
253 if (evt
.m_x
+ x
) < x
:
262 if wx
.Platform
== '__WXMSW__':
263 self
.colWin
.Show(False)
265 self
.grid
.Scroll(x
,y
)
267 x
,y
= self
.lwin
.ClientToScreenXY(evt
.m_x
,0)
268 x
,y
= self
.grid
.ScreenToClientXY(x
,y
)
270 if not self
.colWin
.IsShown():
271 self
.colWin
.Show(True)
275 if px
< 0 + self
.grid
._rlSize
: px
= 0 + self
.grid
._rlSize
277 if px
> w
- self
.colWin
.GetSize()[0] + self
.grid
._rlSize
:
278 px
= w
- self
.colWin
.GetSize()[0] + self
.grid
._rlSize
280 self
.colWin
.DisplayAt(px
,y
)
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
)
292 if self
.grid
.XToEdgeOfCol(px
+ sx
) != wx
.NOT_FOUND
:
296 self
.isDragging
= True
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()
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()
310 def OnRelease(self
,evt
):
312 self
.lwin
.ReleaseMouse()
313 self
.colWin
.Show(False)
314 self
.isDragging
= False
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
)
323 if col
!= wx
.NOT_FOUND
:
324 self
.grid
.SelectCol(col
,evt
.m_controlDown
)
328 bCol
= self
.colWin
.GetInsertionColumn()
329 dCol
= self
.colWin
.GetMoveColumn()
331 wxGridColMoveEvent(self
.grid
.GetId(), dCol
, bCol
))
333 self
.colWin
.Destroy()
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
)
346 class wxGridRowMover(wx
.EvtHandler
):
347 def __init__(self
,grid
):
348 wx
.EvtHandler
.__init
__(self
)
351 self
.grid
._clSize
= self
.grid
.GetColLabelSize()
352 self
.lwin
= grid
.GetGridRowLabelWindow()
353 self
.lwin
.PushEventHandler(self
)
355 self
.uy
= self
.grid
.GetScrollPixelsPerUnit()[1]
359 self
.isDragging
= False
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
)
365 def OnMouseMove(self
,evt
):
367 if abs(self
.startY
- evt
.m_y
) >= 3:
369 x
,sy
= self
.grid
.GetViewStart()
370 w
,h
= self
.lwin
.GetClientSizeTuple()
373 if (evt
.m_y
+ y
) < y
:
384 if wx
.Platform
== '__WXMSW__':
385 self
.rowWin
.Show(False)
387 self
.grid
.Scroll(x
,y
)
389 x
,y
= self
.lwin
.ClientToScreenXY(0,evt
.m_y
)
390 x
,y
= self
.grid
.ScreenToClientXY(x
,y
)
392 if not self
.rowWin
.IsShown():
393 self
.rowWin
.Show(True)
397 if py
< 0 + self
.grid
._clSize
:
398 py
= 0 + self
.grid
._clSize
400 if py
> h
- self
.rowWin
.GetSize()[1] + self
.grid
._clSize
:
401 py
= h
- self
.rowWin
.GetSize()[1] + self
.grid
._clSize
403 self
.rowWin
.DisplayAt(x
,py
)
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
)
415 if self
.grid
.YToEdgeOfRow(py
+ sy
) != wx
.NOT_FOUND
:
419 self
.isDragging
= True
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()
426 rect
.y
-= sy
+ self
.grid
._clSize
428 rowImg
= self
._CaptureImage
(rect
)
429 self
.rowWin
= RowDragWindow(self
.grid
,rowImg
,row
)
430 self
.rowWin
.Show(False)
431 self
.lwin
.CaptureMouse()
433 def OnRelease(self
,evt
):
435 self
.lwin
.ReleaseMouse()
436 self
.rowWin
.Show(False)
437 self
.isDragging
= False
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
)
446 if row
!= wx
.NOT_FOUND
:
447 self
.grid
.SelectRow(row
,evt
.m_controlDown
)
450 bRow
= self
.rowWin
.GetInsertionRow()
451 dRow
= self
.rowWin
.GetMoveRow()
454 wxGridRowMoveEvent(self
.grid
.GetId(), dRow
, bRow
))
456 self
.rowWin
.Destroy()
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
)
469 #----------------------------------------------------------------------------