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