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"
28 #if wxUSE_GRID && !(wxUSE_NEW_GRID)
32 #include "wx/dcclient.h"
33 #include "wx/dcmemory.h"
34 #include "wx/textctrl.h"
35 #include "wx/settings.h"
40 #include "wx/string.h"
42 #include "wx/generic/gridg.h"
45 // Values used to adjust the size of the in-place-edit control, and other
46 // goodies. Per-platform tweaks should be done here.
48 #define wxIPE_ADJUST -2
49 #define wxIPE_STYLE wxNO_BORDER
50 #define wxIPE_HIGHLIGHT 1
51 #define wxUSE_DOUBLE_BUFFERING 1
55 #define wxIPE_ADJUST -1
56 #define wxIPE_STYLE wxNO_BORDER
57 #define wxIPE_HIGHLIGHT 1
58 #define wxUSE_DOUBLE_BUFFERING 1
62 #define wxIPE_ADJUST -1
63 #define wxIPE_STYLE wxNO_BORDER
64 #define wxIPE_HIGHLIGHT 0
65 #define wxUSE_DOUBLE_BUFFERING 1
69 #define wxIPE_ADJUST 2
70 #define wxIPE_STYLE wxNO_BORDER
71 #define wxIPE_HIGHLIGHT 0
72 #define wxUSE_DOUBLE_BUFFERING 0
76 #define wxIPE_ADJUST 2
77 #define wxIPE_STYLE wxNO_BORDER
78 #define wxIPE_HIGHLIGHT 0
79 #define wxUSE_DOUBLE_BUFFERING 0
84 #define wxGRID_DRAG_NONE 0
85 #define wxGRID_DRAG_LEFT_RIGHT 1
86 #define wxGRID_DRAG_UP_DOWN 2
88 IMPLEMENT_DYNAMIC_CLASS(wxGenericGrid
, wxPanel
)
89 IMPLEMENT_DYNAMIC_CLASS(wxGridEvent
, wxEvent
)
91 BEGIN_EVENT_TABLE(wxGenericGrid
, wxPanel
)
92 EVT_SIZE(wxGenericGrid::OnSize
)
93 EVT_PAINT(wxGenericGrid::OnPaint
)
94 EVT_ERASE_BACKGROUND(wxGenericGrid::OnEraseBackground
)
95 EVT_MOUSE_EVENTS(wxGenericGrid::OnMouseEvent
)
96 EVT_TEXT(wxGRID_TEXT_CTRL
, wxGenericGrid::OnText
)
97 EVT_TEXT(wxGRID_EDIT_IN_PLACE_TEXT_CTRL
, wxGenericGrid::OnTextInPlace
)
98 EVT_TEXT_ENTER(wxGRID_TEXT_CTRL
, wxGenericGrid::OnTextEnter
)
99 EVT_TEXT_ENTER(wxGRID_EDIT_IN_PLACE_TEXT_CTRL
, wxGenericGrid::OnTextInPlaceEnter
)
100 EVT_COMMAND_SCROLL(wxGRID_HSCROLL
, wxGenericGrid::OnGridScroll
)
101 EVT_COMMAND_SCROLL(wxGRID_VSCROLL
, wxGenericGrid::OnGridScroll
)
103 // default wxGridEvent handlers
104 EVT_GRID_SELECT_CELL(wxGenericGrid::_OnSelectCell
)
105 EVT_GRID_CREATE_CELL(wxGenericGrid::_OnCreateCell
)
106 EVT_GRID_CHANGE_LABELS(wxGenericGrid::_OnChangeLabels
)
107 EVT_GRID_CHANGE_SEL_LABEL(wxGenericGrid::_OnChangeSelectionLabel
)
108 EVT_GRID_CELL_CHANGE(wxGenericGrid::_OnCellChange
)
109 EVT_GRID_CELL_LCLICK(wxGenericGrid::_OnCellLeftClick
)
110 EVT_GRID_CELL_RCLICK(wxGenericGrid::_OnCellRightClick
)
111 EVT_GRID_LABEL_LCLICK(wxGenericGrid::_OnLabelLeftClick
)
112 EVT_GRID_LABEL_RCLICK(wxGenericGrid::_OnLabelRightClick
)
117 wxGenericGrid::wxGenericGrid()
122 m_hScrollBar
= (wxScrollBar
*) NULL
;
123 m_vScrollBar
= (wxScrollBar
*) NULL
;
124 m_cellTextColour
= *wxBLACK
;
125 m_cellBackgroundColour
= *wxWHITE
;
126 m_labelTextColour
= *wxBLACK
;
127 // m_labelBackgroundColour = *wxLIGHT_GREY;
128 m_labelBackgroundColour
= wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE
);
129 m_labelBackgroundBrush
= wxNullBrush
;
130 m_labelTextFont
= wxNullFont
;
131 m_cellTextFont
= wxNullFont
;
132 m_textItem
= (wxTextCtrl
*) NULL
;
133 m_currentRectVisible
= FALSE
;
136 m_editInPlace
= FALSE
;
137 m_inOnTextInPlace
= FALSE
;
140 #if defined(__WIN95__)
141 m_scrollWidth
= wxSystemSettings::GetMetric(wxSYS_VSCROLL_X
);
142 #elif defined(__WXGTK__)
143 m_scrollWidth
= wxSystemSettings::GetMetric(wxSYS_VSCROLL_X
);
147 m_dragStatus
= wxGRID_DRAG_NONE
;
149 m_dragStartPosition
= 0;
150 m_dragLastPosition
= 0;
151 m_divisionPen
= wxNullPen
;
152 m_highlightPen
= wxNullPen
;
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;
158 m_colWidths
= (short *) NULL
;
159 m_rowHeights
= (short *) NULL
;
160 m_verticalLabelWidth
= wxGRID_DEFAULT_VERTICAL_LABEL_WIDTH
;
161 m_horizontalLabelHeight
= wxGRID_DEFAULT_HORIZONAL_LABEL_HEIGHT
;
162 m_verticalLabelAlignment
= wxCENTRE
;
163 m_horizontalLabelAlignment
= wxCENTRE
;
164 m_editControlPosition
.x
= wxGRID_DEFAULT_EDIT_X
;
165 m_editControlPosition
.y
= wxGRID_DEFAULT_EDIT_Y
;
166 m_editControlPosition
.width
= wxGRID_DEFAULT_EDIT_WIDTH
;
167 m_editControlPosition
.height
= wxGRID_DEFAULT_EDIT_HEIGHT
;
172 m_editCreated
= FALSE
;
175 m_gridCells
= (wxGridCell
***) NULL
;
176 m_rowLabelCells
= (wxGridCell
**) NULL
;
177 m_colLabelCells
= (wxGridCell
**) NULL
;
178 m_textItem
= (wxTextCtrl
*) NULL
;
181 bool wxGenericGrid::Create(wxWindow
*parent
,
186 const wxString
& name
)
191 m_editingPanel
= (wxPanel
*) NULL
;
192 m_hScrollBar
= (wxScrollBar
*) NULL
;
193 m_vScrollBar
= (wxScrollBar
*) NULL
;
194 m_cellTextColour
= *wxBLACK
;
195 m_cellBackgroundColour
= *wxWHITE
;
196 m_labelTextColour
= *wxBLACK
;
197 // m_labelBackgroundColour = *wxLIGHT_GREY;
198 m_labelBackgroundColour
= wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE
);
199 m_labelBackgroundBrush
= wxNullBrush
;
200 m_labelTextFont
= * wxTheFontList
->FindOrCreateFont(10, wxSWISS
, wxNORMAL
, wxBOLD
);
201 m_cellTextFont
= * wxTheFontList
->FindOrCreateFont(10, wxSWISS
, wxNORMAL
, wxNORMAL
);
202 m_textItem
= (wxTextCtrl
*) NULL
;
203 m_currentRectVisible
= FALSE
;
205 m_editInPlace
= FALSE
;
206 m_inOnTextInPlace
= FALSE
;
208 #if defined(__WIN95__)
209 m_scrollWidth
= wxSystemSettings::GetMetric(wxSYS_VSCROLL_X
);
210 #elif defined(__WXGTK__)
211 m_scrollWidth
= wxSystemSettings::GetMetric(wxSYS_VSCROLL_X
);
215 m_dragStatus
= wxGRID_DRAG_NONE
;
217 m_dragStartPosition
= 0;
218 m_dragLastPosition
= 0;
219 m_divisionPen
= * wxThePenList
->FindOrCreatePen("LIGHT GREY", 1, wxSOLID
);
220 m_highlightPen
= * wxBLACK_PEN
;
221 m_doubleBufferingBitmap
= (wxBitmap
*) NULL
;
223 if (!m_horizontalSashCursor
.Ok())
225 m_horizontalSashCursor
= wxCursor(wxCURSOR_SIZEWE
);
226 m_verticalSashCursor
= wxCursor(wxCURSOR_SIZENS
);
229 SetLabelBackgroundColour(m_labelBackgroundColour
);
231 m_leftOfSheet
= wxGRID_DEFAULT_SHEET_LEFT
;
232 m_topOfSheet
= wxGRID_DEFAULT_SHEET_TOP
;
233 m_cellHeight
= wxGRID_DEFAULT_CELL_HEIGHT
;
234 m_totalGridWidth
= 0;
235 m_totalGridHeight
= 0;
236 m_colWidths
= (short *) NULL
;
237 m_rowHeights
= (short *) NULL
;
239 m_verticalLabelWidth
= wxGRID_DEFAULT_VERTICAL_LABEL_WIDTH
;
240 m_horizontalLabelHeight
= wxGRID_DEFAULT_HORIZONAL_LABEL_HEIGHT
;
241 m_verticalLabelAlignment
= wxCENTRE
;
242 m_horizontalLabelAlignment
= wxCENTRE
;
243 m_editControlPosition
.x
= wxGRID_DEFAULT_EDIT_X
;
244 m_editControlPosition
.y
= wxGRID_DEFAULT_EDIT_Y
;
245 m_editControlPosition
.width
= wxGRID_DEFAULT_EDIT_WIDTH
;
246 m_editControlPosition
.height
= wxGRID_DEFAULT_EDIT_HEIGHT
;
254 /* Store the rect. coordinates for the current cell */
255 SetCurrentRect(m_wCursorRow
, m_wCursorColumn
);
257 m_editCreated
= FALSE
;
261 m_gridCells
= (wxGridCell
***) NULL
;
262 m_rowLabelCells
= (wxGridCell
**) NULL
;
263 m_colLabelCells
= (wxGridCell
**) NULL
;
264 m_textItem
= (wxTextCtrl
*) NULL
;
266 wxPanel::Create(parent
, id
, pos
, size
, style
, name
);
268 m_editingPanel
= new wxPanel(this);
270 m_textItem
= new wxTextCtrl(m_editingPanel
, wxGRID_TEXT_CTRL
, "",
271 wxPoint(m_editControlPosition
.x
, m_editControlPosition
.y
),
272 wxSize(m_editControlPosition
.width
, -1),
274 m_textItem
->Show(TRUE
);
275 m_textItem
->SetFocus();
276 int controlW
, controlH
;
278 m_textItem
->GetSize(&controlW
, &controlH
);
279 m_editControlPosition
.height
= controlH
;
281 m_topOfSheet
= m_editControlPosition
.y
+ controlH
+ 2;
283 m_editCreated
= TRUE
;
285 m_hScrollBar
= new wxScrollBar(this, wxGRID_HSCROLL
, wxPoint(0, 0), wxSize(20, 100), wxHORIZONTAL
);
286 m_vScrollBar
= new wxScrollBar(this, wxGRID_VSCROLL
, wxPoint(0, 0), wxSize(100, 20), wxVERTICAL
);
288 // SetSize(pos.x, pos.y, size.x, size.y);
290 m_inPlaceTextItem
= new wxTextCtrl( (wxPanel
*)this, wxGRID_EDIT_IN_PLACE_TEXT_CTRL
, "",
291 wxPoint( m_currentRect
.x
-wxIPE_ADJUST
, m_currentRect
.y
-wxIPE_ADJUST
),
292 wxSize( m_currentRect
.width
+wxIPE_ADJUST
*2, m_currentRect
.height
+wxIPE_ADJUST
*2 ),
293 wxNO_BORDER
| wxTE_PROCESS_ENTER
);
294 m_inPlaceTextItem
->Show(m_editInPlace
);
296 m_inPlaceTextItem
->SetFocus();
301 wxGenericGrid::~wxGenericGrid()
306 void wxGenericGrid::ClearGrid()
311 for (i
= 0; i
< m_totalRows
; i
++)
313 for (j
= 0; j
< m_totalCols
; j
++)
314 if (m_gridCells
[i
][j
])
315 delete m_gridCells
[i
][j
];
316 delete[] m_gridCells
[i
];
318 delete[] m_gridCells
;
319 m_gridCells
= (wxGridCell
***) NULL
;
322 delete[] m_colWidths
;
323 m_colWidths
= (short *) NULL
;
325 delete[] m_rowHeights
;
326 m_rowHeights
= (short *) NULL
;
330 for (i
= 0; i
< m_totalRows
; i
++)
331 delete m_rowLabelCells
[i
];
332 delete[] m_rowLabelCells
;
333 m_rowLabelCells
= (wxGridCell
**) NULL
;
337 for (i
= 0; i
< m_totalCols
; i
++)
338 delete m_colLabelCells
[i
];
339 delete[] m_colLabelCells
;
340 m_colLabelCells
= (wxGridCell
**) NULL
;
342 if (m_doubleBufferingBitmap
)
344 delete m_doubleBufferingBitmap
;
345 m_doubleBufferingBitmap
= (wxBitmap
*) NULL
;
349 bool wxGenericGrid::CreateGrid(int nRows
, int nCols
, wxString
**cellValues
, short *widths
,
350 short defaultWidth
, short defaultHeight
)
356 m_colWidths
= new short[nCols
];
357 m_rowHeights
= new short[nRows
];
358 for (i
= 0; i
< nCols
; i
++)
360 m_colWidths
[i
] = widths
[i
];
362 m_colWidths
[i
] = defaultWidth
;
363 for (i
= 0; i
< nRows
; i
++)
364 m_rowHeights
[i
] = defaultHeight
;
366 m_gridCells
= new wxGridCell
**[nRows
];
368 for (i
= 0; i
< nRows
; i
++)
369 m_gridCells
[i
] = new wxGridCell
*[nCols
];
371 for (i
= 0; i
< nRows
; i
++)
372 for (j
= 0; j
< nCols
; j
++)
375 //m_gridCells[i][j] = OnCreateCell();
376 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CREATE_CELL
, this, i
, j
);
377 GetEventHandler()->ProcessEvent(g_evt
);
378 m_gridCells
[i
][j
] = g_evt
.m_cell
;
379 m_gridCells
[i
][j
]->SetTextValue(cellValues
[i
][j
]);
382 m_gridCells
[i
][j
] = (wxGridCell
*) NULL
;
384 m_rowLabelCells
= new wxGridCell
*[nRows
];
385 for (i
= 0; i
< nRows
; i
++)
386 m_rowLabelCells
[i
] = new wxGridCell(this);
387 m_colLabelCells
= new wxGridCell
*[nCols
];
388 for (i
= 0; i
< nCols
; i
++)
389 m_colLabelCells
[i
] = new wxGridCell(this);
391 m_wCursorRow
= m_wCursorColumn
= 0;
392 SetCurrentRect(0, 0);
394 // Need to determine various dimensions
398 int objectSizeX
= m_totalCols
;
400 int viewLengthX
= m_totalCols
;
403 m_hScrollBar->SetViewLength(viewLengthX);
404 m_hScrollBar->SetObjectLength(objectSizeX);
405 m_hScrollBar->SetPageSize(pageSizeX);
407 m_hScrollBar
->SetScrollbar(m_hScrollBar
->GetThumbPosition(), pageSizeX
, objectSizeX
, viewLengthX
);
409 int objectSizeY
= m_totalRows
;
411 int viewLengthY
= m_totalRows
;
414 m_vScrollBar->SetViewLength(viewLengthY);
415 m_vScrollBar->SetObjectLength(objectSizeY);
416 m_vScrollBar->SetPageSize(pageSizeY);
419 m_vScrollBar
->SetScrollbar(m_vScrollBar
->GetThumbPosition(), pageSizeY
, objectSizeY
, viewLengthY
);
424 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
425 GetEventHandler()->ProcessEvent(g_evt
);
427 //OnChangeSelectionLabel();
428 wxGridEvent
g_evt2(GetId(), wxEVT_GRID_CHANGE_SEL_LABEL
, this);
429 GetEventHandler()->ProcessEvent(g_evt2
);
434 // Need to determine various dimensions
435 void wxGenericGrid::UpdateDimensions()
437 int canvasWidth
, canvasHeight
;
438 GetSize(&canvasWidth
, &canvasHeight
);
440 if (m_editCreated
&& m_editable
)
442 int controlW
, controlH
;
443 GetTextItem()->GetSize(&controlW
, &controlH
);
444 m_topOfSheet
= m_editControlPosition
.y
+ controlH
+ 2;
448 m_rightOfSheet
= m_leftOfSheet
+ m_verticalLabelWidth
;
450 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
452 if (m_rightOfSheet
> canvasWidth
)
455 m_rightOfSheet
+= m_colWidths
[i
];
457 m_bottomOfSheet
= m_topOfSheet
+ m_horizontalLabelHeight
;
458 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
460 if (m_bottomOfSheet
> canvasHeight
)
463 m_bottomOfSheet
+= m_rowHeights
[i
];
466 m_totalGridWidth
= m_leftOfSheet
+ m_verticalLabelWidth
;
467 for (i
= 0; i
< m_totalCols
; i
++)
469 m_totalGridWidth
+= m_colWidths
[i
];
471 m_totalGridHeight
= m_topOfSheet
+ m_horizontalLabelHeight
;
472 for (i
= 0; i
< m_totalRows
; i
++)
474 m_totalGridHeight
+= m_rowHeights
[i
];
478 wxGridCell
*wxGenericGrid::GetCell(int row
, int col
) const
481 return (wxGridCell
*) NULL
;
483 if ((row
>= m_totalRows
) || (col
>= m_totalCols
))
484 return (wxGridCell
*) NULL
;
486 wxGridCell
*cell
= m_gridCells
[row
][col
];
489 // m_gridCells[row][col] = OnCreateCell();
490 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CREATE_CELL
, (wxGenericGrid
*) this, row
, col
);
491 GetEventHandler()->ProcessEvent(g_evt
);
492 m_gridCells
[row
][col
] = g_evt
.m_cell
;
493 return m_gridCells
[row
][col
];
499 void wxGenericGrid::SetGridClippingRegion(wxDC
*dc
)
501 int m_scrollWidthHoriz
= 0;
502 int m_scrollWidthVert
= 0;
504 GetClientSize(&cw
, &ch
);
506 if (m_hScrollBar
&& m_hScrollBar
->IsShown())
507 m_scrollWidthHoriz
= m_scrollWidth
;
508 if (m_vScrollBar
&& m_vScrollBar
->IsShown())
509 m_scrollWidthVert
= m_scrollWidth
;
511 // Don't paint over the scrollbars
512 dc
->SetClippingRegion(m_leftOfSheet
, m_topOfSheet
,
513 cw
- m_scrollWidthVert
- m_leftOfSheet
, ch
- m_scrollWidthHoriz
- m_topOfSheet
);
516 void wxGenericGrid::OnPaint(wxPaintEvent
& WXUNUSED(event
))
519 GetClientSize(&w
, &h
);
521 bool useDoubleBuffering
= (bool) wxUSE_DOUBLE_BUFFERING
;
522 if (useDoubleBuffering
)
524 // Reuse the old bitmap if possible
526 if (!m_doubleBufferingBitmap
||
527 (m_doubleBufferingBitmap
->GetWidth() < w
|| m_doubleBufferingBitmap
->GetHeight() < h
))
529 if (m_doubleBufferingBitmap
)
530 delete m_doubleBufferingBitmap
;
531 m_doubleBufferingBitmap
= new wxBitmap(w
, h
);
533 if (!m_doubleBufferingBitmap
|| !m_doubleBufferingBitmap
->Ok())
535 // If we couldn't create a new bitmap, perhaps because resources were low,
536 // then don't complain, just don't double-buffer
537 if (m_doubleBufferingBitmap
)
538 delete m_doubleBufferingBitmap
;
539 m_doubleBufferingBitmap
= (wxBitmap
*) NULL
;
540 useDoubleBuffering
= FALSE
;
544 if (useDoubleBuffering
)
546 wxPaintDC
paintDC(this);
547 wxMemoryDC
dc(& paintDC
);
548 dc
.SelectObject(* m_doubleBufferingBitmap
);
552 int vertScrollBarWidth
= m_scrollWidth
;
553 int horizScrollBarHeight
= m_scrollWidth
;
554 if (m_vScrollBar
&& !m_vScrollBar
->IsShown())
555 vertScrollBarWidth
= 0;
556 if (m_hScrollBar
&& !m_hScrollBar
->IsShown())
557 horizScrollBarHeight
= 0;
559 paintDC
.Blit(m_leftOfSheet
, m_topOfSheet
, w
- vertScrollBarWidth
- m_leftOfSheet
, h
- horizScrollBarHeight
- m_topOfSheet
,
560 &dc
, m_leftOfSheet
, m_topOfSheet
, wxCOPY
);
562 dc
.SelectObject(wxNullBitmap
);
571 void wxGenericGrid::PaintGrid(wxDC
& dc
)
574 dc
.SetOptimization(FALSE
);
576 SetGridClippingRegion(& dc
);
578 DrawLabelAreas(& dc
);
580 DrawEditableArea(& dc
);
581 DrawColumnLabels(& dc
);
586 /* Hilight present cell */
587 SetCurrentRect(m_wCursorRow
, m_wCursorColumn
);
588 if (m_currentRectVisible
&& (wxIPE_HIGHLIGHT
|| !(m_editable
&& m_editInPlace
)))
589 HighlightCell(& dc
, TRUE
);
591 dc
.DestroyClippingRegion();
592 dc
.SetOptimization(TRUE
);
596 // Erase (some of) the background.
597 // Currently, a Windows-only optimisation.
598 void wxGenericGrid::OnEraseBackground(wxEraseEvent
& WXUNUSED(event
) )
602 dc
.SetOptimization(FALSE
);
605 GetClientSize(& w
, & h
);
606 dc
.SetBrush(*wxLIGHT_GREY_BRUSH
);
607 dc
.SetPen(*wxLIGHT_GREY_PEN
);
609 if (m_hScrollBar
&& m_hScrollBar
->IsShown() && m_vScrollBar
&& m_vScrollBar
->IsShown())
611 dc
.DrawRectangle(w
- m_scrollWidth
, h
- m_scrollWidth
, m_scrollWidth
, m_scrollWidth
);
614 dc
.SetOptimization(TRUE
);
619 void wxGenericGrid::DrawLabelAreas(wxDC
*dc
)
622 GetClientSize(&cw
, &ch
);
624 dc
->SetPen(*wxTRANSPARENT_PEN
);
625 // dc->SetBrush(*dc->GetBackground());
627 // Should blank out any area which isn't going to be painted over.
628 // dc->DrawRectangle(m_leftOfSheet, m_bottomOfSheet, cw - m_leftOfSheet, ch - m_bottomOfSheet);
629 // dc->DrawRectangle(m_rightOfSheet, m_topOfSheet, cw - m_rightOfSheet, ch - m_topOfSheet);
631 // Paint the label areas
632 dc
->SetBrush(m_labelBackgroundBrush
);
633 // dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, m_rightOfSheet - m_leftOfSheet + 1, m_horizontalLabelHeight + 1);
634 dc
->DrawRectangle(m_leftOfSheet
, m_topOfSheet
, cw
-m_leftOfSheet
, m_horizontalLabelHeight
+ 1);
635 // dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, m_verticalLabelWidth + 1, m_bottomOfSheet - m_topOfSheet + 1);
636 dc
->DrawRectangle(m_leftOfSheet
, m_topOfSheet
, m_verticalLabelWidth
+ 1, ch
-m_topOfSheet
);
639 void wxGenericGrid::DrawEditableArea(wxDC
*dc
)
642 GetClientSize(&cw
, &ch
);
644 dc
->SetPen(*wxTRANSPARENT_PEN
);
645 dc
->SetBrush(*wxTheBrushList
->FindOrCreateBrush(m_cellBackgroundColour
, wxSOLID
));
646 // dc->DrawRectangle(m_leftOfSheet+m_verticalLabelWidth, m_topOfSheet+m_horizontalLabelHeight,
647 // m_rightOfSheet-(m_leftOfSheet+m_verticalLabelWidth) + 1, m_bottomOfSheet - (m_topOfSheet+m_horizontalLabelHeight) + 1);
648 dc
->DrawRectangle(m_leftOfSheet
+m_verticalLabelWidth
, m_topOfSheet
+m_horizontalLabelHeight
,
649 cw
-(m_leftOfSheet
+m_verticalLabelWidth
), ch
- (m_topOfSheet
+m_horizontalLabelHeight
));
652 void wxGenericGrid::DrawGridLines(wxDC
*dc
)
655 GetClientSize(&cw
, &ch
);
659 if (m_divisionPen
.Ok())
661 dc
->SetPen(m_divisionPen
);
663 int heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
665 // Draw horizontal grey lines for cells
666 for (i
= m_scrollPosY
; i
< (m_totalRows
+1); i
++)
668 if (heightCount
> ch
)
672 dc
->DrawLine(m_leftOfSheet
, heightCount
,
675 heightCount
+= m_rowHeights
[i
];
680 if (m_verticalLabelWidth
> 0)
682 dc
->SetPen(*wxBLACK_PEN
);
684 // Draw horizontal black lines for row labels
685 int heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
686 for (i
= m_scrollPosY
; i
< (m_totalRows
+1); i
++)
688 if (heightCount
> ch
)
692 dc
->DrawLine(m_leftOfSheet
, heightCount
,
693 m_verticalLabelWidth
, heightCount
);
695 heightCount
+= m_rowHeights
[i
];
698 // Draw a black vertical line for row number cells
699 dc
->DrawLine(m_leftOfSheet
+ m_verticalLabelWidth
, m_topOfSheet
,
700 m_leftOfSheet
+ m_verticalLabelWidth
, ch
);
701 // First vertical line
702 dc
->DrawLine(m_leftOfSheet
, m_topOfSheet
, m_leftOfSheet
, ch
);
704 dc
->SetPen(*wxWHITE_PEN
);
706 // Draw highlights on row labels
707 heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
708 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
710 if (heightCount
> ch
)
714 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
715 m_verticalLabelWidth
, heightCount
+1);
716 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
717 m_leftOfSheet
+1, heightCount
+ m_rowHeights
[i
] - 1);
718 heightCount
+= m_rowHeights
[i
];
721 // Last one - down to the floor.
722 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
723 m_verticalLabelWidth
, heightCount
+1);
724 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
725 m_leftOfSheet
+1, ch
);
729 if (m_divisionPen
.Ok())
731 dc
->SetPen(m_divisionPen
);
733 // Draw vertical grey lines for cells
734 int widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
735 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
741 // Skip the first one
742 if (i
!= m_scrollPosX
)
744 dc
->DrawLine(widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
,
745 widthCount
, m_bottomOfSheet
);
747 widthCount
+= m_colWidths
[i
];
751 dc
->DrawLine(widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
,
752 widthCount
, m_bottomOfSheet
);
755 dc
->SetPen(*wxBLACK_PEN
);
757 // Draw two black horizontal lines for column number cells
759 m_leftOfSheet
, m_topOfSheet
,
761 dc
->DrawLine(m_leftOfSheet
, m_topOfSheet
+ m_horizontalLabelHeight
,
762 cw
, m_topOfSheet
+ m_horizontalLabelHeight
);
764 if (m_horizontalLabelHeight
> 0)
766 int widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
768 // Draw black vertical lines for column number cells
769 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
775 dc
->DrawLine(widthCount
, m_topOfSheet
,
776 widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
);
777 widthCount
+= m_colWidths
[i
];
782 dc
->DrawLine(widthCount
, m_topOfSheet
,
783 widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
);
786 dc
->SetPen(*wxWHITE_PEN
);
787 widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
789 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
795 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
796 widthCount
+m_colWidths
[i
], m_topOfSheet
+1);
797 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
798 widthCount
+1, m_topOfSheet
+m_horizontalLabelHeight
);
799 widthCount
+= m_colWidths
[i
];
802 // Last one - to the right side of the canvas.
803 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
805 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
806 widthCount
+1, m_topOfSheet
+m_horizontalLabelHeight
);
811 void wxGenericGrid::DrawColumnLabels(wxDC
*dc
)
814 GetClientSize(&cw
, &ch
);
816 if (m_horizontalLabelHeight
== 0)
822 // Draw letters for columns
823 rect
.y
= m_topOfSheet
+ 1;
824 rect
.height
= m_horizontalLabelHeight
- 1;
826 dc
->SetTextBackground(m_labelBackgroundColour
);
827 dc
->SetBackgroundMode(wxTRANSPARENT
);
828 // dc->SetTextForeground(m_labelTextColour);
830 int widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
831 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
837 rect
.x
= 1 + widthCount
;
838 rect
.width
= m_colWidths
[i
];
839 DrawColumnLabel(dc
, &rect
, i
);
841 widthCount
+= m_colWidths
[i
];
846 void wxGenericGrid::DrawColumnLabel(wxDC
*dc
, wxRect
*rect
, int col
)
848 wxGridCell
*cell
= GetLabelCell(wxHORIZONTAL
, col
);
857 dc
->SetTextForeground(GetLabelTextColour());
858 dc
->SetFont(GetLabelTextFont());
859 if ( !cell
->GetTextValue().IsNull() )
860 DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, GetLabelAlignment(wxHORIZONTAL
));
864 void wxGenericGrid::DrawRowLabels(wxDC
*dc
)
867 GetClientSize(&cw
, &ch
);
869 if (m_verticalLabelWidth
== 0)
875 // Draw numbers for rows
876 rect
.x
= m_leftOfSheet
;
877 rect
.width
= m_verticalLabelWidth
;
879 int heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
881 dc
->SetTextBackground(m_labelBackgroundColour
);
882 dc
->SetBackgroundMode(wxTRANSPARENT
);
884 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
886 if (heightCount
> ch
)
890 rect
.y
= 1 + heightCount
;
891 rect
.height
= m_rowHeights
[i
];
892 DrawRowLabel(dc
, &rect
, i
);
894 heightCount
+= m_rowHeights
[i
];
899 void wxGenericGrid::DrawRowLabel(wxDC
*dc
, wxRect
*rect
, int row
)
901 wxGridCell
*cell
= GetLabelCell(wxVERTICAL
, row
);
910 dc
->SetTextForeground(GetLabelTextColour());
911 dc
->SetFont(GetLabelTextFont());
912 if ( !cell
->GetTextValue().IsNull() )
913 DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, GetLabelAlignment(wxVERTICAL
));
917 void wxGenericGrid::DrawCells(wxDC
*dc
)
920 GetClientSize(&cw
, &ch
);
924 // Draw value corresponding to each cell
925 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
927 for (j
= m_scrollPosX
; j
< m_totalCols
; j
++)
929 SetCurrentRect(i
, j
, cw
, ch
);
930 if (m_currentRectVisible
)
932 DrawCellBackground(dc
, &m_currentRect
, i
, j
);
933 DrawCellValue(dc
, &m_currentRect
, i
, j
);
935 if (m_currentRect
.x
> cw
)
938 if (m_currentRect
.y
> ch
)
941 dc
->SetBackgroundMode(wxSOLID
);
942 dc
->SetPen(*wxBLACK_PEN
);
945 void wxGenericGrid::DrawCellBackground(wxDC
*dc
, wxRect
*rect
, int row
, int col
)
947 wxGridCell
*cell
= GetCell(row
, col
);
950 dc
->SetBrush(cell
->GetBackgroundBrush());
951 dc
->SetPen(*wxTRANSPARENT_PEN
);
953 #if 0 // In wxWin 2.0 the dc code is exact. RR.
955 dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
-1, rect
->height
-1);
957 dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
, rect
->height
);
961 dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
-1, rect
->height
-1);
963 dc
->SetPen(*wxBLACK_PEN
);
967 void wxGenericGrid::DrawCellValue(wxDC
*dc
, wxRect
*rect
, int row
, int col
)
969 wxGridCell
*cell
= GetCell(row
, col
);
972 wxBitmap
*bitmap
= cell
->GetCellBitmap();
982 DrawBitmapRect(dc
, bitmap
, &rect2
, cell
->GetAlignment());
986 dc
->SetBackgroundMode(wxTRANSPARENT
);
987 dc
->SetTextForeground(cell
->GetTextColour());
988 dc
->SetFont(cell
->GetFont());
990 if ( !cell
->GetTextValue().IsNull() )
991 DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, cell
->GetAlignment());
996 void wxGenericGrid::AdjustScrollbars()
999 GetClientSize(&cw
, &ch
);
1001 // We find the view size by seeing how many rows/cols fit on
1002 // the current view.
1003 // BUT... this means that the scrollbar should be adjusted every time
1004 // it's scrolled, as well as when sized, because with variable size rows/cols,
1005 // the number of rows/col visible on the view differs according to what bit
1006 // you're looking at. The object length is always the same, but the
1007 // view length differs.
1009 // Since this may not be known until the end of this function, we should probably call AdjustScrollbars
1011 int vertScrollBarWidth
= m_scrollWidth
;
1012 int horizScrollBarHeight
= m_scrollWidth
;
1013 if (m_vScrollBar
&& !m_vScrollBar
->IsShown())
1014 vertScrollBarWidth
= 0;
1015 if (m_hScrollBar
&& !m_hScrollBar
->IsShown())
1016 horizScrollBarHeight
= 0;
1018 int noHorizSteps
= 0;
1019 int noVertSteps
= 0;
1021 if (m_totalGridWidth
+ vertScrollBarWidth
> cw
)
1027 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1029 widthCount
+= m_colWidths
[i
];
1030 // A partial bit doesn't count, we still have to scroll to see the
1032 if (widthCount
+ m_leftOfSheet
+ m_verticalLabelWidth
> (cw
-vertScrollBarWidth
))
1040 m_viewWidth
= noHorizSteps
;
1042 if (m_totalGridHeight
+ horizScrollBarHeight
> ch
)
1044 int heightCount
= 0;
1048 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1050 heightCount
+= m_rowHeights
[i
];
1051 // A partial bit doesn't count, we still have to scroll to see the
1053 if (heightCount
+ m_topOfSheet
+ m_horizontalLabelHeight
> (ch
-horizScrollBarHeight
))
1062 m_viewHeight
= noVertSteps
;
1064 if (m_totalGridWidth
+ vertScrollBarWidth
<= cw
)
1067 m_hScrollBar
->Show(FALSE
);
1073 m_hScrollBar
->Show(TRUE
);
1076 if (m_totalGridHeight
+ horizScrollBarHeight
<= ch
)
1079 m_vScrollBar
->Show(FALSE
);
1085 m_vScrollBar
->Show(TRUE
);
1088 UpdateDimensions(); // Necessary in case m_scrollPosX/Y changed
1090 vertScrollBarWidth
= m_scrollWidth
;
1091 horizScrollBarHeight
= m_scrollWidth
;
1092 if (m_vScrollBar
&& !m_vScrollBar
->IsShown())
1093 vertScrollBarWidth
= 0;
1094 if (m_hScrollBar
&& !m_hScrollBar
->IsShown())
1095 horizScrollBarHeight
= 0;
1097 if (m_hScrollBar
&& m_hScrollBar
->IsShown())
1099 int nCols
= GetCols();
1100 m_hScrollBar
->SetScrollbar(m_hScrollBar
->GetThumbPosition(), wxMax(noHorizSteps
, 1), (noHorizSteps
== 0) ? 1 : nCols
, wxMax(noHorizSteps
, 1));
1103 m_hScrollBar->SetSize(m_leftOfSheet, ch - m_scrollWidth -2, // why -2 ? Robert.
1104 cw - vertScrollBarWidth - m_leftOfSheet, m_scrollWidth);
1106 m_hScrollBar
->SetSize(m_leftOfSheet
, ch
- m_scrollWidth
,
1107 cw
- vertScrollBarWidth
- m_leftOfSheet
, m_scrollWidth
);
1111 if (m_vScrollBar
&& m_vScrollBar
->IsShown())
1113 int nRows
= GetRows();
1115 m_vScrollBar
->SetScrollbar(m_vScrollBar
->GetThumbPosition(), wxMax(noVertSteps
, 1), (noVertSteps
== 0) ? 1 : nRows
, wxMax(noVertSteps
, 1));
1116 m_vScrollBar
->SetSize(cw
- m_scrollWidth
, m_topOfSheet
,
1117 m_scrollWidth
, ch
- m_topOfSheet
- horizScrollBarHeight
);
1121 void wxGenericGrid::OnSize(wxSizeEvent
& WXUNUSED(event
) )
1123 if (!m_vScrollBar
|| !m_hScrollBar
)
1129 GetClientSize(&cw
, &ch
);
1131 if (m_editCreated
&& m_editingPanel
&& GetTextItem() && GetTextItem()->IsShown())
1133 m_editingPanel
->SetSize(0, 0, cw
, m_editControlPosition
.height
+ m_editControlPosition
.y
+ 2);
1134 GetTextItem()->SetSize(m_editControlPosition
.x
, m_editControlPosition
.y
,
1135 cw
- 2*m_editControlPosition
.x
, m_editControlPosition
.height
);
1139 bool wxGenericGrid::CellHitTest(int x
, int y
, int *row
, int *col
)
1141 // Find the selected cell and call OnSelectCell
1142 if (x
>= (m_leftOfSheet
+ m_verticalLabelWidth
) && y
>= (m_topOfSheet
+ m_horizontalLabelHeight
) &&
1143 x
<= m_rightOfSheet
&& y
<= m_bottomOfSheet
)
1145 // Calculate the cell number from x and y
1146 x
-= (m_verticalLabelWidth
+ m_leftOfSheet
);
1147 y
-= (m_topOfSheet
+ m_horizontalLabelHeight
);
1151 // Now we need to do a hit test for which row we're on
1152 int currentHeight
= 0;
1153 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1155 if (y
>= currentHeight
&& y
<= (currentHeight
+ m_rowHeights
[i
]))
1160 currentHeight
+= m_rowHeights
[i
];
1163 // Now we need to do a hit test for which column we're on
1164 int currentWidth
= 0;
1165 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1167 if (x
>= currentWidth
&& x
<= (currentWidth
+ m_colWidths
[i
]))
1172 currentWidth
+= m_colWidths
[i
];
1179 bool wxGenericGrid::LabelSashHitTest(int x
, int y
, int *orientation
, int *rowOrCol
, int *startPos
)
1184 if (x
>= (m_leftOfSheet
+ m_verticalLabelWidth
) && y
>= m_topOfSheet
&&
1185 x
<= m_rightOfSheet
&& y
<= (m_topOfSheet
+ m_horizontalLabelHeight
))
1187 // We may be on a column label sash.
1188 int currentWidth
= m_leftOfSheet
+ m_verticalLabelWidth
;
1189 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1191 if (x
>= (currentWidth
+ m_colWidths
[i
] - tolerance
) && x
<= (currentWidth
+ m_colWidths
[i
] + tolerance
))
1193 *orientation
= wxHORIZONTAL
;
1195 *startPos
= currentWidth
;
1198 currentWidth
+= m_colWidths
[i
];
1202 else if (x
>= m_leftOfSheet
&& y
>= (m_topOfSheet
+ m_horizontalLabelHeight
) &&
1203 x
<= (m_leftOfSheet
+ m_verticalLabelWidth
) && y
<= m_bottomOfSheet
)
1205 // We may be on a row label sash.
1206 int currentHeight
= m_topOfSheet
+ m_horizontalLabelHeight
;
1207 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1209 if (y
>= (currentHeight
+ m_rowHeights
[i
] - tolerance
) && y
<= (currentHeight
+ m_rowHeights
[i
] + tolerance
))
1211 *orientation
= wxVERTICAL
;
1213 *startPos
= currentHeight
;
1216 currentHeight
+= m_rowHeights
[i
];
1223 bool wxGenericGrid::LabelHitTest(int x
, int y
, int *row
, int *col
)
1225 // Find the selected label
1226 if (x
>= m_leftOfSheet
&& y
>= m_topOfSheet
&&
1227 x
<= m_rightOfSheet
&& y
<= m_bottomOfSheet
)
1229 // Calculate the cell number from x and y
1235 // Now we need to do a hit test for which row we're on
1236 int currentHeight
= m_horizontalLabelHeight
;
1237 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1239 if (y
>= currentHeight
&& y
<= (currentHeight
+ m_rowHeights
[i
]))
1244 currentHeight
+= m_rowHeights
[i
];
1246 if (y
>= 0 && y
<= m_horizontalLabelHeight
)
1251 // Now we need to do a hit test for which column we're on
1252 int currentWidth
= m_verticalLabelWidth
;
1253 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1255 if (x
>= currentWidth
&& x
<= (currentWidth
+ m_colWidths
[i
]))
1260 currentWidth
+= m_colWidths
[i
];
1262 if (x
>= 0 && x
<= m_verticalLabelWidth
)
1267 if ((*col
== -1) || (*row
== -1))
1275 void wxGenericGrid::OnMouseEvent(wxMouseEvent
& ev
)
1279 wxClientDC
dc(this);
1283 if (CellHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1285 OnSelectCellImplementation(& dc
, row
, col
);
1287 //OnCellLeftClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1288 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CELL_LCLICK
, this,
1289 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1290 ev
.ControlDown(), ev
.ShiftDown());
1291 GetEventHandler()->ProcessEvent(g_evt
);
1294 if (LabelHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1296 //OnLabelLeftClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1297 wxGridEvent
g_evt(GetId(), wxEVT_GRID_LABEL_LCLICK
, this,
1298 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1299 ev
.ControlDown(), ev
.ShiftDown());
1300 GetEventHandler()->ProcessEvent(g_evt
);
1305 else if (ev
.Dragging() && ev
.LeftIsDown())
1307 switch (m_dragStatus
)
1309 case wxGRID_DRAG_NONE
:
1312 if (LabelSashHitTest((int)ev
.GetX(), (int)ev
.GetY(), &orientation
, &m_dragRowOrCol
, &m_dragStartPosition
))
1314 if (orientation
== wxHORIZONTAL
)
1316 m_dragStatus
= wxGRID_DRAG_LEFT_RIGHT
;
1317 SetCursor(m_horizontalSashCursor
);
1318 m_dragLastPosition
= (int)ev
.GetX();
1322 m_dragStatus
= wxGRID_DRAG_UP_DOWN
;
1323 SetCursor(m_verticalSashCursor
);
1324 m_dragLastPosition
= (int)ev
.GetY();
1326 wxClientDC
dc(this);
1328 dc
.SetLogicalFunction(wxINVERT
);
1329 if (orientation
== wxHORIZONTAL
)
1330 dc
.DrawLine((int)ev
.GetX(), m_topOfSheet
, (int)ev
.GetX(), m_bottomOfSheet
);
1332 dc
.DrawLine(m_leftOfSheet
, (int)ev
.GetY(), m_rightOfSheet
, (int)ev
.GetY());
1339 case wxGRID_DRAG_LEFT_RIGHT
:
1341 wxClientDC
dc(this);
1343 dc
.SetLogicalFunction(wxINVERT
);
1344 dc
.DrawLine(m_dragLastPosition
, m_topOfSheet
, m_dragLastPosition
, m_bottomOfSheet
);
1346 dc
.DrawLine((int)ev
.GetX(), m_topOfSheet
, (int)ev
.GetX(), m_bottomOfSheet
);
1349 m_dragLastPosition
= (int)ev
.GetX();
1350 SetCursor(m_horizontalSashCursor
);
1353 case wxGRID_DRAG_UP_DOWN
:
1355 wxClientDC
dc(this);
1357 dc
.SetLogicalFunction(wxINVERT
);
1358 dc
.DrawLine(m_leftOfSheet
, m_dragLastPosition
, m_rightOfSheet
, m_dragLastPosition
);
1360 dc
.DrawLine(m_leftOfSheet
, (int)ev
.GetY(), m_rightOfSheet
, (int)ev
.GetY());
1363 m_dragLastPosition
= (int)ev
.GetY();
1364 SetCursor(m_verticalSashCursor
);
1369 else if (ev
.Moving())
1371 int rowOrCol
, orientation
, startPos
;
1372 if (LabelSashHitTest((int)ev
.GetX(), (int)ev
.GetY(), &orientation
, &rowOrCol
, &startPos
))
1374 if (orientation
== wxHORIZONTAL
)
1375 SetCursor(m_horizontalSashCursor
);
1377 SetCursor(m_verticalSashCursor
);
1380 SetCursor(*wxSTANDARD_CURSOR
);
1382 else if (ev
.LeftUp())
1384 switch (m_dragStatus
)
1386 case wxGRID_DRAG_LEFT_RIGHT
:
1388 wxClientDC
dc(this);
1390 dc
.SetLogicalFunction(wxINVERT
);
1391 dc
.DrawLine(m_dragLastPosition
, m_topOfSheet
, m_dragLastPosition
, m_bottomOfSheet
);
1392 dc
.SetLogicalFunction(wxCOPY
);
1396 if (ev
.GetX() > m_dragStartPosition
)
1398 m_colWidths
[m_dragRowOrCol
] = (short)(ev
.GetX() - m_dragStartPosition
);
1403 SetCursor(*wxSTANDARD_CURSOR
);
1405 GetClientSize(&cw
, &ch
);
1410 case wxGRID_DRAG_UP_DOWN
:
1412 wxClientDC
dc(this);
1414 dc
.SetLogicalFunction(wxINVERT
);
1415 dc
.DrawLine(m_leftOfSheet
, m_dragLastPosition
, m_rightOfSheet
, m_dragLastPosition
);
1416 dc
.SetLogicalFunction(wxCOPY
);
1420 if (ev
.GetY() > m_dragStartPosition
)
1422 m_rowHeights
[m_dragRowOrCol
] = (short)(ev
.GetY() - m_dragStartPosition
);
1427 SetCursor(*wxSTANDARD_CURSOR
);
1431 m_dragStatus
= wxGRID_DRAG_NONE
;
1433 else if (ev
.RightDown())
1436 if (CellHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1438 //OnCellRightClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1439 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CELL_RCLICK
, this,
1440 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1441 ev
.ControlDown(), ev
.ShiftDown());
1442 GetEventHandler()->ProcessEvent(g_evt
);
1445 if (LabelHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1447 //OnLabelRightClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1448 wxGridEvent
g_evt(GetId(), wxEVT_GRID_LABEL_RCLICK
, this,
1449 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1450 ev
.ControlDown(), ev
.ShiftDown());
1451 GetEventHandler()->ProcessEvent(g_evt
);
1456 void wxGenericGrid::OnSelectCellImplementation(wxDC
*dc
, int row
, int col
)
1458 m_wCursorColumn
= col
;
1461 //OnChangeSelectionLabel();
1462 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_SEL_LABEL
, this);
1463 GetEventHandler()->ProcessEvent(g_evt
);
1465 SetGridClippingRegion(dc
);
1467 // Remove the highlight from the old cell
1468 if ( m_currentRectVisible
&& (wxIPE_HIGHLIGHT
|| !(m_editable
&& m_editInPlace
)))
1470 HighlightCell(dc
, FALSE
);
1474 // Highlight the new cell and copy its content to the edit control
1475 SetCurrentRect(m_wCursorRow
, m_wCursorColumn
);
1476 wxGridCell
*cell
= GetCell(m_wCursorRow
, m_wCursorColumn
);
1479 if ( cell
->GetTextValue().IsNull() )
1480 m_textItem
->SetValue("");
1482 m_textItem
->SetValue(cell
->GetTextValue());
1485 SetGridClippingRegion(dc
);
1488 if ( m_editable
&& m_editInPlace
)
1490 int x
, y
, width
, height
;
1491 if ( m_currentRect
.x
<= 0 )
1494 width
= m_currentRect
.width
+ wxIPE_ADJUST
;
1498 x
= m_currentRect
.x
- wxIPE_ADJUST
;
1499 width
= m_currentRect
.width
+ wxIPE_ADJUST
*2;
1502 if ( m_currentRect
.y
<= 0 )
1505 height
= m_currentRect
.height
+ wxIPE_ADJUST
;
1509 y
= m_currentRect
.y
- wxIPE_ADJUST
;
1510 height
= m_currentRect
.height
+ wxIPE_ADJUST
*2;
1513 m_inPlaceTextItem
->SetSize( x
, y
, width
, height
);
1516 m_inPlaceTextItem
->SetFont( cell
->GetFont() );
1517 m_inPlaceTextItem
->SetBackgroundColour(cell
->GetBackgroundColour());
1518 m_inPlaceTextItem
->SetForegroundColour(cell
->GetTextColour());
1520 if ( cell
->GetTextValue().IsNull() ) {
1521 m_inPlaceTextItem
->SetValue( "" );
1524 m_inPlaceTextItem
->SetValue( cell
->GetTextValue() );
1528 m_inPlaceTextItem
->Show(TRUE
);
1529 m_inPlaceTextItem
->SetFocus();
1530 #if defined(__VISAGECPP__)
1532 int highlight
= wxIPE_HIGHLIGHT
;
1534 HighlightCell(dc
, TRUE
);
1537 if (wxIPE_HIGHLIGHT
!= 0)
1538 HighlightCell(dc
, TRUE
);
1541 else if (!wxIPE_HIGHLIGHT
)
1543 // 1) Why isn't this needed for Windows??
1544 // Probably because of the SetValue?? JS.
1545 // 2) Arrrrrgh. This isn't needed anywhere,
1546 // of course. One hour of debugging... RR.
1548 // 3) It *is* needed for Motif - michael
1550 // 4) It *seems* to be needed whenever
1551 // wxIPE_HIGHLIGHT is not set (i.e.
1552 // for both wxGTK and wxMOTIF)... SN.
1553 if (!(m_editable
&& m_editInPlace
)))
1554 HighlightCell(dc
, TRUE
);
1557 dc
->DestroyClippingRegion();
1559 OnSelectCell(row
, col
);
1560 wxGridEvent
g_evt2(GetId(), wxEVT_GRID_SELECT_CELL
, this, row
, col
);
1561 GetEventHandler()->ProcessEvent(g_evt2
);
1564 wxGridCell
*wxGenericGrid::OnCreateCell()
1566 return new wxGridCell(this);
1569 void wxGenericGrid::OnChangeLabels()
1573 for (i
= 0; i
< m_totalRows
; i
++)
1575 sprintf(buf
, "%d", i
+1);
1576 SetLabelValue(wxVERTICAL
, buf
, i
);
1578 // A...Z,AA...ZZ,AAA...ZZZ, etc.
1579 for (i
= 0; i
< m_totalCols
; i
++)
1582 int noTimes
= (i
/26 + 1);
1583 int ch
= (i
% 26) + 65;
1585 for (j
= 0; j
< noTimes
; j
++)
1588 sprintf(buf2
, "%c", (char)ch
);
1591 SetLabelValue(wxHORIZONTAL
, buf
, i
);
1595 void wxGenericGrid::OnChangeSelectionLabel()
1600 wxString
rowLabel(GetLabelValue(wxVERTICAL
, GetCursorRow()));
1601 wxString
colLabel(GetLabelValue(wxHORIZONTAL
, GetCursorColumn()));
1603 wxString newLabel
= colLabel
+ rowLabel
;
1604 if ((newLabel
.Length() > 0) && (newLabel
.Length() <= 8) && GetTextItem())
1606 // GetTextItem()->SetLabel(newLabel);
1610 void wxGenericGrid::HighlightCell(wxDC
*dc
, bool doHighlight
)
1612 wxPen savePen
= dc
->GetPen();
1614 dc
->SetPen(m_highlightPen
);
1616 dc
->SetPen(*wxThePenList
->FindOrCreatePen(m_cellBackgroundColour
, 1, wxSOLID
));
1619 dc
->DrawLine( m_currentRect
.x
+ 1,
1620 m_currentRect
.y
+ 1,
1621 m_currentRect
.x
+ m_currentRect
.width
- 1,
1622 m_currentRect
.y
+ 1);
1624 dc
->DrawLine( m_currentRect
.x
+ m_currentRect
.width
- 1,
1625 m_currentRect
.y
+ 1,
1626 m_currentRect
.x
+ m_currentRect
.width
- 1,
1627 m_currentRect
.y
+ m_currentRect
.height
- 1 );
1629 dc
->DrawLine( m_currentRect
.x
+ m_currentRect
.width
- 1,
1630 m_currentRect
.y
+ m_currentRect
.height
- 1,
1631 m_currentRect
.x
+ 1,
1632 m_currentRect
.y
+ m_currentRect
.height
- 1);
1634 dc
->DrawLine( m_currentRect
.x
+ 1,
1635 m_currentRect
.y
+ m_currentRect
.height
- 1,
1636 m_currentRect
.x
+ 1,
1637 m_currentRect
.y
+ 1);
1639 dc
->SetPen(savePen
);
1642 void wxGenericGrid::DrawCellText()
1644 if (!m_currentRectVisible
)
1647 wxGridCell
*cell
= GetCell(GetCursorRow(), GetCursorColumn());
1651 wxClientDC
dc(this);
1654 SetGridClippingRegion(& dc
);
1656 dc
.SetBackgroundMode(wxTRANSPARENT
);
1657 dc
.SetBrush(cell
->GetBackgroundBrush());
1659 wxString editValue
= m_textItem
->GetValue();
1662 rect
= m_currentRect
;
1668 // FIXME: what's this string of spaces supposed to represent?
1669 DrawTextRect(& dc
, " ", &rect
, wxLEFT
);
1670 DrawTextRect(& dc
, editValue
, &rect
, cell
->GetAlignment());
1672 dc
.DestroyClippingRegion();
1674 dc
.SetBackgroundMode(wxSOLID
);
1679 void wxGenericGrid::SetCurrentRect(int Row
, int Column
, int canvasW
, int canvasH
)
1681 int currentWidth
= m_leftOfSheet
+ m_verticalLabelWidth
;
1683 for (i
= m_scrollPosX
; i
< Column
; i
++)
1684 currentWidth
+= m_colWidths
[i
];
1686 int currentHeight
= m_topOfSheet
+ m_horizontalLabelHeight
;
1687 for (i
= m_scrollPosY
; i
< Row
; i
++)
1688 currentHeight
+= m_rowHeights
[i
];
1690 m_currentRect
.x
= currentWidth
;
1691 m_currentRect
.y
= currentHeight
;
1692 m_currentRect
.width
= m_colWidths
? (m_colWidths
[Column
]) : 0;
1693 m_currentRect
.height
= m_rowHeights
? (m_rowHeights
[Row
]) : 0;
1695 if (Row
< m_scrollPosY
|| Column
< m_scrollPosX
)
1696 m_currentRectVisible
= FALSE
;
1697 else if ((canvasW
!= -1 && canvasH
!= -1) && (m_currentRect
.x
> canvasW
|| m_currentRect
.y
> canvasH
))
1698 m_currentRectVisible
= FALSE
;
1699 else m_currentRectVisible
= TRUE
;
1702 static bool wxRectIntersection(wxRect
*rect1
, wxRect
*rect2
, wxRect
*rect3
)
1704 int x2_1
= rect1
->x
+ rect1
->width
;
1705 int y2_1
= rect1
->y
+ rect1
->height
;
1707 int x2_2
= rect2
->x
+ rect2
->width
;
1708 int y2_2
= rect2
->y
+ rect2
->height
;
1712 // Check for intersection
1713 if ((rect1
->x
> x2_2
) || (rect2
->x
> x2_1
) ||
1714 (rect1
->y
> y2_2
) || (rect2
->y
> y2_1
))
1717 rect3
->x
= rect3
->y
= rect3
->width
= rect3
->height
= 0;
1721 if (rect1
->x
> rect2
->x
)
1722 rect3
->x
= rect1
->x
;
1724 rect3
->x
= rect2
->x
;
1725 if (rect1
->y
> rect2
->y
)
1726 rect3
->y
= rect1
->y
;
1728 rect3
->y
= rect2
->y
;
1739 rect3
->width
= (int)(x2_3
- rect3
->x
);
1740 rect3
->height
= (int)(y2_3
- rect3
->y
);
1744 void wxGenericGrid::DrawTextRect(wxDC
*dc
, const wxString
& text
, wxRect
*rect
, int flag
)
1748 // Ultimately, this functionality should be built into wxWindows,
1749 // and optimized for each platform. E.g. on Windows, use DrawText
1750 // passing a clipping rectangle, so that the wxWindows clipping region
1751 // does not have to be used to implement this.
1753 // If we're already clipping, we need to find the intersection
1754 // between current clipping area and text clipping area.
1758 long clipX
, clipY
, clipW
, clipH
;
1759 dc
->GetClippingBox(&clipX
, &clipY
, &clipW
, &clipH
);
1760 clipRect
.x
= (int)clipX
; clipRect
.y
= (int)clipY
;
1761 clipRect
.width
= (int)clipW
; clipRect
.height
= (int)clipH
;
1763 bool alreadyClipping
= TRUE
;
1765 if (clipRect
.x
== 0 && clipRect
.y
== 0 && clipRect
.width
== 0 && clipRect
.height
== 0)
1767 alreadyClipping
= FALSE
;
1768 clipRect2
.x
= rect
->x
; clipRect2
.y
= rect
->y
;
1769 clipRect2
.width
= rect
->width
; clipRect2
.height
= rect
->height
;
1773 // Find intersection.
1774 if (!wxRectIntersection(rect
, &clipRect
, &clipRect2
))
1778 if (alreadyClipping
)
1779 dc
->DestroyClippingRegion();
1781 dc
->SetClippingRegion(clipRect2
.x
, clipRect2
.y
, clipRect2
.width
, clipRect2
.height
);
1782 long textWidth
, textHeight
;
1784 dc
->GetTextExtent(text
, &textWidth
, &textHeight
);
1792 x
= (rect
->x
+ rect
->width
- textWidth
- (float)1.0);
1793 y
= (rect
->y
+ (rect
->height
- textHeight
)/(float)2.0);
1798 x
= (rect
->x
+ (rect
->width
- textWidth
)/(float)2.0);
1799 y
= (rect
->y
+ (rect
->height
- textHeight
)/(float)2.0);
1805 x
= (rect
->x
+ (float)1.0);
1806 y
= (rect
->y
+ (rect
->height
- textHeight
)/(float)2.0);
1810 dc
->DrawText(text
, (long)x
, (long)y
);
1812 dc
->DestroyClippingRegion();
1814 // Restore old clipping
1815 if (alreadyClipping
)
1816 dc
->SetClippingRegion(clipRect
.x
, clipRect
.y
, clipRect
.width
, clipRect
.height
);
1821 void wxGenericGrid::DrawBitmapRect(wxDC
*dc
, wxBitmap
*bitmap
, wxRect
*rect
, int flag
)
1825 // Ultimately, this functionality should be built into wxWindows,
1826 // and optimized for each platform. E.g. on Windows, use DrawText
1827 // passing a clipping rectangle, so that the wxWindows clipping region
1828 // does not have to be used to implement this.
1830 // If we're already clipping, we need to find the intersection
1831 // between current clipping area and text clipping area.
1835 long clipX
, clipY
, clipW
, clipH
;
1836 dc
->GetClippingBox(&clipX
, &clipY
, &clipW
, &clipH
);
1837 clipRect
.x
= (int)clipX
; clipRect
.y
= (int)clipY
;
1838 clipRect
.width
= (int)clipW
; clipRect
.height
= (int)clipH
;
1840 bool alreadyClipping
= TRUE
;
1842 if (clipRect
.x
== 0 && clipRect
.y
== 0 && clipRect
.width
== 0 && clipRect
.height
== 0)
1844 alreadyClipping
= FALSE
;
1845 clipRect2
.x
= rect
->x
; clipRect2
.y
= rect
->y
;
1846 clipRect2
.width
= rect
->width
; clipRect2
.height
= rect
->height
;
1850 // Find intersection.
1851 if (!wxRectIntersection(rect
, &clipRect
, &clipRect2
))
1855 if (alreadyClipping
)
1856 dc
->DestroyClippingRegion();
1858 dc
->SetClippingRegion(clipRect2
.x
, clipRect2
.y
, clipRect2
.width
, clipRect2
.height
);
1859 float bitmapWidth
, bitmapHeight
;
1861 bitmapWidth
= bitmap
->GetWidth();
1862 bitmapHeight
= bitmap
->GetHeight();
1870 x
= (long)(rect
->x
+ rect
->width
- bitmapWidth
- 1);
1871 y
= (long)(rect
->y
+ (rect
->height
- bitmapHeight
)/2.0);
1876 x
= (long)(rect
->x
+ (rect
->width
- bitmapWidth
)/2.0);
1877 y
= (long)(rect
->y
+ (rect
->height
- bitmapHeight
)/2.0);
1883 x
= (long)(rect
->x
+ 1);
1884 y
= (long)(rect
->y
+ (rect
->height
- bitmapHeight
)/2.0);
1889 dcTemp
.SelectObject(*bitmap
);
1891 dc
->Blit( (long)x
, (long)y
, (long)bitmapWidth
, (long)bitmapHeight
, &dcTemp
, 0, 0);
1892 dcTemp
.SelectObject(wxNullBitmap
);
1894 dc
->DestroyClippingRegion();
1896 // Restore old clipping
1897 if (alreadyClipping
)
1898 dc
->SetClippingRegion(clipRect
.x
, clipRect
.y
, clipRect
.width
, clipRect
.height
);
1903 void wxGenericGrid::OnActivate(bool active
)
1907 // Edit control should always have the focus
1908 if (GetTextItem() && GetEditable())
1910 GetTextItem()->SetFocus();
1911 wxGridCell
*cell
= GetCell(GetCursorRow(), GetCursorColumn());
1913 GetTextItem()->SetValue(cell
->GetTextValue());
1918 void wxGenericGrid::SetCellValue(const wxString
& val
, int row
, int col
)
1920 wxGridCell
*cell
= GetCell(row
, col
);
1923 cell
->SetTextValue(val
);
1925 RefreshCell(row
, col
, TRUE
);
1929 void wxGenericGrid::RefreshCell(int row
, int col
, bool setText
)
1931 // Don't refresh within a pair of batch brackets
1932 if (GetBatchCount() > 0)
1936 GetClientSize(&cw
, &ch
);
1938 SetCurrentRect(row
, col
, cw
, ch
);
1939 if (m_currentRectVisible
)
1941 wxGridCell
*cell
= GetCell(row
, col
);
1943 bool currentPos
= FALSE
;
1944 if (row
== m_wCursorRow
&& col
== m_wCursorColumn
&& GetTextItem() && GetTextItem()->IsShown() && setText
)
1946 GetTextItem()->SetValue(cell
->GetTextValue());
1949 // Gets refreshed anyway in MSW
1954 wxClientDC
dc(this);
1956 DrawCellBackground(& dc
, &m_currentRect
, row
, col
);
1957 DrawCellValue(& dc
, &m_currentRect
, row
, col
);
1963 wxString
& wxGenericGrid::GetCellValue(int row
, int col
) const
1965 static wxString
emptyString("");
1967 wxGridCell
*cell
= GetCell(row
, col
);
1969 return cell
->GetTextValue();
1974 void wxGenericGrid::SetColumnWidth(int col
, int width
)
1976 if (col
<= m_totalCols
)
1977 m_colWidths
[col
] = width
;
1980 int wxGenericGrid::GetColumnWidth(int col
) const
1982 if (col
<= m_totalCols
)
1983 return m_colWidths
[col
];
1988 void wxGenericGrid::SetRowHeight(int row
, int height
)
1990 if (row
<= m_totalRows
)
1991 m_rowHeights
[row
] = height
;
1994 int wxGenericGrid::GetRowHeight(int row
) const
1996 if (row
<= m_totalRows
)
1997 return m_rowHeights
[row
];
2002 void wxGenericGrid::SetLabelSize(int orientation
, int sz
)
2004 if (orientation
== wxHORIZONTAL
)
2005 m_horizontalLabelHeight
= sz
;
2007 m_verticalLabelWidth
= sz
;
2009 SetCurrentRect(GetCursorRow(), GetCursorColumn());
2012 int wxGenericGrid::GetLabelSize(int orientation
) const
2014 if (orientation
== wxHORIZONTAL
)
2015 return m_horizontalLabelHeight
;
2017 return m_verticalLabelWidth
;
2020 wxGridCell
*wxGenericGrid::GetLabelCell(int orientation
, int pos
) const
2022 if (orientation
== wxHORIZONTAL
)
2024 if (m_colLabelCells
&& pos
< m_totalCols
)
2025 return m_colLabelCells
[pos
];
2027 return (wxGridCell
*) NULL
;
2031 if (m_rowLabelCells
&& pos
< m_totalRows
)
2032 return m_rowLabelCells
[pos
];
2034 return (wxGridCell
*) NULL
;
2038 void wxGenericGrid::SetLabelValue(int orientation
, const wxString
& val
, int pos
)
2040 wxGridCell
*cell
= GetLabelCell(orientation
, pos
);
2042 cell
->SetTextValue(val
);
2045 wxString
& wxGenericGrid::GetLabelValue(int orientation
, int pos
) const
2047 static wxString emptyString
= "";
2048 wxGridCell
*cell
= GetLabelCell(orientation
, pos
);
2050 return cell
->GetTextValue();
2055 void wxGenericGrid::SetLabelAlignment(int orientation
, int align
)
2057 if (orientation
== wxHORIZONTAL
)
2058 m_horizontalLabelAlignment
= align
;
2060 m_verticalLabelAlignment
= align
;
2062 SetCurrentRect(GetCursorRow(), GetCursorColumn());
2065 int wxGenericGrid::GetLabelAlignment(int orientation
) const
2067 if (orientation
== wxHORIZONTAL
)
2068 return m_horizontalLabelAlignment
;
2070 return m_verticalLabelAlignment
;
2073 void wxGenericGrid::SetLabelTextColour(const wxColour
& colour
)
2075 m_labelTextColour
= colour
;
2079 void wxGenericGrid::SetLabelBackgroundColour(const wxColour
& colour
)
2081 m_labelBackgroundColour
= colour
;
2082 m_labelBackgroundBrush
= * wxTheBrushList
->FindOrCreateBrush(m_labelBackgroundColour
, wxSOLID
);
2085 void wxGenericGrid::SetEditable(bool edit
)
2090 int controlW
, controlH
;
2091 m_textItem
->GetSize(&controlW
, &controlH
);
2092 m_editControlPosition
.height
= controlH
;
2094 m_topOfSheet
= m_editControlPosition
.x
+ controlH
+ 2;
2097 m_editingPanel
->Show(TRUE
);
2098 m_textItem
->Show(TRUE
);
2099 m_textItem
->SetFocus();
2102 if (m_inPlaceTextItem
)
2104 m_inPlaceTextItem
->Show(TRUE
);
2105 m_inPlaceTextItem
->SetFocus();
2113 m_textItem
->Show(FALSE
);
2114 m_editingPanel
->Show(FALSE
);
2117 if ( m_inPlaceTextItem
)
2119 m_inPlaceTextItem
->Show(FALSE
);
2123 SetCurrentRect(GetCursorRow(), GetCursorColumn());
2126 GetClientSize(&cw
, &ch
);
2131 int m_scrollWidth = 16;
2132 GetClientSize(&cw, &ch);
2135 m_vScrollBar->SetSize(cw - m_scrollWidth, m_topOfSheet,
2136 m_scrollWidth, ch - m_topOfSheet - m_scrollWidth);
2141 void wxGenericGrid::SetEditInPlace(bool edit
)
2143 if ( m_editInPlace
!= edit
)
2145 m_editInPlace
= edit
;
2147 if ( m_editInPlace
) // switched on
2149 if ( m_currentRectVisible
&& m_editable
)
2151 m_inPlaceTextItem
->SetSize( m_currentRect
.x
-wxIPE_ADJUST
,
2152 m_currentRect
.y
-wxIPE_ADJUST
,
2153 m_currentRect
.width
+wxIPE_ADJUST
*2,
2154 m_currentRect
.height
+wxIPE_ADJUST
*2 );
2156 wxGridCell
*cell
= GetCell(m_wCursorRow
, m_wCursorColumn
);
2159 m_inPlaceTextItem
->SetFont( cell
->GetFont() );
2160 m_inPlaceTextItem
->SetBackgroundColour(cell
->GetBackgroundColour());
2161 m_inPlaceTextItem
->SetForegroundColour(cell
->GetTextColour());
2163 if ( cell
->GetTextValue().IsNull() ) {
2164 m_inPlaceTextItem
->SetValue( "" );
2167 m_inPlaceTextItem
->SetValue( cell
->GetTextValue() );
2171 m_inPlaceTextItem
->Show( TRUE
);
2172 m_inPlaceTextItem
->SetFocus();
2175 else // switched off
2177 m_inPlaceTextItem
->Show( FALSE
);
2183 void wxGenericGrid::SetCellAlignment(int flag
, int row
, int col
)
2185 wxGridCell
*cell
= GetCell(row
, col
);
2187 cell
->SetAlignment(flag
);
2190 int wxGenericGrid::GetCellAlignment(int row
, int col
) const
2192 wxGridCell
*cell
= GetCell(row
, col
);
2194 return cell
->GetAlignment();
2196 return m_cellAlignment
;
2199 void wxGenericGrid::SetCellAlignment(int flag
)
2201 m_cellAlignment
= flag
;
2203 for (i
= 0; i
< GetRows(); i
++)
2204 for (j
= 0; j
< GetCols(); j
++)
2206 GetCell(i
, j
)->SetAlignment(flag
);
2209 int wxGenericGrid::GetCellAlignment(void) const
2211 return m_cellAlignment
;
2214 void wxGenericGrid::SetCellBackgroundColour(const wxColour
& col
)
2216 m_cellBackgroundColour
= col
;
2218 for (i
= 0; i
< GetRows(); i
++)
2219 for (j
= 0; j
< GetCols(); j
++)
2221 GetCell(i
, j
)->SetBackgroundColour(col
);
2224 void wxGenericGrid::SetCellBackgroundColour(const wxColour
& val
, int row
, int col
)
2226 wxGridCell
*cell
= GetCell(row
, col
);
2229 cell
->SetBackgroundColour(val
);
2230 RefreshCell(row
, col
);
2234 wxColour
& wxGenericGrid::GetCellBackgroundColour(int row
, int col
) const
2236 wxGridCell
*cell
= GetCell(row
, col
);
2238 return cell
->GetBackgroundColour();
2240 return (wxColour
&) m_cellBackgroundColour
;
2243 void wxGenericGrid::SetCellTextColour(const wxColour
& val
, int row
, int col
)
2245 wxGridCell
*cell
= GetCell(row
, col
);
2248 cell
->SetTextColour(val
);
2249 RefreshCell(row
, col
);
2253 void wxGenericGrid::SetCellTextFont(const wxFont
& fnt
, int row
, int col
)
2255 wxGridCell
*cell
= GetCell(row
, col
);
2259 RefreshCell(row
, col
);
2263 wxFont
& wxGenericGrid::GetCellTextFont(int row
, int col
) const
2265 wxGridCell
*cell
= GetCell(row
, col
);
2267 return (wxFont
&) cell
->GetFont();
2269 return (wxFont
&) m_cellTextFont
;
2272 wxColour
& wxGenericGrid::GetCellTextColour(int row
, int col
) const
2274 wxGridCell
*cell
= GetCell(row
, col
);
2276 return (wxColour
&) cell
->GetTextColour();
2278 return (wxColour
&) m_cellTextColour
;
2281 void wxGenericGrid::SetCellTextColour(const wxColour
& val
)
2283 m_cellTextColour
= val
;
2285 for (i
= 0; i
< GetRows(); i
++)
2286 for (j
= 0; j
< GetCols(); j
++)
2288 GetCell(i
, j
)->SetTextColour(val
);
2291 void wxGenericGrid::SetCellTextFont(const wxFont
& fnt
)
2293 m_cellTextFont
= fnt
;
2295 for (i
= 0; i
< GetRows(); i
++)
2296 for (j
= 0; j
< GetCols(); j
++)
2298 GetCell(i
, j
)->SetFont(fnt
);
2301 void wxGenericGrid::SetCellBitmap(wxBitmap
*bitmap
, int row
, int col
)
2303 wxGridCell
*cell
= GetCell(row
, col
);
2306 cell
->SetCellBitmap(bitmap
);
2307 RefreshCell(row
, col
);
2311 wxBitmap
*wxGenericGrid::GetCellBitmap(int row
, int col
) const
2313 wxGridCell
*cell
= GetCell(row
, col
);
2316 return cell
->GetCellBitmap();
2319 return (wxBitmap
*) NULL
;
2322 bool wxGenericGrid::InsertCols(int pos
, int n
, bool updateLabels
)
2324 if (pos
> m_totalCols
)
2328 return CreateGrid(1, n
);
2333 for (i
= 0; i
< m_totalRows
; i
++)
2335 wxGridCell
**cols
= m_gridCells
[i
];
2336 wxGridCell
**newCols
= new wxGridCell
*[m_totalCols
+ n
];
2337 for (j
= 0; j
< pos
; j
++)
2338 newCols
[j
] = cols
[j
];
2339 for (j
= pos
; j
< pos
+ n
; j
++)
2340 newCols
[j
] = new wxGridCell(this);
2341 for (j
= pos
+ n
; j
< m_totalCols
+ n
; j
++)
2342 newCols
[j
] = cols
[j
- n
];
2345 m_gridCells
[i
] = newCols
;
2349 short *newColWidths
= new short[m_totalCols
+ n
];
2350 for (j
= 0; j
< pos
; j
++)
2351 newColWidths
[j
] = m_colWidths
[j
];
2352 for (j
= pos
; j
< pos
+ n
; j
++)
2353 newColWidths
[j
] = wxGRID_DEFAULT_CELL_WIDTH
;
2354 for (j
= pos
+ n
; j
< m_totalCols
+ n
; j
++)
2355 newColWidths
[j
] = m_colWidths
[j
- n
];
2356 delete[] m_colWidths
;
2357 m_colWidths
= newColWidths
;
2360 wxGridCell
**newLabels
= new wxGridCell
*[m_totalCols
+ n
];
2361 for (j
= 0; j
< pos
; j
++)
2362 newLabels
[j
] = m_colLabelCells
[j
];
2363 for (j
= pos
; j
< pos
+ n
; j
++)
2364 newLabels
[j
] = new wxGridCell(this);
2365 for (j
= pos
+ n
; j
< m_totalCols
+ n
; j
++)
2366 newLabels
[j
] = m_colLabelCells
[j
- n
];
2368 delete[] m_colLabelCells
;
2369 m_colLabelCells
= newLabels
;
2375 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2376 GetEventHandler()->ProcessEvent(g_evt
);
2385 bool wxGenericGrid::InsertRows(int pos
, int n
, bool updateLabels
)
2387 if (pos
> m_totalRows
)
2391 return CreateGrid(n
, 1);
2396 wxGridCell
***rows
= new wxGridCell
**[m_totalRows
+ n
];
2399 for (i
= 0; i
< pos
; i
++)
2400 rows
[i
] = m_gridCells
[i
];
2402 for (i
= pos
; i
< pos
+ n
; i
++)
2404 rows
[i
] = new wxGridCell
*[m_totalCols
];
2405 for (j
= 0; j
< m_totalCols
; j
++)
2406 rows
[i
][j
] = new wxGridCell(this);
2409 for (i
= pos
+ n
; i
< m_totalRows
+ n
; i
++)
2410 rows
[i
] = m_gridCells
[i
- n
];
2412 delete[] m_gridCells
;
2416 short *newRowHeights
= new short[m_totalRows
+ n
];
2417 for (i
= 0; i
< pos
; i
++)
2418 newRowHeights
[i
] = m_rowHeights
[i
];
2419 for (i
= pos
; i
< pos
+ n
; i
++)
2420 newRowHeights
[i
] = wxGRID_DEFAULT_CELL_HEIGHT
;
2421 for (i
= pos
+ n
; i
< m_totalRows
+ n
; i
++)
2422 newRowHeights
[i
] = m_rowHeights
[i
- n
];
2423 delete[] m_rowHeights
;
2424 m_rowHeights
= newRowHeights
;
2427 wxGridCell
**newLabels
= new wxGridCell
*[m_totalRows
+ n
];
2428 for (i
= 0; i
< pos
; i
++)
2429 newLabels
[i
] = m_rowLabelCells
[i
];
2430 for (i
= pos
; i
< pos
+ n
; i
++)
2431 newLabels
[i
] = new wxGridCell(this);
2432 for (i
= pos
+ n
; i
< m_totalRows
+ n
; i
++)
2433 newLabels
[i
] = m_rowLabelCells
[i
- n
];
2435 delete[] m_rowLabelCells
;
2436 m_rowLabelCells
= newLabels
;
2442 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2443 GetEventHandler()->ProcessEvent(g_evt
);
2452 bool wxGenericGrid::AppendCols(int n
, bool updateLabels
)
2454 return InsertCols(GetCols(), n
, updateLabels
);
2457 bool wxGenericGrid::AppendRows(int n
, bool updateLabels
)
2459 return InsertRows(GetRows(), n
, updateLabels
);
2462 bool wxGenericGrid::DeleteRows(int pos
, int n
, bool updateLabels
)
2464 if (pos
> m_totalRows
)
2471 wxGridCell
***rows
= new wxGridCell
**[m_totalRows
- n
];
2474 for (i
= 0; i
< pos
; i
++)
2475 rows
[i
] = m_gridCells
[i
];
2477 for (i
= pos
+ n
; i
< m_totalRows
; i
++)
2478 rows
[i
-n
] = m_gridCells
[i
];
2480 delete[] m_gridCells
;
2484 short *newRowHeights
= new short[m_totalRows
- n
];
2485 for (i
= 0; i
< pos
; i
++)
2486 newRowHeights
[i
] = m_rowHeights
[i
];
2487 for (i
= pos
+ n
; i
< m_totalRows
; i
++)
2488 newRowHeights
[i
-n
] = m_rowHeights
[i
];
2489 delete[] m_rowHeights
;
2490 m_rowHeights
= newRowHeights
;
2493 wxGridCell
**newLabels
= new wxGridCell
*[m_totalRows
- n
];
2494 for (i
= 0; i
< pos
; i
++)
2495 newLabels
[i
] = m_rowLabelCells
[i
];
2496 for (i
= pos
+ n
; i
< m_totalRows
; i
++)
2497 newLabels
[i
-n
] = m_rowLabelCells
[i
];
2499 delete[] m_rowLabelCells
;
2500 m_rowLabelCells
= newLabels
;
2506 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2507 GetEventHandler()->ProcessEvent(g_evt
);
2514 bool wxGenericGrid::DeleteCols(int pos
, int n
, bool updateLabels
)
2516 if (pos
+ n
> m_totalCols
)
2524 for (i
= 0; i
< m_totalRows
; i
++)
2526 wxGridCell
**cols
= m_gridCells
[i
];
2527 wxGridCell
**newCols
= new wxGridCell
*[m_totalCols
- n
];
2528 for (j
= 0; j
< pos
; j
++)
2529 newCols
[j
] = cols
[j
];
2530 for (j
= pos
; j
< pos
+ n
; j
++)
2532 for (j
= pos
+ n
; j
< m_totalCols
; j
++)
2533 newCols
[j
-n
] = cols
[j
];
2536 m_gridCells
[i
] = newCols
;
2540 short *newColWidths
= new short[m_totalCols
- n
];
2541 for (j
= 0; j
< pos
; j
++)
2542 newColWidths
[j
] = m_colWidths
[j
];
2543 for (j
= pos
+ n
; j
< m_totalCols
; j
++)
2544 newColWidths
[j
-n
] = m_colWidths
[j
];
2545 delete[] m_colWidths
;
2546 m_colWidths
= newColWidths
;
2549 wxGridCell
**newLabels
= new wxGridCell
*[m_totalCols
- n
];
2550 for (j
= 0; j
< pos
; j
++)
2551 newLabels
[j
] = m_colLabelCells
[j
];
2552 for (j
= pos
+ n
; j
< m_totalCols
; j
++)
2553 newLabels
[j
-n
] = m_colLabelCells
[j
];
2555 delete[] m_colLabelCells
;
2556 m_colLabelCells
= newLabels
;
2562 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2563 GetEventHandler()->ProcessEvent(g_evt
);
2570 void wxGenericGrid::SetGridCursor(int row
, int col
)
2572 if (row
>= m_totalRows
|| col
>= m_totalCols
)
2575 if (row
== GetCursorRow() && col
== GetCursorColumn())
2578 wxClientDC
dc(this);
2581 SetGridClippingRegion(& dc
);
2583 if (m_currentRectVisible
&& (wxIPE_HIGHLIGHT
|| !(m_editable
&& m_editInPlace
)))
2584 HighlightCell(& dc
, FALSE
);
2587 m_wCursorColumn
= col
;
2590 GetClientSize(&cw
, &ch
);
2592 SetCurrentRect(row
, col
, cw
, ch
);
2594 if (m_currentRectVisible
&& (wxIPE_HIGHLIGHT
|| !(m_editable
&& m_editInPlace
)))
2595 HighlightCell(& dc
, TRUE
);
2597 dc
.DestroyClippingRegion();
2601 // ----------------------------------------------------------------------------
2603 // ----------------------------------------------------------------------------
2605 wxGridCell::wxGridCell(wxGenericGrid
*window
)
2607 cellBitmap
= (wxBitmap
*) NULL
;
2609 backgroundBrush
= wxNullBrush
;
2611 textColour
= window
->GetCellTextColour();
2613 textColour
.Set(0,0,0);
2615 backgroundColour
= window
->GetCellBackgroundColour();
2617 backgroundColour
.Set(255,255,255);
2620 font
= window
->GetCellTextFont();
2622 font
= * wxTheFontList
->FindOrCreateFont(12, wxSWISS
, wxNORMAL
, wxNORMAL
);
2624 SetBackgroundColour(backgroundColour
);
2627 alignment
= window
->GetCellAlignment();
2631 cellData
= (void *)NULL
;
2634 wxGridCell::~wxGridCell()
2638 void wxGridCell::SetBackgroundColour(const wxColour
& colour
)
2640 backgroundColour
= colour
;
2641 backgroundBrush
= * wxTheBrushList
->FindOrCreateBrush(backgroundColour
, wxSOLID
);
2644 void wxGenericGrid::OnText(wxCommandEvent
& WXUNUSED(ev
) )
2646 // michael - added this conditional to prevent change to
2647 // grid cell text when edit control is hidden but still has
2652 wxGenericGrid
*grid
= this;
2653 wxGridCell
*cell
= grid
->GetCell(grid
->GetCursorRow(), grid
->GetCursorColumn());
2654 if (cell
&& grid
->CurrentCellVisible())
2656 cell
->SetTextValue(grid
->GetTextItem()->GetValue());
2657 if ( m_editInPlace
&& !m_inOnTextInPlace
)
2659 m_inPlaceTextItem
->SetValue( grid
->GetTextItem()->GetValue() );
2662 if (!m_editInPlace
) {
2663 wxClientDC
dc(grid
);
2666 grid
->SetGridClippingRegion(& dc
);
2667 grid
->DrawCellBackground(& dc
, &grid
->GetCurrentRect(), grid
->GetCursorRow(), grid
->GetCursorColumn());
2668 grid
->DrawCellValue(& dc
, &grid
->GetCurrentRect(), grid
->GetCursorRow(), grid
->GetCursorColumn());
2669 grid
->HighlightCell(& dc
, TRUE
);
2670 dc
.DestroyClippingRegion();
2674 //grid->OnCellChange(grid->GetCursorRow(), grid->GetCursorColumn());
2675 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CELL_CHANGE
, grid
,
2676 grid
->GetCursorRow(), grid
->GetCursorColumn());
2677 GetEventHandler()->ProcessEvent(g_evt
);
2679 // grid->DrawCellText();
2684 void wxGenericGrid::OnTextEnter(wxCommandEvent
& WXUNUSED(ev
) )
2686 // move the cursor down the current row (if possible)
2687 // when the enter key has been pressed
2691 if ( GetCursorRow() < GetRows()-1 )
2693 wxClientDC
dc( this );
2695 OnSelectCellImplementation(& dc
,
2697 GetCursorColumn() );
2703 void wxGenericGrid::OnTextInPlace(wxCommandEvent
& ev
)
2707 wxGenericGrid
*grid
= this;
2708 wxGridCell
*cell
= grid
->GetCell(grid
->GetCursorRow(), grid
->GetCursorColumn());
2709 if (cell
&& grid
->CurrentCellVisible())
2711 m_inOnTextInPlace
= TRUE
;
2712 grid
->GetTextItem()->SetValue( m_inPlaceTextItem
->GetValue() );
2714 m_inOnTextInPlace
= FALSE
;
2719 void wxGenericGrid::OnTextInPlaceEnter(wxCommandEvent
& WXUNUSED(ev
) )
2721 // move the cursor down the current row (if possible)
2722 // when the enter key has been pressed
2726 if ( GetCursorRow() < GetRows()-1 )
2728 wxClientDC
dc( this );
2730 OnSelectCellImplementation(& dc
,
2732 GetCursorColumn() );
2738 void wxGenericGrid::OnGridScroll(wxScrollEvent
& ev
)
2743 if ( m_editInPlace
) m_inPlaceTextItem
->Show(FALSE
);
2746 wxGenericGrid
*win
= this;
2748 bool change
= FALSE
;
2750 if (ev
.GetEventObject() == win
->GetHorizScrollBar())
2752 change
= (ev
.GetPosition() != m_scrollPosX
);
2753 win
->SetScrollPosX(ev
.GetPosition());
2757 change
= (ev
.GetPosition() != m_scrollPosY
);
2758 win
->SetScrollPosY(ev
.GetPosition());
2761 win
->UpdateDimensions();
2763 win
->SetCurrentRect(win
->GetCursorRow(), win
->GetCursorColumn());
2765 // Because rows and columns can be arbitrary sizes,
2766 // the scrollbars will need to be adjusted to reflect the
2770 if (change
) win
->Refresh(FALSE
);
2772 if ( m_editInPlace
&& m_currentRectVisible
)
2774 m_inPlaceTextItem
->SetSize( m_currentRect
.x
-wxIPE_ADJUST
,
2775 m_currentRect
.y
-wxIPE_ADJUST
,
2776 m_currentRect
.width
+wxIPE_ADJUST
*2,
2777 m_currentRect
.height
+wxIPE_ADJUST
*2 );
2778 m_inPlaceTextItem
->Show( TRUE
);
2779 m_inPlaceTextItem
->SetFocus();
2787 //----------------------------------------------------------------------
2788 // Default wxGridEvent handlers
2789 // (just redirect to the pre-existing virtual methods)
2791 void wxGenericGrid::_OnSelectCell(wxGridEvent
& ev
)
2793 OnSelectCell(ev
.m_row
, ev
.m_col
);
2796 void wxGenericGrid::_OnCreateCell(wxGridEvent
& ev
)
2798 ev
.m_cell
= OnCreateCell();
2801 void wxGenericGrid::_OnChangeLabels(wxGridEvent
& WXUNUSED(ev
))
2806 void wxGenericGrid::_OnChangeSelectionLabel(wxGridEvent
& WXUNUSED(ev
))
2808 OnChangeSelectionLabel();
2811 void wxGenericGrid::_OnCellChange(wxGridEvent
& ev
)
2813 OnCellChange(ev
.m_row
, ev
.m_col
);
2816 void wxGenericGrid::_OnCellLeftClick(wxGridEvent
& ev
)
2818 OnCellLeftClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2821 void wxGenericGrid::_OnCellRightClick(wxGridEvent
& ev
)
2823 OnCellRightClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2826 void wxGenericGrid::_OnLabelLeftClick(wxGridEvent
& ev
)
2828 OnLabelLeftClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2831 void wxGenericGrid::_OnLabelRightClick(wxGridEvent
& ev
)
2833 OnLabelRightClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2836 void *wxGenericGrid::SetCellData(void *data
, int row
, int col
)
2840 wxGridCell
*cell
= GetCell(row
, col
);
2842 rc
= cell
->SetCellData(data
);
2847 void *wxGenericGrid::GetCellData(int row
, int col
)
2851 wxGridCell
*cell
= GetCell(row
, col
);
2853 rc
= cell
->GetCellData();
2858 #endif // wxUSE_GRID && !(wxUSE_NEW_GRID)