]> git.saurik.com Git - wxWidgets.git/blob - src/generic/gridg.cpp
fixed wrong assert
[wxWidgets.git] / src / generic / gridg.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: gridg.cpp
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
8 // Gerhard Gruber
9 // Added keyboard navigation, client data, other fixes
10 // Created: 04/01/98
11 // RCS-ID: $Id$
12 // Copyright: (c) Julian Smart and Markus Holzem
13 // Licence: wxWindows license
14 /////////////////////////////////////////////////////////////////////////////
15
16 #ifdef __GNUG__
17 #pragma implementation "gridg.h"
18 #pragma interface
19 #endif
20
21 // For compilers that support precompilation, includes "wx/wx.h".
22 #include "wx/wxprec.h"
23
24 #ifdef __BORLANDC__
25 #pragma hdrstop
26 #endif
27
28 #ifndef WX_PRECOMP
29 #include "wx/utils.h"
30 #include "wx/dcclient.h"
31 #include "wx/dcmemory.h"
32 #include "wx/textctrl.h"
33 #include "wx/settings.h"
34 #endif
35
36 #include <string.h>
37
38 #include "wx/string.h"
39
40 #include "wx/generic/gridg.h"
41
42 // Set to zero to use no double-buffering
43 #ifdef __WXMSW__
44 #define wxUSE_DOUBLE_BUFFERING 1
45 #else
46 #define wxUSE_DOUBLE_BUFFERING 0
47 #endif
48
49 #define wxGRID_DRAG_NONE 0
50 #define wxGRID_DRAG_LEFT_RIGHT 1
51 #define wxGRID_DRAG_UP_DOWN 2
52
53 IMPLEMENT_DYNAMIC_CLASS(wxGenericGrid, wxPanel)
54 IMPLEMENT_DYNAMIC_CLASS(wxGridEvent, wxEvent)
55
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)
67
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)
78
79 END_EVENT_TABLE()
80
81
82 wxGenericGrid::wxGenericGrid()
83 {
84 m_viewWidth = 0;
85 m_viewHeight = 0;
86 m_batchCount = 0;
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;
99 m_editable = TRUE;
100
101 m_editInPlace = TRUE;
102 m_inOnTextInPlace = FALSE;
103
104 #if defined(__WIN95__)
105 m_scrollWidth = wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X);
106 #elif defined(__WXGTK__)
107 m_scrollWidth = wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X);
108 #else
109 m_scrollWidth = 16;
110 #endif
111 m_dragStatus = wxGRID_DRAG_NONE;
112 m_dragRowOrCol = 0;
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;
131 m_wCursorRow = 0;
132 m_wCursorColumn = 0;
133 m_scrollPosX = 0;
134 m_scrollPosY = 0;
135 m_editCreated = FALSE;
136 m_totalRows = 0;
137 m_totalCols = 0;
138 m_gridCells = (wxGridCell ***) NULL;
139 m_rowLabelCells = (wxGridCell **) NULL;
140 m_colLabelCells = (wxGridCell **) NULL;
141 m_textItem = (wxTextCtrl *) NULL;
142 }
143
144 bool wxGenericGrid::Create(wxWindow *parent,
145 wxWindowID id,
146 const wxPoint& pos,
147 const wxSize& size,
148 long style,
149 const wxString& name)
150 {
151 m_viewWidth = 0;
152 m_viewHeight = 0;
153 m_batchCount = 0;
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;
167 m_editable = TRUE;
168 #if defined(__WIN95__)
169 m_scrollWidth = wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X);
170 #elif defined(__WXGTK__)
171 m_scrollWidth = wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X);
172 #else
173 m_scrollWidth = 16;
174 #endif
175 m_dragStatus = wxGRID_DRAG_NONE;
176 m_dragRowOrCol = 0;
177 m_dragStartPosition = 0;
178 m_dragLastPosition = 0;
179 m_divisionPen = * wxThePenList->FindOrCreatePen("LIGHT GREY", 1, wxSOLID);
180 m_doubleBufferingBitmap = (wxBitmap *) NULL;
181
182 if (!m_horizontalSashCursor.Ok())
183 {
184 m_horizontalSashCursor = wxCursor(wxCURSOR_SIZEWE);
185 m_verticalSashCursor = wxCursor(wxCURSOR_SIZENS);
186 }
187
188 SetLabelBackgroundColour(m_labelBackgroundColour);
189
190 m_leftOfSheet = wxGRID_DEFAULT_SHEET_LEFT;
191 m_topOfSheet = wxGRID_DEFAULT_SHEET_TOP;
192 m_cellHeight = wxGRID_DEFAULT_CELL_HEIGHT;
193 m_totalGridWidth = 0;
194 m_totalGridHeight = 0;
195 m_colWidths = (short *) NULL;
196 m_rowHeights = (short *) NULL;
197
198 m_verticalLabelWidth = wxGRID_DEFAULT_VERTICAL_LABEL_WIDTH;
199 m_horizontalLabelHeight = wxGRID_DEFAULT_HORIZONAL_LABEL_HEIGHT;
200 m_verticalLabelAlignment = wxCENTRE;
201 m_horizontalLabelAlignment = wxCENTRE;
202 m_editControlPosition.x = wxGRID_DEFAULT_EDIT_X;
203 m_editControlPosition.y = wxGRID_DEFAULT_EDIT_Y;
204 m_editControlPosition.width = wxGRID_DEFAULT_EDIT_WIDTH;
205 m_editControlPosition.height = wxGRID_DEFAULT_EDIT_HEIGHT;
206
207 m_wCursorRow = 0;
208 m_wCursorColumn = 0;
209
210 m_scrollPosX = 0;
211 m_scrollPosY = 0;
212
213 /* Store the rect. coordinates for the current cell */
214 SetCurrentRect(m_wCursorRow, m_wCursorColumn);
215
216 m_editCreated = FALSE;
217
218 m_totalRows = 0;
219 m_totalCols = 0;
220 m_gridCells = (wxGridCell ***) NULL;
221 m_rowLabelCells = (wxGridCell **) NULL;
222 m_colLabelCells = (wxGridCell **) NULL;
223 m_textItem = (wxTextCtrl *) NULL;
224
225 wxPanel::Create(parent, id, pos, size, style, name);
226
227 m_editingPanel = new wxPanel(this);
228
229 m_textItem = new wxTextCtrl(m_editingPanel, wxGRID_TEXT_CTRL, "",
230 wxPoint(m_editControlPosition.x, m_editControlPosition.y),
231 wxSize(m_editControlPosition.width, -1),
232 wxTE_PROCESS_ENTER);
233 m_textItem->Show(TRUE);
234 m_textItem->SetFocus();
235 int controlW, controlH;
236
237 m_textItem->GetSize(&controlW, &controlH);
238 m_editControlPosition.height = controlH;
239
240 m_topOfSheet = m_editControlPosition.y + controlH + 2;
241
242 m_editCreated = TRUE;
243
244 m_hScrollBar = new wxScrollBar(this, wxGRID_HSCROLL, wxPoint(0, 0), wxSize(20, 100), wxHORIZONTAL);
245 m_vScrollBar = new wxScrollBar(this, wxGRID_VSCROLL, wxPoint(0, 0), wxSize(100, 20), wxVERTICAL);
246
247 // SetSize(pos.x, pos.y, size.x, size.y);
248
249 m_inPlaceTextItem = new wxTextCtrl( (wxPanel*)this, wxGRID_EDIT_IN_PLACE_TEXT_CTRL, "",
250 wxPoint( m_currentRect.x-2, m_currentRect.y-2 ),
251 wxSize( m_currentRect.width+4, m_currentRect.height+4 ),
252 wxNO_BORDER | wxTE_PROCESS_ENTER );
253 m_inPlaceTextItem->Show(TRUE);
254 m_inPlaceTextItem->SetFocus();
255
256 return TRUE;
257 }
258
259 wxGenericGrid::~wxGenericGrid()
260 {
261 ClearGrid();
262 }
263
264 void wxGenericGrid::ClearGrid()
265 {
266 int i,j;
267 if (m_gridCells)
268 {
269 for (i = 0; i < m_totalRows; i++)
270 {
271 for (j = 0; j < m_totalCols; j++)
272 if (m_gridCells[i][j])
273 delete m_gridCells[i][j];
274 delete[] m_gridCells[i];
275 }
276 delete[] m_gridCells;
277 m_gridCells = (wxGridCell ***) NULL;
278 }
279 if (m_colWidths)
280 delete[] m_colWidths;
281 m_colWidths = (short *) NULL;
282 if (m_rowHeights)
283 delete[] m_rowHeights;
284 m_rowHeights = (short *) NULL;
285
286 if (m_rowLabelCells)
287 {
288 for (i = 0; i < m_totalRows; i++)
289 delete m_rowLabelCells[i];
290 delete[] m_rowLabelCells;
291 m_rowLabelCells = (wxGridCell **) NULL;
292 }
293 if (m_colLabelCells)
294 {
295 for (i = 0; i < m_totalCols; i++)
296 delete m_colLabelCells[i];
297 delete[] m_colLabelCells;
298 m_colLabelCells = (wxGridCell **) NULL;
299 }
300 if (m_doubleBufferingBitmap)
301 {
302 delete m_doubleBufferingBitmap;
303 m_doubleBufferingBitmap = (wxBitmap *) NULL;
304 }
305 }
306
307 bool wxGenericGrid::CreateGrid(int nRows, int nCols, wxString **cellValues, short *widths,
308 short defaultWidth, short defaultHeight)
309 {
310 m_totalRows = nRows;
311 m_totalCols = nCols;
312
313 int i,j;
314 m_colWidths = new short[nCols];
315 m_rowHeights = new short[nRows];
316 for (i = 0; i < nCols; i++)
317 if (widths)
318 m_colWidths[i] = widths[i];
319 else
320 m_colWidths[i] = defaultWidth;
321 for (i = 0; i < nRows; i++)
322 m_rowHeights[i] = defaultHeight;
323
324 m_gridCells = new wxGridCell **[nRows];
325
326 for (i = 0; i < nRows; i++)
327 m_gridCells[i] = new wxGridCell *[nCols];
328
329 for (i = 0; i < nRows; i++)
330 for (j = 0; j < nCols; j++)
331 if (cellValues)
332 {
333 //m_gridCells[i][j] = OnCreateCell();
334 wxGridEvent g_evt(GetId(), wxEVT_GRID_CREATE_CELL, this, i, j);
335 GetEventHandler()->ProcessEvent(g_evt);
336 m_gridCells[i][j] = g_evt.m_cell;
337 m_gridCells[i][j]->SetTextValue(cellValues[i][j]);
338 }
339 else
340 m_gridCells[i][j] = (wxGridCell *) NULL;
341
342 m_rowLabelCells = new wxGridCell *[nRows];
343 for (i = 0; i < nRows; i++)
344 m_rowLabelCells[i] = new wxGridCell(this);
345 m_colLabelCells = new wxGridCell *[nCols];
346 for (i = 0; i < nCols; i++)
347 m_colLabelCells[i] = new wxGridCell(this);
348
349 m_wCursorRow = m_wCursorColumn = 0;
350 SetCurrentRect(0, 0);
351
352 // Need to determine various dimensions
353 UpdateDimensions();
354
355 // Number of 'lines'
356 int objectSizeX = m_totalCols;
357 int pageSizeX = 1;
358 int viewLengthX = m_totalCols;
359
360 /*
361 m_hScrollBar->SetViewLength(viewLengthX);
362 m_hScrollBar->SetObjectLength(objectSizeX);
363 m_hScrollBar->SetPageSize(pageSizeX);
364 */
365 m_hScrollBar->SetScrollbar(m_hScrollBar->GetThumbPosition(), pageSizeX, objectSizeX, viewLengthX);
366
367 int objectSizeY = m_totalRows;
368 int pageSizeY = 1;
369 int viewLengthY = m_totalRows;
370
371 /*
372 m_vScrollBar->SetViewLength(viewLengthY);
373 m_vScrollBar->SetObjectLength(objectSizeY);
374 m_vScrollBar->SetPageSize(pageSizeY);
375 */
376
377 m_vScrollBar->SetScrollbar(m_vScrollBar->GetThumbPosition(), pageSizeY, objectSizeY, viewLengthY);
378
379 AdjustScrollbars();
380
381 //OnChangeLabels();
382 wxGridEvent g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS, this);
383 GetEventHandler()->ProcessEvent(g_evt);
384
385 //OnChangeSelectionLabel();
386 wxGridEvent g_evt2(GetId(), wxEVT_GRID_CHANGE_SEL_LABEL, this);
387 GetEventHandler()->ProcessEvent(g_evt2);
388
389 return TRUE;
390 }
391
392 // Need to determine various dimensions
393 void wxGenericGrid::UpdateDimensions()
394 {
395 int canvasWidth, canvasHeight;
396 GetSize(&canvasWidth, &canvasHeight);
397
398 if (m_editCreated && m_editable)
399 {
400 int controlW, controlH;
401 GetTextItem()->GetSize(&controlW, &controlH);
402 m_topOfSheet = m_editControlPosition.y + controlH + 2;
403 }
404 else
405 m_topOfSheet = 0;
406 m_rightOfSheet = m_leftOfSheet + m_verticalLabelWidth;
407 int i;
408 for (i = m_scrollPosX; i < m_totalCols; i++)
409 {
410 if (m_rightOfSheet > canvasWidth)
411 break;
412 else
413 m_rightOfSheet += m_colWidths[i];
414 }
415 m_bottomOfSheet = m_topOfSheet + m_horizontalLabelHeight;
416 for (i = m_scrollPosY; i < m_totalRows; i++)
417 {
418 if (m_bottomOfSheet > canvasHeight)
419 break;
420 else
421 m_bottomOfSheet += m_rowHeights[i];
422 }
423
424 m_totalGridWidth = m_leftOfSheet + m_verticalLabelWidth;
425 for (i = 0; i < m_totalCols; i++)
426 {
427 m_totalGridWidth += m_colWidths[i];
428 }
429 m_totalGridHeight = m_topOfSheet + m_horizontalLabelHeight;
430 for (i = 0; i < m_totalRows; i++)
431 {
432 m_totalGridHeight += m_rowHeights[i];
433 }
434 }
435
436 wxGridCell *wxGenericGrid::GetCell(int row, int col) const
437 {
438 if (!m_gridCells)
439 return (wxGridCell *) NULL;
440
441 if ((row >= m_totalRows) || (col >= m_totalCols))
442 return (wxGridCell *) NULL;
443
444 wxGridCell *cell = m_gridCells[row][col];
445 if (!cell)
446 {
447 // m_gridCells[row][col] = OnCreateCell();
448 wxGridEvent g_evt(GetId(), wxEVT_GRID_CREATE_CELL, (wxGenericGrid*) this, row, col);
449 GetEventHandler()->ProcessEvent(g_evt);
450 m_gridCells[row][col] = g_evt.m_cell;
451 return m_gridCells[row][col];
452 }
453 else
454 return cell;
455 }
456
457 void wxGenericGrid::SetGridClippingRegion(wxDC *dc)
458 {
459 int m_scrollWidthHoriz = 0;
460 int m_scrollWidthVert = 0;
461 int cw, ch;
462 GetClientSize(&cw, &ch);
463
464 if (m_hScrollBar && m_hScrollBar->IsShown())
465 m_scrollWidthHoriz = m_scrollWidth;
466 if (m_vScrollBar && m_vScrollBar->IsShown())
467 m_scrollWidthVert = m_scrollWidth;
468
469 // Don't paint over the scrollbars
470 dc->SetClippingRegion(m_leftOfSheet, m_topOfSheet,
471 cw - m_scrollWidthVert - m_leftOfSheet, ch - m_scrollWidthHoriz - m_topOfSheet);
472 }
473
474 void wxGenericGrid::OnPaint(wxPaintEvent& WXUNUSED(event))
475 {
476 int w, h;
477 GetClientSize(&w, &h);
478
479 bool useDoubleBuffering = (bool) wxUSE_DOUBLE_BUFFERING;
480 if (useDoubleBuffering)
481 {
482 // Reuse the old bitmap if possible
483
484 if (!m_doubleBufferingBitmap ||
485 (m_doubleBufferingBitmap->GetWidth() < w || m_doubleBufferingBitmap->GetHeight() < h))
486 {
487 if (m_doubleBufferingBitmap)
488 delete m_doubleBufferingBitmap;
489 m_doubleBufferingBitmap = new wxBitmap(w, h);
490 }
491 if (!m_doubleBufferingBitmap || !m_doubleBufferingBitmap->Ok())
492 {
493 // If we couldn't create a new bitmap, perhaps because resources were low,
494 // then don't complain, just don't double-buffer
495 if (m_doubleBufferingBitmap)
496 delete m_doubleBufferingBitmap;
497 m_doubleBufferingBitmap = (wxBitmap *) NULL;
498 useDoubleBuffering = FALSE;
499 }
500 }
501
502 if (useDoubleBuffering)
503 {
504 wxPaintDC paintDC(this);
505 wxMemoryDC dc(& paintDC);
506 dc.SelectObject(* m_doubleBufferingBitmap);
507
508 PaintGrid(dc);
509
510 int vertScrollBarWidth = m_scrollWidth;
511 int horizScrollBarHeight = m_scrollWidth;
512 if (m_vScrollBar && !m_vScrollBar->IsShown())
513 vertScrollBarWidth = 0;
514 if (m_hScrollBar && !m_hScrollBar->IsShown())
515 horizScrollBarHeight = 0;
516
517 paintDC.Blit(m_leftOfSheet, m_topOfSheet, w - vertScrollBarWidth - m_leftOfSheet, h - horizScrollBarHeight - m_topOfSheet,
518 &dc, m_leftOfSheet, m_topOfSheet, wxCOPY);
519
520 dc.SelectObject(wxNullBitmap);
521 }
522 else
523 {
524 wxPaintDC dc(this);
525 PaintGrid(dc);
526 }
527 }
528
529 void wxGenericGrid::PaintGrid(wxDC& dc)
530 {
531 dc.BeginDrawing();
532 dc.SetOptimization(FALSE);
533
534 SetGridClippingRegion(& dc);
535
536 DrawLabelAreas(& dc);
537
538 DrawEditableArea(& dc);
539 DrawColumnLabels(& dc);
540 DrawRowLabels(& dc);
541 DrawCells(& dc);
542 DrawGridLines(& dc);
543
544 /* Hilight present cell */
545 SetCurrentRect(m_wCursorRow, m_wCursorColumn);
546 if (m_currentRectVisible && !(m_editable && m_editInPlace))
547 HighlightCell(& dc);
548
549 dc.DestroyClippingRegion();
550 dc.SetOptimization(TRUE);
551 dc.EndDrawing();
552 }
553
554 // Erase (some of) the background.
555 // Currently, a Windows-only optimisation.
556 void wxGenericGrid::OnEraseBackground(wxEraseEvent& WXUNUSED(event) )
557 {
558 wxClientDC dc(this);
559 dc.BeginDrawing();
560 dc.SetOptimization(FALSE);
561
562 int w, h;
563 GetClientSize(& w, & h);
564 dc.SetBrush(*wxLIGHT_GREY_BRUSH);
565 dc.SetPen(*wxLIGHT_GREY_PEN);
566
567 if (m_hScrollBar && m_hScrollBar->IsShown() && m_vScrollBar && m_vScrollBar->IsShown())
568 {
569 dc.DrawRectangle(w - m_scrollWidth, h - m_scrollWidth, m_scrollWidth, m_scrollWidth);
570 }
571
572 dc.SetOptimization(TRUE);
573 dc.EndDrawing();
574 }
575
576
577 void wxGenericGrid::DrawLabelAreas(wxDC *dc)
578 {
579 int cw, ch;
580 GetClientSize(&cw, &ch);
581
582 dc->SetPen(*wxTRANSPARENT_PEN);
583 // dc->SetBrush(*dc->GetBackground());
584
585 // Should blank out any area which isn't going to be painted over.
586 // dc->DrawRectangle(m_leftOfSheet, m_bottomOfSheet, cw - m_leftOfSheet, ch - m_bottomOfSheet);
587 // dc->DrawRectangle(m_rightOfSheet, m_topOfSheet, cw - m_rightOfSheet, ch - m_topOfSheet);
588
589 // Paint the label areas
590 dc->SetBrush(m_labelBackgroundBrush);
591 // dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, m_rightOfSheet - m_leftOfSheet + 1, m_horizontalLabelHeight + 1);
592 dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, cw-m_leftOfSheet, m_horizontalLabelHeight + 1);
593 // dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, m_verticalLabelWidth + 1, m_bottomOfSheet - m_topOfSheet + 1);
594 dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, m_verticalLabelWidth + 1, ch-m_topOfSheet);
595 }
596
597 void wxGenericGrid::DrawEditableArea(wxDC *dc)
598 {
599 int cw, ch;
600 GetClientSize(&cw, &ch);
601
602 dc->SetPen(*wxTRANSPARENT_PEN);
603 dc->SetBrush(*wxTheBrushList->FindOrCreateBrush(m_cellBackgroundColour, wxSOLID));
604 // dc->DrawRectangle(m_leftOfSheet+m_verticalLabelWidth, m_topOfSheet+m_horizontalLabelHeight,
605 // m_rightOfSheet-(m_leftOfSheet+m_verticalLabelWidth) + 1, m_bottomOfSheet - (m_topOfSheet+m_horizontalLabelHeight) + 1);
606 dc->DrawRectangle(m_leftOfSheet+m_verticalLabelWidth, m_topOfSheet+m_horizontalLabelHeight,
607 cw-(m_leftOfSheet+m_verticalLabelWidth), ch - (m_topOfSheet+m_horizontalLabelHeight));
608 }
609
610 void wxGenericGrid::DrawGridLines(wxDC *dc)
611 {
612 int cw, ch;
613 GetClientSize(&cw, &ch);
614
615 int i;
616
617 if (m_divisionPen.Ok())
618 {
619 dc->SetPen(m_divisionPen);
620
621 int heightCount = m_topOfSheet + m_horizontalLabelHeight;
622
623 // Draw horizontal grey lines for cells
624 for (i = m_scrollPosY; i < (m_totalRows+1); i++)
625 {
626 if (heightCount > ch)
627 break;
628 else
629 {
630 dc->DrawLine(m_leftOfSheet, heightCount,
631 cw, heightCount);
632 if (i < m_totalRows)
633 heightCount += m_rowHeights[i];
634 }
635 }
636 }
637
638 if (m_verticalLabelWidth > 0)
639 {
640 dc->SetPen(*wxBLACK_PEN);
641
642 // Draw horizontal black lines for row labels
643 int heightCount = m_topOfSheet + m_horizontalLabelHeight;
644 for (i = m_scrollPosY; i < (m_totalRows+1); i++)
645 {
646 if (heightCount > ch)
647 break;
648 else
649 {
650 dc->DrawLine(m_leftOfSheet, heightCount,
651 m_verticalLabelWidth, heightCount);
652 if (i < m_totalRows)
653 heightCount += m_rowHeights[i];
654 }
655 }
656 // Draw a black vertical line for row number cells
657 dc->DrawLine(m_leftOfSheet + m_verticalLabelWidth, m_topOfSheet,
658 m_leftOfSheet + m_verticalLabelWidth, ch);
659 // First vertical line
660 dc->DrawLine(m_leftOfSheet, m_topOfSheet, m_leftOfSheet, ch);
661
662 dc->SetPen(*wxWHITE_PEN);
663
664 // Draw highlights on row labels
665 heightCount = m_topOfSheet + m_horizontalLabelHeight;
666 for (i = m_scrollPosY; i < m_totalRows; i++)
667 {
668 if (heightCount > ch)
669 break;
670 else
671 {
672 dc->DrawLine(m_leftOfSheet+1, heightCount+1,
673 m_verticalLabelWidth, heightCount+1);
674 dc->DrawLine(m_leftOfSheet+1, heightCount+1,
675 m_leftOfSheet+1, heightCount + m_rowHeights[i] - 1);
676 heightCount += m_rowHeights[i];
677 }
678 }
679 // Last one - down to the floor.
680 dc->DrawLine(m_leftOfSheet+1, heightCount+1,
681 m_verticalLabelWidth, heightCount+1);
682 dc->DrawLine(m_leftOfSheet+1, heightCount+1,
683 m_leftOfSheet+1, ch);
684
685 }
686
687 if (m_divisionPen.Ok())
688 {
689 dc->SetPen(m_divisionPen);
690
691 // Draw vertical grey lines for cells
692 int widthCount = m_leftOfSheet + m_verticalLabelWidth;
693 for (i = m_scrollPosX; i < m_totalCols; i++)
694 {
695 if (widthCount > cw)
696 break;
697 else
698 {
699 // Skip the first one
700 if (i != m_scrollPosX)
701 {
702 dc->DrawLine(widthCount, m_topOfSheet + m_horizontalLabelHeight,
703 widthCount, m_bottomOfSheet);
704 }
705 widthCount += m_colWidths[i];
706 }
707 }
708 // Last one
709 dc->DrawLine(widthCount, m_topOfSheet + m_horizontalLabelHeight,
710 widthCount, m_bottomOfSheet);
711 }
712
713 dc->SetPen(*wxBLACK_PEN);
714
715 // Draw two black horizontal lines for column number cells
716 dc->DrawLine(
717 m_leftOfSheet, m_topOfSheet,
718 cw, m_topOfSheet);
719 dc->DrawLine(m_leftOfSheet, m_topOfSheet + m_horizontalLabelHeight,
720 cw, m_topOfSheet + m_horizontalLabelHeight);
721
722 if (m_horizontalLabelHeight > 0)
723 {
724 int widthCount = m_leftOfSheet + m_verticalLabelWidth;
725
726 // Draw black vertical lines for column number cells
727 for (i = m_scrollPosX; i < m_totalCols; i++)
728 {
729 if (widthCount > cw)
730 break;
731 else
732 {
733 dc->DrawLine(widthCount, m_topOfSheet,
734 widthCount, m_topOfSheet + m_horizontalLabelHeight);
735 widthCount += m_colWidths[i];
736 }
737 }
738
739 // Last one
740 dc->DrawLine(widthCount, m_topOfSheet,
741 widthCount, m_topOfSheet + m_horizontalLabelHeight);
742
743 // Draw highlights
744 dc->SetPen(*wxWHITE_PEN);
745 widthCount = m_leftOfSheet + m_verticalLabelWidth;
746
747 for (i = m_scrollPosX; i < m_totalCols; i++)
748 {
749 if (widthCount > cw)
750 break;
751 else
752 {
753 dc->DrawLine(widthCount+1, m_topOfSheet+1,
754 widthCount+m_colWidths[i], m_topOfSheet+1);
755 dc->DrawLine(widthCount+1, m_topOfSheet+1,
756 widthCount+1, m_topOfSheet+m_horizontalLabelHeight);
757 widthCount += m_colWidths[i];
758 }
759 }
760 // Last one - to the right side of the canvas.
761 dc->DrawLine(widthCount+1, m_topOfSheet+1,
762 cw, m_topOfSheet+1);
763 dc->DrawLine(widthCount+1, m_topOfSheet+1,
764 widthCount+1, m_topOfSheet+m_horizontalLabelHeight);
765
766 }
767 }
768
769 void wxGenericGrid::DrawColumnLabels(wxDC *dc)
770 {
771 int cw, ch;
772 GetClientSize(&cw, &ch);
773
774 if (m_horizontalLabelHeight == 0)
775 return;
776
777 int i;
778 wxRect rect;
779
780 // Draw letters for columns
781 rect.y = m_topOfSheet + 1;
782 rect.height = m_horizontalLabelHeight - 1;
783
784 dc->SetTextBackground(m_labelBackgroundColour);
785 dc->SetBackgroundMode(wxTRANSPARENT);
786 // dc->SetTextForeground(m_labelTextColour);
787
788 int widthCount = m_leftOfSheet + m_verticalLabelWidth;
789 for (i = m_scrollPosX; i < m_totalCols; i++)
790 {
791 if (widthCount > cw)
792 break;
793 else
794 {
795 rect.x = 1 + widthCount;
796 rect.width = m_colWidths[i];
797 DrawColumnLabel(dc, &rect, i);
798
799 widthCount += m_colWidths[i];
800 }
801 }
802 }
803
804 void wxGenericGrid::DrawColumnLabel(wxDC *dc, wxRect *rect, int col)
805 {
806 wxGridCell *cell = GetLabelCell(wxHORIZONTAL, col);
807 if (cell)
808 {
809 wxRect rect2;
810 rect2 = *rect;
811 rect2.x += 3;
812 rect2.y += 2;
813 rect2.width -= 5;
814 rect2.height -= 4;
815 dc->SetTextForeground(GetLabelTextColour());
816 dc->SetFont(GetLabelTextFont());
817 if ( !cell->GetTextValue().IsNull() )
818 DrawTextRect(dc, cell->GetTextValue(), &rect2, GetLabelAlignment(wxHORIZONTAL));
819 }
820 }
821
822 void wxGenericGrid::DrawRowLabels(wxDC *dc)
823 {
824 int cw, ch;
825 GetClientSize(&cw, &ch);
826
827 if (m_verticalLabelWidth == 0)
828 return;
829
830 int i;
831 wxRect rect;
832
833 // Draw numbers for rows
834 rect.x = m_leftOfSheet;
835 rect.width = m_verticalLabelWidth;
836
837 int heightCount = m_topOfSheet + m_horizontalLabelHeight;
838
839 dc->SetTextBackground(m_labelBackgroundColour);
840 dc->SetBackgroundMode(wxTRANSPARENT);
841
842 for (i = m_scrollPosY; i < m_totalRows; i++)
843 {
844 if (heightCount > ch)
845 break;
846 else
847 {
848 rect.y = 1 + heightCount;
849 rect.height = m_rowHeights[i];
850 DrawRowLabel(dc, &rect, i);
851
852 heightCount += m_rowHeights[i];
853 }
854 }
855 }
856
857 void wxGenericGrid::DrawRowLabel(wxDC *dc, wxRect *rect, int row)
858 {
859 wxGridCell *cell = GetLabelCell(wxVERTICAL, row);
860 if (cell)
861 {
862 wxRect rect2;
863 rect2 = *rect;
864 rect2.x += 3;
865 rect2.y += 2;
866 rect2.width -= 5;
867 rect2.height -= 4;
868 dc->SetTextForeground(GetLabelTextColour());
869 dc->SetFont(GetLabelTextFont());
870 if ( !cell->GetTextValue().IsNull() )
871 DrawTextRect(dc, cell->GetTextValue(), &rect2, GetLabelAlignment(wxVERTICAL));
872 }
873 }
874
875 void wxGenericGrid::DrawCells(wxDC *dc)
876 {
877 int cw, ch;
878 GetClientSize(&cw, &ch);
879
880 int i,j;
881
882 // Draw value corresponding to each cell
883 for (i = m_scrollPosY; i < m_totalRows; i++)
884 {
885 for (j = m_scrollPosX; j < m_totalCols; j++)
886 {
887 SetCurrentRect(i, j, cw, ch);
888 if (m_currentRectVisible)
889 {
890 DrawCellBackground(dc, &m_currentRect, i, j);
891 DrawCellValue(dc, &m_currentRect, i, j);
892 }
893 if (m_currentRect.x > cw)
894 break;
895 }
896 if (m_currentRect.y > ch)
897 break;
898 }
899 dc->SetBackgroundMode(wxSOLID);
900 dc->SetPen(*wxBLACK_PEN);
901 }
902
903 void wxGenericGrid::DrawCellBackground(wxDC *dc, wxRect *rect, int row, int col)
904 {
905 wxGridCell *cell = GetCell(row, col);
906 if (cell)
907 {
908 dc->SetBrush(cell->GetBackgroundBrush());
909 dc->SetPen(*wxTRANSPARENT_PEN);
910
911 #if 0 // In wxWin 2.0 the dc code is exact. RR.
912 #ifdef __WXMOTIF__
913 dc->DrawRectangle(rect->x+1, rect->y+1, rect->width-1, rect->height-1);
914 #else
915 dc->DrawRectangle(rect->x+1, rect->y+1, rect->width, rect->height);
916 #endif
917 #endif
918
919 dc->DrawRectangle(rect->x+1, rect->y+1, rect->width-1, rect->height-1);
920
921 dc->SetPen(*wxBLACK_PEN);
922 }
923 }
924
925 void wxGenericGrid::DrawCellValue(wxDC *dc, wxRect *rect, int row, int col)
926 {
927 wxGridCell *cell = GetCell(row, col);
928 if (cell)
929 {
930 wxBitmap *bitmap = cell->GetCellBitmap();
931 wxRect rect2;
932 rect2 = *rect;
933 rect2.x += 3;
934 rect2.y += 2;
935 rect2.width -= 5;
936 rect2.height -= 4;
937
938 if (bitmap)
939 {
940 DrawBitmapRect(dc, bitmap, &rect2, cell->GetAlignment());
941 }
942 else
943 {
944 dc->SetBackgroundMode(wxTRANSPARENT);
945 dc->SetTextForeground(cell->GetTextColour());
946 dc->SetFont(cell->GetFont());
947
948 if ( !cell->GetTextValue().IsNull() )
949 DrawTextRect(dc, cell->GetTextValue(), &rect2, cell->GetAlignment());
950 }
951 }
952 }
953
954 void wxGenericGrid::AdjustScrollbars()
955 {
956 int cw, ch;
957 GetClientSize(&cw, &ch);
958
959 // We find the view size by seeing how many rows/cols fit on
960 // the current view.
961 // BUT... this means that the scrollbar should be adjusted every time
962 // it's scrolled, as well as when sized, because with variable size rows/cols,
963 // the number of rows/col visible on the view differs according to what bit
964 // you're looking at. The object length is always the same, but the
965 // view length differs.
966
967 // Since this may not be known until the end of this function, we should probably call AdjustScrollbars
968 // twice.
969 int vertScrollBarWidth = m_scrollWidth;
970 int horizScrollBarHeight = m_scrollWidth;
971 if (m_vScrollBar && !m_vScrollBar->IsShown())
972 vertScrollBarWidth = 0;
973 if (m_hScrollBar && !m_hScrollBar->IsShown())
974 horizScrollBarHeight = 0;
975
976 int noHorizSteps = 0;
977 int noVertSteps = 0;
978
979 if (m_totalGridWidth + vertScrollBarWidth > cw)
980 {
981 int widthCount = 0;
982
983 int i;
984 int nx = 0;
985 for (i = m_scrollPosX ; i < m_totalCols; i++)
986 {
987 widthCount += m_colWidths[i];
988 // A partial bit doesn't count, we still have to scroll to see the
989 // rest of it
990 if (widthCount + m_leftOfSheet + m_verticalLabelWidth > (cw-vertScrollBarWidth))
991 break;
992 else
993 nx ++;
994 }
995
996 noHorizSteps += nx;
997 }
998 m_viewWidth = noHorizSteps;
999
1000 if (m_totalGridHeight + horizScrollBarHeight > ch)
1001 {
1002 int heightCount = 0;
1003
1004 int i;
1005 int ny = 0;
1006 for (i = m_scrollPosY ; i < m_totalRows; i++)
1007 {
1008 heightCount += m_rowHeights[i];
1009 // A partial bit doesn't count, we still have to scroll to see the
1010 // rest of it
1011 if (heightCount + m_topOfSheet + m_horizontalLabelHeight > (ch-horizScrollBarHeight))
1012 break;
1013 else
1014 ny ++;
1015 }
1016
1017 noVertSteps += ny;
1018 }
1019
1020 m_viewHeight = noVertSteps;
1021
1022 if (m_totalGridWidth + vertScrollBarWidth <= cw)
1023 {
1024 if ( m_hScrollBar )
1025 m_hScrollBar->Show(FALSE);
1026 SetScrollPosX(0);
1027 }
1028 else
1029 {
1030 if ( m_hScrollBar )
1031 m_hScrollBar->Show(TRUE);
1032 }
1033
1034 if (m_totalGridHeight + horizScrollBarHeight <= ch)
1035 {
1036 if ( m_vScrollBar )
1037 m_vScrollBar->Show(FALSE);
1038 SetScrollPosY(0);
1039 }
1040 else
1041 {
1042 if ( m_vScrollBar )
1043 m_vScrollBar->Show(TRUE);
1044 }
1045
1046 UpdateDimensions(); // Necessary in case m_scrollPosX/Y changed
1047
1048 vertScrollBarWidth = m_scrollWidth;
1049 horizScrollBarHeight = m_scrollWidth;
1050 if (m_vScrollBar && !m_vScrollBar->IsShown())
1051 vertScrollBarWidth = 0;
1052 if (m_hScrollBar && !m_hScrollBar->IsShown())
1053 horizScrollBarHeight = 0;
1054
1055 if (m_hScrollBar && m_hScrollBar->IsShown())
1056 {
1057 int nCols = GetCols();
1058 m_hScrollBar->SetScrollbar(m_hScrollBar->GetThumbPosition(), wxMax(noHorizSteps, 1), (noHorizSteps == 0) ? 1 : nCols, wxMax(noHorizSteps, 1));
1059
1060 /*
1061 m_hScrollBar->SetSize(m_leftOfSheet, ch - m_scrollWidth -2, // why -2 ? Robert.
1062 cw - vertScrollBarWidth - m_leftOfSheet, m_scrollWidth);
1063 */
1064 m_hScrollBar->SetSize(m_leftOfSheet, ch - m_scrollWidth,
1065 cw - vertScrollBarWidth - m_leftOfSheet, m_scrollWidth);
1066
1067 }
1068
1069 if (m_vScrollBar && m_vScrollBar->IsShown())
1070 {
1071 int nRows = GetRows();
1072
1073 m_vScrollBar->SetScrollbar(m_vScrollBar->GetThumbPosition(), wxMax(noVertSteps, 1), (noVertSteps == 0) ? 1 : nRows, wxMax(noVertSteps, 1));
1074 m_vScrollBar->SetSize(cw - m_scrollWidth, m_topOfSheet,
1075 m_scrollWidth, ch - m_topOfSheet - horizScrollBarHeight);
1076 }
1077 }
1078
1079 void wxGenericGrid::OnSize(wxSizeEvent& WXUNUSED(event) )
1080 {
1081 if (!m_vScrollBar || !m_hScrollBar)
1082 return;
1083
1084 AdjustScrollbars();
1085
1086 int cw, ch;
1087 GetClientSize(&cw, &ch);
1088
1089 if (m_editCreated && m_editingPanel && GetTextItem() && GetTextItem()->IsShown())
1090 {
1091 m_editingPanel->SetSize(0, 0, cw, m_editControlPosition.height + m_editControlPosition.y + 2);
1092 GetTextItem()->SetSize(m_editControlPosition.x, m_editControlPosition.y,
1093 cw - 2*m_editControlPosition.x, m_editControlPosition.height);
1094 }
1095 }
1096
1097 bool wxGenericGrid::CellHitTest(int x, int y, int *row, int *col)
1098 {
1099 // Find the selected cell and call OnSelectCell
1100 if (x >= (m_leftOfSheet + m_verticalLabelWidth) && y >= (m_topOfSheet + m_horizontalLabelHeight) &&
1101 x <= m_rightOfSheet && y <= m_bottomOfSheet)
1102 {
1103 // Calculate the cell number from x and y
1104 x -= (m_verticalLabelWidth + m_leftOfSheet);
1105 y -= (m_topOfSheet + m_horizontalLabelHeight);
1106
1107 int i;
1108
1109 // Now we need to do a hit test for which row we're on
1110 int currentHeight = 0;
1111 for (i = m_scrollPosY; i < m_totalRows; i++)
1112 {
1113 if (y >= currentHeight && y <= (currentHeight + m_rowHeights[i]))
1114 {
1115 *row = i;
1116 break;
1117 }
1118 currentHeight += m_rowHeights[i];
1119 }
1120
1121 // Now we need to do a hit test for which column we're on
1122 int currentWidth = 0;
1123 for (i = m_scrollPosX; i < m_totalCols; i++)
1124 {
1125 if (x >= currentWidth && x <= (currentWidth + m_colWidths[i]))
1126 {
1127 *col = i;
1128 break;
1129 }
1130 currentWidth += m_colWidths[i];
1131 }
1132 return TRUE;
1133 }
1134 return FALSE;
1135 }
1136
1137 bool wxGenericGrid::LabelSashHitTest(int x, int y, int *orientation, int *rowOrCol, int *startPos)
1138 {
1139 int i;
1140 int tolerance = 3;
1141
1142 if (x >= (m_leftOfSheet + m_verticalLabelWidth) && y >= m_topOfSheet &&
1143 x <= m_rightOfSheet && y <= (m_topOfSheet + m_horizontalLabelHeight))
1144 {
1145 // We may be on a column label sash.
1146 int currentWidth = m_leftOfSheet + m_verticalLabelWidth;
1147 for (i = m_scrollPosX; i < m_totalCols; i++)
1148 {
1149 if (x >= (currentWidth + m_colWidths[i] - tolerance) && x <= (currentWidth + m_colWidths[i] + tolerance))
1150 {
1151 *orientation = wxHORIZONTAL;
1152 *rowOrCol = i;
1153 *startPos = currentWidth;
1154 return TRUE;
1155 }
1156 currentWidth += m_colWidths[i];
1157 }
1158 return FALSE;
1159 }
1160 else if (x >= m_leftOfSheet && y >= (m_topOfSheet + m_horizontalLabelHeight) &&
1161 x <= (m_leftOfSheet + m_verticalLabelWidth) && y <= m_bottomOfSheet)
1162 {
1163 // We may be on a row label sash.
1164 int currentHeight = m_topOfSheet + m_horizontalLabelHeight;
1165 for (i = m_scrollPosY; i < m_totalRows; i++)
1166 {
1167 if (y >= (currentHeight + m_rowHeights[i] - tolerance) && y <= (currentHeight + m_rowHeights[i] + tolerance))
1168 {
1169 *orientation = wxVERTICAL;
1170 *rowOrCol = i;
1171 *startPos = currentHeight;
1172 return TRUE;
1173 }
1174 currentHeight += m_rowHeights[i];
1175 }
1176 return FALSE;
1177 }
1178 return FALSE;
1179 }
1180
1181 bool wxGenericGrid::LabelHitTest(int x, int y, int *row, int *col)
1182 {
1183 // Find the selected label
1184 if (x >= m_leftOfSheet && y >= m_topOfSheet &&
1185 x <= m_rightOfSheet && y <= m_bottomOfSheet)
1186 {
1187 // Calculate the cell number from x and y
1188 x -= m_leftOfSheet;
1189 y -= m_topOfSheet;
1190
1191 int i;
1192
1193 // Now we need to do a hit test for which row we're on
1194 int currentHeight = m_horizontalLabelHeight;
1195 for (i = m_scrollPosY; i < m_totalRows; i++)
1196 {
1197 if (y >= currentHeight && y <= (currentHeight + m_rowHeights[i]))
1198 {
1199 *row = i;
1200 break;
1201 }
1202 currentHeight += m_rowHeights[i];
1203 }
1204 if (y >= 0 && y <= m_horizontalLabelHeight)
1205 {
1206 *row = -1;
1207 }
1208
1209 // Now we need to do a hit test for which column we're on
1210 int currentWidth = m_verticalLabelWidth;
1211 for (i = m_scrollPosX; i < m_totalCols; i++)
1212 {
1213 if (x >= currentWidth && x <= (currentWidth + m_colWidths[i]))
1214 {
1215 *col = i;
1216 break;
1217 }
1218 currentWidth += m_colWidths[i];
1219 }
1220 if (x >= 0 && x <= m_verticalLabelWidth)
1221 {
1222 *col = -1;
1223 }
1224
1225 if ((*col == -1) || (*row == -1))
1226 {
1227 return TRUE;
1228 }
1229 }
1230 return FALSE;
1231 }
1232
1233 void wxGenericGrid::OnMouseEvent(wxMouseEvent& ev)
1234 {
1235 if (ev.LeftDown())
1236 {
1237 wxClientDC dc(this);
1238 dc.BeginDrawing();
1239
1240 int row, col;
1241 if (CellHitTest((int)ev.GetX(), (int)ev.GetY(), &row, &col))
1242 {
1243 OnSelectCellImplementation(& dc, row, col);
1244
1245 //OnCellLeftClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1246 wxGridEvent g_evt(GetId(), wxEVT_GRID_CELL_LCLICK, this,
1247 row, col, (int)ev.GetX(), (int)ev.GetY(),
1248 ev.ControlDown(), ev.ShiftDown());
1249 GetEventHandler()->ProcessEvent(g_evt);
1250
1251 }
1252 if (LabelHitTest((int)ev.GetX(), (int)ev.GetY(), &row, &col))
1253 {
1254 //OnLabelLeftClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1255 wxGridEvent g_evt(GetId(), wxEVT_GRID_LABEL_LCLICK, this,
1256 row, col, (int)ev.GetX(), (int)ev.GetY(),
1257 ev.ControlDown(), ev.ShiftDown());
1258 GetEventHandler()->ProcessEvent(g_evt);
1259
1260 }
1261 dc.EndDrawing();
1262 }
1263 else if (ev.Dragging() && ev.LeftIsDown())
1264 {
1265 switch (m_dragStatus)
1266 {
1267 case wxGRID_DRAG_NONE:
1268 {
1269 int orientation;
1270 if (LabelSashHitTest((int)ev.GetX(), (int)ev.GetY(), &orientation, &m_dragRowOrCol, &m_dragStartPosition))
1271 {
1272 if (orientation == wxHORIZONTAL)
1273 {
1274 m_dragStatus = wxGRID_DRAG_LEFT_RIGHT;
1275 SetCursor(m_horizontalSashCursor);
1276 m_dragLastPosition = (int)ev.GetX();
1277 }
1278 else
1279 {
1280 m_dragStatus = wxGRID_DRAG_UP_DOWN;
1281 SetCursor(m_verticalSashCursor);
1282 m_dragLastPosition = (int)ev.GetY();
1283 }
1284 wxClientDC dc(this);
1285 dc.BeginDrawing();
1286 dc.SetLogicalFunction(wxINVERT);
1287 if (orientation == wxHORIZONTAL)
1288 dc.DrawLine((int)ev.GetX(), m_topOfSheet, (int)ev.GetX(), m_bottomOfSheet);
1289 else
1290 dc.DrawLine(m_leftOfSheet, (int)ev.GetY(), m_rightOfSheet, (int)ev.GetY());
1291 dc.EndDrawing();
1292
1293 CaptureMouse();
1294 }
1295 break;
1296 }
1297 case wxGRID_DRAG_LEFT_RIGHT:
1298 {
1299 wxClientDC dc(this);
1300 dc.BeginDrawing();
1301 dc.SetLogicalFunction(wxINVERT);
1302 dc.DrawLine(m_dragLastPosition, m_topOfSheet, m_dragLastPosition, m_bottomOfSheet);
1303
1304 dc.DrawLine((int)ev.GetX(), m_topOfSheet, (int)ev.GetX(), m_bottomOfSheet);
1305 dc.EndDrawing();
1306
1307 m_dragLastPosition = (int)ev.GetX();
1308 SetCursor(m_horizontalSashCursor);
1309 break;
1310 }
1311 case wxGRID_DRAG_UP_DOWN:
1312 {
1313 wxClientDC dc(this);
1314 dc.BeginDrawing();
1315 dc.SetLogicalFunction(wxINVERT);
1316 dc.DrawLine(m_leftOfSheet, m_dragLastPosition, m_rightOfSheet, m_dragLastPosition);
1317
1318 dc.DrawLine(m_leftOfSheet, (int)ev.GetY(), m_rightOfSheet, (int)ev.GetY());
1319 dc.EndDrawing();
1320
1321 m_dragLastPosition = (int)ev.GetY();
1322 SetCursor(m_verticalSashCursor);
1323 break;
1324 }
1325 }
1326 }
1327 else if (ev.Moving())
1328 {
1329 int rowOrCol, orientation, startPos;
1330 if (LabelSashHitTest((int)ev.GetX(), (int)ev.GetY(), &orientation, &rowOrCol, &startPos))
1331 {
1332 if (orientation == wxHORIZONTAL)
1333 SetCursor(m_horizontalSashCursor);
1334 else
1335 SetCursor(m_verticalSashCursor);
1336 }
1337 else
1338 SetCursor(*wxSTANDARD_CURSOR);
1339 }
1340 else if (ev.LeftUp())
1341 {
1342 switch (m_dragStatus)
1343 {
1344 case wxGRID_DRAG_LEFT_RIGHT:
1345 {
1346 wxClientDC dc(this);
1347 dc.BeginDrawing();
1348 dc.SetLogicalFunction(wxINVERT);
1349 dc.DrawLine(m_dragLastPosition, m_topOfSheet, m_dragLastPosition, m_bottomOfSheet);
1350 dc.SetLogicalFunction(wxCOPY);
1351 dc.EndDrawing();
1352
1353 ReleaseMouse();
1354 if (ev.GetX() > m_dragStartPosition)
1355 {
1356 m_colWidths[m_dragRowOrCol] = (short)(ev.GetX() - m_dragStartPosition);
1357 UpdateDimensions();
1358 AdjustScrollbars();
1359 Refresh();
1360 }
1361 SetCursor(*wxSTANDARD_CURSOR);
1362 int cw, ch;
1363 GetClientSize(&cw, &ch);
1364 wxSizeEvent evt;
1365 OnSize(evt);
1366 break;
1367 }
1368 case wxGRID_DRAG_UP_DOWN:
1369 {
1370 wxClientDC dc(this);
1371 dc.BeginDrawing();
1372 dc.SetLogicalFunction(wxINVERT);
1373 dc.DrawLine(m_leftOfSheet, m_dragLastPosition, m_rightOfSheet, m_dragLastPosition);
1374 dc.SetLogicalFunction(wxCOPY);
1375 dc.EndDrawing();
1376
1377 ReleaseMouse();
1378 if (ev.GetY() > m_dragStartPosition)
1379 {
1380 m_rowHeights[m_dragRowOrCol] = (short)(ev.GetY() - m_dragStartPosition);
1381 UpdateDimensions();
1382 AdjustScrollbars();
1383 Refresh();
1384 }
1385 SetCursor(*wxSTANDARD_CURSOR);
1386 break;
1387 }
1388 }
1389 m_dragStatus = wxGRID_DRAG_NONE;
1390 }
1391 else if (ev.RightDown())
1392 {
1393 int row, col;
1394 if (CellHitTest((int)ev.GetX(), (int)ev.GetY(), &row, &col))
1395 {
1396 //OnCellRightClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1397 wxGridEvent g_evt(GetId(), wxEVT_GRID_CELL_RCLICK, this,
1398 row, col, (int)ev.GetX(), (int)ev.GetY(),
1399 ev.ControlDown(), ev.ShiftDown());
1400 GetEventHandler()->ProcessEvent(g_evt);
1401
1402 }
1403 if (LabelHitTest((int)ev.GetX(), (int)ev.GetY(), &row, &col))
1404 {
1405 //OnLabelRightClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1406 wxGridEvent g_evt(GetId(), wxEVT_GRID_LABEL_RCLICK, this,
1407 row, col, (int)ev.GetX(), (int)ev.GetY(),
1408 ev.ControlDown(), ev.ShiftDown());
1409 GetEventHandler()->ProcessEvent(g_evt);
1410 }
1411 }
1412 }
1413
1414 void wxGenericGrid::OnSelectCellImplementation(wxDC *dc, int row, int col)
1415 {
1416 m_wCursorColumn = col;
1417 m_wCursorRow = row;
1418
1419 //OnChangeSelectionLabel();
1420 wxGridEvent g_evt(GetId(), wxEVT_GRID_CHANGE_SEL_LABEL, this);
1421 GetEventHandler()->ProcessEvent(g_evt);
1422
1423 SetGridClippingRegion(dc);
1424
1425 // Remove the highlight from the old cell
1426 if ( m_currentRectVisible && !(m_editable && m_editInPlace) )
1427 {
1428 HighlightCell(dc);
1429 }
1430
1431
1432 // Highlight the new cell and copy its content to the edit control
1433 SetCurrentRect(m_wCursorRow, m_wCursorColumn);
1434 wxGridCell *cell = GetCell(m_wCursorRow, m_wCursorColumn);
1435 if (cell)
1436 {
1437 if ( cell->GetTextValue().IsNull() )
1438 m_textItem->SetValue("");
1439 else
1440 m_textItem->SetValue(cell->GetTextValue());
1441 }
1442
1443 SetGridClippingRegion(dc);
1444
1445
1446 if ( m_editable && m_editInPlace )
1447 {
1448 m_inPlaceTextItem->SetSize( m_currentRect.x-2, m_currentRect.y-2,
1449 m_currentRect.width+4, m_currentRect.height+4 );
1450
1451 if ( cell )
1452 {
1453 if ( cell->GetTextValue().IsNull() )
1454 {
1455 m_inPlaceTextItem->SetValue( "" );
1456 }
1457 else
1458 {
1459 m_inPlaceTextItem->SetFont( cell->GetFont() );
1460 m_inPlaceTextItem->SetValue( cell->GetTextValue() );
1461 }
1462 }
1463
1464 m_inPlaceTextItem->Show(TRUE);
1465 m_inPlaceTextItem->SetFocus();
1466 }
1467 else
1468 {
1469 // 1) Why isn't this needed for Windows??
1470 // Probably because of the SetValue?? JS.
1471 // 2) Arrrrrgh. This isn't needed anywhere,
1472 // of course. One hour of debugging... RR.
1473 //
1474 // 3) It *is* needed for Motif - michael
1475 //
1476 #ifdef __WXMOTIF__
1477 if ( !(m_editable && m_editInPlace) )
1478 HighlightCell(dc);
1479 #endif
1480 }
1481
1482 dc->DestroyClippingRegion();
1483
1484 OnSelectCell(row, col);
1485 wxGridEvent g_evt2(GetId(), wxEVT_GRID_SELECT_CELL, this, row, col);
1486 GetEventHandler()->ProcessEvent(g_evt2);
1487 }
1488
1489 wxGridCell *wxGenericGrid::OnCreateCell()
1490 {
1491 return new wxGridCell(this);
1492 }
1493
1494 void wxGenericGrid::OnChangeLabels()
1495 {
1496 char buf[100];
1497 int i;
1498 for (i = 0; i < m_totalRows; i++)
1499 {
1500 sprintf(buf, "%d", i+1);
1501 SetLabelValue(wxVERTICAL, buf, i);
1502 }
1503 // A...Z,AA...ZZ,AAA...ZZZ, etc.
1504 for (i = 0; i < m_totalCols; i++)
1505 {
1506 int j;
1507 int noTimes = (i/26 + 1);
1508 int ch = (i % 26) + 65;
1509 buf[0] = 0;
1510 for (j = 0; j < noTimes; j++)
1511 {
1512 char buf2[20];
1513 sprintf(buf2, "%c", (char)ch);
1514 strcat(buf, buf2);
1515 }
1516 SetLabelValue(wxHORIZONTAL, buf, i);
1517 }
1518 }
1519
1520 void wxGenericGrid::OnChangeSelectionLabel()
1521 {
1522 if (!GetEditable())
1523 return;
1524
1525 wxString rowLabel(GetLabelValue(wxVERTICAL, GetCursorRow()));
1526 wxString colLabel(GetLabelValue(wxHORIZONTAL, GetCursorColumn()));
1527
1528 wxString newLabel = colLabel + rowLabel;
1529 if ((newLabel.Length() > 0) && (newLabel.Length() <= 8) && GetTextItem())
1530 {
1531 // GetTextItem()->SetLabel(newLabel);
1532 }
1533 }
1534
1535 void wxGenericGrid::HighlightCell(wxDC *dc)
1536 {
1537 dc->SetLogicalFunction(wxINVERT);
1538
1539 // Top
1540 dc->DrawLine( m_currentRect.x + 1,
1541 m_currentRect.y + 1,
1542 m_currentRect.x + m_currentRect.width - 1,
1543 m_currentRect.y + 1);
1544 // Right
1545 dc->DrawLine( m_currentRect.x + m_currentRect.width - 1,
1546 m_currentRect.y + 1,
1547 m_currentRect.x + m_currentRect.width - 1,
1548 m_currentRect.y +m_currentRect.height - 1 );
1549 // Bottom
1550 dc->DrawLine( m_currentRect.x + m_currentRect.width - 1,
1551 m_currentRect.y + m_currentRect.height - 1,
1552 m_currentRect.x + 1,
1553 m_currentRect.y + m_currentRect.height - 1);
1554 // Left
1555 dc->DrawLine( m_currentRect.x + 1,
1556 m_currentRect.y + m_currentRect.height - 1,
1557 m_currentRect.x + 1,
1558 m_currentRect.y + 1);
1559
1560 dc->SetLogicalFunction(wxCOPY);
1561 }
1562
1563 void wxGenericGrid::DrawCellText()
1564 {
1565 if (!m_currentRectVisible)
1566 return;
1567
1568 wxGridCell *cell = GetCell(GetCursorRow(), GetCursorColumn());
1569 if (!cell)
1570 return;
1571
1572 wxClientDC dc(this);
1573 dc.BeginDrawing();
1574
1575 SetGridClippingRegion(& dc);
1576
1577 dc.SetBackgroundMode(wxTRANSPARENT);
1578 dc.SetBrush(cell->GetBackgroundBrush());
1579
1580 wxString editValue = m_textItem->GetValue();
1581
1582 wxRect rect;
1583 rect = m_currentRect;
1584 rect.x += 3;
1585 rect.y += 2;
1586 rect.width -= 5;
1587 rect.height -= 4;
1588
1589 // FIXME: what's this string of spaces supposed to represent?
1590 DrawTextRect(& dc, " ", &rect, wxLEFT);
1591 DrawTextRect(& dc, editValue, &rect, cell->GetAlignment());
1592
1593 dc.DestroyClippingRegion();
1594
1595 dc.SetBackgroundMode(wxSOLID);
1596
1597 dc.EndDrawing();
1598 }
1599
1600 void wxGenericGrid::SetCurrentRect(int Row, int Column, int canvasW, int canvasH)
1601 {
1602 int currentWidth = m_leftOfSheet + m_verticalLabelWidth;
1603 int i;
1604 for (i = m_scrollPosX; i < Column; i++)
1605 currentWidth += m_colWidths[i];
1606
1607 int currentHeight = m_topOfSheet + m_horizontalLabelHeight;
1608 for (i = m_scrollPosY; i < Row; i++)
1609 currentHeight += m_rowHeights[i];
1610
1611 m_currentRect.x = currentWidth;
1612 m_currentRect.y = currentHeight;
1613 m_currentRect.width = m_colWidths ? (m_colWidths[Column]) : 0;
1614 m_currentRect.height = m_rowHeights ? (m_rowHeights[Row]) : 0;
1615
1616 if (Row < m_scrollPosY || Column < m_scrollPosX)
1617 m_currentRectVisible = FALSE;
1618 else if ((canvasW != -1 && canvasH != -1) && (m_currentRect.x > canvasW || m_currentRect.y > canvasH))
1619 m_currentRectVisible = FALSE;
1620 else m_currentRectVisible = TRUE;
1621 }
1622
1623 static bool wxRectIntersection(wxRect *rect1, wxRect *rect2, wxRect *rect3)
1624 {
1625 int x2_1 = rect1->x + rect1->width;
1626 int y2_1 = rect1->y + rect1->height;
1627
1628 int x2_2 = rect2->x + rect2->width;
1629 int y2_2 = rect2->y + rect2->height;
1630
1631 int x2_3, y2_3;
1632
1633 // Check for intersection
1634 if ((rect1->x > x2_2) || (rect2->x > x2_1) ||
1635 (rect1->y > y2_2) || (rect2->y > y2_1))
1636 {
1637 // No intersection
1638 rect3->x = rect3->y = rect3->width = rect3->height = 0;
1639 return FALSE;
1640 }
1641
1642 if (rect1->x > rect2->x)
1643 rect3->x = rect1->x;
1644 else
1645 rect3->x = rect2->x;
1646 if (rect1->y > rect2->y)
1647 rect3->y = rect1->y;
1648 else
1649 rect3->y = rect2->y;
1650
1651 if (x2_1 > x2_2)
1652 x2_3 = x2_2;
1653 else
1654 x2_3 = x2_1;
1655 if (y2_1 > y2_2)
1656 y2_3 = y2_2;
1657 else
1658 y2_3 = y2_1;
1659
1660 rect3->width = (int)(x2_3 - rect3->x);
1661 rect3->height = (int)(y2_3 - rect3->y);
1662 return TRUE;
1663 }
1664
1665 void wxGenericGrid::DrawTextRect(wxDC *dc, const wxString& text, wxRect *rect, int flag)
1666 {
1667 dc->BeginDrawing();
1668
1669 // Ultimately, this functionality should be built into wxWindows,
1670 // and optimized for each platform. E.g. on Windows, use DrawText
1671 // passing a clipping rectangle, so that the wxWindows clipping region
1672 // does not have to be used to implement this.
1673
1674 // If we're already clipping, we need to find the intersection
1675 // between current clipping area and text clipping area.
1676
1677 wxRect clipRect;
1678 wxRect clipRect2;
1679 long clipX, clipY, clipW, clipH;
1680 dc->GetClippingBox(&clipX, &clipY, &clipW, &clipH);
1681 clipRect.x = (int)clipX; clipRect.y = (int)clipY;
1682 clipRect.width = (int)clipW; clipRect.height = (int)clipH;
1683
1684 bool alreadyClipping = TRUE;
1685
1686 if (clipRect.x == 0 && clipRect.y == 0 && clipRect.width == 0 && clipRect.height == 0)
1687 {
1688 alreadyClipping = FALSE;
1689 clipRect2.x = rect->x; clipRect2.y = rect->y;
1690 clipRect2.width = rect->width; clipRect2.height = rect->height;
1691 }
1692 else
1693 {
1694 // Find intersection.
1695 if (!wxRectIntersection(rect, &clipRect, &clipRect2))
1696 return;
1697 }
1698
1699 if (alreadyClipping)
1700 dc->DestroyClippingRegion();
1701
1702 dc->SetClippingRegion(clipRect2.x, clipRect2.y, clipRect2.width, clipRect2.height);
1703 long textWidth, textHeight;
1704
1705 dc->GetTextExtent(text, &textWidth, &textHeight);
1706
1707 // Do alignment
1708 float x,y;
1709 switch (flag)
1710 {
1711 case wxRIGHT:
1712 {
1713 x = (rect->x + rect->width - textWidth - 1.0);
1714 y = (rect->y + (rect->height - textHeight)/2.0);
1715 break;
1716 }
1717 case wxCENTRE:
1718 {
1719 x = (rect->x + (rect->width - textWidth)/2.0);
1720 y = (rect->y + (rect->height - textHeight)/2.0);
1721 break;
1722 }
1723 case wxLEFT:
1724 default:
1725 {
1726 x = (rect->x + 1.0);
1727 y = (rect->y + (rect->height - textHeight)/2.0);
1728 break;
1729 }
1730 }
1731 dc->DrawText(text, (long)x, (long)y );
1732
1733 dc->DestroyClippingRegion();
1734
1735 // Restore old clipping
1736 if (alreadyClipping)
1737 dc->SetClippingRegion(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
1738
1739 dc->EndDrawing();
1740 }
1741
1742 void wxGenericGrid::DrawBitmapRect(wxDC *dc, wxBitmap *bitmap, wxRect *rect, int flag)
1743 {
1744 dc->BeginDrawing();
1745
1746 // Ultimately, this functionality should be built into wxWindows,
1747 // and optimized for each platform. E.g. on Windows, use DrawText
1748 // passing a clipping rectangle, so that the wxWindows clipping region
1749 // does not have to be used to implement this.
1750
1751 // If we're already clipping, we need to find the intersection
1752 // between current clipping area and text clipping area.
1753
1754 wxRect clipRect;
1755 wxRect clipRect2;
1756 long clipX, clipY, clipW, clipH;
1757 dc->GetClippingBox(&clipX, &clipY, &clipW, &clipH);
1758 clipRect.x = (int)clipX; clipRect.y = (int)clipY;
1759 clipRect.width = (int)clipW; clipRect.height = (int)clipH;
1760
1761 bool alreadyClipping = TRUE;
1762
1763 if (clipRect.x == 0 && clipRect.y == 0 && clipRect.width == 0 && clipRect.height == 0)
1764 {
1765 alreadyClipping = FALSE;
1766 clipRect2.x = rect->x; clipRect2.y = rect->y;
1767 clipRect2.width = rect->width; clipRect2.height = rect->height;
1768 }
1769 else
1770 {
1771 // Find intersection.
1772 if (!wxRectIntersection(rect, &clipRect, &clipRect2))
1773 return;
1774 }
1775
1776 if (alreadyClipping)
1777 dc->DestroyClippingRegion();
1778
1779 dc->SetClippingRegion(clipRect2.x, clipRect2.y, clipRect2.width, clipRect2.height);
1780 float bitmapWidth, bitmapHeight;
1781
1782 bitmapWidth = bitmap->GetWidth();
1783 bitmapHeight = bitmap->GetHeight();
1784
1785 // Do alignment
1786 long x,y;
1787 switch (flag)
1788 {
1789 case wxRIGHT:
1790 {
1791 x = (long)(rect->x + rect->width - bitmapWidth - 1);
1792 y = (long)(rect->y + (rect->height - bitmapHeight)/2.0);
1793 break;
1794 }
1795 case wxCENTRE:
1796 {
1797 x = (long)(rect->x + (rect->width - bitmapWidth)/2.0);
1798 y = (long)(rect->y + (rect->height - bitmapHeight)/2.0);
1799 break;
1800 }
1801 case wxLEFT:
1802 default:
1803 {
1804 x = (long)(rect->x + 1);
1805 y = (long)(rect->y + (rect->height - bitmapHeight)/2.0);
1806 break;
1807 }
1808 }
1809 wxMemoryDC dcTemp;
1810 dcTemp.SelectObject(*bitmap);
1811
1812 dc->Blit( (long)x, (long)y, (long)bitmapWidth, (long)bitmapHeight, &dcTemp, 0, 0);
1813 dcTemp.SelectObject(wxNullBitmap);
1814
1815 dc->DestroyClippingRegion();
1816
1817 // Restore old clipping
1818 if (alreadyClipping)
1819 dc->SetClippingRegion(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
1820
1821 dc->EndDrawing();
1822 }
1823
1824 void wxGenericGrid::OnActivate(bool active)
1825 {
1826 if (active)
1827 {
1828 // Edit control should always have the focus
1829 if (GetTextItem() && GetEditable())
1830 {
1831 GetTextItem()->SetFocus();
1832 wxGridCell *cell = GetCell(GetCursorRow(), GetCursorColumn());
1833 if (cell)
1834 GetTextItem()->SetValue(cell->GetTextValue());
1835 }
1836 }
1837 }
1838
1839 void wxGenericGrid::SetCellValue(const wxString& val, int row, int col)
1840 {
1841 wxGridCell *cell = GetCell(row, col);
1842 if (cell)
1843 {
1844 cell->SetTextValue(val);
1845
1846 RefreshCell(row, col, TRUE);
1847 }
1848 }
1849
1850 void wxGenericGrid::RefreshCell(int row, int col, bool setText)
1851 {
1852 // Don't refresh within a pair of batch brackets
1853 if (GetBatchCount() > 0)
1854 return;
1855
1856 int cw, ch;
1857 GetClientSize(&cw, &ch);
1858
1859 SetCurrentRect(row, col, cw, ch);
1860 if (m_currentRectVisible)
1861 {
1862 wxGridCell *cell = GetCell(row, col);
1863
1864 bool currentPos = FALSE;
1865 if (row == m_wCursorRow && col == m_wCursorColumn && GetTextItem() && GetTextItem()->IsShown() && setText)
1866 {
1867 GetTextItem()->SetValue(cell->GetTextValue());
1868 currentPos = TRUE;
1869 }
1870 // Gets refreshed anyway in MSW
1871 #ifdef __WXMSW__
1872 if (!currentPos)
1873 #endif
1874 {
1875 wxClientDC dc(this);
1876 dc.BeginDrawing();
1877 DrawCellBackground(& dc, &m_currentRect, row, col);
1878 DrawCellValue(& dc, &m_currentRect, row, col);
1879 dc.EndDrawing();
1880 }
1881 }
1882 }
1883
1884 wxString& wxGenericGrid::GetCellValue(int row, int col) const
1885 {
1886 static wxString emptyString("");
1887
1888 wxGridCell *cell = GetCell(row, col);
1889 if (cell)
1890 return cell->GetTextValue();
1891 else
1892 return emptyString;
1893 }
1894
1895 void wxGenericGrid::SetColumnWidth(int col, int width)
1896 {
1897 if (col <= m_totalCols)
1898 m_colWidths[col] = width;
1899 }
1900
1901 int wxGenericGrid::GetColumnWidth(int col) const
1902 {
1903 if (col <= m_totalCols)
1904 return m_colWidths[col];
1905 else
1906 return 0;
1907 }
1908
1909 void wxGenericGrid::SetRowHeight(int row, int height)
1910 {
1911 if (row <= m_totalRows)
1912 m_rowHeights[row] = height;
1913 }
1914
1915 int wxGenericGrid::GetRowHeight(int row) const
1916 {
1917 if (row <= m_totalRows)
1918 return m_rowHeights[row];
1919 else
1920 return 0;
1921 }
1922
1923 void wxGenericGrid::SetLabelSize(int orientation, int sz)
1924 {
1925 if (orientation == wxHORIZONTAL)
1926 m_horizontalLabelHeight = sz;
1927 else
1928 m_verticalLabelWidth = sz;
1929 UpdateDimensions();
1930 SetCurrentRect(GetCursorRow(), GetCursorColumn());
1931 }
1932
1933 int wxGenericGrid::GetLabelSize(int orientation) const
1934 {
1935 if (orientation == wxHORIZONTAL)
1936 return m_horizontalLabelHeight;
1937 else
1938 return m_verticalLabelWidth;
1939 }
1940
1941 wxGridCell *wxGenericGrid::GetLabelCell(int orientation, int pos) const
1942 {
1943 if (orientation == wxHORIZONTAL)
1944 {
1945 if (m_colLabelCells && pos < m_totalCols)
1946 return m_colLabelCells[pos];
1947 else
1948 return (wxGridCell *) NULL;
1949 }
1950 else
1951 {
1952 if (m_rowLabelCells && pos < m_totalRows)
1953 return m_rowLabelCells[pos];
1954 else
1955 return (wxGridCell *) NULL;
1956 }
1957 }
1958
1959 void wxGenericGrid::SetLabelValue(int orientation, const wxString& val, int pos)
1960 {
1961 wxGridCell *cell = GetLabelCell(orientation, pos);
1962 if (cell)
1963 cell->SetTextValue(val);
1964 }
1965
1966 wxString& wxGenericGrid::GetLabelValue(int orientation, int pos) const
1967 {
1968 static wxString emptyString = "";
1969 wxGridCell *cell = GetLabelCell(orientation, pos);
1970 if (cell)
1971 return cell->GetTextValue();
1972 else
1973 return emptyString;
1974 }
1975
1976 void wxGenericGrid::SetLabelAlignment(int orientation, int align)
1977 {
1978 if (orientation == wxHORIZONTAL)
1979 m_horizontalLabelAlignment = align;
1980 else
1981 m_verticalLabelAlignment = align;
1982 UpdateDimensions();
1983 SetCurrentRect(GetCursorRow(), GetCursorColumn());
1984 }
1985
1986 int wxGenericGrid::GetLabelAlignment(int orientation) const
1987 {
1988 if (orientation == wxHORIZONTAL)
1989 return m_horizontalLabelAlignment;
1990 else
1991 return m_verticalLabelAlignment;
1992 }
1993
1994 void wxGenericGrid::SetLabelTextColour(const wxColour& colour)
1995 {
1996 m_labelTextColour = colour;
1997
1998 }
1999
2000 void wxGenericGrid::SetLabelBackgroundColour(const wxColour& colour)
2001 {
2002 m_labelBackgroundColour = colour;
2003 m_labelBackgroundBrush = * wxTheBrushList->FindOrCreateBrush(m_labelBackgroundColour, wxSOLID);
2004 }
2005
2006 void wxGenericGrid::SetEditable(bool edit)
2007 {
2008 m_editable = edit;
2009 if (edit)
2010 {
2011 int controlW, controlH;
2012 m_textItem->GetSize(&controlW, &controlH);
2013 m_editControlPosition.height = controlH;
2014
2015 m_topOfSheet = m_editControlPosition.x + controlH + 2;
2016 if (m_textItem)
2017 {
2018 m_editingPanel->Show(TRUE);
2019 m_textItem->Show(TRUE);
2020 m_textItem->SetFocus();
2021 }
2022
2023 if (m_inPlaceTextItem)
2024 {
2025 m_inPlaceTextItem->Show(TRUE);
2026 m_inPlaceTextItem->SetFocus();
2027 }
2028 }
2029 else
2030 {
2031 m_topOfSheet = 0;
2032 if (m_textItem)
2033 {
2034 m_textItem->Show(FALSE);
2035 m_editingPanel->Show(FALSE);
2036 }
2037
2038 if ( m_inPlaceTextItem )
2039 {
2040 m_inPlaceTextItem->Show(FALSE);
2041 }
2042 }
2043 UpdateDimensions();
2044 SetCurrentRect(GetCursorRow(), GetCursorColumn());
2045
2046 int cw, ch;
2047 GetClientSize(&cw, &ch);
2048 wxSizeEvent evt;
2049 OnSize(evt);
2050 /*
2051 int cw, ch;
2052 int m_scrollWidth = 16;
2053 GetClientSize(&cw, &ch);
2054
2055 if (m_vScrollBar)
2056 m_vScrollBar->SetSize(cw - m_scrollWidth, m_topOfSheet,
2057 m_scrollWidth, ch - m_topOfSheet - m_scrollWidth);
2058 */
2059 }
2060
2061
2062 void wxGenericGrid::SetEditInPlace(bool edit)
2063 {
2064 if ( m_editInPlace != edit )
2065 {
2066 m_editInPlace = edit;
2067
2068 if ( m_editInPlace ) // switched on
2069 {
2070 if ( m_currentRectVisible && m_editable )
2071 {
2072 m_inPlaceTextItem->SetSize( m_currentRect.x-2, m_currentRect.y-2,
2073 m_currentRect.width+4, m_currentRect.height+4 );
2074
2075 wxGridCell *cell = GetCell(m_wCursorRow, m_wCursorColumn);
2076
2077 if ( cell )
2078 {
2079 if ( cell->GetTextValue().IsNull() )
2080 {
2081 m_inPlaceTextItem->SetValue( "" );
2082 }
2083 else
2084 {
2085 m_inPlaceTextItem->SetFont( cell->GetFont() );
2086 m_inPlaceTextItem->SetValue( cell->GetTextValue() );
2087 }
2088 }
2089
2090 m_inPlaceTextItem->Show( TRUE );
2091 m_inPlaceTextItem->SetFocus();
2092 }
2093 }
2094 else // switched off
2095 {
2096 m_inPlaceTextItem->Show( FALSE );
2097 }
2098 }
2099 }
2100
2101
2102 void wxGenericGrid::SetCellAlignment(int flag, int row, int col)
2103 {
2104 wxGridCell *cell = GetCell(row, col);
2105 if (cell)
2106 cell->SetAlignment(flag);
2107 }
2108
2109 int wxGenericGrid::GetCellAlignment(int row, int col) const
2110 {
2111 wxGridCell *cell = GetCell(row, col);
2112 if (cell)
2113 return cell->GetAlignment();
2114 else
2115 return m_cellAlignment;
2116 }
2117
2118 void wxGenericGrid::SetCellAlignment(int flag)
2119 {
2120 m_cellAlignment = flag;
2121 int i,j;
2122 for (i = 0; i < GetRows(); i++)
2123 for (j = 0; j < GetCols(); j++)
2124 if (GetCell(i, j))
2125 GetCell(i, j)->SetAlignment(flag);
2126 }
2127
2128 int wxGenericGrid::GetCellAlignment(void) const
2129 {
2130 return m_cellAlignment;
2131 }
2132
2133 void wxGenericGrid::SetCellBackgroundColour(const wxColour& col)
2134 {
2135 m_cellBackgroundColour = col;
2136 int i,j;
2137 for (i = 0; i < GetRows(); i++)
2138 for (j = 0; j < GetCols(); j++)
2139 if (GetCell(i, j))
2140 GetCell(i, j)->SetBackgroundColour(col);
2141 }
2142
2143 void wxGenericGrid::SetCellBackgroundColour(const wxColour& val, int row, int col)
2144 {
2145 wxGridCell *cell = GetCell(row, col);
2146 if (cell)
2147 {
2148 cell->SetBackgroundColour(val);
2149 RefreshCell(row, col);
2150 }
2151 }
2152
2153 wxColour& wxGenericGrid::GetCellBackgroundColour(int row, int col) const
2154 {
2155 wxGridCell *cell = GetCell(row, col);
2156 if (cell)
2157 return cell->GetBackgroundColour();
2158 else
2159 return (wxColour&) m_cellBackgroundColour;
2160 }
2161
2162 void wxGenericGrid::SetCellTextColour(const wxColour& val, int row, int col)
2163 {
2164 wxGridCell *cell = GetCell(row, col);
2165 if (cell)
2166 {
2167 cell->SetTextColour(val);
2168 RefreshCell(row, col);
2169 }
2170 }
2171
2172 void wxGenericGrid::SetCellTextFont(const wxFont& fnt, int row, int col)
2173 {
2174 wxGridCell *cell = GetCell(row, col);
2175 if (cell)
2176 {
2177 cell->SetFont(fnt);
2178 RefreshCell(row, col);
2179 }
2180 }
2181
2182 wxFont& wxGenericGrid::GetCellTextFont(int row, int col) const
2183 {
2184 wxGridCell *cell = GetCell(row, col);
2185 if (cell)
2186 return (wxFont&) cell->GetFont();
2187 else
2188 return (wxFont&) m_cellTextFont;
2189 }
2190
2191 wxColour& wxGenericGrid::GetCellTextColour(int row, int col) const
2192 {
2193 wxGridCell *cell = GetCell(row, col);
2194 if (cell)
2195 return (wxColour&) cell->GetTextColour();
2196 else
2197 return (wxColour&) m_cellTextColour;
2198 }
2199
2200 void wxGenericGrid::SetCellTextColour(const wxColour& val)
2201 {
2202 m_cellTextColour = val;
2203 int i,j;
2204 for (i = 0; i < GetRows(); i++)
2205 for (j = 0; j < GetCols(); j++)
2206 if (GetCell(i, j))
2207 GetCell(i, j)->SetTextColour(val);
2208 }
2209
2210 void wxGenericGrid::SetCellTextFont(const wxFont& fnt)
2211 {
2212 m_cellTextFont = fnt;
2213 int i,j;
2214 for (i = 0; i < GetRows(); i++)
2215 for (j = 0; j < GetCols(); j++)
2216 if (GetCell(i, j))
2217 GetCell(i, j)->SetFont(fnt);
2218 }
2219
2220 void wxGenericGrid::SetCellBitmap(wxBitmap *bitmap, int row, int col)
2221 {
2222 wxGridCell *cell = GetCell(row, col);
2223 if (cell)
2224 {
2225 cell->SetCellBitmap(bitmap);
2226 RefreshCell(row, col);
2227 }
2228 }
2229
2230 wxBitmap *wxGenericGrid::GetCellBitmap(int row, int col) const
2231 {
2232 wxGridCell *cell = GetCell(row, col);
2233 if (cell)
2234 {
2235 return cell->GetCellBitmap();
2236 }
2237 else
2238 return (wxBitmap *) NULL;
2239 }
2240
2241 bool wxGenericGrid::InsertCols(int pos, int n, bool updateLabels)
2242 {
2243 if (pos > m_totalCols)
2244 return FALSE;
2245
2246 if (!m_gridCells)
2247 return CreateGrid(1, n);
2248 else
2249 {
2250 int i, j;
2251 // Cells
2252 for (i = 0; i < m_totalRows; i++)
2253 {
2254 wxGridCell **cols = m_gridCells[i];
2255 wxGridCell **newCols = new wxGridCell *[m_totalCols + n];
2256 for (j = 0; j < pos; j++)
2257 newCols[j] = cols[j];
2258 for (j = pos; j < pos + n; j++)
2259 newCols[j] = new wxGridCell(this);
2260 for (j = pos + n; j < m_totalCols + n; j++)
2261 newCols[j] = cols[j - n];
2262
2263 delete[] cols;
2264 m_gridCells[i] = newCols;
2265 }
2266
2267 // Column widths
2268 short *newColWidths = new short[m_totalCols + n];
2269 for (j = 0; j < pos; j++)
2270 newColWidths[j] = m_colWidths[j];
2271 for (j = pos; j < pos + n; j++)
2272 newColWidths[j] = wxGRID_DEFAULT_CELL_WIDTH;
2273 for (j = pos + n; j < m_totalCols + n; j++)
2274 newColWidths[j] = m_colWidths[j - n];
2275 delete[] m_colWidths;
2276 m_colWidths = newColWidths;
2277
2278 // Column labels
2279 wxGridCell **newLabels = new wxGridCell *[m_totalCols + n];
2280 for (j = 0; j < pos; j++)
2281 newLabels[j] = m_colLabelCells[j];
2282 for (j = pos; j < pos + n; j++)
2283 newLabels[j] = new wxGridCell(this);
2284 for (j = pos + n; j < m_totalCols + n; j++)
2285 newLabels[j] = m_colLabelCells[j - n];
2286
2287 delete[] m_colLabelCells;
2288 m_colLabelCells = newLabels;
2289
2290 m_totalCols += n;
2291
2292 if (updateLabels) {
2293 //OnChangeLabels();
2294 wxGridEvent g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS, this);
2295 GetEventHandler()->ProcessEvent(g_evt);
2296 }
2297
2298 UpdateDimensions();
2299 AdjustScrollbars();
2300 return TRUE;
2301 }
2302 }
2303
2304 bool wxGenericGrid::InsertRows(int pos, int n, bool updateLabels)
2305 {
2306 if (pos > m_totalRows)
2307 return FALSE;
2308
2309 if (!m_gridCells)
2310 return CreateGrid(n, 1);
2311 else
2312 {
2313 int i, j;
2314
2315 wxGridCell ***rows = new wxGridCell **[m_totalRows + n];
2316
2317 // Cells
2318 for (i = 0; i < pos; i++)
2319 rows[i] = m_gridCells[i];
2320
2321 for (i = pos; i < pos + n; i++)
2322 {
2323 rows[i] = new wxGridCell *[m_totalCols];
2324 for (j = 0; j < m_totalCols; j++)
2325 rows[i][j] = new wxGridCell(this);
2326 }
2327
2328 for (i = pos + n; i < m_totalRows + n; i++)
2329 rows[i] = m_gridCells[i - n];
2330
2331 delete[] m_gridCells;
2332 m_gridCells = rows;
2333
2334 // Row heights
2335 short *newRowHeights = new short[m_totalRows + n];
2336 for (i = 0; i < pos; i++)
2337 newRowHeights[i] = m_rowHeights[i];
2338 for (i = pos; i < pos + n; i++)
2339 newRowHeights[i] = wxGRID_DEFAULT_CELL_HEIGHT;
2340 for (i = pos + n; i < m_totalRows + n; i++)
2341 newRowHeights[i] = m_rowHeights[i - n];
2342 delete[] m_rowHeights;
2343 m_rowHeights = newRowHeights;
2344
2345 // Column labels
2346 wxGridCell **newLabels = new wxGridCell *[m_totalRows + n];
2347 for (i = 0; i < pos; i++)
2348 newLabels[i] = m_rowLabelCells[i];
2349 for (i = pos; i < pos + n; i++)
2350 newLabels[i] = new wxGridCell(this);
2351 for (i = pos + n; i < m_totalRows + n; i++)
2352 newLabels[i] = m_rowLabelCells[i - n];
2353
2354 delete[] m_rowLabelCells;
2355 m_rowLabelCells = newLabels;
2356
2357 m_totalRows += n;
2358
2359 if (updateLabels) {
2360 //OnChangeLabels();
2361 wxGridEvent g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS, this);
2362 GetEventHandler()->ProcessEvent(g_evt);
2363 }
2364
2365 UpdateDimensions();
2366 AdjustScrollbars();
2367 return TRUE;
2368 }
2369 }
2370
2371 bool wxGenericGrid::AppendCols(int n, bool updateLabels)
2372 {
2373 return InsertCols(GetCols(), n, updateLabels);
2374 }
2375
2376 bool wxGenericGrid::AppendRows(int n, bool updateLabels)
2377 {
2378 return InsertRows(GetRows(), n, updateLabels);
2379 }
2380
2381 bool wxGenericGrid::DeleteRows(int pos, int n, bool updateLabels)
2382 {
2383 if (pos > m_totalRows)
2384 return FALSE;
2385 if (!m_gridCells)
2386 return FALSE;
2387
2388 int i;
2389
2390 wxGridCell ***rows = new wxGridCell **[m_totalRows - n];
2391
2392 // Cells
2393 for (i = 0; i < pos; i++)
2394 rows[i] = m_gridCells[i];
2395
2396 for (i = pos + n; i < m_totalRows; i++)
2397 rows[i-n] = m_gridCells[i];
2398
2399 delete[] m_gridCells;
2400 m_gridCells = rows;
2401
2402 // Row heights
2403 short *newRowHeights = new short[m_totalRows - n];
2404 for (i = 0; i < pos; i++)
2405 newRowHeights[i] = m_rowHeights[i];
2406 for (i = pos + n; i < m_totalRows; i++)
2407 newRowHeights[i-n] = m_rowHeights[i];
2408 delete[] m_rowHeights;
2409 m_rowHeights = newRowHeights;
2410
2411 // Column labels
2412 wxGridCell **newLabels = new wxGridCell *[m_totalRows - n];
2413 for (i = 0; i < pos; i++)
2414 newLabels[i] = m_rowLabelCells[i];
2415 for (i = pos + n; i < m_totalRows; i++)
2416 newLabels[i-n] = m_rowLabelCells[i];
2417
2418 delete[] m_rowLabelCells;
2419 m_rowLabelCells = newLabels;
2420
2421 m_totalRows -= n;
2422
2423 if (updateLabels){
2424 //OnChangeLabels();
2425 wxGridEvent g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS, this);
2426 GetEventHandler()->ProcessEvent(g_evt);
2427 }
2428 UpdateDimensions();
2429 AdjustScrollbars();
2430 return TRUE;
2431 }
2432
2433 bool wxGenericGrid::DeleteCols(int pos, int n, bool updateLabels)
2434 {
2435 if (pos + n > m_totalCols)
2436 return FALSE;
2437 if (!m_gridCells)
2438 return FALSE;
2439
2440 int i, j;
2441
2442 // Cells
2443 for (i = 0; i < m_totalRows; i++)
2444 {
2445 wxGridCell **cols = m_gridCells[i];
2446 wxGridCell **newCols = new wxGridCell *[m_totalCols - n];
2447 for (j = 0; j < pos; j++)
2448 newCols[j] = cols[j];
2449 for (j = pos; j < pos + n; j++)
2450 delete cols[j];
2451 for (j = pos + n; j < m_totalCols; j++)
2452 newCols[j-n] = cols[j];
2453
2454 delete[] cols;
2455 m_gridCells[i] = newCols;
2456 }
2457
2458 // Column widths
2459 short *newColWidths = new short[m_totalCols - n];
2460 for (j = 0; j < pos; j++)
2461 newColWidths[j] = m_colWidths[j];
2462 for (j = pos + n; j < m_totalCols; j++)
2463 newColWidths[j-n] = m_colWidths[j];
2464 delete[] m_colWidths;
2465 m_colWidths = newColWidths;
2466
2467 // Column labels
2468 wxGridCell **newLabels = new wxGridCell *[m_totalCols - n];
2469 for (j = 0; j < pos; j++)
2470 newLabels[j] = m_colLabelCells[j];
2471 for (j = pos + n; j < m_totalCols; j++)
2472 newLabels[j-n] = m_colLabelCells[j];
2473
2474 delete[] m_colLabelCells;
2475 m_colLabelCells = newLabels;
2476
2477 m_totalCols -= n;
2478
2479 if (updateLabels) {
2480 //OnChangeLabels();
2481 wxGridEvent g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS, this);
2482 GetEventHandler()->ProcessEvent(g_evt);
2483 }
2484 UpdateDimensions();
2485 AdjustScrollbars();
2486 return TRUE;
2487 }
2488
2489 void wxGenericGrid::SetGridCursor(int row, int col)
2490 {
2491 if (row >= m_totalRows || col >= m_totalCols)
2492 return;
2493
2494 if (row == GetCursorRow() && col == GetCursorColumn())
2495 return;
2496
2497 wxClientDC dc(this);
2498 dc.BeginDrawing();
2499
2500 SetGridClippingRegion(& dc);
2501
2502 if (m_currentRectVisible && !(m_editable && m_editInPlace) )
2503 HighlightCell(& dc);
2504
2505 m_wCursorRow = row;
2506 m_wCursorColumn = col;
2507
2508 int cw, ch;
2509 GetClientSize(&cw, &ch);
2510
2511 SetCurrentRect(row, col, cw, ch);
2512
2513 if (m_currentRectVisible && !(m_editable && m_editInPlace) )
2514 HighlightCell(& dc);
2515
2516 dc.DestroyClippingRegion();
2517 dc.EndDrawing();
2518 }
2519
2520 // ----------------------------------------------------------------------------
2521 // Grid cell
2522 // ----------------------------------------------------------------------------
2523
2524 wxGridCell::wxGridCell(wxGenericGrid *window)
2525 {
2526 cellBitmap = (wxBitmap *) NULL;
2527 font = wxNullFont;
2528 backgroundBrush = wxNullBrush;
2529 if (window)
2530 textColour = window->GetCellTextColour();
2531 else
2532 textColour.Set(0,0,0);
2533 if (window)
2534 backgroundColour = window->GetCellBackgroundColour();
2535 else
2536 backgroundColour.Set(255,255,255);
2537
2538 if (window)
2539 font = window->GetCellTextFont();
2540 else
2541 font = * wxTheFontList->FindOrCreateFont(12, wxSWISS, wxNORMAL, wxNORMAL);
2542
2543 SetBackgroundColour(backgroundColour);
2544
2545 if (window)
2546 alignment = window->GetCellAlignment();
2547 else
2548 alignment = wxLEFT;
2549
2550 cellData = (void *)NULL;
2551 }
2552
2553 wxGridCell::~wxGridCell()
2554 {
2555 }
2556
2557 void wxGridCell::SetBackgroundColour(const wxColour& colour)
2558 {
2559 backgroundColour = colour;
2560 backgroundBrush = * wxTheBrushList->FindOrCreateBrush(backgroundColour, wxSOLID);
2561 }
2562
2563 void wxGenericGrid::OnText(wxCommandEvent& WXUNUSED(ev) )
2564 {
2565 // michael - added this conditional to prevent change to
2566 // grid cell text when edit control is hidden but still has
2567 // focus
2568 //
2569 if ( m_editable )
2570 {
2571 wxGenericGrid *grid = this;
2572 wxGridCell *cell = grid->GetCell(grid->GetCursorRow(), grid->GetCursorColumn());
2573 if (cell && grid->CurrentCellVisible())
2574 {
2575 cell->SetTextValue(grid->GetTextItem()->GetValue());
2576 if ( m_editInPlace && !m_inOnTextInPlace )
2577 {
2578 m_inPlaceTextItem->SetValue( grid->GetTextItem()->GetValue() );
2579 }
2580
2581 wxClientDC dc(grid);
2582
2583 dc.BeginDrawing();
2584 grid->SetGridClippingRegion(& dc);
2585 grid->DrawCellBackground(& dc, &grid->GetCurrentRect(), grid->GetCursorRow(), grid->GetCursorColumn());
2586 grid->DrawCellValue(& dc, &grid->GetCurrentRect(), grid->GetCursorRow(), grid->GetCursorColumn());
2587 if ( !(m_editable && m_editInPlace ) ) grid->HighlightCell(& dc);
2588 dc.DestroyClippingRegion();
2589 dc.EndDrawing();
2590
2591 //grid->OnCellChange(grid->GetCursorRow(), grid->GetCursorColumn());
2592 wxGridEvent g_evt(GetId(), wxEVT_GRID_CELL_CHANGE, grid,
2593 grid->GetCursorRow(), grid->GetCursorColumn());
2594 GetEventHandler()->ProcessEvent(g_evt);
2595
2596 // grid->DrawCellText();
2597 }
2598 }
2599 }
2600
2601 void wxGenericGrid::OnTextEnter(wxCommandEvent& WXUNUSED(ev) )
2602 {
2603 // move the cursor down the current row (if possible)
2604 // when the enter key has been pressed
2605 //
2606 if ( m_editable )
2607 {
2608 if ( GetCursorRow() < GetRows()-1 )
2609 {
2610 wxClientDC dc( this );
2611 dc.BeginDrawing();
2612 OnSelectCellImplementation(& dc,
2613 GetCursorRow()+1,
2614 GetCursorColumn() );
2615 dc.EndDrawing();
2616 }
2617 }
2618 }
2619
2620 void wxGenericGrid::OnTextInPlace(wxCommandEvent& ev )
2621 {
2622 if ( m_editable )
2623 {
2624 wxGenericGrid *grid = this;
2625 wxGridCell *cell = grid->GetCell(grid->GetCursorRow(), grid->GetCursorColumn());
2626 if (cell && grid->CurrentCellVisible())
2627 {
2628 m_inOnTextInPlace = TRUE;
2629 grid->GetTextItem()->SetValue( m_inPlaceTextItem->GetValue() );
2630 OnText( ev );
2631 m_inOnTextInPlace = FALSE;
2632 }
2633 }
2634 }
2635
2636 void wxGenericGrid::OnTextInPlaceEnter(wxCommandEvent& WXUNUSED(ev) )
2637 {
2638 // move the cursor down the current row (if possible)
2639 // when the enter key has been pressed
2640 //
2641 if ( m_editable )
2642 {
2643 if ( GetCursorRow() < GetRows()-1 )
2644 {
2645 wxClientDC dc( this );
2646 dc.BeginDrawing();
2647 OnSelectCellImplementation(& dc,
2648 GetCursorRow()+1,
2649 GetCursorColumn() );
2650 dc.EndDrawing();
2651 }
2652 }
2653 }
2654
2655 void wxGenericGrid::OnGridScroll(wxScrollEvent& ev)
2656 {
2657 static bool inScroll = FALSE;
2658
2659 if ( inScroll )
2660 return;
2661
2662 if ( m_editInPlace ) m_inPlaceTextItem->Show(FALSE);
2663
2664 inScroll = TRUE;
2665 wxGenericGrid *win = this;
2666
2667 bool change = FALSE;
2668
2669 if (ev.GetEventObject() == win->GetHorizScrollBar())
2670 {
2671 change = (ev.GetPosition() != m_scrollPosX);
2672 win->SetScrollPosX(ev.GetPosition());
2673 }
2674 else
2675 {
2676 change = (ev.GetPosition() != m_scrollPosY);
2677 win->SetScrollPosY(ev.GetPosition());
2678 }
2679
2680 win->UpdateDimensions();
2681
2682 win->SetCurrentRect(win->GetCursorRow(), win->GetCursorColumn());
2683
2684 // Because rows and columns can be arbitrary sizes,
2685 // the scrollbars will need to be adjusted to reflect the
2686 // current view.
2687 AdjustScrollbars();
2688
2689 if (change) win->Refresh(FALSE);
2690
2691 if ( m_editInPlace && m_currentRectVisible )
2692 {
2693 m_inPlaceTextItem->SetSize( m_currentRect.x-2, m_currentRect.y-2,
2694 m_currentRect.width+4, m_currentRect.height+4 );
2695 m_inPlaceTextItem->Show( TRUE );
2696 m_inPlaceTextItem->SetFocus();
2697 }
2698
2699 inScroll = FALSE;
2700
2701 }
2702
2703
2704 //----------------------------------------------------------------------
2705 // Default wxGridEvent handlers
2706 // (just redirect to the pre-existing virtual methods)
2707
2708 void wxGenericGrid::_OnSelectCell(wxGridEvent& ev)
2709 {
2710 OnSelectCell(ev.m_row, ev.m_col);
2711 }
2712
2713 void wxGenericGrid::_OnCreateCell(wxGridEvent& ev)
2714 {
2715 ev.m_cell = OnCreateCell();
2716 }
2717
2718 void wxGenericGrid::_OnChangeLabels(wxGridEvent& WXUNUSED(ev))
2719 {
2720 OnChangeLabels();
2721 }
2722
2723 void wxGenericGrid::_OnChangeSelectionLabel(wxGridEvent& WXUNUSED(ev))
2724 {
2725 OnChangeSelectionLabel();
2726 }
2727
2728 void wxGenericGrid::_OnCellChange(wxGridEvent& ev)
2729 {
2730 OnCellChange(ev.m_row, ev.m_col);
2731 }
2732
2733 void wxGenericGrid::_OnCellLeftClick(wxGridEvent& ev)
2734 {
2735 OnCellLeftClick(ev.m_row, ev.m_col, ev.m_x, ev.m_y, ev.m_control, ev.m_shift);
2736 }
2737
2738 void wxGenericGrid::_OnCellRightClick(wxGridEvent& ev)
2739 {
2740 OnCellRightClick(ev.m_row, ev.m_col, ev.m_x, ev.m_y, ev.m_control, ev.m_shift);
2741 }
2742
2743 void wxGenericGrid::_OnLabelLeftClick(wxGridEvent& ev)
2744 {
2745 OnLabelLeftClick(ev.m_row, ev.m_col, ev.m_x, ev.m_y, ev.m_control, ev.m_shift);
2746 }
2747
2748 void wxGenericGrid::_OnLabelRightClick(wxGridEvent& ev)
2749 {
2750 OnLabelRightClick(ev.m_row, ev.m_col, ev.m_x, ev.m_y, ev.m_control, ev.m_shift);
2751 }
2752
2753 void *wxGenericGrid::SetCellData(void *data, int row, int col)
2754 {
2755 void *rc = NULL;
2756
2757 wxGridCell *cell = GetCell(row, col);
2758 if ( cell )
2759 rc = cell->SetCellData(data);
2760
2761 return rc;
2762 }
2763
2764 void *wxGenericGrid::GetCellData(int row, int col)
2765 {
2766 void *rc = NULL;
2767
2768 wxGridCell *cell = GetCell(row, col);
2769 if ( cell )
2770 rc = cell->GetCellData();
2771
2772 return rc;
2773 }
2774