1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxGenericGrid
4 // Author: Julian Smart
5 // Modified by: Michael Bedward
6 // Added edit in place facility, 20 Apr 1999
7 // Added cursor key control, 29 Jun 1999
9 // Added keyboard navigation, client data, other fixes
12 // Copyright: (c) Julian Smart and Markus Holzem
13 // Licence: wxWindows license
14 /////////////////////////////////////////////////////////////////////////////
17 #pragma implementation "gridg.h"
21 // For compilers that support precompilation, includes "wx/wx.h".
22 #include "wx/wxprec.h"
30 #include "wx/dcclient.h"
31 #include "wx/dcmemory.h"
32 #include "wx/textctrl.h"
33 #include "wx/settings.h"
38 #include "wx/string.h"
40 #include "wx/generic/gridg.h"
42 // Set to zero to use no double-buffering
44 #define wxUSE_DOUBLE_BUFFERING 1
46 #define wxUSE_DOUBLE_BUFFERING 0
49 #define wxGRID_DRAG_NONE 0
50 #define wxGRID_DRAG_LEFT_RIGHT 1
51 #define wxGRID_DRAG_UP_DOWN 2
53 IMPLEMENT_DYNAMIC_CLASS(wxGenericGrid
, wxPanel
)
54 IMPLEMENT_DYNAMIC_CLASS(wxGridEvent
, wxEvent
)
56 BEGIN_EVENT_TABLE(wxGenericGrid
, wxPanel
)
57 EVT_SIZE(wxGenericGrid::OnSize
)
58 EVT_PAINT(wxGenericGrid::OnPaint
)
59 EVT_ERASE_BACKGROUND(wxGenericGrid::OnEraseBackground
)
60 EVT_MOUSE_EVENTS(wxGenericGrid::OnMouseEvent
)
61 EVT_TEXT(wxGRID_TEXT_CTRL
, wxGenericGrid::OnText
)
62 EVT_TEXT(wxGRID_EDIT_IN_PLACE_TEXT_CTRL
, wxGenericGrid::OnTextInPlace
)
63 EVT_TEXT_ENTER(wxGRID_TEXT_CTRL
, wxGenericGrid::OnTextEnter
)
64 EVT_TEXT_ENTER(wxGRID_EDIT_IN_PLACE_TEXT_CTRL
, wxGenericGrid::OnTextInPlaceEnter
)
65 EVT_COMMAND_SCROLL(wxGRID_HSCROLL
, wxGenericGrid::OnGridScroll
)
66 EVT_COMMAND_SCROLL(wxGRID_VSCROLL
, wxGenericGrid::OnGridScroll
)
68 // default wxGridEvent handlers
69 EVT_GRID_SELECT_CELL(wxGenericGrid::_OnSelectCell
)
70 EVT_GRID_CREATE_CELL(wxGenericGrid::_OnCreateCell
)
71 EVT_GRID_CHANGE_LABELS(wxGenericGrid::_OnChangeLabels
)
72 EVT_GRID_CHANGE_SEL_LABEL(wxGenericGrid::_OnChangeSelectionLabel
)
73 EVT_GRID_CELL_CHANGE(wxGenericGrid::_OnCellChange
)
74 EVT_GRID_CELL_LCLICK(wxGenericGrid::_OnCellLeftClick
)
75 EVT_GRID_CELL_RCLICK(wxGenericGrid::_OnCellRightClick
)
76 EVT_GRID_LABEL_LCLICK(wxGenericGrid::_OnLabelLeftClick
)
77 EVT_GRID_LABEL_RCLICK(wxGenericGrid::_OnLabelRightClick
)
82 wxGenericGrid::wxGenericGrid()
87 m_hScrollBar
= (wxScrollBar
*) NULL
;
88 m_vScrollBar
= (wxScrollBar
*) NULL
;
89 m_cellTextColour
= *wxBLACK
;
90 m_cellBackgroundColour
= *wxWHITE
;
91 m_labelTextColour
= *wxBLACK
;
92 // m_labelBackgroundColour = *wxLIGHT_GREY;
93 m_labelBackgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
94 m_labelBackgroundBrush
= wxNullBrush
;
95 m_labelTextFont
= wxNullFont
;
96 m_cellTextFont
= wxNullFont
;
97 m_textItem
= (wxTextCtrl
*) NULL
;
98 m_currentRectVisible
= FALSE
;
101 m_editInPlace
= TRUE
;
102 m_inOnTextInPlace
= FALSE
;
104 #if defined(__WIN95__)
105 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
106 #elif defined(__WXGTK__)
107 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
111 m_dragStatus
= wxGRID_DRAG_NONE
;
113 m_dragStartPosition
= 0;
114 m_dragLastPosition
= 0;
115 m_divisionPen
= wxNullPen
;
116 m_leftOfSheet
= wxGRID_DEFAULT_SHEET_LEFT
;
117 m_topOfSheet
= wxGRID_DEFAULT_SHEET_TOP
;
118 m_cellHeight
= wxGRID_DEFAULT_CELL_HEIGHT
;
119 m_totalGridWidth
= 0;
120 m_totalGridHeight
= 0;
121 m_colWidths
= (short *) NULL
;
122 m_rowHeights
= (short *) NULL
;
123 m_verticalLabelWidth
= wxGRID_DEFAULT_VERTICAL_LABEL_WIDTH
;
124 m_horizontalLabelHeight
= wxGRID_DEFAULT_HORIZONAL_LABEL_HEIGHT
;
125 m_verticalLabelAlignment
= wxCENTRE
;
126 m_horizontalLabelAlignment
= wxCENTRE
;
127 m_editControlPosition
.x
= wxGRID_DEFAULT_EDIT_X
;
128 m_editControlPosition
.y
= wxGRID_DEFAULT_EDIT_Y
;
129 m_editControlPosition
.width
= wxGRID_DEFAULT_EDIT_WIDTH
;
130 m_editControlPosition
.height
= wxGRID_DEFAULT_EDIT_HEIGHT
;
135 m_editCreated
= FALSE
;
138 m_gridCells
= (wxGridCell
***) NULL
;
139 m_rowLabelCells
= (wxGridCell
**) NULL
;
140 m_colLabelCells
= (wxGridCell
**) NULL
;
141 m_textItem
= (wxTextCtrl
*) NULL
;
144 bool wxGenericGrid::Create(wxWindow
*parent
,
149 const wxString
& name
)
154 m_editingPanel
= (wxPanel
*) NULL
;
155 m_hScrollBar
= (wxScrollBar
*) NULL
;
156 m_vScrollBar
= (wxScrollBar
*) NULL
;
157 m_cellTextColour
= *wxBLACK
;
158 m_cellBackgroundColour
= *wxWHITE
;
159 m_labelTextColour
= *wxBLACK
;
160 // m_labelBackgroundColour = *wxLIGHT_GREY;
161 m_labelBackgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
162 m_labelBackgroundBrush
= wxNullBrush
;
163 m_labelTextFont
= * wxTheFontList
->FindOrCreateFont(10, wxSWISS
, wxNORMAL
, wxBOLD
);
164 m_cellTextFont
= * wxTheFontList
->FindOrCreateFont(10, wxSWISS
, wxNORMAL
, wxNORMAL
);
165 m_textItem
= (wxTextCtrl
*) NULL
;
166 m_currentRectVisible
= FALSE
;
168 #if defined(__WIN95__)
169 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
170 #elif defined(__WXGTK__)
171 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
175 m_dragStatus
= wxGRID_DRAG_NONE
;
177 m_dragStartPosition
= 0;
178 m_dragLastPosition
= 0;
179 m_divisionPen
= * wxThePenList
->FindOrCreatePen("LIGHT GREY", 1, wxSOLID
);
180 m_doubleBufferingBitmap
= (wxBitmap
*) NULL
;
182 if (!m_horizontalSashCursor
.Ok())
184 m_horizontalSashCursor
= wxCursor(wxCURSOR_SIZEWE
);
185 m_verticalSashCursor
= wxCursor(wxCURSOR_SIZENS
);
188 SetLabelBackgroundColour(m_labelBackgroundColour
);
190 m_leftOfSheet
= wxGRID_DEFAULT_SHEET_LEFT
;
191 m_topOfSheet
= wxGRID_DEFAULT_SHEET_TOP
;
192 m_cellHeight
= wxGRID_DEFAULT_CELL_HEIGHT
;
193 m_totalGridWidth
= 0;
194 m_totalGridHeight
= 0;
195 m_colWidths
= (short *) NULL
;
196 m_rowHeights
= (short *) NULL
;
198 m_verticalLabelWidth
= wxGRID_DEFAULT_VERTICAL_LABEL_WIDTH
;
199 m_horizontalLabelHeight
= wxGRID_DEFAULT_HORIZONAL_LABEL_HEIGHT
;
200 m_verticalLabelAlignment
= wxCENTRE
;
201 m_horizontalLabelAlignment
= wxCENTRE
;
202 m_editControlPosition
.x
= wxGRID_DEFAULT_EDIT_X
;
203 m_editControlPosition
.y
= wxGRID_DEFAULT_EDIT_Y
;
204 m_editControlPosition
.width
= wxGRID_DEFAULT_EDIT_WIDTH
;
205 m_editControlPosition
.height
= wxGRID_DEFAULT_EDIT_HEIGHT
;
213 /* Store the rect. coordinates for the current cell */
214 SetCurrentRect(m_wCursorRow
, m_wCursorColumn
);
216 m_editCreated
= FALSE
;
220 m_gridCells
= (wxGridCell
***) NULL
;
221 m_rowLabelCells
= (wxGridCell
**) NULL
;
222 m_colLabelCells
= (wxGridCell
**) NULL
;
223 m_textItem
= (wxTextCtrl
*) NULL
;
225 wxPanel::Create(parent
, id
, pos
, size
, style
, name
);
227 m_editingPanel
= new wxPanel(this);
229 m_textItem
= new wxTextCtrl(m_editingPanel
, wxGRID_TEXT_CTRL
, "",
230 wxPoint(m_editControlPosition
.x
, m_editControlPosition
.y
),
231 wxSize(m_editControlPosition
.width
, -1),
233 m_textItem
->Show(TRUE
);
234 m_textItem
->SetFocus();
235 int controlW
, controlH
;
237 m_textItem
->GetSize(&controlW
, &controlH
);
238 m_editControlPosition
.height
= controlH
;
240 m_topOfSheet
= m_editControlPosition
.y
+ controlH
+ 2;
242 m_editCreated
= TRUE
;
244 m_hScrollBar
= new wxScrollBar(this, wxGRID_HSCROLL
, wxPoint(0, 0), wxSize(20, 100), wxHORIZONTAL
);
245 m_vScrollBar
= new wxScrollBar(this, wxGRID_VSCROLL
, wxPoint(0, 0), wxSize(100, 20), wxVERTICAL
);
247 // SetSize(pos.x, pos.y, size.x, size.y);
249 m_inPlaceTextItem
= new wxTextCtrl( (wxPanel
*)this, wxGRID_EDIT_IN_PLACE_TEXT_CTRL
, "",
250 wxPoint( m_currentRect
.x
-2, m_currentRect
.y
-2 ),
251 wxSize( m_currentRect
.width
+4, m_currentRect
.height
+4 ),
252 wxNO_BORDER
| wxTE_PROCESS_ENTER
);
253 m_inPlaceTextItem
->Show(TRUE
);
254 m_inPlaceTextItem
->SetFocus();
259 wxGenericGrid::~wxGenericGrid()
264 void wxGenericGrid::ClearGrid()
269 for (i
= 0; i
< m_totalRows
; i
++)
271 for (j
= 0; j
< m_totalCols
; j
++)
272 if (m_gridCells
[i
][j
])
273 delete m_gridCells
[i
][j
];
274 delete[] m_gridCells
[i
];
276 delete[] m_gridCells
;
277 m_gridCells
= (wxGridCell
***) NULL
;
280 delete[] m_colWidths
;
281 m_colWidths
= (short *) NULL
;
283 delete[] m_rowHeights
;
284 m_rowHeights
= (short *) NULL
;
288 for (i
= 0; i
< m_totalRows
; i
++)
289 delete m_rowLabelCells
[i
];
290 delete[] m_rowLabelCells
;
291 m_rowLabelCells
= (wxGridCell
**) NULL
;
295 for (i
= 0; i
< m_totalCols
; i
++)
296 delete m_colLabelCells
[i
];
297 delete[] m_colLabelCells
;
298 m_colLabelCells
= (wxGridCell
**) NULL
;
300 if (m_doubleBufferingBitmap
)
302 delete m_doubleBufferingBitmap
;
303 m_doubleBufferingBitmap
= (wxBitmap
*) NULL
;
307 bool wxGenericGrid::CreateGrid(int nRows
, int nCols
, wxString
**cellValues
, short *widths
,
308 short defaultWidth
, short defaultHeight
)
314 m_colWidths
= new short[nCols
];
315 m_rowHeights
= new short[nRows
];
316 for (i
= 0; i
< nCols
; i
++)
318 m_colWidths
[i
] = widths
[i
];
320 m_colWidths
[i
] = defaultWidth
;
321 for (i
= 0; i
< nRows
; i
++)
322 m_rowHeights
[i
] = defaultHeight
;
324 m_gridCells
= new wxGridCell
**[nRows
];
326 for (i
= 0; i
< nRows
; i
++)
327 m_gridCells
[i
] = new wxGridCell
*[nCols
];
329 for (i
= 0; i
< nRows
; i
++)
330 for (j
= 0; j
< nCols
; j
++)
333 //m_gridCells[i][j] = OnCreateCell();
334 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CREATE_CELL
, this, i
, j
);
335 GetEventHandler()->ProcessEvent(g_evt
);
336 m_gridCells
[i
][j
] = g_evt
.m_cell
;
337 m_gridCells
[i
][j
]->SetTextValue(cellValues
[i
][j
]);
340 m_gridCells
[i
][j
] = (wxGridCell
*) NULL
;
342 m_rowLabelCells
= new wxGridCell
*[nRows
];
343 for (i
= 0; i
< nRows
; i
++)
344 m_rowLabelCells
[i
] = new wxGridCell(this);
345 m_colLabelCells
= new wxGridCell
*[nCols
];
346 for (i
= 0; i
< nCols
; i
++)
347 m_colLabelCells
[i
] = new wxGridCell(this);
349 m_wCursorRow
= m_wCursorColumn
= 0;
350 SetCurrentRect(0, 0);
352 // Need to determine various dimensions
356 int objectSizeX
= m_totalCols
;
358 int viewLengthX
= m_totalCols
;
361 m_hScrollBar->SetViewLength(viewLengthX);
362 m_hScrollBar->SetObjectLength(objectSizeX);
363 m_hScrollBar->SetPageSize(pageSizeX);
365 m_hScrollBar
->SetScrollbar(m_hScrollBar
->GetThumbPosition(), pageSizeX
, objectSizeX
, viewLengthX
);
367 int objectSizeY
= m_totalRows
;
369 int viewLengthY
= m_totalRows
;
372 m_vScrollBar->SetViewLength(viewLengthY);
373 m_vScrollBar->SetObjectLength(objectSizeY);
374 m_vScrollBar->SetPageSize(pageSizeY);
377 m_vScrollBar
->SetScrollbar(m_vScrollBar
->GetThumbPosition(), pageSizeY
, objectSizeY
, viewLengthY
);
382 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
383 GetEventHandler()->ProcessEvent(g_evt
);
385 //OnChangeSelectionLabel();
386 wxGridEvent
g_evt2(GetId(), wxEVT_GRID_CHANGE_SEL_LABEL
, this);
387 GetEventHandler()->ProcessEvent(g_evt2
);
392 // Need to determine various dimensions
393 void wxGenericGrid::UpdateDimensions()
395 int canvasWidth
, canvasHeight
;
396 GetSize(&canvasWidth
, &canvasHeight
);
398 if (m_editCreated
&& m_editable
)
400 int controlW
, controlH
;
401 GetTextItem()->GetSize(&controlW
, &controlH
);
402 m_topOfSheet
= m_editControlPosition
.y
+ controlH
+ 2;
406 m_rightOfSheet
= m_leftOfSheet
+ m_verticalLabelWidth
;
408 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
410 if (m_rightOfSheet
> canvasWidth
)
413 m_rightOfSheet
+= m_colWidths
[i
];
415 m_bottomOfSheet
= m_topOfSheet
+ m_horizontalLabelHeight
;
416 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
418 if (m_bottomOfSheet
> canvasHeight
)
421 m_bottomOfSheet
+= m_rowHeights
[i
];
424 m_totalGridWidth
= m_leftOfSheet
+ m_verticalLabelWidth
;
425 for (i
= 0; i
< m_totalCols
; i
++)
427 m_totalGridWidth
+= m_colWidths
[i
];
429 m_totalGridHeight
= m_topOfSheet
+ m_horizontalLabelHeight
;
430 for (i
= 0; i
< m_totalRows
; i
++)
432 m_totalGridHeight
+= m_rowHeights
[i
];
436 wxGridCell
*wxGenericGrid::GetCell(int row
, int col
) const
439 return (wxGridCell
*) NULL
;
441 if ((row
>= m_totalRows
) || (col
>= m_totalCols
))
442 return (wxGridCell
*) NULL
;
444 wxGridCell
*cell
= m_gridCells
[row
][col
];
447 // m_gridCells[row][col] = OnCreateCell();
448 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CREATE_CELL
, (wxGenericGrid
*) this, row
, col
);
449 GetEventHandler()->ProcessEvent(g_evt
);
450 m_gridCells
[row
][col
] = g_evt
.m_cell
;
451 return m_gridCells
[row
][col
];
457 void wxGenericGrid::SetGridClippingRegion(wxDC
*dc
)
459 int m_scrollWidthHoriz
= 0;
460 int m_scrollWidthVert
= 0;
462 GetClientSize(&cw
, &ch
);
464 if (m_hScrollBar
&& m_hScrollBar
->IsShown())
465 m_scrollWidthHoriz
= m_scrollWidth
;
466 if (m_vScrollBar
&& m_vScrollBar
->IsShown())
467 m_scrollWidthVert
= m_scrollWidth
;
469 // Don't paint over the scrollbars
470 dc
->SetClippingRegion(m_leftOfSheet
, m_topOfSheet
,
471 cw
- m_scrollWidthVert
- m_leftOfSheet
, ch
- m_scrollWidthHoriz
- m_topOfSheet
);
474 void wxGenericGrid::OnPaint(wxPaintEvent
& WXUNUSED(event
))
477 GetClientSize(&w
, &h
);
479 bool useDoubleBuffering
= (bool) wxUSE_DOUBLE_BUFFERING
;
480 if (useDoubleBuffering
)
482 // Reuse the old bitmap if possible
484 if (!m_doubleBufferingBitmap
||
485 (m_doubleBufferingBitmap
->GetWidth() < w
|| m_doubleBufferingBitmap
->GetHeight() < h
))
487 if (m_doubleBufferingBitmap
)
488 delete m_doubleBufferingBitmap
;
489 m_doubleBufferingBitmap
= new wxBitmap(w
, h
);
491 if (!m_doubleBufferingBitmap
|| !m_doubleBufferingBitmap
->Ok())
493 // If we couldn't create a new bitmap, perhaps because resources were low,
494 // then don't complain, just don't double-buffer
495 if (m_doubleBufferingBitmap
)
496 delete m_doubleBufferingBitmap
;
497 m_doubleBufferingBitmap
= (wxBitmap
*) NULL
;
498 useDoubleBuffering
= FALSE
;
502 if (useDoubleBuffering
)
504 wxPaintDC
paintDC(this);
505 wxMemoryDC
dc(& paintDC
);
506 dc
.SelectObject(* m_doubleBufferingBitmap
);
510 int vertScrollBarWidth
= m_scrollWidth
;
511 int horizScrollBarHeight
= m_scrollWidth
;
512 if (m_vScrollBar
&& !m_vScrollBar
->IsShown())
513 vertScrollBarWidth
= 0;
514 if (m_hScrollBar
&& !m_hScrollBar
->IsShown())
515 horizScrollBarHeight
= 0;
517 paintDC
.Blit(m_leftOfSheet
, m_topOfSheet
, w
- vertScrollBarWidth
- m_leftOfSheet
, h
- horizScrollBarHeight
- m_topOfSheet
,
518 &dc
, m_leftOfSheet
, m_topOfSheet
, wxCOPY
);
520 dc
.SelectObject(wxNullBitmap
);
529 void wxGenericGrid::PaintGrid(wxDC
& dc
)
532 dc
.SetOptimization(FALSE
);
534 SetGridClippingRegion(& dc
);
536 DrawLabelAreas(& dc
);
538 DrawEditableArea(& dc
);
539 DrawColumnLabels(& dc
);
544 /* Hilight present cell */
545 SetCurrentRect(m_wCursorRow
, m_wCursorColumn
);
546 if (m_currentRectVisible
&& !(m_editable
&& m_editInPlace
))
549 dc
.DestroyClippingRegion();
550 dc
.SetOptimization(TRUE
);
554 // Erase (some of) the background.
555 // Currently, a Windows-only optimisation.
556 void wxGenericGrid::OnEraseBackground(wxEraseEvent
& WXUNUSED(event
) )
560 dc
.SetOptimization(FALSE
);
563 GetClientSize(& w
, & h
);
564 dc
.SetBrush(*wxLIGHT_GREY_BRUSH
);
565 dc
.SetPen(*wxLIGHT_GREY_PEN
);
567 if (m_hScrollBar
&& m_hScrollBar
->IsShown() && m_vScrollBar
&& m_vScrollBar
->IsShown())
569 dc
.DrawRectangle(w
- m_scrollWidth
, h
- m_scrollWidth
, m_scrollWidth
, m_scrollWidth
);
572 dc
.SetOptimization(TRUE
);
577 void wxGenericGrid::DrawLabelAreas(wxDC
*dc
)
580 GetClientSize(&cw
, &ch
);
582 dc
->SetPen(*wxTRANSPARENT_PEN
);
583 // dc->SetBrush(*dc->GetBackground());
585 // Should blank out any area which isn't going to be painted over.
586 // dc->DrawRectangle(m_leftOfSheet, m_bottomOfSheet, cw - m_leftOfSheet, ch - m_bottomOfSheet);
587 // dc->DrawRectangle(m_rightOfSheet, m_topOfSheet, cw - m_rightOfSheet, ch - m_topOfSheet);
589 // Paint the label areas
590 dc
->SetBrush(m_labelBackgroundBrush
);
591 // dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, m_rightOfSheet - m_leftOfSheet + 1, m_horizontalLabelHeight + 1);
592 dc
->DrawRectangle(m_leftOfSheet
, m_topOfSheet
, cw
-m_leftOfSheet
, m_horizontalLabelHeight
+ 1);
593 // dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, m_verticalLabelWidth + 1, m_bottomOfSheet - m_topOfSheet + 1);
594 dc
->DrawRectangle(m_leftOfSheet
, m_topOfSheet
, m_verticalLabelWidth
+ 1, ch
-m_topOfSheet
);
597 void wxGenericGrid::DrawEditableArea(wxDC
*dc
)
600 GetClientSize(&cw
, &ch
);
602 dc
->SetPen(*wxTRANSPARENT_PEN
);
603 dc
->SetBrush(*wxTheBrushList
->FindOrCreateBrush(m_cellBackgroundColour
, wxSOLID
));
604 // dc->DrawRectangle(m_leftOfSheet+m_verticalLabelWidth, m_topOfSheet+m_horizontalLabelHeight,
605 // m_rightOfSheet-(m_leftOfSheet+m_verticalLabelWidth) + 1, m_bottomOfSheet - (m_topOfSheet+m_horizontalLabelHeight) + 1);
606 dc
->DrawRectangle(m_leftOfSheet
+m_verticalLabelWidth
, m_topOfSheet
+m_horizontalLabelHeight
,
607 cw
-(m_leftOfSheet
+m_verticalLabelWidth
), ch
- (m_topOfSheet
+m_horizontalLabelHeight
));
610 void wxGenericGrid::DrawGridLines(wxDC
*dc
)
613 GetClientSize(&cw
, &ch
);
617 if (m_divisionPen
.Ok())
619 dc
->SetPen(m_divisionPen
);
621 int heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
623 // Draw horizontal grey lines for cells
624 for (i
= m_scrollPosY
; i
< (m_totalRows
+1); i
++)
626 if (heightCount
> ch
)
630 dc
->DrawLine(m_leftOfSheet
, heightCount
,
633 heightCount
+= m_rowHeights
[i
];
638 if (m_verticalLabelWidth
> 0)
640 dc
->SetPen(*wxBLACK_PEN
);
642 // Draw horizontal black lines for row labels
643 int heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
644 for (i
= m_scrollPosY
; i
< (m_totalRows
+1); i
++)
646 if (heightCount
> ch
)
650 dc
->DrawLine(m_leftOfSheet
, heightCount
,
651 m_verticalLabelWidth
, heightCount
);
653 heightCount
+= m_rowHeights
[i
];
656 // Draw a black vertical line for row number cells
657 dc
->DrawLine(m_leftOfSheet
+ m_verticalLabelWidth
, m_topOfSheet
,
658 m_leftOfSheet
+ m_verticalLabelWidth
, ch
);
659 // First vertical line
660 dc
->DrawLine(m_leftOfSheet
, m_topOfSheet
, m_leftOfSheet
, ch
);
662 dc
->SetPen(*wxWHITE_PEN
);
664 // Draw highlights on row labels
665 heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
666 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
668 if (heightCount
> ch
)
672 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
673 m_verticalLabelWidth
, heightCount
+1);
674 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
675 m_leftOfSheet
+1, heightCount
+ m_rowHeights
[i
] - 1);
676 heightCount
+= m_rowHeights
[i
];
679 // Last one - down to the floor.
680 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
681 m_verticalLabelWidth
, heightCount
+1);
682 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
683 m_leftOfSheet
+1, ch
);
687 if (m_divisionPen
.Ok())
689 dc
->SetPen(m_divisionPen
);
691 // Draw vertical grey lines for cells
692 int widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
693 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
699 // Skip the first one
700 if (i
!= m_scrollPosX
)
702 dc
->DrawLine(widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
,
703 widthCount
, m_bottomOfSheet
);
705 widthCount
+= m_colWidths
[i
];
709 dc
->DrawLine(widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
,
710 widthCount
, m_bottomOfSheet
);
713 dc
->SetPen(*wxBLACK_PEN
);
715 // Draw two black horizontal lines for column number cells
717 m_leftOfSheet
, m_topOfSheet
,
719 dc
->DrawLine(m_leftOfSheet
, m_topOfSheet
+ m_horizontalLabelHeight
,
720 cw
, m_topOfSheet
+ m_horizontalLabelHeight
);
722 if (m_horizontalLabelHeight
> 0)
724 int widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
726 // Draw black vertical lines for column number cells
727 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
733 dc
->DrawLine(widthCount
, m_topOfSheet
,
734 widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
);
735 widthCount
+= m_colWidths
[i
];
740 dc
->DrawLine(widthCount
, m_topOfSheet
,
741 widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
);
744 dc
->SetPen(*wxWHITE_PEN
);
745 widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
747 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
753 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
754 widthCount
+m_colWidths
[i
], m_topOfSheet
+1);
755 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
756 widthCount
+1, m_topOfSheet
+m_horizontalLabelHeight
);
757 widthCount
+= m_colWidths
[i
];
760 // Last one - to the right side of the canvas.
761 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
763 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
764 widthCount
+1, m_topOfSheet
+m_horizontalLabelHeight
);
769 void wxGenericGrid::DrawColumnLabels(wxDC
*dc
)
772 GetClientSize(&cw
, &ch
);
774 if (m_horizontalLabelHeight
== 0)
780 // Draw letters for columns
781 rect
.y
= m_topOfSheet
+ 1;
782 rect
.height
= m_horizontalLabelHeight
- 1;
784 dc
->SetTextBackground(m_labelBackgroundColour
);
785 dc
->SetBackgroundMode(wxTRANSPARENT
);
786 // dc->SetTextForeground(m_labelTextColour);
788 int widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
789 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
795 rect
.x
= 1 + widthCount
;
796 rect
.width
= m_colWidths
[i
];
797 DrawColumnLabel(dc
, &rect
, i
);
799 widthCount
+= m_colWidths
[i
];
804 void wxGenericGrid::DrawColumnLabel(wxDC
*dc
, wxRect
*rect
, int col
)
806 wxGridCell
*cell
= GetLabelCell(wxHORIZONTAL
, col
);
815 dc
->SetTextForeground(GetLabelTextColour());
816 dc
->SetFont(GetLabelTextFont());
817 if ( !cell
->GetTextValue().IsNull() )
818 DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, GetLabelAlignment(wxHORIZONTAL
));
822 void wxGenericGrid::DrawRowLabels(wxDC
*dc
)
825 GetClientSize(&cw
, &ch
);
827 if (m_verticalLabelWidth
== 0)
833 // Draw numbers for rows
834 rect
.x
= m_leftOfSheet
;
835 rect
.width
= m_verticalLabelWidth
;
837 int heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
839 dc
->SetTextBackground(m_labelBackgroundColour
);
840 dc
->SetBackgroundMode(wxTRANSPARENT
);
842 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
844 if (heightCount
> ch
)
848 rect
.y
= 1 + heightCount
;
849 rect
.height
= m_rowHeights
[i
];
850 DrawRowLabel(dc
, &rect
, i
);
852 heightCount
+= m_rowHeights
[i
];
857 void wxGenericGrid::DrawRowLabel(wxDC
*dc
, wxRect
*rect
, int row
)
859 wxGridCell
*cell
= GetLabelCell(wxVERTICAL
, row
);
868 dc
->SetTextForeground(GetLabelTextColour());
869 dc
->SetFont(GetLabelTextFont());
870 if ( !cell
->GetTextValue().IsNull() )
871 DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, GetLabelAlignment(wxVERTICAL
));
875 void wxGenericGrid::DrawCells(wxDC
*dc
)
878 GetClientSize(&cw
, &ch
);
882 // Draw value corresponding to each cell
883 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
885 for (j
= m_scrollPosX
; j
< m_totalCols
; j
++)
887 SetCurrentRect(i
, j
, cw
, ch
);
888 if (m_currentRectVisible
)
890 DrawCellBackground(dc
, &m_currentRect
, i
, j
);
891 DrawCellValue(dc
, &m_currentRect
, i
, j
);
893 if (m_currentRect
.x
> cw
)
896 if (m_currentRect
.y
> ch
)
899 dc
->SetBackgroundMode(wxSOLID
);
900 dc
->SetPen(*wxBLACK_PEN
);
903 void wxGenericGrid::DrawCellBackground(wxDC
*dc
, wxRect
*rect
, int row
, int col
)
905 wxGridCell
*cell
= GetCell(row
, col
);
908 dc
->SetBrush(cell
->GetBackgroundBrush());
909 dc
->SetPen(*wxTRANSPARENT_PEN
);
911 #if 0 // In wxWin 2.0 the dc code is exact. RR.
913 dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
-1, rect
->height
-1);
915 dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
, rect
->height
);
919 dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
-1, rect
->height
-1);
921 dc
->SetPen(*wxBLACK_PEN
);
925 void wxGenericGrid::DrawCellValue(wxDC
*dc
, wxRect
*rect
, int row
, int col
)
927 wxGridCell
*cell
= GetCell(row
, col
);
930 wxBitmap
*bitmap
= cell
->GetCellBitmap();
940 DrawBitmapRect(dc
, bitmap
, &rect2
, cell
->GetAlignment());
944 dc
->SetBackgroundMode(wxTRANSPARENT
);
945 dc
->SetTextForeground(cell
->GetTextColour());
946 dc
->SetFont(cell
->GetFont());
948 if ( !cell
->GetTextValue().IsNull() )
949 DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, cell
->GetAlignment());
954 void wxGenericGrid::AdjustScrollbars()
957 GetClientSize(&cw
, &ch
);
959 // We find the view size by seeing how many rows/cols fit on
961 // BUT... this means that the scrollbar should be adjusted every time
962 // it's scrolled, as well as when sized, because with variable size rows/cols,
963 // the number of rows/col visible on the view differs according to what bit
964 // you're looking at. The object length is always the same, but the
965 // view length differs.
967 // Since this may not be known until the end of this function, we should probably call AdjustScrollbars
969 int vertScrollBarWidth
= m_scrollWidth
;
970 int horizScrollBarHeight
= m_scrollWidth
;
971 if (m_vScrollBar
&& !m_vScrollBar
->IsShown())
972 vertScrollBarWidth
= 0;
973 if (m_hScrollBar
&& !m_hScrollBar
->IsShown())
974 horizScrollBarHeight
= 0;
976 int noHorizSteps
= 0;
979 if (m_totalGridWidth
+ vertScrollBarWidth
> cw
)
985 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
987 widthCount
+= m_colWidths
[i
];
988 // A partial bit doesn't count, we still have to scroll to see the
990 if (widthCount
+ m_leftOfSheet
+ m_verticalLabelWidth
> (cw
-vertScrollBarWidth
))
998 m_viewWidth
= noHorizSteps
;
1000 if (m_totalGridHeight
+ horizScrollBarHeight
> ch
)
1002 int heightCount
= 0;
1006 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1008 heightCount
+= m_rowHeights
[i
];
1009 // A partial bit doesn't count, we still have to scroll to see the
1011 if (heightCount
+ m_topOfSheet
+ m_horizontalLabelHeight
> (ch
-horizScrollBarHeight
))
1020 m_viewHeight
= noVertSteps
;
1022 if (m_totalGridWidth
+ vertScrollBarWidth
<= cw
)
1025 m_hScrollBar
->Show(FALSE
);
1031 m_hScrollBar
->Show(TRUE
);
1034 if (m_totalGridHeight
+ horizScrollBarHeight
<= ch
)
1037 m_vScrollBar
->Show(FALSE
);
1043 m_vScrollBar
->Show(TRUE
);
1046 UpdateDimensions(); // Necessary in case m_scrollPosX/Y changed
1048 vertScrollBarWidth
= m_scrollWidth
;
1049 horizScrollBarHeight
= m_scrollWidth
;
1050 if (m_vScrollBar
&& !m_vScrollBar
->IsShown())
1051 vertScrollBarWidth
= 0;
1052 if (m_hScrollBar
&& !m_hScrollBar
->IsShown())
1053 horizScrollBarHeight
= 0;
1055 if (m_hScrollBar
&& m_hScrollBar
->IsShown())
1057 int nCols
= GetCols();
1058 m_hScrollBar
->SetScrollbar(m_hScrollBar
->GetThumbPosition(), wxMax(noHorizSteps
, 1), (noHorizSteps
== 0) ? 1 : nCols
, wxMax(noHorizSteps
, 1));
1061 m_hScrollBar->SetSize(m_leftOfSheet, ch - m_scrollWidth -2, // why -2 ? Robert.
1062 cw - vertScrollBarWidth - m_leftOfSheet, m_scrollWidth);
1064 m_hScrollBar
->SetSize(m_leftOfSheet
, ch
- m_scrollWidth
,
1065 cw
- vertScrollBarWidth
- m_leftOfSheet
, m_scrollWidth
);
1069 if (m_vScrollBar
&& m_vScrollBar
->IsShown())
1071 int nRows
= GetRows();
1073 m_vScrollBar
->SetScrollbar(m_vScrollBar
->GetThumbPosition(), wxMax(noVertSteps
, 1), (noVertSteps
== 0) ? 1 : nRows
, wxMax(noVertSteps
, 1));
1074 m_vScrollBar
->SetSize(cw
- m_scrollWidth
, m_topOfSheet
,
1075 m_scrollWidth
, ch
- m_topOfSheet
- horizScrollBarHeight
);
1079 void wxGenericGrid::OnSize(wxSizeEvent
& WXUNUSED(event
) )
1081 if (!m_vScrollBar
|| !m_hScrollBar
)
1087 GetClientSize(&cw
, &ch
);
1089 if (m_editCreated
&& m_editingPanel
&& GetTextItem() && GetTextItem()->IsShown())
1091 m_editingPanel
->SetSize(0, 0, cw
, m_editControlPosition
.height
+ m_editControlPosition
.y
+ 2);
1092 GetTextItem()->SetSize(m_editControlPosition
.x
, m_editControlPosition
.y
,
1093 cw
- 2*m_editControlPosition
.x
, m_editControlPosition
.height
);
1097 bool wxGenericGrid::CellHitTest(int x
, int y
, int *row
, int *col
)
1099 // Find the selected cell and call OnSelectCell
1100 if (x
>= (m_leftOfSheet
+ m_verticalLabelWidth
) && y
>= (m_topOfSheet
+ m_horizontalLabelHeight
) &&
1101 x
<= m_rightOfSheet
&& y
<= m_bottomOfSheet
)
1103 // Calculate the cell number from x and y
1104 x
-= (m_verticalLabelWidth
+ m_leftOfSheet
);
1105 y
-= (m_topOfSheet
+ m_horizontalLabelHeight
);
1109 // Now we need to do a hit test for which row we're on
1110 int currentHeight
= 0;
1111 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1113 if (y
>= currentHeight
&& y
<= (currentHeight
+ m_rowHeights
[i
]))
1118 currentHeight
+= m_rowHeights
[i
];
1121 // Now we need to do a hit test for which column we're on
1122 int currentWidth
= 0;
1123 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1125 if (x
>= currentWidth
&& x
<= (currentWidth
+ m_colWidths
[i
]))
1130 currentWidth
+= m_colWidths
[i
];
1137 bool wxGenericGrid::LabelSashHitTest(int x
, int y
, int *orientation
, int *rowOrCol
, int *startPos
)
1142 if (x
>= (m_leftOfSheet
+ m_verticalLabelWidth
) && y
>= m_topOfSheet
&&
1143 x
<= m_rightOfSheet
&& y
<= (m_topOfSheet
+ m_horizontalLabelHeight
))
1145 // We may be on a column label sash.
1146 int currentWidth
= m_leftOfSheet
+ m_verticalLabelWidth
;
1147 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1149 if (x
>= (currentWidth
+ m_colWidths
[i
] - tolerance
) && x
<= (currentWidth
+ m_colWidths
[i
] + tolerance
))
1151 *orientation
= wxHORIZONTAL
;
1153 *startPos
= currentWidth
;
1156 currentWidth
+= m_colWidths
[i
];
1160 else if (x
>= m_leftOfSheet
&& y
>= (m_topOfSheet
+ m_horizontalLabelHeight
) &&
1161 x
<= (m_leftOfSheet
+ m_verticalLabelWidth
) && y
<= m_bottomOfSheet
)
1163 // We may be on a row label sash.
1164 int currentHeight
= m_topOfSheet
+ m_horizontalLabelHeight
;
1165 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1167 if (y
>= (currentHeight
+ m_rowHeights
[i
] - tolerance
) && y
<= (currentHeight
+ m_rowHeights
[i
] + tolerance
))
1169 *orientation
= wxVERTICAL
;
1171 *startPos
= currentHeight
;
1174 currentHeight
+= m_rowHeights
[i
];
1181 bool wxGenericGrid::LabelHitTest(int x
, int y
, int *row
, int *col
)
1183 // Find the selected label
1184 if (x
>= m_leftOfSheet
&& y
>= m_topOfSheet
&&
1185 x
<= m_rightOfSheet
&& y
<= m_bottomOfSheet
)
1187 // Calculate the cell number from x and y
1193 // Now we need to do a hit test for which row we're on
1194 int currentHeight
= m_horizontalLabelHeight
;
1195 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1197 if (y
>= currentHeight
&& y
<= (currentHeight
+ m_rowHeights
[i
]))
1202 currentHeight
+= m_rowHeights
[i
];
1204 if (y
>= 0 && y
<= m_horizontalLabelHeight
)
1209 // Now we need to do a hit test for which column we're on
1210 int currentWidth
= m_verticalLabelWidth
;
1211 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1213 if (x
>= currentWidth
&& x
<= (currentWidth
+ m_colWidths
[i
]))
1218 currentWidth
+= m_colWidths
[i
];
1220 if (x
>= 0 && x
<= m_verticalLabelWidth
)
1225 if ((*col
== -1) || (*row
== -1))
1233 void wxGenericGrid::OnMouseEvent(wxMouseEvent
& ev
)
1237 wxClientDC
dc(this);
1241 if (CellHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1243 OnSelectCellImplementation(& dc
, row
, col
);
1245 //OnCellLeftClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1246 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CELL_LCLICK
, this,
1247 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1248 ev
.ControlDown(), ev
.ShiftDown());
1249 GetEventHandler()->ProcessEvent(g_evt
);
1252 if (LabelHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1254 //OnLabelLeftClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1255 wxGridEvent
g_evt(GetId(), wxEVT_GRID_LABEL_LCLICK
, this,
1256 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1257 ev
.ControlDown(), ev
.ShiftDown());
1258 GetEventHandler()->ProcessEvent(g_evt
);
1263 else if (ev
.Dragging() && ev
.LeftIsDown())
1265 switch (m_dragStatus
)
1267 case wxGRID_DRAG_NONE
:
1270 if (LabelSashHitTest((int)ev
.GetX(), (int)ev
.GetY(), &orientation
, &m_dragRowOrCol
, &m_dragStartPosition
))
1272 if (orientation
== wxHORIZONTAL
)
1274 m_dragStatus
= wxGRID_DRAG_LEFT_RIGHT
;
1275 SetCursor(m_horizontalSashCursor
);
1276 m_dragLastPosition
= (int)ev
.GetX();
1280 m_dragStatus
= wxGRID_DRAG_UP_DOWN
;
1281 SetCursor(m_verticalSashCursor
);
1282 m_dragLastPosition
= (int)ev
.GetY();
1284 wxClientDC
dc(this);
1286 dc
.SetLogicalFunction(wxINVERT
);
1287 if (orientation
== wxHORIZONTAL
)
1288 dc
.DrawLine((int)ev
.GetX(), m_topOfSheet
, (int)ev
.GetX(), m_bottomOfSheet
);
1290 dc
.DrawLine(m_leftOfSheet
, (int)ev
.GetY(), m_rightOfSheet
, (int)ev
.GetY());
1297 case wxGRID_DRAG_LEFT_RIGHT
:
1299 wxClientDC
dc(this);
1301 dc
.SetLogicalFunction(wxINVERT
);
1302 dc
.DrawLine(m_dragLastPosition
, m_topOfSheet
, m_dragLastPosition
, m_bottomOfSheet
);
1304 dc
.DrawLine((int)ev
.GetX(), m_topOfSheet
, (int)ev
.GetX(), m_bottomOfSheet
);
1307 m_dragLastPosition
= (int)ev
.GetX();
1308 SetCursor(m_horizontalSashCursor
);
1311 case wxGRID_DRAG_UP_DOWN
:
1313 wxClientDC
dc(this);
1315 dc
.SetLogicalFunction(wxINVERT
);
1316 dc
.DrawLine(m_leftOfSheet
, m_dragLastPosition
, m_rightOfSheet
, m_dragLastPosition
);
1318 dc
.DrawLine(m_leftOfSheet
, (int)ev
.GetY(), m_rightOfSheet
, (int)ev
.GetY());
1321 m_dragLastPosition
= (int)ev
.GetY();
1322 SetCursor(m_verticalSashCursor
);
1327 else if (ev
.Moving())
1329 int rowOrCol
, orientation
, startPos
;
1330 if (LabelSashHitTest((int)ev
.GetX(), (int)ev
.GetY(), &orientation
, &rowOrCol
, &startPos
))
1332 if (orientation
== wxHORIZONTAL
)
1333 SetCursor(m_horizontalSashCursor
);
1335 SetCursor(m_verticalSashCursor
);
1338 SetCursor(*wxSTANDARD_CURSOR
);
1340 else if (ev
.LeftUp())
1342 switch (m_dragStatus
)
1344 case wxGRID_DRAG_LEFT_RIGHT
:
1346 wxClientDC
dc(this);
1348 dc
.SetLogicalFunction(wxINVERT
);
1349 dc
.DrawLine(m_dragLastPosition
, m_topOfSheet
, m_dragLastPosition
, m_bottomOfSheet
);
1350 dc
.SetLogicalFunction(wxCOPY
);
1354 if (ev
.GetX() > m_dragStartPosition
)
1356 m_colWidths
[m_dragRowOrCol
] = (short)(ev
.GetX() - m_dragStartPosition
);
1361 SetCursor(*wxSTANDARD_CURSOR
);
1363 GetClientSize(&cw
, &ch
);
1368 case wxGRID_DRAG_UP_DOWN
:
1370 wxClientDC
dc(this);
1372 dc
.SetLogicalFunction(wxINVERT
);
1373 dc
.DrawLine(m_leftOfSheet
, m_dragLastPosition
, m_rightOfSheet
, m_dragLastPosition
);
1374 dc
.SetLogicalFunction(wxCOPY
);
1378 if (ev
.GetY() > m_dragStartPosition
)
1380 m_rowHeights
[m_dragRowOrCol
] = (short)(ev
.GetY() - m_dragStartPosition
);
1385 SetCursor(*wxSTANDARD_CURSOR
);
1389 m_dragStatus
= wxGRID_DRAG_NONE
;
1391 else if (ev
.RightDown())
1394 if (CellHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1396 //OnCellRightClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1397 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CELL_RCLICK
, this,
1398 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1399 ev
.ControlDown(), ev
.ShiftDown());
1400 GetEventHandler()->ProcessEvent(g_evt
);
1403 if (LabelHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1405 //OnLabelRightClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1406 wxGridEvent
g_evt(GetId(), wxEVT_GRID_LABEL_RCLICK
, this,
1407 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1408 ev
.ControlDown(), ev
.ShiftDown());
1409 GetEventHandler()->ProcessEvent(g_evt
);
1414 void wxGenericGrid::OnSelectCellImplementation(wxDC
*dc
, int row
, int col
)
1416 m_wCursorColumn
= col
;
1419 //OnChangeSelectionLabel();
1420 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_SEL_LABEL
, this);
1421 GetEventHandler()->ProcessEvent(g_evt
);
1423 SetGridClippingRegion(dc
);
1425 // Remove the highlight from the old cell
1426 if ( m_currentRectVisible
&& !(m_editable
&& m_editInPlace
) )
1432 // Highlight the new cell and copy its content to the edit control
1433 SetCurrentRect(m_wCursorRow
, m_wCursorColumn
);
1434 wxGridCell
*cell
= GetCell(m_wCursorRow
, m_wCursorColumn
);
1437 if ( cell
->GetTextValue().IsNull() )
1438 m_textItem
->SetValue("");
1440 m_textItem
->SetValue(cell
->GetTextValue());
1443 SetGridClippingRegion(dc
);
1446 if ( m_editable
&& m_editInPlace
)
1448 int x
, y
, width
, height
;
1449 if ( m_currentRect
.x
<= 0 )
1452 width
= m_currentRect
.width
+ 2;
1456 x
= m_currentRect
.x
- 2;
1457 width
= m_currentRect
.width
+ 4;
1460 if ( m_currentRect
.y
<= 0 )
1463 height
= m_currentRect
.height
+ 2;
1467 y
= m_currentRect
.y
- 2;
1468 height
= m_currentRect
.height
+ 4;
1471 m_inPlaceTextItem
->SetSize( x
, y
, width
, height
);
1475 if ( cell
->GetTextValue().IsNull() )
1477 m_inPlaceTextItem
->SetValue( "" );
1481 m_inPlaceTextItem
->SetFont( cell
->GetFont() );
1482 m_inPlaceTextItem
->SetValue( cell
->GetTextValue() );
1486 m_inPlaceTextItem
->Show(TRUE
);
1487 m_inPlaceTextItem
->SetFocus();
1491 // 1) Why isn't this needed for Windows??
1492 // Probably because of the SetValue?? JS.
1493 // 2) Arrrrrgh. This isn't needed anywhere,
1494 // of course. One hour of debugging... RR.
1496 // 3) It *is* needed for Motif - michael
1499 if ( !(m_editable
&& m_editInPlace
) )
1504 dc
->DestroyClippingRegion();
1506 OnSelectCell(row
, col
);
1507 wxGridEvent
g_evt2(GetId(), wxEVT_GRID_SELECT_CELL
, this, row
, col
);
1508 GetEventHandler()->ProcessEvent(g_evt2
);
1511 wxGridCell
*wxGenericGrid::OnCreateCell()
1513 return new wxGridCell(this);
1516 void wxGenericGrid::OnChangeLabels()
1520 for (i
= 0; i
< m_totalRows
; i
++)
1522 sprintf(buf
, "%d", i
+1);
1523 SetLabelValue(wxVERTICAL
, buf
, i
);
1525 // A...Z,AA...ZZ,AAA...ZZZ, etc.
1526 for (i
= 0; i
< m_totalCols
; i
++)
1529 int noTimes
= (i
/26 + 1);
1530 int ch
= (i
% 26) + 65;
1532 for (j
= 0; j
< noTimes
; j
++)
1535 sprintf(buf2
, "%c", (char)ch
);
1538 SetLabelValue(wxHORIZONTAL
, buf
, i
);
1542 void wxGenericGrid::OnChangeSelectionLabel()
1547 wxString
rowLabel(GetLabelValue(wxVERTICAL
, GetCursorRow()));
1548 wxString
colLabel(GetLabelValue(wxHORIZONTAL
, GetCursorColumn()));
1550 wxString newLabel
= colLabel
+ rowLabel
;
1551 if ((newLabel
.Length() > 0) && (newLabel
.Length() <= 8) && GetTextItem())
1553 // GetTextItem()->SetLabel(newLabel);
1557 void wxGenericGrid::HighlightCell(wxDC
*dc
)
1559 dc
->SetLogicalFunction(wxINVERT
);
1562 dc
->DrawLine( m_currentRect
.x
+ 1,
1563 m_currentRect
.y
+ 1,
1564 m_currentRect
.x
+ m_currentRect
.width
- 1,
1565 m_currentRect
.y
+ 1);
1567 dc
->DrawLine( m_currentRect
.x
+ m_currentRect
.width
- 1,
1568 m_currentRect
.y
+ 1,
1569 m_currentRect
.x
+ m_currentRect
.width
- 1,
1570 m_currentRect
.y
+m_currentRect
.height
- 1 );
1572 dc
->DrawLine( m_currentRect
.x
+ m_currentRect
.width
- 1,
1573 m_currentRect
.y
+ m_currentRect
.height
- 1,
1574 m_currentRect
.x
+ 1,
1575 m_currentRect
.y
+ m_currentRect
.height
- 1);
1577 dc
->DrawLine( m_currentRect
.x
+ 1,
1578 m_currentRect
.y
+ m_currentRect
.height
- 1,
1579 m_currentRect
.x
+ 1,
1580 m_currentRect
.y
+ 1);
1582 dc
->SetLogicalFunction(wxCOPY
);
1585 void wxGenericGrid::DrawCellText()
1587 if (!m_currentRectVisible
)
1590 wxGridCell
*cell
= GetCell(GetCursorRow(), GetCursorColumn());
1594 wxClientDC
dc(this);
1597 SetGridClippingRegion(& dc
);
1599 dc
.SetBackgroundMode(wxTRANSPARENT
);
1600 dc
.SetBrush(cell
->GetBackgroundBrush());
1602 wxString editValue
= m_textItem
->GetValue();
1605 rect
= m_currentRect
;
1611 // FIXME: what's this string of spaces supposed to represent?
1612 DrawTextRect(& dc
, " ", &rect
, wxLEFT
);
1613 DrawTextRect(& dc
, editValue
, &rect
, cell
->GetAlignment());
1615 dc
.DestroyClippingRegion();
1617 dc
.SetBackgroundMode(wxSOLID
);
1622 void wxGenericGrid::SetCurrentRect(int Row
, int Column
, int canvasW
, int canvasH
)
1624 int currentWidth
= m_leftOfSheet
+ m_verticalLabelWidth
;
1626 for (i
= m_scrollPosX
; i
< Column
; i
++)
1627 currentWidth
+= m_colWidths
[i
];
1629 int currentHeight
= m_topOfSheet
+ m_horizontalLabelHeight
;
1630 for (i
= m_scrollPosY
; i
< Row
; i
++)
1631 currentHeight
+= m_rowHeights
[i
];
1633 m_currentRect
.x
= currentWidth
;
1634 m_currentRect
.y
= currentHeight
;
1635 m_currentRect
.width
= m_colWidths
? (m_colWidths
[Column
]) : 0;
1636 m_currentRect
.height
= m_rowHeights
? (m_rowHeights
[Row
]) : 0;
1638 if (Row
< m_scrollPosY
|| Column
< m_scrollPosX
)
1639 m_currentRectVisible
= FALSE
;
1640 else if ((canvasW
!= -1 && canvasH
!= -1) && (m_currentRect
.x
> canvasW
|| m_currentRect
.y
> canvasH
))
1641 m_currentRectVisible
= FALSE
;
1642 else m_currentRectVisible
= TRUE
;
1645 static bool wxRectIntersection(wxRect
*rect1
, wxRect
*rect2
, wxRect
*rect3
)
1647 int x2_1
= rect1
->x
+ rect1
->width
;
1648 int y2_1
= rect1
->y
+ rect1
->height
;
1650 int x2_2
= rect2
->x
+ rect2
->width
;
1651 int y2_2
= rect2
->y
+ rect2
->height
;
1655 // Check for intersection
1656 if ((rect1
->x
> x2_2
) || (rect2
->x
> x2_1
) ||
1657 (rect1
->y
> y2_2
) || (rect2
->y
> y2_1
))
1660 rect3
->x
= rect3
->y
= rect3
->width
= rect3
->height
= 0;
1664 if (rect1
->x
> rect2
->x
)
1665 rect3
->x
= rect1
->x
;
1667 rect3
->x
= rect2
->x
;
1668 if (rect1
->y
> rect2
->y
)
1669 rect3
->y
= rect1
->y
;
1671 rect3
->y
= rect2
->y
;
1682 rect3
->width
= (int)(x2_3
- rect3
->x
);
1683 rect3
->height
= (int)(y2_3
- rect3
->y
);
1687 void wxGenericGrid::DrawTextRect(wxDC
*dc
, const wxString
& text
, wxRect
*rect
, int flag
)
1691 // Ultimately, this functionality should be built into wxWindows,
1692 // and optimized for each platform. E.g. on Windows, use DrawText
1693 // passing a clipping rectangle, so that the wxWindows clipping region
1694 // does not have to be used to implement this.
1696 // If we're already clipping, we need to find the intersection
1697 // between current clipping area and text clipping area.
1701 long clipX
, clipY
, clipW
, clipH
;
1702 dc
->GetClippingBox(&clipX
, &clipY
, &clipW
, &clipH
);
1703 clipRect
.x
= (int)clipX
; clipRect
.y
= (int)clipY
;
1704 clipRect
.width
= (int)clipW
; clipRect
.height
= (int)clipH
;
1706 bool alreadyClipping
= TRUE
;
1708 if (clipRect
.x
== 0 && clipRect
.y
== 0 && clipRect
.width
== 0 && clipRect
.height
== 0)
1710 alreadyClipping
= FALSE
;
1711 clipRect2
.x
= rect
->x
; clipRect2
.y
= rect
->y
;
1712 clipRect2
.width
= rect
->width
; clipRect2
.height
= rect
->height
;
1716 // Find intersection.
1717 if (!wxRectIntersection(rect
, &clipRect
, &clipRect2
))
1721 if (alreadyClipping
)
1722 dc
->DestroyClippingRegion();
1724 dc
->SetClippingRegion(clipRect2
.x
, clipRect2
.y
, clipRect2
.width
, clipRect2
.height
);
1725 long textWidth
, textHeight
;
1727 dc
->GetTextExtent(text
, &textWidth
, &textHeight
);
1735 x
= (rect
->x
+ rect
->width
- textWidth
- 1.0);
1736 y
= (rect
->y
+ (rect
->height
- textHeight
)/2.0);
1741 x
= (rect
->x
+ (rect
->width
- textWidth
)/2.0);
1742 y
= (rect
->y
+ (rect
->height
- textHeight
)/2.0);
1748 x
= (rect
->x
+ 1.0);
1749 y
= (rect
->y
+ (rect
->height
- textHeight
)/2.0);
1753 dc
->DrawText(text
, (long)x
, (long)y
);
1755 dc
->DestroyClippingRegion();
1757 // Restore old clipping
1758 if (alreadyClipping
)
1759 dc
->SetClippingRegion(clipRect
.x
, clipRect
.y
, clipRect
.width
, clipRect
.height
);
1764 void wxGenericGrid::DrawBitmapRect(wxDC
*dc
, wxBitmap
*bitmap
, wxRect
*rect
, int flag
)
1768 // Ultimately, this functionality should be built into wxWindows,
1769 // and optimized for each platform. E.g. on Windows, use DrawText
1770 // passing a clipping rectangle, so that the wxWindows clipping region
1771 // does not have to be used to implement this.
1773 // If we're already clipping, we need to find the intersection
1774 // between current clipping area and text clipping area.
1778 long clipX
, clipY
, clipW
, clipH
;
1779 dc
->GetClippingBox(&clipX
, &clipY
, &clipW
, &clipH
);
1780 clipRect
.x
= (int)clipX
; clipRect
.y
= (int)clipY
;
1781 clipRect
.width
= (int)clipW
; clipRect
.height
= (int)clipH
;
1783 bool alreadyClipping
= TRUE
;
1785 if (clipRect
.x
== 0 && clipRect
.y
== 0 && clipRect
.width
== 0 && clipRect
.height
== 0)
1787 alreadyClipping
= FALSE
;
1788 clipRect2
.x
= rect
->x
; clipRect2
.y
= rect
->y
;
1789 clipRect2
.width
= rect
->width
; clipRect2
.height
= rect
->height
;
1793 // Find intersection.
1794 if (!wxRectIntersection(rect
, &clipRect
, &clipRect2
))
1798 if (alreadyClipping
)
1799 dc
->DestroyClippingRegion();
1801 dc
->SetClippingRegion(clipRect2
.x
, clipRect2
.y
, clipRect2
.width
, clipRect2
.height
);
1802 float bitmapWidth
, bitmapHeight
;
1804 bitmapWidth
= bitmap
->GetWidth();
1805 bitmapHeight
= bitmap
->GetHeight();
1813 x
= (long)(rect
->x
+ rect
->width
- bitmapWidth
- 1);
1814 y
= (long)(rect
->y
+ (rect
->height
- bitmapHeight
)/2.0);
1819 x
= (long)(rect
->x
+ (rect
->width
- bitmapWidth
)/2.0);
1820 y
= (long)(rect
->y
+ (rect
->height
- bitmapHeight
)/2.0);
1826 x
= (long)(rect
->x
+ 1);
1827 y
= (long)(rect
->y
+ (rect
->height
- bitmapHeight
)/2.0);
1832 dcTemp
.SelectObject(*bitmap
);
1834 dc
->Blit( (long)x
, (long)y
, (long)bitmapWidth
, (long)bitmapHeight
, &dcTemp
, 0, 0);
1835 dcTemp
.SelectObject(wxNullBitmap
);
1837 dc
->DestroyClippingRegion();
1839 // Restore old clipping
1840 if (alreadyClipping
)
1841 dc
->SetClippingRegion(clipRect
.x
, clipRect
.y
, clipRect
.width
, clipRect
.height
);
1846 void wxGenericGrid::OnActivate(bool active
)
1850 // Edit control should always have the focus
1851 if (GetTextItem() && GetEditable())
1853 GetTextItem()->SetFocus();
1854 wxGridCell
*cell
= GetCell(GetCursorRow(), GetCursorColumn());
1856 GetTextItem()->SetValue(cell
->GetTextValue());
1861 void wxGenericGrid::SetCellValue(const wxString
& val
, int row
, int col
)
1863 wxGridCell
*cell
= GetCell(row
, col
);
1866 cell
->SetTextValue(val
);
1868 RefreshCell(row
, col
, TRUE
);
1872 void wxGenericGrid::RefreshCell(int row
, int col
, bool setText
)
1874 // Don't refresh within a pair of batch brackets
1875 if (GetBatchCount() > 0)
1879 GetClientSize(&cw
, &ch
);
1881 SetCurrentRect(row
, col
, cw
, ch
);
1882 if (m_currentRectVisible
)
1884 wxGridCell
*cell
= GetCell(row
, col
);
1886 bool currentPos
= FALSE
;
1887 if (row
== m_wCursorRow
&& col
== m_wCursorColumn
&& GetTextItem() && GetTextItem()->IsShown() && setText
)
1889 GetTextItem()->SetValue(cell
->GetTextValue());
1892 // Gets refreshed anyway in MSW
1897 wxClientDC
dc(this);
1899 DrawCellBackground(& dc
, &m_currentRect
, row
, col
);
1900 DrawCellValue(& dc
, &m_currentRect
, row
, col
);
1906 wxString
& wxGenericGrid::GetCellValue(int row
, int col
) const
1908 static wxString
emptyString("");
1910 wxGridCell
*cell
= GetCell(row
, col
);
1912 return cell
->GetTextValue();
1917 void wxGenericGrid::SetColumnWidth(int col
, int width
)
1919 if (col
<= m_totalCols
)
1920 m_colWidths
[col
] = width
;
1923 int wxGenericGrid::GetColumnWidth(int col
) const
1925 if (col
<= m_totalCols
)
1926 return m_colWidths
[col
];
1931 void wxGenericGrid::SetRowHeight(int row
, int height
)
1933 if (row
<= m_totalRows
)
1934 m_rowHeights
[row
] = height
;
1937 int wxGenericGrid::GetRowHeight(int row
) const
1939 if (row
<= m_totalRows
)
1940 return m_rowHeights
[row
];
1945 void wxGenericGrid::SetLabelSize(int orientation
, int sz
)
1947 if (orientation
== wxHORIZONTAL
)
1948 m_horizontalLabelHeight
= sz
;
1950 m_verticalLabelWidth
= sz
;
1952 SetCurrentRect(GetCursorRow(), GetCursorColumn());
1955 int wxGenericGrid::GetLabelSize(int orientation
) const
1957 if (orientation
== wxHORIZONTAL
)
1958 return m_horizontalLabelHeight
;
1960 return m_verticalLabelWidth
;
1963 wxGridCell
*wxGenericGrid::GetLabelCell(int orientation
, int pos
) const
1965 if (orientation
== wxHORIZONTAL
)
1967 if (m_colLabelCells
&& pos
< m_totalCols
)
1968 return m_colLabelCells
[pos
];
1970 return (wxGridCell
*) NULL
;
1974 if (m_rowLabelCells
&& pos
< m_totalRows
)
1975 return m_rowLabelCells
[pos
];
1977 return (wxGridCell
*) NULL
;
1981 void wxGenericGrid::SetLabelValue(int orientation
, const wxString
& val
, int pos
)
1983 wxGridCell
*cell
= GetLabelCell(orientation
, pos
);
1985 cell
->SetTextValue(val
);
1988 wxString
& wxGenericGrid::GetLabelValue(int orientation
, int pos
) const
1990 static wxString emptyString
= "";
1991 wxGridCell
*cell
= GetLabelCell(orientation
, pos
);
1993 return cell
->GetTextValue();
1998 void wxGenericGrid::SetLabelAlignment(int orientation
, int align
)
2000 if (orientation
== wxHORIZONTAL
)
2001 m_horizontalLabelAlignment
= align
;
2003 m_verticalLabelAlignment
= align
;
2005 SetCurrentRect(GetCursorRow(), GetCursorColumn());
2008 int wxGenericGrid::GetLabelAlignment(int orientation
) const
2010 if (orientation
== wxHORIZONTAL
)
2011 return m_horizontalLabelAlignment
;
2013 return m_verticalLabelAlignment
;
2016 void wxGenericGrid::SetLabelTextColour(const wxColour
& colour
)
2018 m_labelTextColour
= colour
;
2022 void wxGenericGrid::SetLabelBackgroundColour(const wxColour
& colour
)
2024 m_labelBackgroundColour
= colour
;
2025 m_labelBackgroundBrush
= * wxTheBrushList
->FindOrCreateBrush(m_labelBackgroundColour
, wxSOLID
);
2028 void wxGenericGrid::SetEditable(bool edit
)
2033 int controlW
, controlH
;
2034 m_textItem
->GetSize(&controlW
, &controlH
);
2035 m_editControlPosition
.height
= controlH
;
2037 m_topOfSheet
= m_editControlPosition
.x
+ controlH
+ 2;
2040 m_editingPanel
->Show(TRUE
);
2041 m_textItem
->Show(TRUE
);
2042 m_textItem
->SetFocus();
2045 if (m_inPlaceTextItem
)
2047 m_inPlaceTextItem
->Show(TRUE
);
2048 m_inPlaceTextItem
->SetFocus();
2056 m_textItem
->Show(FALSE
);
2057 m_editingPanel
->Show(FALSE
);
2060 if ( m_inPlaceTextItem
)
2062 m_inPlaceTextItem
->Show(FALSE
);
2066 SetCurrentRect(GetCursorRow(), GetCursorColumn());
2069 GetClientSize(&cw
, &ch
);
2074 int m_scrollWidth = 16;
2075 GetClientSize(&cw, &ch);
2078 m_vScrollBar->SetSize(cw - m_scrollWidth, m_topOfSheet,
2079 m_scrollWidth, ch - m_topOfSheet - m_scrollWidth);
2084 void wxGenericGrid::SetEditInPlace(bool edit
)
2086 if ( m_editInPlace
!= edit
)
2088 m_editInPlace
= edit
;
2090 if ( m_editInPlace
) // switched on
2092 if ( m_currentRectVisible
&& m_editable
)
2094 m_inPlaceTextItem
->SetSize( m_currentRect
.x
-2, m_currentRect
.y
-2,
2095 m_currentRect
.width
+4, m_currentRect
.height
+4 );
2097 wxGridCell
*cell
= GetCell(m_wCursorRow
, m_wCursorColumn
);
2101 if ( cell
->GetTextValue().IsNull() )
2103 m_inPlaceTextItem
->SetValue( "" );
2107 m_inPlaceTextItem
->SetFont( cell
->GetFont() );
2108 m_inPlaceTextItem
->SetValue( cell
->GetTextValue() );
2112 m_inPlaceTextItem
->Show( TRUE
);
2113 m_inPlaceTextItem
->SetFocus();
2116 else // switched off
2118 m_inPlaceTextItem
->Show( FALSE
);
2124 void wxGenericGrid::SetCellAlignment(int flag
, int row
, int col
)
2126 wxGridCell
*cell
= GetCell(row
, col
);
2128 cell
->SetAlignment(flag
);
2131 int wxGenericGrid::GetCellAlignment(int row
, int col
) const
2133 wxGridCell
*cell
= GetCell(row
, col
);
2135 return cell
->GetAlignment();
2137 return m_cellAlignment
;
2140 void wxGenericGrid::SetCellAlignment(int flag
)
2142 m_cellAlignment
= flag
;
2144 for (i
= 0; i
< GetRows(); i
++)
2145 for (j
= 0; j
< GetCols(); j
++)
2147 GetCell(i
, j
)->SetAlignment(flag
);
2150 int wxGenericGrid::GetCellAlignment(void) const
2152 return m_cellAlignment
;
2155 void wxGenericGrid::SetCellBackgroundColour(const wxColour
& col
)
2157 m_cellBackgroundColour
= col
;
2159 for (i
= 0; i
< GetRows(); i
++)
2160 for (j
= 0; j
< GetCols(); j
++)
2162 GetCell(i
, j
)->SetBackgroundColour(col
);
2165 void wxGenericGrid::SetCellBackgroundColour(const wxColour
& val
, int row
, int col
)
2167 wxGridCell
*cell
= GetCell(row
, col
);
2170 cell
->SetBackgroundColour(val
);
2171 RefreshCell(row
, col
);
2175 wxColour
& wxGenericGrid::GetCellBackgroundColour(int row
, int col
) const
2177 wxGridCell
*cell
= GetCell(row
, col
);
2179 return cell
->GetBackgroundColour();
2181 return (wxColour
&) m_cellBackgroundColour
;
2184 void wxGenericGrid::SetCellTextColour(const wxColour
& val
, int row
, int col
)
2186 wxGridCell
*cell
= GetCell(row
, col
);
2189 cell
->SetTextColour(val
);
2190 RefreshCell(row
, col
);
2194 void wxGenericGrid::SetCellTextFont(const wxFont
& fnt
, int row
, int col
)
2196 wxGridCell
*cell
= GetCell(row
, col
);
2200 RefreshCell(row
, col
);
2204 wxFont
& wxGenericGrid::GetCellTextFont(int row
, int col
) const
2206 wxGridCell
*cell
= GetCell(row
, col
);
2208 return (wxFont
&) cell
->GetFont();
2210 return (wxFont
&) m_cellTextFont
;
2213 wxColour
& wxGenericGrid::GetCellTextColour(int row
, int col
) const
2215 wxGridCell
*cell
= GetCell(row
, col
);
2217 return (wxColour
&) cell
->GetTextColour();
2219 return (wxColour
&) m_cellTextColour
;
2222 void wxGenericGrid::SetCellTextColour(const wxColour
& val
)
2224 m_cellTextColour
= val
;
2226 for (i
= 0; i
< GetRows(); i
++)
2227 for (j
= 0; j
< GetCols(); j
++)
2229 GetCell(i
, j
)->SetTextColour(val
);
2232 void wxGenericGrid::SetCellTextFont(const wxFont
& fnt
)
2234 m_cellTextFont
= fnt
;
2236 for (i
= 0; i
< GetRows(); i
++)
2237 for (j
= 0; j
< GetCols(); j
++)
2239 GetCell(i
, j
)->SetFont(fnt
);
2242 void wxGenericGrid::SetCellBitmap(wxBitmap
*bitmap
, int row
, int col
)
2244 wxGridCell
*cell
= GetCell(row
, col
);
2247 cell
->SetCellBitmap(bitmap
);
2248 RefreshCell(row
, col
);
2252 wxBitmap
*wxGenericGrid::GetCellBitmap(int row
, int col
) const
2254 wxGridCell
*cell
= GetCell(row
, col
);
2257 return cell
->GetCellBitmap();
2260 return (wxBitmap
*) NULL
;
2263 bool wxGenericGrid::InsertCols(int pos
, int n
, bool updateLabels
)
2265 if (pos
> m_totalCols
)
2269 return CreateGrid(1, n
);
2274 for (i
= 0; i
< m_totalRows
; i
++)
2276 wxGridCell
**cols
= m_gridCells
[i
];
2277 wxGridCell
**newCols
= new wxGridCell
*[m_totalCols
+ n
];
2278 for (j
= 0; j
< pos
; j
++)
2279 newCols
[j
] = cols
[j
];
2280 for (j
= pos
; j
< pos
+ n
; j
++)
2281 newCols
[j
] = new wxGridCell(this);
2282 for (j
= pos
+ n
; j
< m_totalCols
+ n
; j
++)
2283 newCols
[j
] = cols
[j
- n
];
2286 m_gridCells
[i
] = newCols
;
2290 short *newColWidths
= new short[m_totalCols
+ n
];
2291 for (j
= 0; j
< pos
; j
++)
2292 newColWidths
[j
] = m_colWidths
[j
];
2293 for (j
= pos
; j
< pos
+ n
; j
++)
2294 newColWidths
[j
] = wxGRID_DEFAULT_CELL_WIDTH
;
2295 for (j
= pos
+ n
; j
< m_totalCols
+ n
; j
++)
2296 newColWidths
[j
] = m_colWidths
[j
- n
];
2297 delete[] m_colWidths
;
2298 m_colWidths
= newColWidths
;
2301 wxGridCell
**newLabels
= new wxGridCell
*[m_totalCols
+ n
];
2302 for (j
= 0; j
< pos
; j
++)
2303 newLabels
[j
] = m_colLabelCells
[j
];
2304 for (j
= pos
; j
< pos
+ n
; j
++)
2305 newLabels
[j
] = new wxGridCell(this);
2306 for (j
= pos
+ n
; j
< m_totalCols
+ n
; j
++)
2307 newLabels
[j
] = m_colLabelCells
[j
- n
];
2309 delete[] m_colLabelCells
;
2310 m_colLabelCells
= newLabels
;
2316 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2317 GetEventHandler()->ProcessEvent(g_evt
);
2326 bool wxGenericGrid::InsertRows(int pos
, int n
, bool updateLabels
)
2328 if (pos
> m_totalRows
)
2332 return CreateGrid(n
, 1);
2337 wxGridCell
***rows
= new wxGridCell
**[m_totalRows
+ n
];
2340 for (i
= 0; i
< pos
; i
++)
2341 rows
[i
] = m_gridCells
[i
];
2343 for (i
= pos
; i
< pos
+ n
; i
++)
2345 rows
[i
] = new wxGridCell
*[m_totalCols
];
2346 for (j
= 0; j
< m_totalCols
; j
++)
2347 rows
[i
][j
] = new wxGridCell(this);
2350 for (i
= pos
+ n
; i
< m_totalRows
+ n
; i
++)
2351 rows
[i
] = m_gridCells
[i
- n
];
2353 delete[] m_gridCells
;
2357 short *newRowHeights
= new short[m_totalRows
+ n
];
2358 for (i
= 0; i
< pos
; i
++)
2359 newRowHeights
[i
] = m_rowHeights
[i
];
2360 for (i
= pos
; i
< pos
+ n
; i
++)
2361 newRowHeights
[i
] = wxGRID_DEFAULT_CELL_HEIGHT
;
2362 for (i
= pos
+ n
; i
< m_totalRows
+ n
; i
++)
2363 newRowHeights
[i
] = m_rowHeights
[i
- n
];
2364 delete[] m_rowHeights
;
2365 m_rowHeights
= newRowHeights
;
2368 wxGridCell
**newLabels
= new wxGridCell
*[m_totalRows
+ n
];
2369 for (i
= 0; i
< pos
; i
++)
2370 newLabels
[i
] = m_rowLabelCells
[i
];
2371 for (i
= pos
; i
< pos
+ n
; i
++)
2372 newLabels
[i
] = new wxGridCell(this);
2373 for (i
= pos
+ n
; i
< m_totalRows
+ n
; i
++)
2374 newLabels
[i
] = m_rowLabelCells
[i
- n
];
2376 delete[] m_rowLabelCells
;
2377 m_rowLabelCells
= newLabels
;
2383 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2384 GetEventHandler()->ProcessEvent(g_evt
);
2393 bool wxGenericGrid::AppendCols(int n
, bool updateLabels
)
2395 return InsertCols(GetCols(), n
, updateLabels
);
2398 bool wxGenericGrid::AppendRows(int n
, bool updateLabels
)
2400 return InsertRows(GetRows(), n
, updateLabels
);
2403 bool wxGenericGrid::DeleteRows(int pos
, int n
, bool updateLabels
)
2405 if (pos
> m_totalRows
)
2412 wxGridCell
***rows
= new wxGridCell
**[m_totalRows
- n
];
2415 for (i
= 0; i
< pos
; i
++)
2416 rows
[i
] = m_gridCells
[i
];
2418 for (i
= pos
+ n
; i
< m_totalRows
; i
++)
2419 rows
[i
-n
] = m_gridCells
[i
];
2421 delete[] m_gridCells
;
2425 short *newRowHeights
= new short[m_totalRows
- n
];
2426 for (i
= 0; i
< pos
; i
++)
2427 newRowHeights
[i
] = m_rowHeights
[i
];
2428 for (i
= pos
+ n
; i
< m_totalRows
; i
++)
2429 newRowHeights
[i
-n
] = m_rowHeights
[i
];
2430 delete[] m_rowHeights
;
2431 m_rowHeights
= newRowHeights
;
2434 wxGridCell
**newLabels
= new wxGridCell
*[m_totalRows
- n
];
2435 for (i
= 0; i
< pos
; i
++)
2436 newLabels
[i
] = m_rowLabelCells
[i
];
2437 for (i
= pos
+ n
; i
< m_totalRows
; i
++)
2438 newLabels
[i
-n
] = m_rowLabelCells
[i
];
2440 delete[] m_rowLabelCells
;
2441 m_rowLabelCells
= newLabels
;
2447 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2448 GetEventHandler()->ProcessEvent(g_evt
);
2455 bool wxGenericGrid::DeleteCols(int pos
, int n
, bool updateLabels
)
2457 if (pos
+ n
> m_totalCols
)
2465 for (i
= 0; i
< m_totalRows
; i
++)
2467 wxGridCell
**cols
= m_gridCells
[i
];
2468 wxGridCell
**newCols
= new wxGridCell
*[m_totalCols
- n
];
2469 for (j
= 0; j
< pos
; j
++)
2470 newCols
[j
] = cols
[j
];
2471 for (j
= pos
; j
< pos
+ n
; j
++)
2473 for (j
= pos
+ n
; j
< m_totalCols
; j
++)
2474 newCols
[j
-n
] = cols
[j
];
2477 m_gridCells
[i
] = newCols
;
2481 short *newColWidths
= new short[m_totalCols
- n
];
2482 for (j
= 0; j
< pos
; j
++)
2483 newColWidths
[j
] = m_colWidths
[j
];
2484 for (j
= pos
+ n
; j
< m_totalCols
; j
++)
2485 newColWidths
[j
-n
] = m_colWidths
[j
];
2486 delete[] m_colWidths
;
2487 m_colWidths
= newColWidths
;
2490 wxGridCell
**newLabels
= new wxGridCell
*[m_totalCols
- n
];
2491 for (j
= 0; j
< pos
; j
++)
2492 newLabels
[j
] = m_colLabelCells
[j
];
2493 for (j
= pos
+ n
; j
< m_totalCols
; j
++)
2494 newLabels
[j
-n
] = m_colLabelCells
[j
];
2496 delete[] m_colLabelCells
;
2497 m_colLabelCells
= newLabels
;
2503 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2504 GetEventHandler()->ProcessEvent(g_evt
);
2511 void wxGenericGrid::SetGridCursor(int row
, int col
)
2513 if (row
>= m_totalRows
|| col
>= m_totalCols
)
2516 if (row
== GetCursorRow() && col
== GetCursorColumn())
2519 wxClientDC
dc(this);
2522 SetGridClippingRegion(& dc
);
2524 if (m_currentRectVisible
&& !(m_editable
&& m_editInPlace
) )
2525 HighlightCell(& dc
);
2528 m_wCursorColumn
= col
;
2531 GetClientSize(&cw
, &ch
);
2533 SetCurrentRect(row
, col
, cw
, ch
);
2535 if (m_currentRectVisible
&& !(m_editable
&& m_editInPlace
) )
2536 HighlightCell(& dc
);
2538 dc
.DestroyClippingRegion();
2542 // ----------------------------------------------------------------------------
2544 // ----------------------------------------------------------------------------
2546 wxGridCell::wxGridCell(wxGenericGrid
*window
)
2548 cellBitmap
= (wxBitmap
*) NULL
;
2550 backgroundBrush
= wxNullBrush
;
2552 textColour
= window
->GetCellTextColour();
2554 textColour
.Set(0,0,0);
2556 backgroundColour
= window
->GetCellBackgroundColour();
2558 backgroundColour
.Set(255,255,255);
2561 font
= window
->GetCellTextFont();
2563 font
= * wxTheFontList
->FindOrCreateFont(12, wxSWISS
, wxNORMAL
, wxNORMAL
);
2565 SetBackgroundColour(backgroundColour
);
2568 alignment
= window
->GetCellAlignment();
2572 cellData
= (void *)NULL
;
2575 wxGridCell::~wxGridCell()
2579 void wxGridCell::SetBackgroundColour(const wxColour
& colour
)
2581 backgroundColour
= colour
;
2582 backgroundBrush
= * wxTheBrushList
->FindOrCreateBrush(backgroundColour
, wxSOLID
);
2585 void wxGenericGrid::OnText(wxCommandEvent
& WXUNUSED(ev
) )
2587 // michael - added this conditional to prevent change to
2588 // grid cell text when edit control is hidden but still has
2593 wxGenericGrid
*grid
= this;
2594 wxGridCell
*cell
= grid
->GetCell(grid
->GetCursorRow(), grid
->GetCursorColumn());
2595 if (cell
&& grid
->CurrentCellVisible())
2597 cell
->SetTextValue(grid
->GetTextItem()->GetValue());
2598 if ( m_editInPlace
&& !m_inOnTextInPlace
)
2600 m_inPlaceTextItem
->SetValue( grid
->GetTextItem()->GetValue() );
2603 wxClientDC
dc(grid
);
2606 grid
->SetGridClippingRegion(& dc
);
2607 grid
->DrawCellBackground(& dc
, &grid
->GetCurrentRect(), grid
->GetCursorRow(), grid
->GetCursorColumn());
2608 grid
->DrawCellValue(& dc
, &grid
->GetCurrentRect(), grid
->GetCursorRow(), grid
->GetCursorColumn());
2609 if ( !(m_editable
&& m_editInPlace
) ) grid
->HighlightCell(& dc
);
2610 dc
.DestroyClippingRegion();
2613 //grid->OnCellChange(grid->GetCursorRow(), grid->GetCursorColumn());
2614 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CELL_CHANGE
, grid
,
2615 grid
->GetCursorRow(), grid
->GetCursorColumn());
2616 GetEventHandler()->ProcessEvent(g_evt
);
2618 // grid->DrawCellText();
2623 void wxGenericGrid::OnTextEnter(wxCommandEvent
& WXUNUSED(ev
) )
2625 // move the cursor down the current row (if possible)
2626 // when the enter key has been pressed
2630 if ( GetCursorRow() < GetRows()-1 )
2632 wxClientDC
dc( this );
2634 OnSelectCellImplementation(& dc
,
2636 GetCursorColumn() );
2642 void wxGenericGrid::OnTextInPlace(wxCommandEvent
& ev
)
2646 wxGenericGrid
*grid
= this;
2647 wxGridCell
*cell
= grid
->GetCell(grid
->GetCursorRow(), grid
->GetCursorColumn());
2648 if (cell
&& grid
->CurrentCellVisible())
2650 m_inOnTextInPlace
= TRUE
;
2651 grid
->GetTextItem()->SetValue( m_inPlaceTextItem
->GetValue() );
2653 m_inOnTextInPlace
= FALSE
;
2658 void wxGenericGrid::OnTextInPlaceEnter(wxCommandEvent
& WXUNUSED(ev
) )
2660 // move the cursor down the current row (if possible)
2661 // when the enter key has been pressed
2665 if ( GetCursorRow() < GetRows()-1 )
2667 wxClientDC
dc( this );
2669 OnSelectCellImplementation(& dc
,
2671 GetCursorColumn() );
2677 void wxGenericGrid::OnGridScroll(wxScrollEvent
& ev
)
2679 static bool inScroll
= FALSE
;
2684 if ( m_editInPlace
) m_inPlaceTextItem
->Show(FALSE
);
2687 wxGenericGrid
*win
= this;
2689 bool change
= FALSE
;
2691 if (ev
.GetEventObject() == win
->GetHorizScrollBar())
2693 change
= (ev
.GetPosition() != m_scrollPosX
);
2694 win
->SetScrollPosX(ev
.GetPosition());
2698 change
= (ev
.GetPosition() != m_scrollPosY
);
2699 win
->SetScrollPosY(ev
.GetPosition());
2702 win
->UpdateDimensions();
2704 win
->SetCurrentRect(win
->GetCursorRow(), win
->GetCursorColumn());
2706 // Because rows and columns can be arbitrary sizes,
2707 // the scrollbars will need to be adjusted to reflect the
2711 if (change
) win
->Refresh(FALSE
);
2713 if ( m_editInPlace
&& m_currentRectVisible
)
2715 m_inPlaceTextItem
->SetSize( m_currentRect
.x
-2, m_currentRect
.y
-2,
2716 m_currentRect
.width
+4, m_currentRect
.height
+4 );
2717 m_inPlaceTextItem
->Show( TRUE
);
2718 m_inPlaceTextItem
->SetFocus();
2726 //----------------------------------------------------------------------
2727 // Default wxGridEvent handlers
2728 // (just redirect to the pre-existing virtual methods)
2730 void wxGenericGrid::_OnSelectCell(wxGridEvent
& ev
)
2732 OnSelectCell(ev
.m_row
, ev
.m_col
);
2735 void wxGenericGrid::_OnCreateCell(wxGridEvent
& ev
)
2737 ev
.m_cell
= OnCreateCell();
2740 void wxGenericGrid::_OnChangeLabels(wxGridEvent
& WXUNUSED(ev
))
2745 void wxGenericGrid::_OnChangeSelectionLabel(wxGridEvent
& WXUNUSED(ev
))
2747 OnChangeSelectionLabel();
2750 void wxGenericGrid::_OnCellChange(wxGridEvent
& ev
)
2752 OnCellChange(ev
.m_row
, ev
.m_col
);
2755 void wxGenericGrid::_OnCellLeftClick(wxGridEvent
& ev
)
2757 OnCellLeftClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2760 void wxGenericGrid::_OnCellRightClick(wxGridEvent
& ev
)
2762 OnCellRightClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2765 void wxGenericGrid::_OnLabelLeftClick(wxGridEvent
& ev
)
2767 OnLabelLeftClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2770 void wxGenericGrid::_OnLabelRightClick(wxGridEvent
& ev
)
2772 OnLabelRightClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2775 void *wxGenericGrid::SetCellData(void *data
, int row
, int col
)
2779 wxGridCell
*cell
= GetCell(row
, col
);
2781 rc
= cell
->SetCellData(data
);
2786 void *wxGenericGrid::GetCellData(int row
, int col
)
2790 wxGridCell
*cell
= GetCell(row
, col
);
2792 rc
= cell
->GetCellData();