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