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