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