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