1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxGenericGrid
4 // Author: Julian Smart
5 // Modified by: Michael Bedward
6 // Added edit in place facility, 20 Apr 1999
7 // Added cursor key control, 29 Jun 1999
9 // Added keyboard navigation, client data, other fixes
12 // Copyright: (c) Julian Smart and Markus Holzem
13 // Licence: wxWindows license
14 /////////////////////////////////////////////////////////////////////////////
17 #pragma implementation "gridg.h"
21 // For compilers that support precompilation, includes "wx/wx.h".
22 #include "wx/wxprec.h"
30 #include "wx/dcclient.h"
31 #include "wx/dcmemory.h"
32 #include "wx/textctrl.h"
33 #include "wx/settings.h"
38 #include "wx/string.h"
40 #include "wx/generic/gridg.h"
42 // Set to zero to use no double-buffering
44 #define wxUSE_DOUBLE_BUFFERING 1
46 #define wxUSE_DOUBLE_BUFFERING 0
49 #define wxGRID_DRAG_NONE 0
50 #define wxGRID_DRAG_LEFT_RIGHT 1
51 #define wxGRID_DRAG_UP_DOWN 2
53 IMPLEMENT_DYNAMIC_CLASS(wxGenericGrid
, wxPanel
)
54 IMPLEMENT_DYNAMIC_CLASS(wxGridEvent
, wxEvent
)
56 BEGIN_EVENT_TABLE(wxGenericGrid
, wxPanel
)
57 EVT_SIZE(wxGenericGrid::OnSize
)
58 EVT_PAINT(wxGenericGrid::OnPaint
)
59 EVT_ERASE_BACKGROUND(wxGenericGrid::OnEraseBackground
)
60 EVT_MOUSE_EVENTS(wxGenericGrid::OnMouseEvent
)
61 EVT_TEXT(wxGRID_TEXT_CTRL
, wxGenericGrid::OnText
)
62 EVT_TEXT(wxGRID_EDIT_IN_PLACE_TEXT_CTRL
, wxGenericGrid::OnTextInPlace
)
63 EVT_TEXT_ENTER(wxGRID_TEXT_CTRL
, wxGenericGrid::OnTextEnter
)
64 EVT_TEXT_ENTER(wxGRID_EDIT_IN_PLACE_TEXT_CTRL
, wxGenericGrid::OnTextInPlaceEnter
)
65 EVT_COMMAND_SCROLL(wxGRID_HSCROLL
, wxGenericGrid::OnGridScroll
)
66 EVT_COMMAND_SCROLL(wxGRID_VSCROLL
, wxGenericGrid::OnGridScroll
)
68 // default wxGridEvent handlers
69 EVT_GRID_SELECT_CELL(wxGenericGrid::_OnSelectCell
)
70 EVT_GRID_CREATE_CELL(wxGenericGrid::_OnCreateCell
)
71 EVT_GRID_CHANGE_LABELS(wxGenericGrid::_OnChangeLabels
)
72 EVT_GRID_CHANGE_SEL_LABEL(wxGenericGrid::_OnChangeSelectionLabel
)
73 EVT_GRID_CELL_CHANGE(wxGenericGrid::_OnCellChange
)
74 EVT_GRID_CELL_LCLICK(wxGenericGrid::_OnCellLeftClick
)
75 EVT_GRID_CELL_RCLICK(wxGenericGrid::_OnCellRightClick
)
76 EVT_GRID_LABEL_LCLICK(wxGenericGrid::_OnLabelLeftClick
)
77 EVT_GRID_LABEL_RCLICK(wxGenericGrid::_OnLabelRightClick
)
82 wxGenericGrid::wxGenericGrid()
87 m_hScrollBar
= (wxScrollBar
*) NULL
;
88 m_vScrollBar
= (wxScrollBar
*) NULL
;
89 m_cellTextColour
= *wxBLACK
;
90 m_cellBackgroundColour
= *wxWHITE
;
91 m_labelTextColour
= *wxBLACK
;
92 // m_labelBackgroundColour = *wxLIGHT_GREY;
93 m_labelBackgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
94 m_labelBackgroundBrush
= wxNullBrush
;
95 m_labelTextFont
= wxNullFont
;
96 m_cellTextFont
= wxNullFont
;
97 m_textItem
= (wxTextCtrl
*) NULL
;
98 m_currentRectVisible
= FALSE
;
101 m_editInPlace
= FALSE
;
102 m_inOnTextInPlace
= FALSE
;
104 #if defined(__WIN95__)
105 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
106 #elif defined(__WXGTK__)
107 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
111 m_dragStatus
= wxGRID_DRAG_NONE
;
113 m_dragStartPosition
= 0;
114 m_dragLastPosition
= 0;
115 m_divisionPen
= wxNullPen
;
116 m_leftOfSheet
= wxGRID_DEFAULT_SHEET_LEFT
;
117 m_topOfSheet
= wxGRID_DEFAULT_SHEET_TOP
;
118 m_cellHeight
= wxGRID_DEFAULT_CELL_HEIGHT
;
119 m_totalGridWidth
= 0;
120 m_totalGridHeight
= 0;
121 m_colWidths
= (short *) NULL
;
122 m_rowHeights
= (short *) NULL
;
123 m_verticalLabelWidth
= wxGRID_DEFAULT_VERTICAL_LABEL_WIDTH
;
124 m_horizontalLabelHeight
= wxGRID_DEFAULT_HORIZONAL_LABEL_HEIGHT
;
125 m_verticalLabelAlignment
= wxCENTRE
;
126 m_horizontalLabelAlignment
= wxCENTRE
;
127 m_editControlPosition
.x
= wxGRID_DEFAULT_EDIT_X
;
128 m_editControlPosition
.y
= wxGRID_DEFAULT_EDIT_Y
;
129 m_editControlPosition
.width
= wxGRID_DEFAULT_EDIT_WIDTH
;
130 m_editControlPosition
.height
= wxGRID_DEFAULT_EDIT_HEIGHT
;
135 m_editCreated
= FALSE
;
138 m_gridCells
= (wxGridCell
***) NULL
;
139 m_rowLabelCells
= (wxGridCell
**) NULL
;
140 m_colLabelCells
= (wxGridCell
**) NULL
;
141 m_textItem
= (wxTextCtrl
*) NULL
;
144 bool wxGenericGrid::Create(wxWindow
*parent
,
149 const wxString
& name
)
154 m_editingPanel
= (wxPanel
*) NULL
;
155 m_hScrollBar
= (wxScrollBar
*) NULL
;
156 m_vScrollBar
= (wxScrollBar
*) NULL
;
157 m_cellTextColour
= *wxBLACK
;
158 m_cellBackgroundColour
= *wxWHITE
;
159 m_labelTextColour
= *wxBLACK
;
160 // m_labelBackgroundColour = *wxLIGHT_GREY;
161 m_labelBackgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
162 m_labelBackgroundBrush
= wxNullBrush
;
163 m_labelTextFont
= * wxTheFontList
->FindOrCreateFont(10, wxSWISS
, wxNORMAL
, wxBOLD
);
164 m_cellTextFont
= * wxTheFontList
->FindOrCreateFont(10, wxSWISS
, wxNORMAL
, wxNORMAL
);
165 m_textItem
= (wxTextCtrl
*) NULL
;
166 m_currentRectVisible
= FALSE
;
168 m_editInPlace
= FALSE
;
169 m_inOnTextInPlace
= FALSE
;
170 #if defined(__WIN95__)
171 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
172 #elif defined(__WXGTK__)
173 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
177 m_dragStatus
= wxGRID_DRAG_NONE
;
179 m_dragStartPosition
= 0;
180 m_dragLastPosition
= 0;
181 m_divisionPen
= * wxThePenList
->FindOrCreatePen("LIGHT GREY", 1, wxSOLID
);
182 m_doubleBufferingBitmap
= (wxBitmap
*) NULL
;
184 if (!m_horizontalSashCursor
.Ok())
186 m_horizontalSashCursor
= wxCursor(wxCURSOR_SIZEWE
);
187 m_verticalSashCursor
= wxCursor(wxCURSOR_SIZENS
);
190 SetLabelBackgroundColour(m_labelBackgroundColour
);
192 m_leftOfSheet
= wxGRID_DEFAULT_SHEET_LEFT
;
193 m_topOfSheet
= wxGRID_DEFAULT_SHEET_TOP
;
194 m_cellHeight
= wxGRID_DEFAULT_CELL_HEIGHT
;
195 m_totalGridWidth
= 0;
196 m_totalGridHeight
= 0;
197 m_colWidths
= (short *) NULL
;
198 m_rowHeights
= (short *) NULL
;
200 m_verticalLabelWidth
= wxGRID_DEFAULT_VERTICAL_LABEL_WIDTH
;
201 m_horizontalLabelHeight
= wxGRID_DEFAULT_HORIZONAL_LABEL_HEIGHT
;
202 m_verticalLabelAlignment
= wxCENTRE
;
203 m_horizontalLabelAlignment
= wxCENTRE
;
204 m_editControlPosition
.x
= wxGRID_DEFAULT_EDIT_X
;
205 m_editControlPosition
.y
= wxGRID_DEFAULT_EDIT_Y
;
206 m_editControlPosition
.width
= wxGRID_DEFAULT_EDIT_WIDTH
;
207 m_editControlPosition
.height
= wxGRID_DEFAULT_EDIT_HEIGHT
;
215 /* Store the rect. coordinates for the current cell */
216 SetCurrentRect(m_wCursorRow
, m_wCursorColumn
);
218 m_editCreated
= FALSE
;
222 m_gridCells
= (wxGridCell
***) NULL
;
223 m_rowLabelCells
= (wxGridCell
**) NULL
;
224 m_colLabelCells
= (wxGridCell
**) NULL
;
225 m_textItem
= (wxTextCtrl
*) NULL
;
227 wxPanel::Create(parent
, id
, pos
, size
, style
, name
);
229 m_editingPanel
= new wxPanel(this);
231 m_textItem
= new wxTextCtrl(m_editingPanel
, wxGRID_TEXT_CTRL
, "",
232 wxPoint(m_editControlPosition
.x
, m_editControlPosition
.y
),
233 wxSize(m_editControlPosition
.width
, -1),
235 m_textItem
->Show(TRUE
);
236 m_textItem
->SetFocus();
237 int controlW
, controlH
;
239 m_textItem
->GetSize(&controlW
, &controlH
);
240 m_editControlPosition
.height
= controlH
;
242 m_topOfSheet
= m_editControlPosition
.y
+ controlH
+ 2;
244 m_editCreated
= TRUE
;
246 m_hScrollBar
= new wxScrollBar(this, wxGRID_HSCROLL
, wxPoint(0, 0), wxSize(20, 100), wxHORIZONTAL
);
247 m_vScrollBar
= new wxScrollBar(this, wxGRID_VSCROLL
, wxPoint(0, 0), wxSize(100, 20), wxVERTICAL
);
249 // SetSize(pos.x, pos.y, size.x, size.y);
251 m_inPlaceTextItem
= new wxTextCtrl( (wxPanel
*)this, wxGRID_EDIT_IN_PLACE_TEXT_CTRL
, "",
252 wxPoint( m_currentRect
.x
-2, m_currentRect
.y
-2 ),
253 wxSize( m_currentRect
.width
+4, m_currentRect
.height
+4 ),
254 wxNO_BORDER
| wxTE_PROCESS_ENTER
);
255 m_inPlaceTextItem
->Show(m_editInPlace
);
257 m_inPlaceTextItem
->SetFocus();
262 wxGenericGrid::~wxGenericGrid()
267 void wxGenericGrid::ClearGrid()
272 for (i
= 0; i
< m_totalRows
; i
++)
274 for (j
= 0; j
< m_totalCols
; j
++)
275 if (m_gridCells
[i
][j
])
276 delete m_gridCells
[i
][j
];
277 delete[] m_gridCells
[i
];
279 delete[] m_gridCells
;
280 m_gridCells
= (wxGridCell
***) NULL
;
283 delete[] m_colWidths
;
284 m_colWidths
= (short *) NULL
;
286 delete[] m_rowHeights
;
287 m_rowHeights
= (short *) NULL
;
291 for (i
= 0; i
< m_totalRows
; i
++)
292 delete m_rowLabelCells
[i
];
293 delete[] m_rowLabelCells
;
294 m_rowLabelCells
= (wxGridCell
**) NULL
;
298 for (i
= 0; i
< m_totalCols
; i
++)
299 delete m_colLabelCells
[i
];
300 delete[] m_colLabelCells
;
301 m_colLabelCells
= (wxGridCell
**) NULL
;
303 if (m_doubleBufferingBitmap
)
305 delete m_doubleBufferingBitmap
;
306 m_doubleBufferingBitmap
= (wxBitmap
*) NULL
;
310 bool wxGenericGrid::CreateGrid(int nRows
, int nCols
, wxString
**cellValues
, short *widths
,
311 short defaultWidth
, short defaultHeight
)
317 m_colWidths
= new short[nCols
];
318 m_rowHeights
= new short[nRows
];
319 for (i
= 0; i
< nCols
; i
++)
321 m_colWidths
[i
] = widths
[i
];
323 m_colWidths
[i
] = defaultWidth
;
324 for (i
= 0; i
< nRows
; i
++)
325 m_rowHeights
[i
] = defaultHeight
;
327 m_gridCells
= new wxGridCell
**[nRows
];
329 for (i
= 0; i
< nRows
; i
++)
330 m_gridCells
[i
] = new wxGridCell
*[nCols
];
332 for (i
= 0; i
< nRows
; i
++)
333 for (j
= 0; j
< nCols
; j
++)
336 //m_gridCells[i][j] = OnCreateCell();
337 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CREATE_CELL
, this, i
, j
);
338 GetEventHandler()->ProcessEvent(g_evt
);
339 m_gridCells
[i
][j
] = g_evt
.m_cell
;
340 m_gridCells
[i
][j
]->SetTextValue(cellValues
[i
][j
]);
343 m_gridCells
[i
][j
] = (wxGridCell
*) NULL
;
345 m_rowLabelCells
= new wxGridCell
*[nRows
];
346 for (i
= 0; i
< nRows
; i
++)
347 m_rowLabelCells
[i
] = new wxGridCell(this);
348 m_colLabelCells
= new wxGridCell
*[nCols
];
349 for (i
= 0; i
< nCols
; i
++)
350 m_colLabelCells
[i
] = new wxGridCell(this);
352 m_wCursorRow
= m_wCursorColumn
= 0;
353 SetCurrentRect(0, 0);
355 // Need to determine various dimensions
359 int objectSizeX
= m_totalCols
;
361 int viewLengthX
= m_totalCols
;
364 m_hScrollBar->SetViewLength(viewLengthX);
365 m_hScrollBar->SetObjectLength(objectSizeX);
366 m_hScrollBar->SetPageSize(pageSizeX);
368 m_hScrollBar
->SetScrollbar(m_hScrollBar
->GetThumbPosition(), pageSizeX
, objectSizeX
, viewLengthX
);
370 int objectSizeY
= m_totalRows
;
372 int viewLengthY
= m_totalRows
;
375 m_vScrollBar->SetViewLength(viewLengthY);
376 m_vScrollBar->SetObjectLength(objectSizeY);
377 m_vScrollBar->SetPageSize(pageSizeY);
380 m_vScrollBar
->SetScrollbar(m_vScrollBar
->GetThumbPosition(), pageSizeY
, objectSizeY
, viewLengthY
);
385 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
386 GetEventHandler()->ProcessEvent(g_evt
);
388 //OnChangeSelectionLabel();
389 wxGridEvent
g_evt2(GetId(), wxEVT_GRID_CHANGE_SEL_LABEL
, this);
390 GetEventHandler()->ProcessEvent(g_evt2
);
395 // Need to determine various dimensions
396 void wxGenericGrid::UpdateDimensions()
398 int canvasWidth
, canvasHeight
;
399 GetSize(&canvasWidth
, &canvasHeight
);
401 if (m_editCreated
&& m_editable
)
403 int controlW
, controlH
;
404 GetTextItem()->GetSize(&controlW
, &controlH
);
405 m_topOfSheet
= m_editControlPosition
.y
+ controlH
+ 2;
409 m_rightOfSheet
= m_leftOfSheet
+ m_verticalLabelWidth
;
411 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
413 if (m_rightOfSheet
> canvasWidth
)
416 m_rightOfSheet
+= m_colWidths
[i
];
418 m_bottomOfSheet
= m_topOfSheet
+ m_horizontalLabelHeight
;
419 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
421 if (m_bottomOfSheet
> canvasHeight
)
424 m_bottomOfSheet
+= m_rowHeights
[i
];
427 m_totalGridWidth
= m_leftOfSheet
+ m_verticalLabelWidth
;
428 for (i
= 0; i
< m_totalCols
; i
++)
430 m_totalGridWidth
+= m_colWidths
[i
];
432 m_totalGridHeight
= m_topOfSheet
+ m_horizontalLabelHeight
;
433 for (i
= 0; i
< m_totalRows
; i
++)
435 m_totalGridHeight
+= m_rowHeights
[i
];
439 wxGridCell
*wxGenericGrid::GetCell(int row
, int col
) const
442 return (wxGridCell
*) NULL
;
444 if ((row
>= m_totalRows
) || (col
>= m_totalCols
))
445 return (wxGridCell
*) NULL
;
447 wxGridCell
*cell
= m_gridCells
[row
][col
];
450 // m_gridCells[row][col] = OnCreateCell();
451 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CREATE_CELL
, (wxGenericGrid
*) this, row
, col
);
452 GetEventHandler()->ProcessEvent(g_evt
);
453 m_gridCells
[row
][col
] = g_evt
.m_cell
;
454 return m_gridCells
[row
][col
];
460 void wxGenericGrid::SetGridClippingRegion(wxDC
*dc
)
462 int m_scrollWidthHoriz
= 0;
463 int m_scrollWidthVert
= 0;
465 GetClientSize(&cw
, &ch
);
467 if (m_hScrollBar
&& m_hScrollBar
->IsShown())
468 m_scrollWidthHoriz
= m_scrollWidth
;
469 if (m_vScrollBar
&& m_vScrollBar
->IsShown())
470 m_scrollWidthVert
= m_scrollWidth
;
472 // Don't paint over the scrollbars
473 dc
->SetClippingRegion(m_leftOfSheet
, m_topOfSheet
,
474 cw
- m_scrollWidthVert
- m_leftOfSheet
, ch
- m_scrollWidthHoriz
- m_topOfSheet
);
477 void wxGenericGrid::OnPaint(wxPaintEvent
& WXUNUSED(event
))
480 GetClientSize(&w
, &h
);
482 bool useDoubleBuffering
= (bool) wxUSE_DOUBLE_BUFFERING
;
483 if (useDoubleBuffering
)
485 // Reuse the old bitmap if possible
487 if (!m_doubleBufferingBitmap
||
488 (m_doubleBufferingBitmap
->GetWidth() < w
|| m_doubleBufferingBitmap
->GetHeight() < h
))
490 if (m_doubleBufferingBitmap
)
491 delete m_doubleBufferingBitmap
;
492 m_doubleBufferingBitmap
= new wxBitmap(w
, h
);
494 if (!m_doubleBufferingBitmap
|| !m_doubleBufferingBitmap
->Ok())
496 // If we couldn't create a new bitmap, perhaps because resources were low,
497 // then don't complain, just don't double-buffer
498 if (m_doubleBufferingBitmap
)
499 delete m_doubleBufferingBitmap
;
500 m_doubleBufferingBitmap
= (wxBitmap
*) NULL
;
501 useDoubleBuffering
= FALSE
;
505 if (useDoubleBuffering
)
507 wxPaintDC
paintDC(this);
508 wxMemoryDC
dc(& paintDC
);
509 dc
.SelectObject(* m_doubleBufferingBitmap
);
513 int vertScrollBarWidth
= m_scrollWidth
;
514 int horizScrollBarHeight
= m_scrollWidth
;
515 if (m_vScrollBar
&& !m_vScrollBar
->IsShown())
516 vertScrollBarWidth
= 0;
517 if (m_hScrollBar
&& !m_hScrollBar
->IsShown())
518 horizScrollBarHeight
= 0;
520 paintDC
.Blit(m_leftOfSheet
, m_topOfSheet
, w
- vertScrollBarWidth
- m_leftOfSheet
, h
- horizScrollBarHeight
- m_topOfSheet
,
521 &dc
, m_leftOfSheet
, m_topOfSheet
, wxCOPY
);
523 dc
.SelectObject(wxNullBitmap
);
532 void wxGenericGrid::PaintGrid(wxDC
& dc
)
535 dc
.SetOptimization(FALSE
);
537 SetGridClippingRegion(& dc
);
539 DrawLabelAreas(& dc
);
541 DrawEditableArea(& dc
);
542 DrawColumnLabels(& dc
);
547 /* Hilight present cell */
548 SetCurrentRect(m_wCursorRow
, m_wCursorColumn
);
549 if (m_currentRectVisible
&& !(m_editable
&& m_editInPlace
))
552 dc
.DestroyClippingRegion();
553 dc
.SetOptimization(TRUE
);
557 // Erase (some of) the background.
558 // Currently, a Windows-only optimisation.
559 void wxGenericGrid::OnEraseBackground(wxEraseEvent
& WXUNUSED(event
) )
563 dc
.SetOptimization(FALSE
);
566 GetClientSize(& w
, & h
);
567 dc
.SetBrush(*wxLIGHT_GREY_BRUSH
);
568 dc
.SetPen(*wxLIGHT_GREY_PEN
);
570 if (m_hScrollBar
&& m_hScrollBar
->IsShown() && m_vScrollBar
&& m_vScrollBar
->IsShown())
572 dc
.DrawRectangle(w
- m_scrollWidth
, h
- m_scrollWidth
, m_scrollWidth
, m_scrollWidth
);
575 dc
.SetOptimization(TRUE
);
580 void wxGenericGrid::DrawLabelAreas(wxDC
*dc
)
583 GetClientSize(&cw
, &ch
);
585 dc
->SetPen(*wxTRANSPARENT_PEN
);
586 // dc->SetBrush(*dc->GetBackground());
588 // Should blank out any area which isn't going to be painted over.
589 // dc->DrawRectangle(m_leftOfSheet, m_bottomOfSheet, cw - m_leftOfSheet, ch - m_bottomOfSheet);
590 // dc->DrawRectangle(m_rightOfSheet, m_topOfSheet, cw - m_rightOfSheet, ch - m_topOfSheet);
592 // Paint the label areas
593 dc
->SetBrush(m_labelBackgroundBrush
);
594 // dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, m_rightOfSheet - m_leftOfSheet + 1, m_horizontalLabelHeight + 1);
595 dc
->DrawRectangle(m_leftOfSheet
, m_topOfSheet
, cw
-m_leftOfSheet
, m_horizontalLabelHeight
+ 1);
596 // dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, m_verticalLabelWidth + 1, m_bottomOfSheet - m_topOfSheet + 1);
597 dc
->DrawRectangle(m_leftOfSheet
, m_topOfSheet
, m_verticalLabelWidth
+ 1, ch
-m_topOfSheet
);
600 void wxGenericGrid::DrawEditableArea(wxDC
*dc
)
603 GetClientSize(&cw
, &ch
);
605 dc
->SetPen(*wxTRANSPARENT_PEN
);
606 dc
->SetBrush(*wxTheBrushList
->FindOrCreateBrush(m_cellBackgroundColour
, wxSOLID
));
607 // dc->DrawRectangle(m_leftOfSheet+m_verticalLabelWidth, m_topOfSheet+m_horizontalLabelHeight,
608 // m_rightOfSheet-(m_leftOfSheet+m_verticalLabelWidth) + 1, m_bottomOfSheet - (m_topOfSheet+m_horizontalLabelHeight) + 1);
609 dc
->DrawRectangle(m_leftOfSheet
+m_verticalLabelWidth
, m_topOfSheet
+m_horizontalLabelHeight
,
610 cw
-(m_leftOfSheet
+m_verticalLabelWidth
), ch
- (m_topOfSheet
+m_horizontalLabelHeight
));
613 void wxGenericGrid::DrawGridLines(wxDC
*dc
)
616 GetClientSize(&cw
, &ch
);
620 if (m_divisionPen
.Ok())
622 dc
->SetPen(m_divisionPen
);
624 int heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
626 // Draw horizontal grey lines for cells
627 for (i
= m_scrollPosY
; i
< (m_totalRows
+1); i
++)
629 if (heightCount
> ch
)
633 dc
->DrawLine(m_leftOfSheet
, heightCount
,
636 heightCount
+= m_rowHeights
[i
];
641 if (m_verticalLabelWidth
> 0)
643 dc
->SetPen(*wxBLACK_PEN
);
645 // Draw horizontal black lines for row labels
646 int heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
647 for (i
= m_scrollPosY
; i
< (m_totalRows
+1); i
++)
649 if (heightCount
> ch
)
653 dc
->DrawLine(m_leftOfSheet
, heightCount
,
654 m_verticalLabelWidth
, heightCount
);
656 heightCount
+= m_rowHeights
[i
];
659 // Draw a black vertical line for row number cells
660 dc
->DrawLine(m_leftOfSheet
+ m_verticalLabelWidth
, m_topOfSheet
,
661 m_leftOfSheet
+ m_verticalLabelWidth
, ch
);
662 // First vertical line
663 dc
->DrawLine(m_leftOfSheet
, m_topOfSheet
, m_leftOfSheet
, ch
);
665 dc
->SetPen(*wxWHITE_PEN
);
667 // Draw highlights on row labels
668 heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
669 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
671 if (heightCount
> ch
)
675 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
676 m_verticalLabelWidth
, heightCount
+1);
677 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
678 m_leftOfSheet
+1, heightCount
+ m_rowHeights
[i
] - 1);
679 heightCount
+= m_rowHeights
[i
];
682 // Last one - down to the floor.
683 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
684 m_verticalLabelWidth
, heightCount
+1);
685 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
686 m_leftOfSheet
+1, ch
);
690 if (m_divisionPen
.Ok())
692 dc
->SetPen(m_divisionPen
);
694 // Draw vertical grey lines for cells
695 int widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
696 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
702 // Skip the first one
703 if (i
!= m_scrollPosX
)
705 dc
->DrawLine(widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
,
706 widthCount
, m_bottomOfSheet
);
708 widthCount
+= m_colWidths
[i
];
712 dc
->DrawLine(widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
,
713 widthCount
, m_bottomOfSheet
);
716 dc
->SetPen(*wxBLACK_PEN
);
718 // Draw two black horizontal lines for column number cells
720 m_leftOfSheet
, m_topOfSheet
,
722 dc
->DrawLine(m_leftOfSheet
, m_topOfSheet
+ m_horizontalLabelHeight
,
723 cw
, m_topOfSheet
+ m_horizontalLabelHeight
);
725 if (m_horizontalLabelHeight
> 0)
727 int widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
729 // Draw black vertical lines for column number cells
730 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
736 dc
->DrawLine(widthCount
, m_topOfSheet
,
737 widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
);
738 widthCount
+= m_colWidths
[i
];
743 dc
->DrawLine(widthCount
, m_topOfSheet
,
744 widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
);
747 dc
->SetPen(*wxWHITE_PEN
);
748 widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
750 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
756 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
757 widthCount
+m_colWidths
[i
], m_topOfSheet
+1);
758 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
759 widthCount
+1, m_topOfSheet
+m_horizontalLabelHeight
);
760 widthCount
+= m_colWidths
[i
];
763 // Last one - to the right side of the canvas.
764 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
766 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
767 widthCount
+1, m_topOfSheet
+m_horizontalLabelHeight
);
772 void wxGenericGrid::DrawColumnLabels(wxDC
*dc
)
775 GetClientSize(&cw
, &ch
);
777 if (m_horizontalLabelHeight
== 0)
783 // Draw letters for columns
784 rect
.y
= m_topOfSheet
+ 1;
785 rect
.height
= m_horizontalLabelHeight
- 1;
787 dc
->SetTextBackground(m_labelBackgroundColour
);
788 dc
->SetBackgroundMode(wxTRANSPARENT
);
789 // dc->SetTextForeground(m_labelTextColour);
791 int widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
792 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
798 rect
.x
= 1 + widthCount
;
799 rect
.width
= m_colWidths
[i
];
800 DrawColumnLabel(dc
, &rect
, i
);
802 widthCount
+= m_colWidths
[i
];
807 void wxGenericGrid::DrawColumnLabel(wxDC
*dc
, wxRect
*rect
, int col
)
809 wxGridCell
*cell
= GetLabelCell(wxHORIZONTAL
, col
);
818 dc
->SetTextForeground(GetLabelTextColour());
819 dc
->SetFont(GetLabelTextFont());
820 if ( !cell
->GetTextValue().IsNull() )
821 DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, GetLabelAlignment(wxHORIZONTAL
));
825 void wxGenericGrid::DrawRowLabels(wxDC
*dc
)
828 GetClientSize(&cw
, &ch
);
830 if (m_verticalLabelWidth
== 0)
836 // Draw numbers for rows
837 rect
.x
= m_leftOfSheet
;
838 rect
.width
= m_verticalLabelWidth
;
840 int heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
842 dc
->SetTextBackground(m_labelBackgroundColour
);
843 dc
->SetBackgroundMode(wxTRANSPARENT
);
845 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
847 if (heightCount
> ch
)
851 rect
.y
= 1 + heightCount
;
852 rect
.height
= m_rowHeights
[i
];
853 DrawRowLabel(dc
, &rect
, i
);
855 heightCount
+= m_rowHeights
[i
];
860 void wxGenericGrid::DrawRowLabel(wxDC
*dc
, wxRect
*rect
, int row
)
862 wxGridCell
*cell
= GetLabelCell(wxVERTICAL
, row
);
871 dc
->SetTextForeground(GetLabelTextColour());
872 dc
->SetFont(GetLabelTextFont());
873 if ( !cell
->GetTextValue().IsNull() )
874 DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, GetLabelAlignment(wxVERTICAL
));
878 void wxGenericGrid::DrawCells(wxDC
*dc
)
881 GetClientSize(&cw
, &ch
);
885 // Draw value corresponding to each cell
886 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
888 for (j
= m_scrollPosX
; j
< m_totalCols
; j
++)
890 SetCurrentRect(i
, j
, cw
, ch
);
891 if (m_currentRectVisible
)
893 DrawCellBackground(dc
, &m_currentRect
, i
, j
);
894 DrawCellValue(dc
, &m_currentRect
, i
, j
);
896 if (m_currentRect
.x
> cw
)
899 if (m_currentRect
.y
> ch
)
902 dc
->SetBackgroundMode(wxSOLID
);
903 dc
->SetPen(*wxBLACK_PEN
);
906 void wxGenericGrid::DrawCellBackground(wxDC
*dc
, wxRect
*rect
, int row
, int col
)
908 wxGridCell
*cell
= GetCell(row
, col
);
911 dc
->SetBrush(cell
->GetBackgroundBrush());
912 dc
->SetPen(*wxTRANSPARENT_PEN
);
914 #if 0 // In wxWin 2.0 the dc code is exact. RR.
916 dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
-1, rect
->height
-1);
918 dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
, rect
->height
);
922 dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
-1, rect
->height
-1);
924 dc
->SetPen(*wxBLACK_PEN
);
928 void wxGenericGrid::DrawCellValue(wxDC
*dc
, wxRect
*rect
, int row
, int col
)
930 wxGridCell
*cell
= GetCell(row
, col
);
933 wxBitmap
*bitmap
= cell
->GetCellBitmap();
943 DrawBitmapRect(dc
, bitmap
, &rect2
, cell
->GetAlignment());
947 dc
->SetBackgroundMode(wxTRANSPARENT
);
948 dc
->SetTextForeground(cell
->GetTextColour());
949 dc
->SetFont(cell
->GetFont());
951 if ( !cell
->GetTextValue().IsNull() )
952 DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, cell
->GetAlignment());
957 void wxGenericGrid::AdjustScrollbars()
960 GetClientSize(&cw
, &ch
);
962 // We find the view size by seeing how many rows/cols fit on
964 // BUT... this means that the scrollbar should be adjusted every time
965 // it's scrolled, as well as when sized, because with variable size rows/cols,
966 // the number of rows/col visible on the view differs according to what bit
967 // you're looking at. The object length is always the same, but the
968 // view length differs.
970 // Since this may not be known until the end of this function, we should probably call AdjustScrollbars
972 int vertScrollBarWidth
= m_scrollWidth
;
973 int horizScrollBarHeight
= m_scrollWidth
;
974 if (m_vScrollBar
&& !m_vScrollBar
->IsShown())
975 vertScrollBarWidth
= 0;
976 if (m_hScrollBar
&& !m_hScrollBar
->IsShown())
977 horizScrollBarHeight
= 0;
979 int noHorizSteps
= 0;
982 if (m_totalGridWidth
+ vertScrollBarWidth
> cw
)
988 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
990 widthCount
+= m_colWidths
[i
];
991 // A partial bit doesn't count, we still have to scroll to see the
993 if (widthCount
+ m_leftOfSheet
+ m_verticalLabelWidth
> (cw
-vertScrollBarWidth
))
1001 m_viewWidth
= noHorizSteps
;
1003 if (m_totalGridHeight
+ horizScrollBarHeight
> ch
)
1005 int heightCount
= 0;
1009 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1011 heightCount
+= m_rowHeights
[i
];
1012 // A partial bit doesn't count, we still have to scroll to see the
1014 if (heightCount
+ m_topOfSheet
+ m_horizontalLabelHeight
> (ch
-horizScrollBarHeight
))
1023 m_viewHeight
= noVertSteps
;
1025 if (m_totalGridWidth
+ vertScrollBarWidth
<= cw
)
1028 m_hScrollBar
->Show(FALSE
);
1034 m_hScrollBar
->Show(TRUE
);
1037 if (m_totalGridHeight
+ horizScrollBarHeight
<= ch
)
1040 m_vScrollBar
->Show(FALSE
);
1046 m_vScrollBar
->Show(TRUE
);
1049 UpdateDimensions(); // Necessary in case m_scrollPosX/Y changed
1051 vertScrollBarWidth
= m_scrollWidth
;
1052 horizScrollBarHeight
= m_scrollWidth
;
1053 if (m_vScrollBar
&& !m_vScrollBar
->IsShown())
1054 vertScrollBarWidth
= 0;
1055 if (m_hScrollBar
&& !m_hScrollBar
->IsShown())
1056 horizScrollBarHeight
= 0;
1058 if (m_hScrollBar
&& m_hScrollBar
->IsShown())
1060 int nCols
= GetCols();
1061 m_hScrollBar
->SetScrollbar(m_hScrollBar
->GetThumbPosition(), wxMax(noHorizSteps
, 1), (noHorizSteps
== 0) ? 1 : nCols
, wxMax(noHorizSteps
, 1));
1064 m_hScrollBar->SetSize(m_leftOfSheet, ch - m_scrollWidth -2, // why -2 ? Robert.
1065 cw - vertScrollBarWidth - m_leftOfSheet, m_scrollWidth);
1067 m_hScrollBar
->SetSize(m_leftOfSheet
, ch
- m_scrollWidth
,
1068 cw
- vertScrollBarWidth
- m_leftOfSheet
, m_scrollWidth
);
1072 if (m_vScrollBar
&& m_vScrollBar
->IsShown())
1074 int nRows
= GetRows();
1076 m_vScrollBar
->SetScrollbar(m_vScrollBar
->GetThumbPosition(), wxMax(noVertSteps
, 1), (noVertSteps
== 0) ? 1 : nRows
, wxMax(noVertSteps
, 1));
1077 m_vScrollBar
->SetSize(cw
- m_scrollWidth
, m_topOfSheet
,
1078 m_scrollWidth
, ch
- m_topOfSheet
- horizScrollBarHeight
);
1082 void wxGenericGrid::OnSize(wxSizeEvent
& WXUNUSED(event
) )
1084 if (!m_vScrollBar
|| !m_hScrollBar
)
1090 GetClientSize(&cw
, &ch
);
1092 if (m_editCreated
&& m_editingPanel
&& GetTextItem() && GetTextItem()->IsShown())
1094 m_editingPanel
->SetSize(0, 0, cw
, m_editControlPosition
.height
+ m_editControlPosition
.y
+ 2);
1095 GetTextItem()->SetSize(m_editControlPosition
.x
, m_editControlPosition
.y
,
1096 cw
- 2*m_editControlPosition
.x
, m_editControlPosition
.height
);
1100 bool wxGenericGrid::CellHitTest(int x
, int y
, int *row
, int *col
)
1102 // Find the selected cell and call OnSelectCell
1103 if (x
>= (m_leftOfSheet
+ m_verticalLabelWidth
) && y
>= (m_topOfSheet
+ m_horizontalLabelHeight
) &&
1104 x
<= m_rightOfSheet
&& y
<= m_bottomOfSheet
)
1106 // Calculate the cell number from x and y
1107 x
-= (m_verticalLabelWidth
+ m_leftOfSheet
);
1108 y
-= (m_topOfSheet
+ m_horizontalLabelHeight
);
1112 // Now we need to do a hit test for which row we're on
1113 int currentHeight
= 0;
1114 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1116 if (y
>= currentHeight
&& y
<= (currentHeight
+ m_rowHeights
[i
]))
1121 currentHeight
+= m_rowHeights
[i
];
1124 // Now we need to do a hit test for which column we're on
1125 int currentWidth
= 0;
1126 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1128 if (x
>= currentWidth
&& x
<= (currentWidth
+ m_colWidths
[i
]))
1133 currentWidth
+= m_colWidths
[i
];
1140 bool wxGenericGrid::LabelSashHitTest(int x
, int y
, int *orientation
, int *rowOrCol
, int *startPos
)
1145 if (x
>= (m_leftOfSheet
+ m_verticalLabelWidth
) && y
>= m_topOfSheet
&&
1146 x
<= m_rightOfSheet
&& y
<= (m_topOfSheet
+ m_horizontalLabelHeight
))
1148 // We may be on a column label sash.
1149 int currentWidth
= m_leftOfSheet
+ m_verticalLabelWidth
;
1150 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1152 if (x
>= (currentWidth
+ m_colWidths
[i
] - tolerance
) && x
<= (currentWidth
+ m_colWidths
[i
] + tolerance
))
1154 *orientation
= wxHORIZONTAL
;
1156 *startPos
= currentWidth
;
1159 currentWidth
+= m_colWidths
[i
];
1163 else if (x
>= m_leftOfSheet
&& y
>= (m_topOfSheet
+ m_horizontalLabelHeight
) &&
1164 x
<= (m_leftOfSheet
+ m_verticalLabelWidth
) && y
<= m_bottomOfSheet
)
1166 // We may be on a row label sash.
1167 int currentHeight
= m_topOfSheet
+ m_horizontalLabelHeight
;
1168 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1170 if (y
>= (currentHeight
+ m_rowHeights
[i
] - tolerance
) && y
<= (currentHeight
+ m_rowHeights
[i
] + tolerance
))
1172 *orientation
= wxVERTICAL
;
1174 *startPos
= currentHeight
;
1177 currentHeight
+= m_rowHeights
[i
];
1184 bool wxGenericGrid::LabelHitTest(int x
, int y
, int *row
, int *col
)
1186 // Find the selected label
1187 if (x
>= m_leftOfSheet
&& y
>= m_topOfSheet
&&
1188 x
<= m_rightOfSheet
&& y
<= m_bottomOfSheet
)
1190 // Calculate the cell number from x and y
1196 // Now we need to do a hit test for which row we're on
1197 int currentHeight
= m_horizontalLabelHeight
;
1198 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1200 if (y
>= currentHeight
&& y
<= (currentHeight
+ m_rowHeights
[i
]))
1205 currentHeight
+= m_rowHeights
[i
];
1207 if (y
>= 0 && y
<= m_horizontalLabelHeight
)
1212 // Now we need to do a hit test for which column we're on
1213 int currentWidth
= m_verticalLabelWidth
;
1214 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1216 if (x
>= currentWidth
&& x
<= (currentWidth
+ m_colWidths
[i
]))
1221 currentWidth
+= m_colWidths
[i
];
1223 if (x
>= 0 && x
<= m_verticalLabelWidth
)
1228 if ((*col
== -1) || (*row
== -1))
1236 void wxGenericGrid::OnMouseEvent(wxMouseEvent
& ev
)
1240 wxClientDC
dc(this);
1244 if (CellHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1246 OnSelectCellImplementation(& dc
, row
, col
);
1248 //OnCellLeftClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1249 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CELL_LCLICK
, this,
1250 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1251 ev
.ControlDown(), ev
.ShiftDown());
1252 GetEventHandler()->ProcessEvent(g_evt
);
1255 if (LabelHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1257 //OnLabelLeftClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1258 wxGridEvent
g_evt(GetId(), wxEVT_GRID_LABEL_LCLICK
, this,
1259 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1260 ev
.ControlDown(), ev
.ShiftDown());
1261 GetEventHandler()->ProcessEvent(g_evt
);
1266 else if (ev
.Dragging() && ev
.LeftIsDown())
1268 switch (m_dragStatus
)
1270 case wxGRID_DRAG_NONE
:
1273 if (LabelSashHitTest((int)ev
.GetX(), (int)ev
.GetY(), &orientation
, &m_dragRowOrCol
, &m_dragStartPosition
))
1275 if (orientation
== wxHORIZONTAL
)
1277 m_dragStatus
= wxGRID_DRAG_LEFT_RIGHT
;
1278 SetCursor(m_horizontalSashCursor
);
1279 m_dragLastPosition
= (int)ev
.GetX();
1283 m_dragStatus
= wxGRID_DRAG_UP_DOWN
;
1284 SetCursor(m_verticalSashCursor
);
1285 m_dragLastPosition
= (int)ev
.GetY();
1287 wxClientDC
dc(this);
1289 dc
.SetLogicalFunction(wxINVERT
);
1290 if (orientation
== wxHORIZONTAL
)
1291 dc
.DrawLine((int)ev
.GetX(), m_topOfSheet
, (int)ev
.GetX(), m_bottomOfSheet
);
1293 dc
.DrawLine(m_leftOfSheet
, (int)ev
.GetY(), m_rightOfSheet
, (int)ev
.GetY());
1300 case wxGRID_DRAG_LEFT_RIGHT
:
1302 wxClientDC
dc(this);
1304 dc
.SetLogicalFunction(wxINVERT
);
1305 dc
.DrawLine(m_dragLastPosition
, m_topOfSheet
, m_dragLastPosition
, m_bottomOfSheet
);
1307 dc
.DrawLine((int)ev
.GetX(), m_topOfSheet
, (int)ev
.GetX(), m_bottomOfSheet
);
1310 m_dragLastPosition
= (int)ev
.GetX();
1311 SetCursor(m_horizontalSashCursor
);
1314 case wxGRID_DRAG_UP_DOWN
:
1316 wxClientDC
dc(this);
1318 dc
.SetLogicalFunction(wxINVERT
);
1319 dc
.DrawLine(m_leftOfSheet
, m_dragLastPosition
, m_rightOfSheet
, m_dragLastPosition
);
1321 dc
.DrawLine(m_leftOfSheet
, (int)ev
.GetY(), m_rightOfSheet
, (int)ev
.GetY());
1324 m_dragLastPosition
= (int)ev
.GetY();
1325 SetCursor(m_verticalSashCursor
);
1330 else if (ev
.Moving())
1332 int rowOrCol
, orientation
, startPos
;
1333 if (LabelSashHitTest((int)ev
.GetX(), (int)ev
.GetY(), &orientation
, &rowOrCol
, &startPos
))
1335 if (orientation
== wxHORIZONTAL
)
1336 SetCursor(m_horizontalSashCursor
);
1338 SetCursor(m_verticalSashCursor
);
1341 SetCursor(*wxSTANDARD_CURSOR
);
1343 else if (ev
.LeftUp())
1345 switch (m_dragStatus
)
1347 case wxGRID_DRAG_LEFT_RIGHT
:
1349 wxClientDC
dc(this);
1351 dc
.SetLogicalFunction(wxINVERT
);
1352 dc
.DrawLine(m_dragLastPosition
, m_topOfSheet
, m_dragLastPosition
, m_bottomOfSheet
);
1353 dc
.SetLogicalFunction(wxCOPY
);
1357 if (ev
.GetX() > m_dragStartPosition
)
1359 m_colWidths
[m_dragRowOrCol
] = (short)(ev
.GetX() - m_dragStartPosition
);
1364 SetCursor(*wxSTANDARD_CURSOR
);
1366 GetClientSize(&cw
, &ch
);
1371 case wxGRID_DRAG_UP_DOWN
:
1373 wxClientDC
dc(this);
1375 dc
.SetLogicalFunction(wxINVERT
);
1376 dc
.DrawLine(m_leftOfSheet
, m_dragLastPosition
, m_rightOfSheet
, m_dragLastPosition
);
1377 dc
.SetLogicalFunction(wxCOPY
);
1381 if (ev
.GetY() > m_dragStartPosition
)
1383 m_rowHeights
[m_dragRowOrCol
] = (short)(ev
.GetY() - m_dragStartPosition
);
1388 SetCursor(*wxSTANDARD_CURSOR
);
1392 m_dragStatus
= wxGRID_DRAG_NONE
;
1394 else if (ev
.RightDown())
1397 if (CellHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1399 //OnCellRightClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1400 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CELL_RCLICK
, this,
1401 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1402 ev
.ControlDown(), ev
.ShiftDown());
1403 GetEventHandler()->ProcessEvent(g_evt
);
1406 if (LabelHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1408 //OnLabelRightClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1409 wxGridEvent
g_evt(GetId(), wxEVT_GRID_LABEL_RCLICK
, this,
1410 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1411 ev
.ControlDown(), ev
.ShiftDown());
1412 GetEventHandler()->ProcessEvent(g_evt
);
1417 void wxGenericGrid::OnSelectCellImplementation(wxDC
*dc
, int row
, int col
)
1419 m_wCursorColumn
= col
;
1422 //OnChangeSelectionLabel();
1423 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_SEL_LABEL
, this);
1424 GetEventHandler()->ProcessEvent(g_evt
);
1426 SetGridClippingRegion(dc
);
1428 // Remove the highlight from the old cell
1429 if ( m_currentRectVisible
&& !(m_editable
&& m_editInPlace
) )
1435 // Highlight the new cell and copy its content to the edit control
1436 SetCurrentRect(m_wCursorRow
, m_wCursorColumn
);
1437 wxGridCell
*cell
= GetCell(m_wCursorRow
, m_wCursorColumn
);
1440 if ( cell
->GetTextValue().IsNull() )
1441 m_textItem
->SetValue("");
1443 m_textItem
->SetValue(cell
->GetTextValue());
1446 SetGridClippingRegion(dc
);
1449 if ( m_editable
&& m_editInPlace
)
1451 int x
, y
, width
, height
;
1452 if ( m_currentRect
.x
<= 0 )
1455 width
= m_currentRect
.width
+ 2;
1459 x
= m_currentRect
.x
- 2;
1460 width
= m_currentRect
.width
+ 4;
1463 if ( m_currentRect
.y
<= 0 )
1466 height
= m_currentRect
.height
+ 2;
1470 y
= m_currentRect
.y
- 2;
1471 height
= m_currentRect
.height
+ 4;
1474 m_inPlaceTextItem
->SetSize( x
, y
, width
, height
);
1478 if ( cell
->GetTextValue().IsNull() )
1480 m_inPlaceTextItem
->SetValue( "" );
1484 m_inPlaceTextItem
->SetFont( cell
->GetFont() );
1485 m_inPlaceTextItem
->SetValue( cell
->GetTextValue() );
1489 m_inPlaceTextItem
->Show(TRUE
);
1490 m_inPlaceTextItem
->SetFocus();
1494 // 1) Why isn't this needed for Windows??
1495 // Probably because of the SetValue?? JS.
1496 // 2) Arrrrrgh. This isn't needed anywhere,
1497 // of course. One hour of debugging... RR.
1499 // 3) It *is* needed for Motif - michael
1502 if ( !(m_editable
&& m_editInPlace
) )
1507 dc
->DestroyClippingRegion();
1509 OnSelectCell(row
, col
);
1510 wxGridEvent
g_evt2(GetId(), wxEVT_GRID_SELECT_CELL
, this, row
, col
);
1511 GetEventHandler()->ProcessEvent(g_evt2
);
1514 wxGridCell
*wxGenericGrid::OnCreateCell()
1516 return new wxGridCell(this);
1519 void wxGenericGrid::OnChangeLabels()
1523 for (i
= 0; i
< m_totalRows
; i
++)
1525 sprintf(buf
, "%d", i
+1);
1526 SetLabelValue(wxVERTICAL
, buf
, i
);
1528 // A...Z,AA...ZZ,AAA...ZZZ, etc.
1529 for (i
= 0; i
< m_totalCols
; i
++)
1532 int noTimes
= (i
/26 + 1);
1533 int ch
= (i
% 26) + 65;
1535 for (j
= 0; j
< noTimes
; j
++)
1538 sprintf(buf2
, "%c", (char)ch
);
1541 SetLabelValue(wxHORIZONTAL
, buf
, i
);
1545 void wxGenericGrid::OnChangeSelectionLabel()
1550 wxString
rowLabel(GetLabelValue(wxVERTICAL
, GetCursorRow()));
1551 wxString
colLabel(GetLabelValue(wxHORIZONTAL
, GetCursorColumn()));
1553 wxString newLabel
= colLabel
+ rowLabel
;
1554 if ((newLabel
.Length() > 0) && (newLabel
.Length() <= 8) && GetTextItem())
1556 // GetTextItem()->SetLabel(newLabel);
1560 void wxGenericGrid::HighlightCell(wxDC
*dc
)
1562 dc
->SetLogicalFunction(wxINVERT
);
1565 dc
->DrawLine( m_currentRect
.x
+ 1,
1566 m_currentRect
.y
+ 1,
1567 m_currentRect
.x
+ m_currentRect
.width
- 1,
1568 m_currentRect
.y
+ 1);
1570 dc
->DrawLine( m_currentRect
.x
+ m_currentRect
.width
- 1,
1571 m_currentRect
.y
+ 1,
1572 m_currentRect
.x
+ m_currentRect
.width
- 1,
1573 m_currentRect
.y
+m_currentRect
.height
- 1 );
1575 dc
->DrawLine( m_currentRect
.x
+ m_currentRect
.width
- 1,
1576 m_currentRect
.y
+ m_currentRect
.height
- 1,
1577 m_currentRect
.x
+ 1,
1578 m_currentRect
.y
+ m_currentRect
.height
- 1);
1580 dc
->DrawLine( m_currentRect
.x
+ 1,
1581 m_currentRect
.y
+ m_currentRect
.height
- 1,
1582 m_currentRect
.x
+ 1,
1583 m_currentRect
.y
+ 1);
1585 dc
->SetLogicalFunction(wxCOPY
);
1588 void wxGenericGrid::DrawCellText()
1590 if (!m_currentRectVisible
)
1593 wxGridCell
*cell
= GetCell(GetCursorRow(), GetCursorColumn());
1597 wxClientDC
dc(this);
1600 SetGridClippingRegion(& dc
);
1602 dc
.SetBackgroundMode(wxTRANSPARENT
);
1603 dc
.SetBrush(cell
->GetBackgroundBrush());
1605 wxString editValue
= m_textItem
->GetValue();
1608 rect
= m_currentRect
;
1614 // FIXME: what's this string of spaces supposed to represent?
1615 DrawTextRect(& dc
, " ", &rect
, wxLEFT
);
1616 DrawTextRect(& dc
, editValue
, &rect
, cell
->GetAlignment());
1618 dc
.DestroyClippingRegion();
1620 dc
.SetBackgroundMode(wxSOLID
);
1625 void wxGenericGrid::SetCurrentRect(int Row
, int Column
, int canvasW
, int canvasH
)
1627 int currentWidth
= m_leftOfSheet
+ m_verticalLabelWidth
;
1629 for (i
= m_scrollPosX
; i
< Column
; i
++)
1630 currentWidth
+= m_colWidths
[i
];
1632 int currentHeight
= m_topOfSheet
+ m_horizontalLabelHeight
;
1633 for (i
= m_scrollPosY
; i
< Row
; i
++)
1634 currentHeight
+= m_rowHeights
[i
];
1636 m_currentRect
.x
= currentWidth
;
1637 m_currentRect
.y
= currentHeight
;
1638 m_currentRect
.width
= m_colWidths
? (m_colWidths
[Column
]) : 0;
1639 m_currentRect
.height
= m_rowHeights
? (m_rowHeights
[Row
]) : 0;
1641 if (Row
< m_scrollPosY
|| Column
< m_scrollPosX
)
1642 m_currentRectVisible
= FALSE
;
1643 else if ((canvasW
!= -1 && canvasH
!= -1) && (m_currentRect
.x
> canvasW
|| m_currentRect
.y
> canvasH
))
1644 m_currentRectVisible
= FALSE
;
1645 else m_currentRectVisible
= TRUE
;
1648 static bool wxRectIntersection(wxRect
*rect1
, wxRect
*rect2
, wxRect
*rect3
)
1650 int x2_1
= rect1
->x
+ rect1
->width
;
1651 int y2_1
= rect1
->y
+ rect1
->height
;
1653 int x2_2
= rect2
->x
+ rect2
->width
;
1654 int y2_2
= rect2
->y
+ rect2
->height
;
1658 // Check for intersection
1659 if ((rect1
->x
> x2_2
) || (rect2
->x
> x2_1
) ||
1660 (rect1
->y
> y2_2
) || (rect2
->y
> y2_1
))
1663 rect3
->x
= rect3
->y
= rect3
->width
= rect3
->height
= 0;
1667 if (rect1
->x
> rect2
->x
)
1668 rect3
->x
= rect1
->x
;
1670 rect3
->x
= rect2
->x
;
1671 if (rect1
->y
> rect2
->y
)
1672 rect3
->y
= rect1
->y
;
1674 rect3
->y
= rect2
->y
;
1685 rect3
->width
= (int)(x2_3
- rect3
->x
);
1686 rect3
->height
= (int)(y2_3
- rect3
->y
);
1690 void wxGenericGrid::DrawTextRect(wxDC
*dc
, const wxString
& text
, wxRect
*rect
, int flag
)
1694 // Ultimately, this functionality should be built into wxWindows,
1695 // and optimized for each platform. E.g. on Windows, use DrawText
1696 // passing a clipping rectangle, so that the wxWindows clipping region
1697 // does not have to be used to implement this.
1699 // If we're already clipping, we need to find the intersection
1700 // between current clipping area and text clipping area.
1704 long clipX
, clipY
, clipW
, clipH
;
1705 dc
->GetClippingBox(&clipX
, &clipY
, &clipW
, &clipH
);
1706 clipRect
.x
= (int)clipX
; clipRect
.y
= (int)clipY
;
1707 clipRect
.width
= (int)clipW
; clipRect
.height
= (int)clipH
;
1709 bool alreadyClipping
= TRUE
;
1711 if (clipRect
.x
== 0 && clipRect
.y
== 0 && clipRect
.width
== 0 && clipRect
.height
== 0)
1713 alreadyClipping
= FALSE
;
1714 clipRect2
.x
= rect
->x
; clipRect2
.y
= rect
->y
;
1715 clipRect2
.width
= rect
->width
; clipRect2
.height
= rect
->height
;
1719 // Find intersection.
1720 if (!wxRectIntersection(rect
, &clipRect
, &clipRect2
))
1724 if (alreadyClipping
)
1725 dc
->DestroyClippingRegion();
1727 dc
->SetClippingRegion(clipRect2
.x
, clipRect2
.y
, clipRect2
.width
, clipRect2
.height
);
1728 long textWidth
, textHeight
;
1730 dc
->GetTextExtent(text
, &textWidth
, &textHeight
);
1738 x
= (rect
->x
+ rect
->width
- textWidth
- 1.0);
1739 y
= (rect
->y
+ (rect
->height
- textHeight
)/2.0);
1744 x
= (rect
->x
+ (rect
->width
- textWidth
)/2.0);
1745 y
= (rect
->y
+ (rect
->height
- textHeight
)/2.0);
1751 x
= (rect
->x
+ 1.0);
1752 y
= (rect
->y
+ (rect
->height
- textHeight
)/2.0);
1756 dc
->DrawText(text
, (long)x
, (long)y
);
1758 dc
->DestroyClippingRegion();
1760 // Restore old clipping
1761 if (alreadyClipping
)
1762 dc
->SetClippingRegion(clipRect
.x
, clipRect
.y
, clipRect
.width
, clipRect
.height
);
1767 void wxGenericGrid::DrawBitmapRect(wxDC
*dc
, wxBitmap
*bitmap
, wxRect
*rect
, int flag
)
1771 // Ultimately, this functionality should be built into wxWindows,
1772 // and optimized for each platform. E.g. on Windows, use DrawText
1773 // passing a clipping rectangle, so that the wxWindows clipping region
1774 // does not have to be used to implement this.
1776 // If we're already clipping, we need to find the intersection
1777 // between current clipping area and text clipping area.
1781 long clipX
, clipY
, clipW
, clipH
;
1782 dc
->GetClippingBox(&clipX
, &clipY
, &clipW
, &clipH
);
1783 clipRect
.x
= (int)clipX
; clipRect
.y
= (int)clipY
;
1784 clipRect
.width
= (int)clipW
; clipRect
.height
= (int)clipH
;
1786 bool alreadyClipping
= TRUE
;
1788 if (clipRect
.x
== 0 && clipRect
.y
== 0 && clipRect
.width
== 0 && clipRect
.height
== 0)
1790 alreadyClipping
= FALSE
;
1791 clipRect2
.x
= rect
->x
; clipRect2
.y
= rect
->y
;
1792 clipRect2
.width
= rect
->width
; clipRect2
.height
= rect
->height
;
1796 // Find intersection.
1797 if (!wxRectIntersection(rect
, &clipRect
, &clipRect2
))
1801 if (alreadyClipping
)
1802 dc
->DestroyClippingRegion();
1804 dc
->SetClippingRegion(clipRect2
.x
, clipRect2
.y
, clipRect2
.width
, clipRect2
.height
);
1805 float bitmapWidth
, bitmapHeight
;
1807 bitmapWidth
= bitmap
->GetWidth();
1808 bitmapHeight
= bitmap
->GetHeight();
1816 x
= (long)(rect
->x
+ rect
->width
- bitmapWidth
- 1);
1817 y
= (long)(rect
->y
+ (rect
->height
- bitmapHeight
)/2.0);
1822 x
= (long)(rect
->x
+ (rect
->width
- bitmapWidth
)/2.0);
1823 y
= (long)(rect
->y
+ (rect
->height
- bitmapHeight
)/2.0);
1829 x
= (long)(rect
->x
+ 1);
1830 y
= (long)(rect
->y
+ (rect
->height
- bitmapHeight
)/2.0);
1835 dcTemp
.SelectObject(*bitmap
);
1837 dc
->Blit( (long)x
, (long)y
, (long)bitmapWidth
, (long)bitmapHeight
, &dcTemp
, 0, 0);
1838 dcTemp
.SelectObject(wxNullBitmap
);
1840 dc
->DestroyClippingRegion();
1842 // Restore old clipping
1843 if (alreadyClipping
)
1844 dc
->SetClippingRegion(clipRect
.x
, clipRect
.y
, clipRect
.width
, clipRect
.height
);
1849 void wxGenericGrid::OnActivate(bool active
)
1853 // Edit control should always have the focus
1854 if (GetTextItem() && GetEditable())
1856 GetTextItem()->SetFocus();
1857 wxGridCell
*cell
= GetCell(GetCursorRow(), GetCursorColumn());
1859 GetTextItem()->SetValue(cell
->GetTextValue());
1864 void wxGenericGrid::SetCellValue(const wxString
& val
, int row
, int col
)
1866 wxGridCell
*cell
= GetCell(row
, col
);
1869 cell
->SetTextValue(val
);
1871 RefreshCell(row
, col
, TRUE
);
1875 void wxGenericGrid::RefreshCell(int row
, int col
, bool setText
)
1877 // Don't refresh within a pair of batch brackets
1878 if (GetBatchCount() > 0)
1882 GetClientSize(&cw
, &ch
);
1884 SetCurrentRect(row
, col
, cw
, ch
);
1885 if (m_currentRectVisible
)
1887 wxGridCell
*cell
= GetCell(row
, col
);
1889 bool currentPos
= FALSE
;
1890 if (row
== m_wCursorRow
&& col
== m_wCursorColumn
&& GetTextItem() && GetTextItem()->IsShown() && setText
)
1892 GetTextItem()->SetValue(cell
->GetTextValue());
1895 // Gets refreshed anyway in MSW
1900 wxClientDC
dc(this);
1902 DrawCellBackground(& dc
, &m_currentRect
, row
, col
);
1903 DrawCellValue(& dc
, &m_currentRect
, row
, col
);
1909 wxString
& wxGenericGrid::GetCellValue(int row
, int col
) const
1911 static wxString
emptyString("");
1913 wxGridCell
*cell
= GetCell(row
, col
);
1915 return cell
->GetTextValue();
1920 void wxGenericGrid::SetColumnWidth(int col
, int width
)
1922 if (col
<= m_totalCols
)
1923 m_colWidths
[col
] = width
;
1926 int wxGenericGrid::GetColumnWidth(int col
) const
1928 if (col
<= m_totalCols
)
1929 return m_colWidths
[col
];
1934 void wxGenericGrid::SetRowHeight(int row
, int height
)
1936 if (row
<= m_totalRows
)
1937 m_rowHeights
[row
] = height
;
1940 int wxGenericGrid::GetRowHeight(int row
) const
1942 if (row
<= m_totalRows
)
1943 return m_rowHeights
[row
];
1948 void wxGenericGrid::SetLabelSize(int orientation
, int sz
)
1950 if (orientation
== wxHORIZONTAL
)
1951 m_horizontalLabelHeight
= sz
;
1953 m_verticalLabelWidth
= sz
;
1955 SetCurrentRect(GetCursorRow(), GetCursorColumn());
1958 int wxGenericGrid::GetLabelSize(int orientation
) const
1960 if (orientation
== wxHORIZONTAL
)
1961 return m_horizontalLabelHeight
;
1963 return m_verticalLabelWidth
;
1966 wxGridCell
*wxGenericGrid::GetLabelCell(int orientation
, int pos
) const
1968 if (orientation
== wxHORIZONTAL
)
1970 if (m_colLabelCells
&& pos
< m_totalCols
)
1971 return m_colLabelCells
[pos
];
1973 return (wxGridCell
*) NULL
;
1977 if (m_rowLabelCells
&& pos
< m_totalRows
)
1978 return m_rowLabelCells
[pos
];
1980 return (wxGridCell
*) NULL
;
1984 void wxGenericGrid::SetLabelValue(int orientation
, const wxString
& val
, int pos
)
1986 wxGridCell
*cell
= GetLabelCell(orientation
, pos
);
1988 cell
->SetTextValue(val
);
1991 wxString
& wxGenericGrid::GetLabelValue(int orientation
, int pos
) const
1993 static wxString emptyString
= "";
1994 wxGridCell
*cell
= GetLabelCell(orientation
, pos
);
1996 return cell
->GetTextValue();
2001 void wxGenericGrid::SetLabelAlignment(int orientation
, int align
)
2003 if (orientation
== wxHORIZONTAL
)
2004 m_horizontalLabelAlignment
= align
;
2006 m_verticalLabelAlignment
= align
;
2008 SetCurrentRect(GetCursorRow(), GetCursorColumn());
2011 int wxGenericGrid::GetLabelAlignment(int orientation
) const
2013 if (orientation
== wxHORIZONTAL
)
2014 return m_horizontalLabelAlignment
;
2016 return m_verticalLabelAlignment
;
2019 void wxGenericGrid::SetLabelTextColour(const wxColour
& colour
)
2021 m_labelTextColour
= colour
;
2025 void wxGenericGrid::SetLabelBackgroundColour(const wxColour
& colour
)
2027 m_labelBackgroundColour
= colour
;
2028 m_labelBackgroundBrush
= * wxTheBrushList
->FindOrCreateBrush(m_labelBackgroundColour
, wxSOLID
);
2031 void wxGenericGrid::SetEditable(bool edit
)
2036 int controlW
, controlH
;
2037 m_textItem
->GetSize(&controlW
, &controlH
);
2038 m_editControlPosition
.height
= controlH
;
2040 m_topOfSheet
= m_editControlPosition
.x
+ controlH
+ 2;
2043 m_editingPanel
->Show(TRUE
);
2044 m_textItem
->Show(TRUE
);
2045 m_textItem
->SetFocus();
2048 if (m_inPlaceTextItem
)
2050 m_inPlaceTextItem
->Show(TRUE
);
2051 m_inPlaceTextItem
->SetFocus();
2059 m_textItem
->Show(FALSE
);
2060 m_editingPanel
->Show(FALSE
);
2063 if ( m_inPlaceTextItem
)
2065 m_inPlaceTextItem
->Show(FALSE
);
2069 SetCurrentRect(GetCursorRow(), GetCursorColumn());
2072 GetClientSize(&cw
, &ch
);
2077 int m_scrollWidth = 16;
2078 GetClientSize(&cw, &ch);
2081 m_vScrollBar->SetSize(cw - m_scrollWidth, m_topOfSheet,
2082 m_scrollWidth, ch - m_topOfSheet - m_scrollWidth);
2087 void wxGenericGrid::SetEditInPlace(bool edit
)
2089 if ( m_editInPlace
!= edit
)
2091 m_editInPlace
= edit
;
2093 if ( m_editInPlace
) // switched on
2095 if ( m_currentRectVisible
&& m_editable
)
2097 m_inPlaceTextItem
->SetSize( m_currentRect
.x
-2, m_currentRect
.y
-2,
2098 m_currentRect
.width
+4, m_currentRect
.height
+4 );
2100 wxGridCell
*cell
= GetCell(m_wCursorRow
, m_wCursorColumn
);
2104 if ( cell
->GetTextValue().IsNull() )
2106 m_inPlaceTextItem
->SetValue( "" );
2110 m_inPlaceTextItem
->SetFont( cell
->GetFont() );
2111 m_inPlaceTextItem
->SetValue( cell
->GetTextValue() );
2115 m_inPlaceTextItem
->Show( TRUE
);
2116 m_inPlaceTextItem
->SetFocus();
2119 else // switched off
2121 m_inPlaceTextItem
->Show( FALSE
);
2127 void wxGenericGrid::SetCellAlignment(int flag
, int row
, int col
)
2129 wxGridCell
*cell
= GetCell(row
, col
);
2131 cell
->SetAlignment(flag
);
2134 int wxGenericGrid::GetCellAlignment(int row
, int col
) const
2136 wxGridCell
*cell
= GetCell(row
, col
);
2138 return cell
->GetAlignment();
2140 return m_cellAlignment
;
2143 void wxGenericGrid::SetCellAlignment(int flag
)
2145 m_cellAlignment
= flag
;
2147 for (i
= 0; i
< GetRows(); i
++)
2148 for (j
= 0; j
< GetCols(); j
++)
2150 GetCell(i
, j
)->SetAlignment(flag
);
2153 int wxGenericGrid::GetCellAlignment(void) const
2155 return m_cellAlignment
;
2158 void wxGenericGrid::SetCellBackgroundColour(const wxColour
& col
)
2160 m_cellBackgroundColour
= col
;
2162 for (i
= 0; i
< GetRows(); i
++)
2163 for (j
= 0; j
< GetCols(); j
++)
2165 GetCell(i
, j
)->SetBackgroundColour(col
);
2168 void wxGenericGrid::SetCellBackgroundColour(const wxColour
& val
, int row
, int col
)
2170 wxGridCell
*cell
= GetCell(row
, col
);
2173 cell
->SetBackgroundColour(val
);
2174 RefreshCell(row
, col
);
2178 wxColour
& wxGenericGrid::GetCellBackgroundColour(int row
, int col
) const
2180 wxGridCell
*cell
= GetCell(row
, col
);
2182 return cell
->GetBackgroundColour();
2184 return (wxColour
&) m_cellBackgroundColour
;
2187 void wxGenericGrid::SetCellTextColour(const wxColour
& val
, int row
, int col
)
2189 wxGridCell
*cell
= GetCell(row
, col
);
2192 cell
->SetTextColour(val
);
2193 RefreshCell(row
, col
);
2197 void wxGenericGrid::SetCellTextFont(const wxFont
& fnt
, int row
, int col
)
2199 wxGridCell
*cell
= GetCell(row
, col
);
2203 RefreshCell(row
, col
);
2207 wxFont
& wxGenericGrid::GetCellTextFont(int row
, int col
) const
2209 wxGridCell
*cell
= GetCell(row
, col
);
2211 return (wxFont
&) cell
->GetFont();
2213 return (wxFont
&) m_cellTextFont
;
2216 wxColour
& wxGenericGrid::GetCellTextColour(int row
, int col
) const
2218 wxGridCell
*cell
= GetCell(row
, col
);
2220 return (wxColour
&) cell
->GetTextColour();
2222 return (wxColour
&) m_cellTextColour
;
2225 void wxGenericGrid::SetCellTextColour(const wxColour
& val
)
2227 m_cellTextColour
= val
;
2229 for (i
= 0; i
< GetRows(); i
++)
2230 for (j
= 0; j
< GetCols(); j
++)
2232 GetCell(i
, j
)->SetTextColour(val
);
2235 void wxGenericGrid::SetCellTextFont(const wxFont
& fnt
)
2237 m_cellTextFont
= fnt
;
2239 for (i
= 0; i
< GetRows(); i
++)
2240 for (j
= 0; j
< GetCols(); j
++)
2242 GetCell(i
, j
)->SetFont(fnt
);
2245 void wxGenericGrid::SetCellBitmap(wxBitmap
*bitmap
, int row
, int col
)
2247 wxGridCell
*cell
= GetCell(row
, col
);
2250 cell
->SetCellBitmap(bitmap
);
2251 RefreshCell(row
, col
);
2255 wxBitmap
*wxGenericGrid::GetCellBitmap(int row
, int col
) const
2257 wxGridCell
*cell
= GetCell(row
, col
);
2260 return cell
->GetCellBitmap();
2263 return (wxBitmap
*) NULL
;
2266 bool wxGenericGrid::InsertCols(int pos
, int n
, bool updateLabels
)
2268 if (pos
> m_totalCols
)
2272 return CreateGrid(1, n
);
2277 for (i
= 0; i
< m_totalRows
; i
++)
2279 wxGridCell
**cols
= m_gridCells
[i
];
2280 wxGridCell
**newCols
= new wxGridCell
*[m_totalCols
+ n
];
2281 for (j
= 0; j
< pos
; j
++)
2282 newCols
[j
] = cols
[j
];
2283 for (j
= pos
; j
< pos
+ n
; j
++)
2284 newCols
[j
] = new wxGridCell(this);
2285 for (j
= pos
+ n
; j
< m_totalCols
+ n
; j
++)
2286 newCols
[j
] = cols
[j
- n
];
2289 m_gridCells
[i
] = newCols
;
2293 short *newColWidths
= new short[m_totalCols
+ n
];
2294 for (j
= 0; j
< pos
; j
++)
2295 newColWidths
[j
] = m_colWidths
[j
];
2296 for (j
= pos
; j
< pos
+ n
; j
++)
2297 newColWidths
[j
] = wxGRID_DEFAULT_CELL_WIDTH
;
2298 for (j
= pos
+ n
; j
< m_totalCols
+ n
; j
++)
2299 newColWidths
[j
] = m_colWidths
[j
- n
];
2300 delete[] m_colWidths
;
2301 m_colWidths
= newColWidths
;
2304 wxGridCell
**newLabels
= new wxGridCell
*[m_totalCols
+ n
];
2305 for (j
= 0; j
< pos
; j
++)
2306 newLabels
[j
] = m_colLabelCells
[j
];
2307 for (j
= pos
; j
< pos
+ n
; j
++)
2308 newLabels
[j
] = new wxGridCell(this);
2309 for (j
= pos
+ n
; j
< m_totalCols
+ n
; j
++)
2310 newLabels
[j
] = m_colLabelCells
[j
- n
];
2312 delete[] m_colLabelCells
;
2313 m_colLabelCells
= newLabels
;
2319 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2320 GetEventHandler()->ProcessEvent(g_evt
);
2329 bool wxGenericGrid::InsertRows(int pos
, int n
, bool updateLabels
)
2331 if (pos
> m_totalRows
)
2335 return CreateGrid(n
, 1);
2340 wxGridCell
***rows
= new wxGridCell
**[m_totalRows
+ n
];
2343 for (i
= 0; i
< pos
; i
++)
2344 rows
[i
] = m_gridCells
[i
];
2346 for (i
= pos
; i
< pos
+ n
; i
++)
2348 rows
[i
] = new wxGridCell
*[m_totalCols
];
2349 for (j
= 0; j
< m_totalCols
; j
++)
2350 rows
[i
][j
] = new wxGridCell(this);
2353 for (i
= pos
+ n
; i
< m_totalRows
+ n
; i
++)
2354 rows
[i
] = m_gridCells
[i
- n
];
2356 delete[] m_gridCells
;
2360 short *newRowHeights
= new short[m_totalRows
+ n
];
2361 for (i
= 0; i
< pos
; i
++)
2362 newRowHeights
[i
] = m_rowHeights
[i
];
2363 for (i
= pos
; i
< pos
+ n
; i
++)
2364 newRowHeights
[i
] = wxGRID_DEFAULT_CELL_HEIGHT
;
2365 for (i
= pos
+ n
; i
< m_totalRows
+ n
; i
++)
2366 newRowHeights
[i
] = m_rowHeights
[i
- n
];
2367 delete[] m_rowHeights
;
2368 m_rowHeights
= newRowHeights
;
2371 wxGridCell
**newLabels
= new wxGridCell
*[m_totalRows
+ n
];
2372 for (i
= 0; i
< pos
; i
++)
2373 newLabels
[i
] = m_rowLabelCells
[i
];
2374 for (i
= pos
; i
< pos
+ n
; i
++)
2375 newLabels
[i
] = new wxGridCell(this);
2376 for (i
= pos
+ n
; i
< m_totalRows
+ n
; i
++)
2377 newLabels
[i
] = m_rowLabelCells
[i
- n
];
2379 delete[] m_rowLabelCells
;
2380 m_rowLabelCells
= newLabels
;
2386 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2387 GetEventHandler()->ProcessEvent(g_evt
);
2396 bool wxGenericGrid::AppendCols(int n
, bool updateLabels
)
2398 return InsertCols(GetCols(), n
, updateLabels
);
2401 bool wxGenericGrid::AppendRows(int n
, bool updateLabels
)
2403 return InsertRows(GetRows(), n
, updateLabels
);
2406 bool wxGenericGrid::DeleteRows(int pos
, int n
, bool updateLabels
)
2408 if (pos
> m_totalRows
)
2415 wxGridCell
***rows
= new wxGridCell
**[m_totalRows
- n
];
2418 for (i
= 0; i
< pos
; i
++)
2419 rows
[i
] = m_gridCells
[i
];
2421 for (i
= pos
+ n
; i
< m_totalRows
; i
++)
2422 rows
[i
-n
] = m_gridCells
[i
];
2424 delete[] m_gridCells
;
2428 short *newRowHeights
= new short[m_totalRows
- n
];
2429 for (i
= 0; i
< pos
; i
++)
2430 newRowHeights
[i
] = m_rowHeights
[i
];
2431 for (i
= pos
+ n
; i
< m_totalRows
; i
++)
2432 newRowHeights
[i
-n
] = m_rowHeights
[i
];
2433 delete[] m_rowHeights
;
2434 m_rowHeights
= newRowHeights
;
2437 wxGridCell
**newLabels
= new wxGridCell
*[m_totalRows
- n
];
2438 for (i
= 0; i
< pos
; i
++)
2439 newLabels
[i
] = m_rowLabelCells
[i
];
2440 for (i
= pos
+ n
; i
< m_totalRows
; i
++)
2441 newLabels
[i
-n
] = m_rowLabelCells
[i
];
2443 delete[] m_rowLabelCells
;
2444 m_rowLabelCells
= newLabels
;
2450 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2451 GetEventHandler()->ProcessEvent(g_evt
);
2458 bool wxGenericGrid::DeleteCols(int pos
, int n
, bool updateLabels
)
2460 if (pos
+ n
> m_totalCols
)
2468 for (i
= 0; i
< m_totalRows
; i
++)
2470 wxGridCell
**cols
= m_gridCells
[i
];
2471 wxGridCell
**newCols
= new wxGridCell
*[m_totalCols
- n
];
2472 for (j
= 0; j
< pos
; j
++)
2473 newCols
[j
] = cols
[j
];
2474 for (j
= pos
; j
< pos
+ n
; j
++)
2476 for (j
= pos
+ n
; j
< m_totalCols
; j
++)
2477 newCols
[j
-n
] = cols
[j
];
2480 m_gridCells
[i
] = newCols
;
2484 short *newColWidths
= new short[m_totalCols
- n
];
2485 for (j
= 0; j
< pos
; j
++)
2486 newColWidths
[j
] = m_colWidths
[j
];
2487 for (j
= pos
+ n
; j
< m_totalCols
; j
++)
2488 newColWidths
[j
-n
] = m_colWidths
[j
];
2489 delete[] m_colWidths
;
2490 m_colWidths
= newColWidths
;
2493 wxGridCell
**newLabels
= new wxGridCell
*[m_totalCols
- n
];
2494 for (j
= 0; j
< pos
; j
++)
2495 newLabels
[j
] = m_colLabelCells
[j
];
2496 for (j
= pos
+ n
; j
< m_totalCols
; j
++)
2497 newLabels
[j
-n
] = m_colLabelCells
[j
];
2499 delete[] m_colLabelCells
;
2500 m_colLabelCells
= newLabels
;
2506 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2507 GetEventHandler()->ProcessEvent(g_evt
);
2514 void wxGenericGrid::SetGridCursor(int row
, int col
)
2516 if (row
>= m_totalRows
|| col
>= m_totalCols
)
2519 if (row
== GetCursorRow() && col
== GetCursorColumn())
2522 wxClientDC
dc(this);
2525 SetGridClippingRegion(& dc
);
2527 if (m_currentRectVisible
&& !(m_editable
&& m_editInPlace
) )
2528 HighlightCell(& dc
);
2531 m_wCursorColumn
= col
;
2534 GetClientSize(&cw
, &ch
);
2536 SetCurrentRect(row
, col
, cw
, ch
);
2538 if (m_currentRectVisible
&& !(m_editable
&& m_editInPlace
) )
2539 HighlightCell(& dc
);
2541 dc
.DestroyClippingRegion();
2545 // ----------------------------------------------------------------------------
2547 // ----------------------------------------------------------------------------
2549 wxGridCell::wxGridCell(wxGenericGrid
*window
)
2551 cellBitmap
= (wxBitmap
*) NULL
;
2553 backgroundBrush
= wxNullBrush
;
2555 textColour
= window
->GetCellTextColour();
2557 textColour
.Set(0,0,0);
2559 backgroundColour
= window
->GetCellBackgroundColour();
2561 backgroundColour
.Set(255,255,255);
2564 font
= window
->GetCellTextFont();
2566 font
= * wxTheFontList
->FindOrCreateFont(12, wxSWISS
, wxNORMAL
, wxNORMAL
);
2568 SetBackgroundColour(backgroundColour
);
2571 alignment
= window
->GetCellAlignment();
2575 cellData
= (void *)NULL
;
2578 wxGridCell::~wxGridCell()
2582 void wxGridCell::SetBackgroundColour(const wxColour
& colour
)
2584 backgroundColour
= colour
;
2585 backgroundBrush
= * wxTheBrushList
->FindOrCreateBrush(backgroundColour
, wxSOLID
);
2588 void wxGenericGrid::OnText(wxCommandEvent
& WXUNUSED(ev
) )
2590 // michael - added this conditional to prevent change to
2591 // grid cell text when edit control is hidden but still has
2596 wxGenericGrid
*grid
= this;
2597 wxGridCell
*cell
= grid
->GetCell(grid
->GetCursorRow(), grid
->GetCursorColumn());
2598 if (cell
&& grid
->CurrentCellVisible())
2600 cell
->SetTextValue(grid
->GetTextItem()->GetValue());
2601 if ( m_editInPlace
&& !m_inOnTextInPlace
)
2603 m_inPlaceTextItem
->SetValue( grid
->GetTextItem()->GetValue() );
2606 wxClientDC
dc(grid
);
2609 grid
->SetGridClippingRegion(& dc
);
2610 grid
->DrawCellBackground(& dc
, &grid
->GetCurrentRect(), grid
->GetCursorRow(), grid
->GetCursorColumn());
2611 grid
->DrawCellValue(& dc
, &grid
->GetCurrentRect(), grid
->GetCursorRow(), grid
->GetCursorColumn());
2612 if ( !(m_editable
&& m_editInPlace
) ) grid
->HighlightCell(& dc
);
2613 dc
.DestroyClippingRegion();
2616 //grid->OnCellChange(grid->GetCursorRow(), grid->GetCursorColumn());
2617 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CELL_CHANGE
, grid
,
2618 grid
->GetCursorRow(), grid
->GetCursorColumn());
2619 GetEventHandler()->ProcessEvent(g_evt
);
2621 // grid->DrawCellText();
2626 void wxGenericGrid::OnTextEnter(wxCommandEvent
& WXUNUSED(ev
) )
2628 // move the cursor down the current row (if possible)
2629 // when the enter key has been pressed
2633 if ( GetCursorRow() < GetRows()-1 )
2635 wxClientDC
dc( this );
2637 OnSelectCellImplementation(& dc
,
2639 GetCursorColumn() );
2645 void wxGenericGrid::OnTextInPlace(wxCommandEvent
& ev
)
2649 wxGenericGrid
*grid
= this;
2650 wxGridCell
*cell
= grid
->GetCell(grid
->GetCursorRow(), grid
->GetCursorColumn());
2651 if (cell
&& grid
->CurrentCellVisible())
2653 m_inOnTextInPlace
= TRUE
;
2654 grid
->GetTextItem()->SetValue( m_inPlaceTextItem
->GetValue() );
2656 m_inOnTextInPlace
= FALSE
;
2661 void wxGenericGrid::OnTextInPlaceEnter(wxCommandEvent
& WXUNUSED(ev
) )
2663 // move the cursor down the current row (if possible)
2664 // when the enter key has been pressed
2668 if ( GetCursorRow() < GetRows()-1 )
2670 wxClientDC
dc( this );
2672 OnSelectCellImplementation(& dc
,
2674 GetCursorColumn() );
2680 void wxGenericGrid::OnGridScroll(wxScrollEvent
& ev
)
2682 static bool inScroll
= FALSE
;
2687 if ( m_editInPlace
) m_inPlaceTextItem
->Show(FALSE
);
2690 wxGenericGrid
*win
= this;
2692 bool change
= FALSE
;
2694 if (ev
.GetEventObject() == win
->GetHorizScrollBar())
2696 change
= (ev
.GetPosition() != m_scrollPosX
);
2697 win
->SetScrollPosX(ev
.GetPosition());
2701 change
= (ev
.GetPosition() != m_scrollPosY
);
2702 win
->SetScrollPosY(ev
.GetPosition());
2705 win
->UpdateDimensions();
2707 win
->SetCurrentRect(win
->GetCursorRow(), win
->GetCursorColumn());
2709 // Because rows and columns can be arbitrary sizes,
2710 // the scrollbars will need to be adjusted to reflect the
2714 if (change
) win
->Refresh(FALSE
);
2716 if ( m_editInPlace
&& m_currentRectVisible
)
2718 m_inPlaceTextItem
->SetSize( m_currentRect
.x
-2, m_currentRect
.y
-2,
2719 m_currentRect
.width
+4, m_currentRect
.height
+4 );
2720 m_inPlaceTextItem
->Show( TRUE
);
2721 m_inPlaceTextItem
->SetFocus();
2729 //----------------------------------------------------------------------
2730 // Default wxGridEvent handlers
2731 // (just redirect to the pre-existing virtual methods)
2733 void wxGenericGrid::_OnSelectCell(wxGridEvent
& ev
)
2735 OnSelectCell(ev
.m_row
, ev
.m_col
);
2738 void wxGenericGrid::_OnCreateCell(wxGridEvent
& ev
)
2740 ev
.m_cell
= OnCreateCell();
2743 void wxGenericGrid::_OnChangeLabels(wxGridEvent
& WXUNUSED(ev
))
2748 void wxGenericGrid::_OnChangeSelectionLabel(wxGridEvent
& WXUNUSED(ev
))
2750 OnChangeSelectionLabel();
2753 void wxGenericGrid::_OnCellChange(wxGridEvent
& ev
)
2755 OnCellChange(ev
.m_row
, ev
.m_col
);
2758 void wxGenericGrid::_OnCellLeftClick(wxGridEvent
& ev
)
2760 OnCellLeftClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2763 void wxGenericGrid::_OnCellRightClick(wxGridEvent
& ev
)
2765 OnCellRightClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2768 void wxGenericGrid::_OnLabelLeftClick(wxGridEvent
& ev
)
2770 OnLabelLeftClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2773 void wxGenericGrid::_OnLabelRightClick(wxGridEvent
& ev
)
2775 OnLabelRightClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2778 void *wxGenericGrid::SetCellData(void *data
, int row
, int col
)
2782 wxGridCell
*cell
= GetCell(row
, col
);
2784 rc
= cell
->SetCellData(data
);
2789 void *wxGenericGrid::GetCellData(int row
, int col
)
2793 wxGridCell
*cell
= GetCell(row
, col
);
2795 rc
= cell
->GetCellData();