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
10 // Copyright: (c) Julian Smart and Markus Holzem
11 // Licence: wxWindows license
12 /////////////////////////////////////////////////////////////////////////////
15 #pragma implementation "gridg.h"
19 // For compilers that support precompilation, includes "wx/wx.h".
20 #include "wx/wxprec.h"
28 #include "wx/dcclient.h"
29 #include "wx/dcmemory.h"
30 #include "wx/textctrl.h"
31 #include "wx/settings.h"
36 #include "wx/string.h"
38 #include "wx/generic/gridg.h"
40 // Set to zero to use no double-buffering
42 #define wxUSE_DOUBLE_BUFFERING 1
44 #define wxUSE_DOUBLE_BUFFERING 0
47 #define wxGRID_DRAG_NONE 0
48 #define wxGRID_DRAG_LEFT_RIGHT 1
49 #define wxGRID_DRAG_UP_DOWN 2
51 IMPLEMENT_DYNAMIC_CLASS(wxGenericGrid
, wxPanel
)
52 IMPLEMENT_DYNAMIC_CLASS(wxGridEvent
, wxEvent
)
54 BEGIN_EVENT_TABLE(wxGenericGrid
, wxPanel
)
55 EVT_SIZE(wxGenericGrid::OnSize
)
56 EVT_PAINT(wxGenericGrid::OnPaint
)
57 EVT_ERASE_BACKGROUND(wxGenericGrid::OnEraseBackground
)
58 EVT_MOUSE_EVENTS(wxGenericGrid::OnMouseEvent
)
59 EVT_TEXT(wxGRID_TEXT_CTRL
, wxGenericGrid::OnText
)
60 EVT_TEXT(wxGRID_EDIT_IN_PLACE_TEXT_CTRL
, wxGenericGrid::OnTextInPlace
)
61 EVT_TEXT_ENTER(wxGRID_TEXT_CTRL
, wxGenericGrid::OnTextEnter
)
62 EVT_TEXT_ENTER(wxGRID_EDIT_IN_PLACE_TEXT_CTRL
, wxGenericGrid::OnTextInPlaceEnter
)
63 EVT_COMMAND_SCROLL(wxGRID_HSCROLL
, wxGenericGrid::OnGridScroll
)
64 EVT_COMMAND_SCROLL(wxGRID_VSCROLL
, wxGenericGrid::OnGridScroll
)
66 // default wxGridEvent handlers
67 EVT_GRID_SELECT_CELL(wxGenericGrid::_OnSelectCell
)
68 EVT_GRID_CREATE_CELL(wxGenericGrid::_OnCreateCell
)
69 EVT_GRID_CHANGE_LABELS(wxGenericGrid::_OnChangeLabels
)
70 EVT_GRID_CHANGE_SEL_LABEL(wxGenericGrid::_OnChangeSelectionLabel
)
71 EVT_GRID_CELL_CHANGE(wxGenericGrid::_OnCellChange
)
72 EVT_GRID_CELL_LCLICK(wxGenericGrid::_OnCellLeftClick
)
73 EVT_GRID_CELL_RCLICK(wxGenericGrid::_OnCellRightClick
)
74 EVT_GRID_LABEL_LCLICK(wxGenericGrid::_OnLabelLeftClick
)
75 EVT_GRID_LABEL_RCLICK(wxGenericGrid::_OnLabelRightClick
)
80 wxGenericGrid::wxGenericGrid(void)
83 m_hScrollBar
= (wxScrollBar
*) NULL
;
84 m_vScrollBar
= (wxScrollBar
*) NULL
;
85 m_cellTextColour
= *wxBLACK
;
86 m_cellBackgroundColour
= *wxWHITE
;
87 m_labelTextColour
= *wxBLACK
;
88 // m_labelBackgroundColour = *wxLIGHT_GREY;
89 m_labelBackgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
90 m_labelBackgroundBrush
= wxNullBrush
;
91 m_labelTextFont
= wxNullFont
;
92 m_cellTextFont
= wxNullFont
;
93 m_textItem
= (wxTextCtrl
*) NULL
;
94 m_currentRectVisible
= FALSE
;
98 m_inOnTextInPlace
= FALSE
;
100 #if defined(__WIN95__)
101 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
102 #elif defined(__WXGTK__)
103 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
107 m_dragStatus
= wxGRID_DRAG_NONE
;
109 m_dragStartPosition
= 0;
110 m_dragLastPosition
= 0;
111 m_divisionPen
= wxNullPen
;
112 m_leftOfSheet
= wxGRID_DEFAULT_SHEET_LEFT
;
113 m_topOfSheet
= wxGRID_DEFAULT_SHEET_TOP
;
114 m_cellHeight
= wxGRID_DEFAULT_CELL_HEIGHT
;
115 m_totalGridWidth
= 0;
116 m_totalGridHeight
= 0;
117 m_colWidths
= (short *) NULL
;
118 m_rowHeights
= (short *) NULL
;
119 m_verticalLabelWidth
= wxGRID_DEFAULT_VERTICAL_LABEL_WIDTH
;
120 m_horizontalLabelHeight
= wxGRID_DEFAULT_HORIZONAL_LABEL_HEIGHT
;
121 m_verticalLabelAlignment
= wxCENTRE
;
122 m_horizontalLabelAlignment
= wxCENTRE
;
123 m_editControlPosition
.x
= wxGRID_DEFAULT_EDIT_X
;
124 m_editControlPosition
.y
= wxGRID_DEFAULT_EDIT_Y
;
125 m_editControlPosition
.width
= wxGRID_DEFAULT_EDIT_WIDTH
;
126 m_editControlPosition
.height
= wxGRID_DEFAULT_EDIT_HEIGHT
;
131 m_editCreated
= FALSE
;
134 m_gridCells
= (wxGridCell
***) NULL
;
135 m_rowLabelCells
= (wxGridCell
**) NULL
;
136 m_colLabelCells
= (wxGridCell
**) NULL
;
137 m_textItem
= (wxTextCtrl
*) NULL
;
140 bool wxGenericGrid::Create(wxWindow
*parent
, wxWindowID id
, const wxPoint
& pos
, const wxSize
& size
,
141 long style
, const wxString
& name
)
144 m_editingPanel
= (wxPanel
*) NULL
;
145 m_hScrollBar
= (wxScrollBar
*) NULL
;
146 m_vScrollBar
= (wxScrollBar
*) NULL
;
147 m_cellTextColour
= *wxBLACK
;
148 m_cellBackgroundColour
= *wxWHITE
;
149 m_labelTextColour
= *wxBLACK
;
150 // m_labelBackgroundColour = *wxLIGHT_GREY;
151 m_labelBackgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
152 m_labelBackgroundBrush
= wxNullBrush
;
153 m_labelTextFont
= * wxTheFontList
->FindOrCreateFont(10, wxSWISS
, wxNORMAL
, wxBOLD
);
154 m_cellTextFont
= * wxTheFontList
->FindOrCreateFont(10, wxSWISS
, wxNORMAL
, wxNORMAL
);
155 m_textItem
= (wxTextCtrl
*) NULL
;
156 m_currentRectVisible
= FALSE
;
158 #if defined(__WIN95__)
159 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
160 #elif defined(__WXGTK__)
161 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
165 m_dragStatus
= wxGRID_DRAG_NONE
;
167 m_dragStartPosition
= 0;
168 m_dragLastPosition
= 0;
169 m_divisionPen
= * wxThePenList
->FindOrCreatePen("LIGHT GREY", 1, wxSOLID
);
170 m_doubleBufferingBitmap
= (wxBitmap
*) NULL
;
172 if (!m_horizontalSashCursor
.Ok())
174 m_horizontalSashCursor
= wxCursor(wxCURSOR_SIZEWE
);
175 m_verticalSashCursor
= wxCursor(wxCURSOR_SIZENS
);
178 SetLabelBackgroundColour(m_labelBackgroundColour
);
180 m_leftOfSheet
= wxGRID_DEFAULT_SHEET_LEFT
;
181 m_topOfSheet
= wxGRID_DEFAULT_SHEET_TOP
;
182 m_cellHeight
= wxGRID_DEFAULT_CELL_HEIGHT
;
183 m_totalGridWidth
= 0;
184 m_totalGridHeight
= 0;
185 m_colWidths
= (short *) NULL
;
186 m_rowHeights
= (short *) NULL
;
188 m_verticalLabelWidth
= wxGRID_DEFAULT_VERTICAL_LABEL_WIDTH
;
189 m_horizontalLabelHeight
= wxGRID_DEFAULT_HORIZONAL_LABEL_HEIGHT
;
190 m_verticalLabelAlignment
= wxCENTRE
;
191 m_horizontalLabelAlignment
= wxCENTRE
;
192 m_editControlPosition
.x
= wxGRID_DEFAULT_EDIT_X
;
193 m_editControlPosition
.y
= wxGRID_DEFAULT_EDIT_Y
;
194 m_editControlPosition
.width
= wxGRID_DEFAULT_EDIT_WIDTH
;
195 m_editControlPosition
.height
= wxGRID_DEFAULT_EDIT_HEIGHT
;
203 /* Store the rect. coordinates for the current cell */
204 SetCurrentRect(m_wCursorRow
, m_wCursorColumn
);
206 m_editCreated
= FALSE
;
210 m_gridCells
= (wxGridCell
***) NULL
;
211 m_rowLabelCells
= (wxGridCell
**) NULL
;
212 m_colLabelCells
= (wxGridCell
**) NULL
;
213 m_textItem
= (wxTextCtrl
*) NULL
;
215 wxPanel::Create(parent
, id
, pos
, size
, style
, name
);
217 m_editingPanel
= new wxPanel(this);
219 m_textItem
= new wxTextCtrl(m_editingPanel
, wxGRID_TEXT_CTRL
, "",
220 wxPoint(m_editControlPosition
.x
, m_editControlPosition
.y
),
221 wxSize(m_editControlPosition
.width
, -1),
223 m_textItem
->Show(TRUE
);
224 m_textItem
->SetFocus();
225 int controlW
, controlH
;
227 m_textItem
->GetSize(&controlW
, &controlH
);
228 m_editControlPosition
.height
= controlH
;
230 m_topOfSheet
= m_editControlPosition
.y
+ controlH
+ 2;
232 m_editCreated
= TRUE
;
234 m_hScrollBar
= new wxScrollBar(this, wxGRID_HSCROLL
, wxPoint(0, 0), wxSize(20, 100), wxHORIZONTAL
);
235 m_vScrollBar
= new wxScrollBar(this, wxGRID_VSCROLL
, wxPoint(0, 0), wxSize(100, 20), wxVERTICAL
);
237 // SetSize(pos.x, pos.y, size.x, size.y);
239 m_inPlaceTextItem
= new wxTextCtrl( (wxPanel
*)this, wxGRID_EDIT_IN_PLACE_TEXT_CTRL
, "",
240 wxPoint( m_currentRect
.x
-2, m_currentRect
.y
-2 ),
241 wxSize( m_currentRect
.width
+4, m_currentRect
.height
+4 ),
242 wxNO_BORDER
| wxTE_PROCESS_ENTER
);
243 m_inPlaceTextItem
->Show(TRUE
);
244 m_inPlaceTextItem
->SetFocus();
249 wxGenericGrid::~wxGenericGrid(void)
254 void wxGenericGrid::ClearGrid(void)
259 for (i
= 0; i
< m_totalRows
; i
++)
261 for (j
= 0; j
< m_totalCols
; j
++)
262 if (m_gridCells
[i
][j
])
263 delete m_gridCells
[i
][j
];
264 delete[] m_gridCells
[i
];
266 delete[] m_gridCells
;
267 m_gridCells
= (wxGridCell
***) NULL
;
270 delete[] m_colWidths
;
271 m_colWidths
= (short *) NULL
;
273 delete[] m_rowHeights
;
274 m_rowHeights
= (short *) NULL
;
278 for (i
= 0; i
< m_totalRows
; i
++)
279 delete m_rowLabelCells
[i
];
280 delete[] m_rowLabelCells
;
281 m_rowLabelCells
= (wxGridCell
**) NULL
;
285 for (i
= 0; i
< m_totalCols
; i
++)
286 delete m_colLabelCells
[i
];
287 delete[] m_colLabelCells
;
288 m_colLabelCells
= (wxGridCell
**) NULL
;
290 if (m_doubleBufferingBitmap
)
292 delete m_doubleBufferingBitmap
;
293 m_doubleBufferingBitmap
= (wxBitmap
*) NULL
;
297 bool wxGenericGrid::CreateGrid(int nRows
, int nCols
, wxString
**cellValues
, short *widths
,
298 short defaultWidth
, short defaultHeight
)
304 m_colWidths
= new short[nCols
];
305 m_rowHeights
= new short[nRows
];
306 for (i
= 0; i
< nCols
; i
++)
308 m_colWidths
[i
] = widths
[i
];
310 m_colWidths
[i
] = defaultWidth
;
311 for (i
= 0; i
< nRows
; i
++)
312 m_rowHeights
[i
] = defaultHeight
;
314 m_gridCells
= new wxGridCell
**[nRows
];
316 for (i
= 0; i
< nRows
; i
++)
317 m_gridCells
[i
] = new wxGridCell
*[nCols
];
319 for (i
= 0; i
< nRows
; i
++)
320 for (j
= 0; j
< nCols
; j
++)
323 //m_gridCells[i][j] = OnCreateCell();
324 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CREATE_CELL
, this, i
, j
);
325 GetEventHandler()->ProcessEvent(g_evt
);
326 m_gridCells
[i
][j
] = g_evt
.m_cell
;
327 m_gridCells
[i
][j
]->SetTextValue(cellValues
[i
][j
]);
330 m_gridCells
[i
][j
] = (wxGridCell
*) NULL
;
332 m_rowLabelCells
= new wxGridCell
*[nRows
];
333 for (i
= 0; i
< nRows
; i
++)
334 m_rowLabelCells
[i
] = new wxGridCell(this);
335 m_colLabelCells
= new wxGridCell
*[nCols
];
336 for (i
= 0; i
< nCols
; i
++)
337 m_colLabelCells
[i
] = new wxGridCell(this);
339 m_wCursorRow
= m_wCursorColumn
= 0;
340 SetCurrentRect(0, 0);
342 // Need to determine various dimensions
346 int objectSizeX
= m_totalCols
;
348 int viewLengthX
= m_totalCols
;
351 m_hScrollBar->SetViewLength(viewLengthX);
352 m_hScrollBar->SetObjectLength(objectSizeX);
353 m_hScrollBar->SetPageSize(pageSizeX);
355 m_hScrollBar
->SetScrollbar(m_hScrollBar
->GetThumbPosition(), pageSizeX
, objectSizeX
, viewLengthX
);
357 int objectSizeY
= m_totalRows
;
359 int viewLengthY
= m_totalRows
;
362 m_vScrollBar->SetViewLength(viewLengthY);
363 m_vScrollBar->SetObjectLength(objectSizeY);
364 m_vScrollBar->SetPageSize(pageSizeY);
367 m_vScrollBar
->SetScrollbar(m_vScrollBar
->GetThumbPosition(), pageSizeY
, objectSizeY
, viewLengthY
);
372 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
373 GetEventHandler()->ProcessEvent(g_evt
);
375 //OnChangeSelectionLabel();
376 wxGridEvent
g_evt2(GetId(), wxEVT_GRID_CHANGE_SEL_LABEL
, this);
377 GetEventHandler()->ProcessEvent(g_evt2
);
382 // Need to determine various dimensions
383 void wxGenericGrid::UpdateDimensions(void)
385 int canvasWidth
, canvasHeight
;
386 GetSize(&canvasWidth
, &canvasHeight
);
388 if (m_editCreated
&& m_editable
)
390 int controlW
, controlH
;
391 GetTextItem()->GetSize(&controlW
, &controlH
);
392 m_topOfSheet
= m_editControlPosition
.y
+ controlH
+ 2;
396 m_rightOfSheet
= m_leftOfSheet
+ m_verticalLabelWidth
;
398 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
400 if (m_rightOfSheet
> canvasWidth
)
403 m_rightOfSheet
+= m_colWidths
[i
];
405 m_bottomOfSheet
= m_topOfSheet
+ m_horizontalLabelHeight
;
406 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
408 if (m_bottomOfSheet
> canvasHeight
)
411 m_bottomOfSheet
+= m_rowHeights
[i
];
414 m_totalGridWidth
= m_leftOfSheet
+ m_verticalLabelWidth
;
415 for (i
= 0; i
< m_totalCols
; i
++)
417 m_totalGridWidth
+= m_colWidths
[i
];
419 m_totalGridHeight
= m_topOfSheet
+ m_horizontalLabelHeight
;
420 for (i
= 0; i
< m_totalRows
; i
++)
422 m_totalGridHeight
+= m_rowHeights
[i
];
426 wxGridCell
*wxGenericGrid::GetCell(int row
, int col
) const
429 return (wxGridCell
*) NULL
;
431 if ((row
>= m_totalRows
) || (col
>= m_totalCols
))
432 return (wxGridCell
*) NULL
;
434 wxGridCell
*cell
= m_gridCells
[row
][col
];
437 // m_gridCells[row][col] = OnCreateCell();
438 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CREATE_CELL
, (wxGenericGrid
*) this, row
, col
);
439 GetEventHandler()->ProcessEvent(g_evt
);
440 m_gridCells
[row
][col
] = g_evt
.m_cell
;
441 return m_gridCells
[row
][col
];
447 void wxGenericGrid::SetGridClippingRegion(wxDC
*dc
)
449 int m_scrollWidthHoriz
= 0;
450 int m_scrollWidthVert
= 0;
452 GetClientSize(&cw
, &ch
);
454 if (m_hScrollBar
&& m_hScrollBar
->IsShown())
455 m_scrollWidthHoriz
= m_scrollWidth
;
456 if (m_vScrollBar
&& m_vScrollBar
->IsShown())
457 m_scrollWidthVert
= m_scrollWidth
;
459 // Don't paint over the scrollbars
460 dc
->SetClippingRegion(m_leftOfSheet
, m_topOfSheet
,
461 cw
- m_scrollWidthVert
- m_leftOfSheet
, ch
- m_scrollWidthHoriz
- m_topOfSheet
);
464 void wxGenericGrid::OnPaint(wxPaintEvent
& WXUNUSED(event
))
467 GetClientSize(&w
, &h
);
469 bool useDoubleBuffering
= (bool) wxUSE_DOUBLE_BUFFERING
;
470 if (useDoubleBuffering
)
472 // Reuse the old bitmap if possible
474 if (!m_doubleBufferingBitmap
||
475 (m_doubleBufferingBitmap
->GetWidth() < w
|| m_doubleBufferingBitmap
->GetHeight() < h
))
477 if (m_doubleBufferingBitmap
)
478 delete m_doubleBufferingBitmap
;
479 m_doubleBufferingBitmap
= new wxBitmap(w
, h
);
481 if (!m_doubleBufferingBitmap
|| !m_doubleBufferingBitmap
->Ok())
483 // If we couldn't create a new bitmap, perhaps because resources were low,
484 // then don't complain, just don't double-buffer
485 if (m_doubleBufferingBitmap
)
486 delete m_doubleBufferingBitmap
;
487 m_doubleBufferingBitmap
= (wxBitmap
*) NULL
;
488 useDoubleBuffering
= FALSE
;
492 if (useDoubleBuffering
)
494 wxPaintDC
paintDC(this);
495 wxMemoryDC
dc(& paintDC
);
496 dc
.SelectObject(* m_doubleBufferingBitmap
);
500 int vertScrollBarWidth
= m_scrollWidth
;
501 int horizScrollBarHeight
= m_scrollWidth
;
502 if (m_vScrollBar
&& !m_vScrollBar
->IsShown())
503 vertScrollBarWidth
= 0;
504 if (m_hScrollBar
&& !m_hScrollBar
->IsShown())
505 horizScrollBarHeight
= 0;
507 paintDC
.Blit(m_leftOfSheet
, m_topOfSheet
, w
- vertScrollBarWidth
- m_leftOfSheet
, h
- horizScrollBarHeight
- m_topOfSheet
,
508 &dc
, m_leftOfSheet
, m_topOfSheet
, wxCOPY
);
510 dc
.SelectObject(wxNullBitmap
);
519 void wxGenericGrid::PaintGrid(wxDC
& dc
)
522 dc
.SetOptimization(FALSE
);
524 SetGridClippingRegion(& dc
);
526 DrawLabelAreas(& dc
);
528 DrawEditableArea(& dc
);
529 DrawColumnLabels(& dc
);
534 /* Hilight present cell */
535 SetCurrentRect(m_wCursorRow
, m_wCursorColumn
);
536 if (m_currentRectVisible
&& !(m_editable
&& m_editInPlace
))
539 dc
.DestroyClippingRegion();
540 dc
.SetOptimization(TRUE
);
544 // Erase (some of) the background.
545 // Currently, a Windows-only optimisation.
546 void wxGenericGrid::OnEraseBackground(wxEraseEvent
& WXUNUSED(event
) )
550 dc
.SetOptimization(FALSE
);
553 GetClientSize(& w
, & h
);
554 dc
.SetBrush(*wxLIGHT_GREY_BRUSH
);
555 dc
.SetPen(*wxLIGHT_GREY_PEN
);
557 if (m_hScrollBar
&& m_hScrollBar
->IsShown() && m_vScrollBar
&& m_vScrollBar
->IsShown())
559 dc
.DrawRectangle(w
- m_scrollWidth
, h
- m_scrollWidth
, m_scrollWidth
, m_scrollWidth
);
562 dc
.SetOptimization(TRUE
);
567 void wxGenericGrid::DrawLabelAreas(wxDC
*dc
)
570 GetClientSize(&cw
, &ch
);
572 dc
->SetPen(*wxTRANSPARENT_PEN
);
573 // dc->SetBrush(*dc->GetBackground());
575 // Should blank out any area which isn't going to be painted over.
576 // dc->DrawRectangle(m_leftOfSheet, m_bottomOfSheet, cw - m_leftOfSheet, ch - m_bottomOfSheet);
577 // dc->DrawRectangle(m_rightOfSheet, m_topOfSheet, cw - m_rightOfSheet, ch - m_topOfSheet);
579 // Paint the label areas
580 dc
->SetBrush(m_labelBackgroundBrush
);
581 // dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, m_rightOfSheet - m_leftOfSheet + 1, m_horizontalLabelHeight + 1);
582 dc
->DrawRectangle(m_leftOfSheet
, m_topOfSheet
, cw
-m_leftOfSheet
, m_horizontalLabelHeight
+ 1);
583 // dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, m_verticalLabelWidth + 1, m_bottomOfSheet - m_topOfSheet + 1);
584 dc
->DrawRectangle(m_leftOfSheet
, m_topOfSheet
, m_verticalLabelWidth
+ 1, ch
-m_topOfSheet
);
587 void wxGenericGrid::DrawEditableArea(wxDC
*dc
)
590 GetClientSize(&cw
, &ch
);
592 dc
->SetPen(*wxTRANSPARENT_PEN
);
593 dc
->SetBrush(*wxTheBrushList
->FindOrCreateBrush(m_cellBackgroundColour
, wxSOLID
));
594 // dc->DrawRectangle(m_leftOfSheet+m_verticalLabelWidth, m_topOfSheet+m_horizontalLabelHeight,
595 // m_rightOfSheet-(m_leftOfSheet+m_verticalLabelWidth) + 1, m_bottomOfSheet - (m_topOfSheet+m_horizontalLabelHeight) + 1);
596 dc
->DrawRectangle(m_leftOfSheet
+m_verticalLabelWidth
, m_topOfSheet
+m_horizontalLabelHeight
,
597 cw
-(m_leftOfSheet
+m_verticalLabelWidth
), ch
- (m_topOfSheet
+m_horizontalLabelHeight
));
600 void wxGenericGrid::DrawGridLines(wxDC
*dc
)
603 GetClientSize(&cw
, &ch
);
607 if (m_divisionPen
.Ok())
609 dc
->SetPen(m_divisionPen
);
611 int heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
613 // Draw horizontal grey lines for cells
614 for (i
= m_scrollPosY
; i
< (m_totalRows
+1); i
++)
616 if (heightCount
> ch
)
620 dc
->DrawLine(m_leftOfSheet
, heightCount
,
623 heightCount
+= m_rowHeights
[i
];
628 if (m_verticalLabelWidth
> 0)
630 dc
->SetPen(*wxBLACK_PEN
);
632 // Draw horizontal black lines for row labels
633 int heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
634 for (i
= m_scrollPosY
; i
< (m_totalRows
+1); i
++)
636 if (heightCount
> ch
)
640 dc
->DrawLine(m_leftOfSheet
, heightCount
,
641 m_verticalLabelWidth
, heightCount
);
643 heightCount
+= m_rowHeights
[i
];
646 // Draw a black vertical line for row number cells
647 dc
->DrawLine(m_leftOfSheet
+ m_verticalLabelWidth
, m_topOfSheet
,
648 m_leftOfSheet
+ m_verticalLabelWidth
, ch
);
649 // First vertical line
650 dc
->DrawLine(m_leftOfSheet
, m_topOfSheet
, m_leftOfSheet
, ch
);
652 dc
->SetPen(*wxWHITE_PEN
);
654 // Draw highlights on row labels
655 heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
656 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
658 if (heightCount
> ch
)
662 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
663 m_verticalLabelWidth
, heightCount
+1);
664 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
665 m_leftOfSheet
+1, heightCount
+ m_rowHeights
[i
] - 1);
666 heightCount
+= m_rowHeights
[i
];
669 // Last one - down to the floor.
670 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
671 m_verticalLabelWidth
, heightCount
+1);
672 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
673 m_leftOfSheet
+1, ch
);
677 if (m_divisionPen
.Ok())
679 dc
->SetPen(m_divisionPen
);
681 // Draw vertical grey lines for cells
682 int widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
683 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
689 // Skip the first one
690 if (i
!= m_scrollPosX
)
692 dc
->DrawLine(widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
,
693 widthCount
, m_bottomOfSheet
);
695 widthCount
+= m_colWidths
[i
];
699 dc
->DrawLine(widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
,
700 widthCount
, m_bottomOfSheet
);
703 dc
->SetPen(*wxBLACK_PEN
);
705 // Draw two black horizontal lines for column number cells
707 m_leftOfSheet
, m_topOfSheet
,
709 dc
->DrawLine(m_leftOfSheet
, m_topOfSheet
+ m_horizontalLabelHeight
,
710 cw
, m_topOfSheet
+ m_horizontalLabelHeight
);
712 if (m_horizontalLabelHeight
> 0)
714 int widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
716 // Draw black vertical lines for column number cells
717 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
723 dc
->DrawLine(widthCount
, m_topOfSheet
,
724 widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
);
725 widthCount
+= m_colWidths
[i
];
730 dc
->DrawLine(widthCount
, m_topOfSheet
,
731 widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
);
734 dc
->SetPen(*wxWHITE_PEN
);
735 widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
737 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
743 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
744 widthCount
+m_colWidths
[i
], m_topOfSheet
+1);
745 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
746 widthCount
+1, m_topOfSheet
+m_horizontalLabelHeight
);
747 widthCount
+= m_colWidths
[i
];
750 // Last one - to the right side of the canvas.
751 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
753 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
754 widthCount
+1, m_topOfSheet
+m_horizontalLabelHeight
);
759 void wxGenericGrid::DrawColumnLabels(wxDC
*dc
)
762 GetClientSize(&cw
, &ch
);
764 if (m_horizontalLabelHeight
== 0)
770 // Draw letters for columns
771 rect
.y
= m_topOfSheet
+ 1;
772 rect
.height
= m_horizontalLabelHeight
- 1;
774 dc
->SetTextBackground(m_labelBackgroundColour
);
775 dc
->SetBackgroundMode(wxTRANSPARENT
);
776 // dc->SetTextForeground(m_labelTextColour);
778 int widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
779 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
785 rect
.x
= 1 + widthCount
;
786 rect
.width
= m_colWidths
[i
];
787 DrawColumnLabel(dc
, &rect
, i
);
789 widthCount
+= m_colWidths
[i
];
794 void wxGenericGrid::DrawColumnLabel(wxDC
*dc
, wxRect
*rect
, int col
)
796 wxGridCell
*cell
= GetLabelCell(wxHORIZONTAL
, col
);
805 dc
->SetTextForeground(GetLabelTextColour());
806 dc
->SetFont(GetLabelTextFont());
807 if ( !cell
->GetTextValue().IsNull() )
808 DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, GetLabelAlignment(wxHORIZONTAL
));
812 void wxGenericGrid::DrawRowLabels(wxDC
*dc
)
815 GetClientSize(&cw
, &ch
);
817 if (m_verticalLabelWidth
== 0)
823 // Draw numbers for rows
824 rect
.x
= m_leftOfSheet
;
825 rect
.width
= m_verticalLabelWidth
;
827 int heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
829 dc
->SetTextBackground(m_labelBackgroundColour
);
830 dc
->SetBackgroundMode(wxTRANSPARENT
);
832 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
834 if (heightCount
> ch
)
838 rect
.y
= 1 + heightCount
;
839 rect
.height
= m_rowHeights
[i
];
840 DrawRowLabel(dc
, &rect
, i
);
842 heightCount
+= m_rowHeights
[i
];
847 void wxGenericGrid::DrawRowLabel(wxDC
*dc
, wxRect
*rect
, int row
)
849 wxGridCell
*cell
= GetLabelCell(wxVERTICAL
, row
);
858 dc
->SetTextForeground(GetLabelTextColour());
859 dc
->SetFont(GetLabelTextFont());
860 if ( !cell
->GetTextValue().IsNull() )
861 DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, GetLabelAlignment(wxVERTICAL
));
865 void wxGenericGrid::DrawCells(wxDC
*dc
)
868 GetClientSize(&cw
, &ch
);
872 // Draw value corresponding to each cell
873 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
875 for (j
= m_scrollPosX
; j
< m_totalCols
; j
++)
877 SetCurrentRect(i
, j
, cw
, ch
);
878 if (m_currentRectVisible
)
880 DrawCellBackground(dc
, &m_currentRect
, i
, j
);
881 DrawCellValue(dc
, &m_currentRect
, i
, j
);
883 if (m_currentRect
.x
> cw
)
886 if (m_currentRect
.y
> ch
)
889 dc
->SetBackgroundMode(wxSOLID
);
890 dc
->SetPen(*wxBLACK_PEN
);
893 void wxGenericGrid::DrawCellBackground(wxDC
*dc
, wxRect
*rect
, int row
, int col
)
895 wxGridCell
*cell
= GetCell(row
, col
);
898 dc
->SetBrush(cell
->GetBackgroundBrush());
899 dc
->SetPen(*wxTRANSPARENT_PEN
);
901 #if 0 // In wxWin 2.0 the dc code is exact. RR.
903 dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
-1, rect
->height
-1);
905 dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
, rect
->height
);
909 dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
-1, rect
->height
-1);
911 dc
->SetPen(*wxBLACK_PEN
);
915 void wxGenericGrid::DrawCellValue(wxDC
*dc
, wxRect
*rect
, int row
, int col
)
917 wxGridCell
*cell
= GetCell(row
, col
);
920 wxBitmap
*bitmap
= cell
->GetCellBitmap();
930 DrawBitmapRect(dc
, bitmap
, &rect2
, cell
->GetAlignment());
934 dc
->SetBackgroundMode(wxTRANSPARENT
);
935 dc
->SetTextForeground(cell
->GetTextColour());
936 dc
->SetFont(cell
->GetFont());
938 if ( !cell
->GetTextValue().IsNull() )
939 DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, cell
->GetAlignment());
944 void wxGenericGrid::AdjustScrollbars(void)
947 GetClientSize(&cw
, &ch
);
949 // We find the view size by seeing how many rows/cols fit on
951 // BUT... this means that the scrollbar should be adjusted every time
952 // it's scrolled, as well as when sized, because with variable size rows/cols,
953 // the number of rows/col visible on the view differs according to what bit
954 // you're looking at. The object length is always the same, but the
955 // view length differs.
957 // Since this may not be known until the end of this function, we should probably call AdjustScrollbars
959 int vertScrollBarWidth
= m_scrollWidth
;
960 int horizScrollBarHeight
= m_scrollWidth
;
961 if (m_vScrollBar
&& !m_vScrollBar
->IsShown())
962 vertScrollBarWidth
= 0;
963 if (m_hScrollBar
&& !m_hScrollBar
->IsShown())
964 horizScrollBarHeight
= 0;
966 int noHorizSteps
= 0;
969 if (m_totalGridWidth
+ vertScrollBarWidth
<= cw
)
978 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
980 widthCount
+= m_colWidths
[i
];
981 // A partial bit doesn't count, we still have to scroll to see the
983 if (widthCount
+ m_leftOfSheet
+ m_verticalLabelWidth
> (cw
-vertScrollBarWidth
))
992 if (m_totalGridHeight
+ horizScrollBarHeight
<= ch
)
1001 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1003 heightCount
+= m_rowHeights
[i
];
1004 // A partial bit doesn't count, we still have to scroll to see the
1006 if (heightCount
+ m_topOfSheet
+ m_horizontalLabelHeight
> (ch
-horizScrollBarHeight
))
1015 if (m_totalGridWidth
+ vertScrollBarWidth
<= cw
)
1018 m_hScrollBar
->Show(FALSE
);
1024 m_hScrollBar
->Show(TRUE
);
1027 if (m_totalGridHeight
+ horizScrollBarHeight
<= ch
)
1030 m_vScrollBar
->Show(FALSE
);
1036 m_vScrollBar
->Show(TRUE
);
1039 UpdateDimensions(); // Necessary in case m_scrollPosX/Y changed
1041 vertScrollBarWidth
= m_scrollWidth
;
1042 horizScrollBarHeight
= m_scrollWidth
;
1043 if (m_vScrollBar
&& !m_vScrollBar
->IsShown())
1044 vertScrollBarWidth
= 0;
1045 if (m_hScrollBar
&& !m_hScrollBar
->IsShown())
1046 horizScrollBarHeight
= 0;
1048 if (m_hScrollBar
&& m_hScrollBar
->IsShown())
1050 int nCols
= GetCols();
1051 m_hScrollBar
->SetScrollbar(m_hScrollBar
->GetThumbPosition(), wxMax(noHorizSteps
, 1), (noHorizSteps
== 0) ? 1 : nCols
, wxMax(noHorizSteps
, 1));
1054 m_hScrollBar->SetSize(m_leftOfSheet, ch - m_scrollWidth -2, // why -2 ? Robert.
1055 cw - vertScrollBarWidth - m_leftOfSheet, m_scrollWidth);
1057 m_hScrollBar
->SetSize(m_leftOfSheet
, ch
- m_scrollWidth
,
1058 cw
- vertScrollBarWidth
- m_leftOfSheet
, m_scrollWidth
);
1062 if (m_vScrollBar
&& m_vScrollBar
->IsShown())
1064 int nRows
= GetRows();
1066 m_vScrollBar
->SetScrollbar(m_vScrollBar
->GetThumbPosition(), wxMax(noVertSteps
, 1), (noVertSteps
== 0) ? 1 : nRows
, wxMax(noVertSteps
, 1));
1067 m_vScrollBar
->SetSize(cw
- m_scrollWidth
, m_topOfSheet
,
1068 m_scrollWidth
, ch
- m_topOfSheet
- horizScrollBarHeight
);
1072 void wxGenericGrid::OnSize(wxSizeEvent
& WXUNUSED(event
) )
1074 if (!m_vScrollBar
|| !m_hScrollBar
)
1080 GetClientSize(&cw
, &ch
);
1082 if (m_editCreated
&& m_editingPanel
&& GetTextItem() && GetTextItem()->IsShown())
1084 m_editingPanel
->SetSize(0, 0, cw
, m_editControlPosition
.height
+ m_editControlPosition
.y
+ 2);
1085 GetTextItem()->SetSize(m_editControlPosition
.x
, m_editControlPosition
.y
,
1086 cw
- 2*m_editControlPosition
.x
, m_editControlPosition
.height
);
1090 bool wxGenericGrid::CellHitTest(int x
, int y
, int *row
, int *col
)
1092 // Find the selected cell and call OnSelectCell
1093 if (x
>= (m_leftOfSheet
+ m_verticalLabelWidth
) && y
>= (m_topOfSheet
+ m_horizontalLabelHeight
) &&
1094 x
<= m_rightOfSheet
&& y
<= m_bottomOfSheet
)
1096 // Calculate the cell number from x and y
1097 x
-= (m_verticalLabelWidth
+ m_leftOfSheet
);
1098 y
-= (m_topOfSheet
+ m_horizontalLabelHeight
);
1102 // Now we need to do a hit test for which row we're on
1103 int currentHeight
= 0;
1104 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1106 if (y
>= currentHeight
&& y
<= (currentHeight
+ m_rowHeights
[i
]))
1111 currentHeight
+= m_rowHeights
[i
];
1114 // Now we need to do a hit test for which column we're on
1115 int currentWidth
= 0;
1116 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1118 if (x
>= currentWidth
&& x
<= (currentWidth
+ m_colWidths
[i
]))
1123 currentWidth
+= m_colWidths
[i
];
1130 bool wxGenericGrid::LabelSashHitTest(int x
, int y
, int *orientation
, int *rowOrCol
, int *startPos
)
1135 if (x
>= (m_leftOfSheet
+ m_verticalLabelWidth
) && y
>= m_topOfSheet
&&
1136 x
<= m_rightOfSheet
&& y
<= (m_topOfSheet
+ m_horizontalLabelHeight
))
1138 // We may be on a column label sash.
1139 int currentWidth
= m_leftOfSheet
+ m_verticalLabelWidth
;
1140 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1142 if (x
>= (currentWidth
+ m_colWidths
[i
] - tolerance
) && x
<= (currentWidth
+ m_colWidths
[i
] + tolerance
))
1144 *orientation
= wxHORIZONTAL
;
1146 *startPos
= currentWidth
;
1149 currentWidth
+= m_colWidths
[i
];
1153 else if (x
>= m_leftOfSheet
&& y
>= (m_topOfSheet
+ m_horizontalLabelHeight
) &&
1154 x
<= (m_leftOfSheet
+ m_verticalLabelWidth
) && y
<= m_bottomOfSheet
)
1156 // We may be on a row label sash.
1157 int currentHeight
= m_topOfSheet
+ m_horizontalLabelHeight
;
1158 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1160 if (y
>= (currentHeight
+ m_rowHeights
[i
] - tolerance
) && y
<= (currentHeight
+ m_rowHeights
[i
] + tolerance
))
1162 *orientation
= wxVERTICAL
;
1164 *startPos
= currentHeight
;
1167 currentHeight
+= m_rowHeights
[i
];
1174 bool wxGenericGrid::LabelHitTest(int x
, int y
, int *row
, int *col
)
1176 // Find the selected label
1177 if (x
>= m_leftOfSheet
&& y
>= m_topOfSheet
&&
1178 x
<= m_rightOfSheet
&& y
<= m_bottomOfSheet
)
1180 // Calculate the cell number from x and y
1186 // Now we need to do a hit test for which row we're on
1187 int currentHeight
= m_horizontalLabelHeight
;
1188 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1190 if (y
>= currentHeight
&& y
<= (currentHeight
+ m_rowHeights
[i
]))
1195 currentHeight
+= m_rowHeights
[i
];
1197 if (y
>= 0 && y
<= m_horizontalLabelHeight
)
1202 // Now we need to do a hit test for which column we're on
1203 int currentWidth
= m_verticalLabelWidth
;
1204 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1206 if (x
>= currentWidth
&& x
<= (currentWidth
+ m_colWidths
[i
]))
1211 currentWidth
+= m_colWidths
[i
];
1213 if (x
>= 0 && x
<= m_verticalLabelWidth
)
1218 if ((*col
== -1) || (*row
== -1))
1226 void wxGenericGrid::OnMouseEvent(wxMouseEvent
& ev
)
1230 wxClientDC
dc(this);
1234 if (CellHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1236 OnSelectCellImplementation(& dc
, row
, col
);
1238 //OnCellLeftClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1239 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CELL_LCLICK
, this,
1240 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1241 ev
.ControlDown(), ev
.ShiftDown());
1242 GetEventHandler()->ProcessEvent(g_evt
);
1245 if (LabelHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1247 //OnLabelLeftClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1248 wxGridEvent
g_evt(GetId(), wxEVT_GRID_LABEL_LCLICK
, this,
1249 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1250 ev
.ControlDown(), ev
.ShiftDown());
1251 GetEventHandler()->ProcessEvent(g_evt
);
1256 else if (ev
.Dragging() && ev
.LeftIsDown())
1258 switch (m_dragStatus
)
1260 case wxGRID_DRAG_NONE
:
1263 if (LabelSashHitTest((int)ev
.GetX(), (int)ev
.GetY(), &orientation
, &m_dragRowOrCol
, &m_dragStartPosition
))
1265 if (orientation
== wxHORIZONTAL
)
1267 m_dragStatus
= wxGRID_DRAG_LEFT_RIGHT
;
1268 SetCursor(m_horizontalSashCursor
);
1269 m_dragLastPosition
= (int)ev
.GetX();
1273 m_dragStatus
= wxGRID_DRAG_UP_DOWN
;
1274 SetCursor(m_verticalSashCursor
);
1275 m_dragLastPosition
= (int)ev
.GetY();
1277 wxClientDC
dc(this);
1279 dc
.SetLogicalFunction(wxINVERT
);
1280 if (orientation
== wxHORIZONTAL
)
1281 dc
.DrawLine((int)ev
.GetX(), m_topOfSheet
, (int)ev
.GetX(), m_bottomOfSheet
);
1283 dc
.DrawLine(m_leftOfSheet
, (int)ev
.GetY(), m_rightOfSheet
, (int)ev
.GetY());
1290 case wxGRID_DRAG_LEFT_RIGHT
:
1292 wxClientDC
dc(this);
1294 dc
.SetLogicalFunction(wxINVERT
);
1295 dc
.DrawLine(m_dragLastPosition
, m_topOfSheet
, m_dragLastPosition
, m_bottomOfSheet
);
1297 dc
.DrawLine((int)ev
.GetX(), m_topOfSheet
, (int)ev
.GetX(), m_bottomOfSheet
);
1300 m_dragLastPosition
= (int)ev
.GetX();
1301 SetCursor(m_horizontalSashCursor
);
1304 case wxGRID_DRAG_UP_DOWN
:
1306 wxClientDC
dc(this);
1308 dc
.SetLogicalFunction(wxINVERT
);
1309 dc
.DrawLine(m_leftOfSheet
, m_dragLastPosition
, m_rightOfSheet
, m_dragLastPosition
);
1311 dc
.DrawLine(m_leftOfSheet
, (int)ev
.GetY(), m_rightOfSheet
, (int)ev
.GetY());
1314 m_dragLastPosition
= (int)ev
.GetY();
1315 SetCursor(m_verticalSashCursor
);
1320 else if (ev
.Moving())
1322 int rowOrCol
, orientation
, startPos
;
1323 if (LabelSashHitTest((int)ev
.GetX(), (int)ev
.GetY(), &orientation
, &rowOrCol
, &startPos
))
1325 if (orientation
== wxHORIZONTAL
)
1326 SetCursor(m_horizontalSashCursor
);
1328 SetCursor(m_verticalSashCursor
);
1331 SetCursor(*wxSTANDARD_CURSOR
);
1333 else if (ev
.LeftUp())
1335 switch (m_dragStatus
)
1337 case wxGRID_DRAG_LEFT_RIGHT
:
1339 wxClientDC
dc(this);
1341 dc
.SetLogicalFunction(wxINVERT
);
1342 dc
.DrawLine(m_dragLastPosition
, m_topOfSheet
, m_dragLastPosition
, m_bottomOfSheet
);
1343 dc
.SetLogicalFunction(wxCOPY
);
1347 if (ev
.GetX() > m_dragStartPosition
)
1349 m_colWidths
[m_dragRowOrCol
] = (short)(ev
.GetX() - m_dragStartPosition
);
1354 SetCursor(*wxSTANDARD_CURSOR
);
1356 GetClientSize(&cw
, &ch
);
1361 case wxGRID_DRAG_UP_DOWN
:
1363 wxClientDC
dc(this);
1365 dc
.SetLogicalFunction(wxINVERT
);
1366 dc
.DrawLine(m_leftOfSheet
, m_dragLastPosition
, m_rightOfSheet
, m_dragLastPosition
);
1367 dc
.SetLogicalFunction(wxCOPY
);
1371 if (ev
.GetY() > m_dragStartPosition
)
1373 m_rowHeights
[m_dragRowOrCol
] = (short)(ev
.GetY() - m_dragStartPosition
);
1378 SetCursor(*wxSTANDARD_CURSOR
);
1382 m_dragStatus
= wxGRID_DRAG_NONE
;
1384 else if (ev
.RightDown())
1387 if (CellHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1389 //OnCellRightClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1390 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CELL_RCLICK
, this,
1391 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1392 ev
.ControlDown(), ev
.ShiftDown());
1393 GetEventHandler()->ProcessEvent(g_evt
);
1396 if (LabelHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1398 //OnLabelRightClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1399 wxGridEvent
g_evt(GetId(), wxEVT_GRID_LABEL_RCLICK
, this,
1400 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1401 ev
.ControlDown(), ev
.ShiftDown());
1402 GetEventHandler()->ProcessEvent(g_evt
);
1407 void wxGenericGrid::OnSelectCellImplementation(wxDC
*dc
, int row
, int col
)
1409 m_wCursorColumn
= col
;
1412 //OnChangeSelectionLabel();
1413 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_SEL_LABEL
, this);
1414 GetEventHandler()->ProcessEvent(g_evt
);
1416 SetGridClippingRegion(dc
);
1418 // Remove the highlight from the old cell
1419 if ( m_currentRectVisible
&& !(m_editable
&& m_editInPlace
) )
1425 // Highlight the new cell and copy its content to the edit control
1426 SetCurrentRect(m_wCursorRow
, m_wCursorColumn
);
1427 wxGridCell
*cell
= GetCell(m_wCursorRow
, m_wCursorColumn
);
1430 if ( cell
->GetTextValue().IsNull() )
1431 m_textItem
->SetValue("");
1433 m_textItem
->SetValue(cell
->GetTextValue());
1436 SetGridClippingRegion(dc
);
1439 if ( m_editable
&& m_editInPlace
)
1441 m_inPlaceTextItem
->SetSize( m_currentRect
.x
-2, m_currentRect
.y
-2,
1442 m_currentRect
.width
+4, m_currentRect
.height
+4 );
1446 if ( cell
->GetTextValue().IsNull() )
1448 m_inPlaceTextItem
->SetValue( "" );
1452 m_inPlaceTextItem
->SetFont( cell
->GetFont() );
1453 m_inPlaceTextItem
->SetValue( cell
->GetTextValue() );
1457 m_inPlaceTextItem
->Show(TRUE
);
1458 m_inPlaceTextItem
->SetFocus();
1462 // 1) Why isn't this needed for Windows??
1463 // Probably because of the SetValue?? JS.
1464 // 2) Arrrrrgh. This isn't needed anywhere,
1465 // of course. One hour of debugging... RR.
1467 // 3) It *is* needed for Motif - michael
1470 if ( !(m_editable
&& m_editInPlace
) )
1475 dc
->DestroyClippingRegion();
1477 OnSelectCell(row
, col
);
1478 wxGridEvent
g_evt2(GetId(), wxEVT_GRID_SELECT_CELL
, this, row
, col
);
1479 GetEventHandler()->ProcessEvent(g_evt2
);
1482 wxGridCell
*wxGenericGrid::OnCreateCell(void)
1484 return new wxGridCell(this);
1487 void wxGenericGrid::OnChangeLabels(void)
1491 for (i
= 0; i
< m_totalRows
; i
++)
1493 sprintf(buf
, "%d", i
+1);
1494 SetLabelValue(wxVERTICAL
, buf
, i
);
1496 // A...Z,AA...ZZ,AAA...ZZZ, etc.
1497 for (i
= 0; i
< m_totalCols
; i
++)
1500 int noTimes
= (i
/26 + 1);
1501 int ch
= (i
% 26) + 65;
1503 for (j
= 0; j
< noTimes
; j
++)
1506 sprintf(buf2
, "%c", (char)ch
);
1509 SetLabelValue(wxHORIZONTAL
, buf
, i
);
1513 void wxGenericGrid::OnChangeSelectionLabel(void)
1518 wxString
rowLabel(GetLabelValue(wxVERTICAL
, GetCursorRow()));
1519 wxString
colLabel(GetLabelValue(wxHORIZONTAL
, GetCursorColumn()));
1521 wxString newLabel
= colLabel
+ rowLabel
;
1522 if ((newLabel
.Length() > 0) && (newLabel
.Length() <= 8) && GetTextItem())
1524 // GetTextItem()->SetLabel(newLabel);
1528 void wxGenericGrid::HighlightCell(wxDC
*dc
)
1530 dc
->SetLogicalFunction(wxINVERT
);
1533 dc
->DrawLine( m_currentRect
.x
+ 1,
1534 m_currentRect
.y
+ 1,
1535 m_currentRect
.x
+ m_currentRect
.width
- 1,
1536 m_currentRect
.y
+ 1);
1538 dc
->DrawLine( m_currentRect
.x
+ m_currentRect
.width
- 1,
1539 m_currentRect
.y
+ 1,
1540 m_currentRect
.x
+ m_currentRect
.width
- 1,
1541 m_currentRect
.y
+m_currentRect
.height
- 1 );
1543 dc
->DrawLine( m_currentRect
.x
+ m_currentRect
.width
- 1,
1544 m_currentRect
.y
+ m_currentRect
.height
- 1,
1545 m_currentRect
.x
+ 1,
1546 m_currentRect
.y
+ m_currentRect
.height
- 1);
1548 dc
->DrawLine( m_currentRect
.x
+ 1,
1549 m_currentRect
.y
+ m_currentRect
.height
- 1,
1550 m_currentRect
.x
+ 1,
1551 m_currentRect
.y
+ 1);
1553 dc
->SetLogicalFunction(wxCOPY
);
1556 void wxGenericGrid::DrawCellText(void)
1558 if (!m_currentRectVisible
)
1561 wxGridCell
*cell
= GetCell(GetCursorRow(), GetCursorColumn());
1565 wxClientDC
dc(this);
1568 SetGridClippingRegion(& dc
);
1570 dc
.SetBackgroundMode(wxTRANSPARENT
);
1571 dc
.SetBrush(cell
->GetBackgroundBrush());
1573 wxString editValue
= m_textItem
->GetValue();
1576 rect
= m_currentRect
;
1582 // FIXME: what's this string of spaces supposed to represent?
1583 DrawTextRect(& dc
, " ", &rect
, wxLEFT
);
1584 DrawTextRect(& dc
, editValue
, &rect
, cell
->GetAlignment());
1586 dc
.DestroyClippingRegion();
1588 dc
.SetBackgroundMode(wxSOLID
);
1593 void wxGenericGrid::SetCurrentRect(int Row
, int Column
, int canvasW
, int canvasH
)
1595 int currentWidth
= m_leftOfSheet
+ m_verticalLabelWidth
;
1597 for (i
= m_scrollPosX
; i
< Column
; i
++)
1598 currentWidth
+= m_colWidths
[i
];
1600 int currentHeight
= m_topOfSheet
+ m_horizontalLabelHeight
;
1601 for (i
= m_scrollPosY
; i
< Row
; i
++)
1602 currentHeight
+= m_rowHeights
[i
];
1604 m_currentRect
.x
= currentWidth
;
1605 m_currentRect
.y
= currentHeight
;
1606 m_currentRect
.width
= m_colWidths
? (m_colWidths
[Column
]) : 0;
1607 m_currentRect
.height
= m_rowHeights
? (m_rowHeights
[Row
]) : 0;
1609 if (Row
< m_scrollPosY
|| Column
< m_scrollPosX
)
1610 m_currentRectVisible
= FALSE
;
1611 else if ((canvasW
!= -1 && canvasH
!= -1) && (m_currentRect
.x
> canvasW
|| m_currentRect
.y
> canvasH
))
1612 m_currentRectVisible
= FALSE
;
1613 else m_currentRectVisible
= TRUE
;
1616 static bool wxRectIntersection(wxRect
*rect1
, wxRect
*rect2
, wxRect
*rect3
)
1618 int x2_1
= rect1
->x
+ rect1
->width
;
1619 int y2_1
= rect1
->y
+ rect1
->height
;
1621 int x2_2
= rect2
->x
+ rect2
->width
;
1622 int y2_2
= rect2
->y
+ rect2
->height
;
1626 // Check for intersection
1627 if ((rect1
->x
> x2_2
) || (rect2
->x
> x2_1
) ||
1628 (rect1
->y
> y2_2
) || (rect2
->y
> y2_1
))
1631 rect3
->x
= rect3
->y
= rect3
->width
= rect3
->height
= 0;
1635 if (rect1
->x
> rect2
->x
)
1636 rect3
->x
= rect1
->x
;
1638 rect3
->x
= rect2
->x
;
1639 if (rect1
->y
> rect2
->y
)
1640 rect3
->y
= rect1
->y
;
1642 rect3
->y
= rect2
->y
;
1653 rect3
->width
= (int)(x2_3
- rect3
->x
);
1654 rect3
->height
= (int)(y2_3
- rect3
->y
);
1658 void wxGenericGrid::DrawTextRect(wxDC
*dc
, const wxString
& text
, wxRect
*rect
, int flag
)
1662 // Ultimately, this functionality should be built into wxWindows,
1663 // and optimized for each platform. E.g. on Windows, use DrawText
1664 // passing a clipping rectangle, so that the wxWindows clipping region
1665 // does not have to be used to implement this.
1667 // If we're already clipping, we need to find the intersection
1668 // between current clipping area and text clipping area.
1672 long clipX
, clipY
, clipW
, clipH
;
1673 dc
->GetClippingBox(&clipX
, &clipY
, &clipW
, &clipH
);
1674 clipRect
.x
= (int)clipX
; clipRect
.y
= (int)clipY
;
1675 clipRect
.width
= (int)clipW
; clipRect
.height
= (int)clipH
;
1677 bool alreadyClipping
= TRUE
;
1679 if (clipRect
.x
== 0 && clipRect
.y
== 0 && clipRect
.width
== 0 && clipRect
.height
== 0)
1681 alreadyClipping
= FALSE
;
1682 clipRect2
.x
= rect
->x
; clipRect2
.y
= rect
->y
;
1683 clipRect2
.width
= rect
->width
; clipRect2
.height
= rect
->height
;
1687 // Find intersection.
1688 if (!wxRectIntersection(rect
, &clipRect
, &clipRect2
))
1692 if (alreadyClipping
)
1693 dc
->DestroyClippingRegion();
1695 dc
->SetClippingRegion(clipRect2
.x
, clipRect2
.y
, clipRect2
.width
, clipRect2
.height
);
1696 long textWidth
, textHeight
;
1698 dc
->GetTextExtent(text
, &textWidth
, &textHeight
);
1706 x
= (rect
->x
+ rect
->width
- textWidth
- 1.0);
1707 y
= (rect
->y
+ (rect
->height
- textHeight
)/2.0);
1712 x
= (rect
->x
+ (rect
->width
- textWidth
)/2.0);
1713 y
= (rect
->y
+ (rect
->height
- textHeight
)/2.0);
1719 x
= (rect
->x
+ 1.0);
1720 y
= (rect
->y
+ (rect
->height
- textHeight
)/2.0);
1724 dc
->DrawText(text
, (long)x
, (long)y
);
1726 dc
->DestroyClippingRegion();
1728 // Restore old clipping
1729 if (alreadyClipping
)
1730 dc
->SetClippingRegion(clipRect
.x
, clipRect
.y
, clipRect
.width
, clipRect
.height
);
1735 void wxGenericGrid::DrawBitmapRect(wxDC
*dc
, wxBitmap
*bitmap
, wxRect
*rect
, int flag
)
1739 // Ultimately, this functionality should be built into wxWindows,
1740 // and optimized for each platform. E.g. on Windows, use DrawText
1741 // passing a clipping rectangle, so that the wxWindows clipping region
1742 // does not have to be used to implement this.
1744 // If we're already clipping, we need to find the intersection
1745 // between current clipping area and text clipping area.
1749 long clipX
, clipY
, clipW
, clipH
;
1750 dc
->GetClippingBox(&clipX
, &clipY
, &clipW
, &clipH
);
1751 clipRect
.x
= (int)clipX
; clipRect
.y
= (int)clipY
;
1752 clipRect
.width
= (int)clipW
; clipRect
.height
= (int)clipH
;
1754 bool alreadyClipping
= TRUE
;
1756 if (clipRect
.x
== 0 && clipRect
.y
== 0 && clipRect
.width
== 0 && clipRect
.height
== 0)
1758 alreadyClipping
= FALSE
;
1759 clipRect2
.x
= rect
->x
; clipRect2
.y
= rect
->y
;
1760 clipRect2
.width
= rect
->width
; clipRect2
.height
= rect
->height
;
1764 // Find intersection.
1765 if (!wxRectIntersection(rect
, &clipRect
, &clipRect2
))
1769 if (alreadyClipping
)
1770 dc
->DestroyClippingRegion();
1772 dc
->SetClippingRegion(clipRect2
.x
, clipRect2
.y
, clipRect2
.width
, clipRect2
.height
);
1773 float bitmapWidth
, bitmapHeight
;
1775 bitmapWidth
= bitmap
->GetWidth();
1776 bitmapHeight
= bitmap
->GetHeight();
1784 x
= (long)(rect
->x
+ rect
->width
- bitmapWidth
- 1);
1785 y
= (long)(rect
->y
+ (rect
->height
- bitmapHeight
)/2.0);
1790 x
= (long)(rect
->x
+ (rect
->width
- bitmapWidth
)/2.0);
1791 y
= (long)(rect
->y
+ (rect
->height
- bitmapHeight
)/2.0);
1797 x
= (long)(rect
->x
+ 1);
1798 y
= (long)(rect
->y
+ (rect
->height
- bitmapHeight
)/2.0);
1803 dcTemp
.SelectObject(*bitmap
);
1805 dc
->Blit( (long)x
, (long)y
, (long)bitmapWidth
, (long)bitmapHeight
, &dcTemp
, 0, 0);
1806 dcTemp
.SelectObject(wxNullBitmap
);
1808 dc
->DestroyClippingRegion();
1810 // Restore old clipping
1811 if (alreadyClipping
)
1812 dc
->SetClippingRegion(clipRect
.x
, clipRect
.y
, clipRect
.width
, clipRect
.height
);
1817 void wxGenericGrid::OnActivate(bool active
)
1821 // Edit control should always have the focus
1822 if (GetTextItem() && GetEditable())
1824 GetTextItem()->SetFocus();
1825 wxGridCell
*cell
= GetCell(GetCursorRow(), GetCursorColumn());
1827 GetTextItem()->SetValue(cell
->GetTextValue());
1832 void wxGenericGrid::SetCellValue(const wxString
& val
, int row
, int col
)
1834 wxGridCell
*cell
= GetCell(row
, col
);
1837 cell
->SetTextValue(val
);
1839 RefreshCell(row
, col
, TRUE
);
1843 void wxGenericGrid::RefreshCell(int row
, int col
, bool setText
)
1845 // Don't refresh within a pair of batch brackets
1846 if (GetBatchCount() > 0)
1850 GetClientSize(&cw
, &ch
);
1852 SetCurrentRect(row
, col
, cw
, ch
);
1853 if (m_currentRectVisible
)
1855 wxGridCell
*cell
= GetCell(row
, col
);
1857 bool currentPos
= FALSE
;
1858 if (row
== m_wCursorRow
&& col
== m_wCursorColumn
&& GetTextItem() && GetTextItem()->IsShown() && setText
)
1860 GetTextItem()->SetValue(cell
->GetTextValue());
1863 // Gets refreshed anyway in MSW
1868 wxClientDC
dc(this);
1870 DrawCellBackground(& dc
, &m_currentRect
, row
, col
);
1871 DrawCellValue(& dc
, &m_currentRect
, row
, col
);
1877 wxString
& wxGenericGrid::GetCellValue(int row
, int col
) const
1879 static wxString
emptyString("");
1881 wxGridCell
*cell
= GetCell(row
, col
);
1883 return cell
->GetTextValue();
1888 void wxGenericGrid::SetColumnWidth(int col
, int width
)
1890 if (col
<= m_totalCols
)
1891 m_colWidths
[col
] = width
;
1894 int wxGenericGrid::GetColumnWidth(int col
) const
1896 if (col
<= m_totalCols
)
1897 return m_colWidths
[col
];
1902 void wxGenericGrid::SetRowHeight(int row
, int height
)
1904 if (row
<= m_totalRows
)
1905 m_rowHeights
[row
] = height
;
1908 int wxGenericGrid::GetRowHeight(int row
) const
1910 if (row
<= m_totalRows
)
1911 return m_rowHeights
[row
];
1916 void wxGenericGrid::SetLabelSize(int orientation
, int sz
)
1918 if (orientation
== wxHORIZONTAL
)
1919 m_horizontalLabelHeight
= sz
;
1921 m_verticalLabelWidth
= sz
;
1923 SetCurrentRect(GetCursorRow(), GetCursorColumn());
1926 int wxGenericGrid::GetLabelSize(int orientation
) const
1928 if (orientation
== wxHORIZONTAL
)
1929 return m_horizontalLabelHeight
;
1931 return m_verticalLabelWidth
;
1934 wxGridCell
*wxGenericGrid::GetLabelCell(int orientation
, int pos
) const
1936 if (orientation
== wxHORIZONTAL
)
1938 if (m_colLabelCells
&& pos
< m_totalCols
)
1939 return m_colLabelCells
[pos
];
1941 return (wxGridCell
*) NULL
;
1945 if (m_rowLabelCells
&& pos
< m_totalRows
)
1946 return m_rowLabelCells
[pos
];
1948 return (wxGridCell
*) NULL
;
1952 void wxGenericGrid::SetLabelValue(int orientation
, const wxString
& val
, int pos
)
1954 wxGridCell
*cell
= GetLabelCell(orientation
, pos
);
1956 cell
->SetTextValue(val
);
1959 wxString
& wxGenericGrid::GetLabelValue(int orientation
, int pos
) const
1961 static wxString emptyString
= "";
1962 wxGridCell
*cell
= GetLabelCell(orientation
, pos
);
1964 return cell
->GetTextValue();
1969 void wxGenericGrid::SetLabelAlignment(int orientation
, int align
)
1971 if (orientation
== wxHORIZONTAL
)
1972 m_horizontalLabelAlignment
= align
;
1974 m_verticalLabelAlignment
= align
;
1976 SetCurrentRect(GetCursorRow(), GetCursorColumn());
1979 int wxGenericGrid::GetLabelAlignment(int orientation
) const
1981 if (orientation
== wxHORIZONTAL
)
1982 return m_horizontalLabelAlignment
;
1984 return m_verticalLabelAlignment
;
1987 void wxGenericGrid::SetLabelTextColour(const wxColour
& colour
)
1989 m_labelTextColour
= colour
;
1993 void wxGenericGrid::SetLabelBackgroundColour(const wxColour
& colour
)
1995 m_labelBackgroundColour
= colour
;
1996 m_labelBackgroundBrush
= * wxTheBrushList
->FindOrCreateBrush(m_labelBackgroundColour
, wxSOLID
);
1999 void wxGenericGrid::SetEditable(bool edit
)
2004 int controlW
, controlH
;
2005 m_textItem
->GetSize(&controlW
, &controlH
);
2006 m_editControlPosition
.height
= controlH
;
2008 m_topOfSheet
= m_editControlPosition
.x
+ controlH
+ 2;
2011 m_editingPanel
->Show(TRUE
);
2012 m_textItem
->Show(TRUE
);
2013 m_textItem
->SetFocus();
2016 if (m_inPlaceTextItem
)
2018 m_inPlaceTextItem
->Show(TRUE
);
2019 m_inPlaceTextItem
->SetFocus();
2027 m_textItem
->Show(FALSE
);
2028 m_editingPanel
->Show(FALSE
);
2031 if ( m_inPlaceTextItem
)
2033 m_inPlaceTextItem
->Show(FALSE
);
2037 SetCurrentRect(GetCursorRow(), GetCursorColumn());
2040 GetClientSize(&cw
, &ch
);
2045 int m_scrollWidth = 16;
2046 GetClientSize(&cw, &ch);
2049 m_vScrollBar->SetSize(cw - m_scrollWidth, m_topOfSheet,
2050 m_scrollWidth, ch - m_topOfSheet - m_scrollWidth);
2055 void wxGenericGrid::SetEditInPlace(bool edit
)
2057 if ( m_editInPlace
!= edit
)
2059 m_editInPlace
= edit
;
2061 if ( m_editInPlace
) // switched on
2063 if ( m_currentRectVisible
&& m_editable
)
2065 m_inPlaceTextItem
->SetSize( m_currentRect
.x
-2, m_currentRect
.y
-2,
2066 m_currentRect
.width
+4, m_currentRect
.height
+4 );
2068 wxGridCell
*cell
= GetCell(m_wCursorRow
, m_wCursorColumn
);
2072 if ( cell
->GetTextValue().IsNull() )
2074 m_inPlaceTextItem
->SetValue( "" );
2078 m_inPlaceTextItem
->SetFont( cell
->GetFont() );
2079 m_inPlaceTextItem
->SetValue( cell
->GetTextValue() );
2083 m_inPlaceTextItem
->Show( TRUE
);
2084 m_inPlaceTextItem
->SetFocus();
2087 else // switched off
2089 m_inPlaceTextItem
->Show( FALSE
);
2095 void wxGenericGrid::SetCellAlignment(int flag
, int row
, int col
)
2097 wxGridCell
*cell
= GetCell(row
, col
);
2099 cell
->SetAlignment(flag
);
2102 int wxGenericGrid::GetCellAlignment(int row
, int col
) const
2104 wxGridCell
*cell
= GetCell(row
, col
);
2106 return cell
->GetAlignment();
2108 return m_cellAlignment
;
2111 void wxGenericGrid::SetCellAlignment(int flag
)
2113 m_cellAlignment
= flag
;
2115 for (i
= 0; i
< GetRows(); i
++)
2116 for (j
= 0; j
< GetCols(); j
++)
2118 GetCell(i
, j
)->SetAlignment(flag
);
2121 int wxGenericGrid::GetCellAlignment(void) const
2123 return m_cellAlignment
;
2126 void wxGenericGrid::SetCellBackgroundColour(const wxColour
& col
)
2128 m_cellBackgroundColour
= col
;
2130 for (i
= 0; i
< GetRows(); i
++)
2131 for (j
= 0; j
< GetCols(); j
++)
2133 GetCell(i
, j
)->SetBackgroundColour(col
);
2136 void wxGenericGrid::SetCellBackgroundColour(const wxColour
& val
, int row
, int col
)
2138 wxGridCell
*cell
= GetCell(row
, col
);
2141 cell
->SetBackgroundColour(val
);
2142 RefreshCell(row
, col
);
2146 wxColour
& wxGenericGrid::GetCellBackgroundColour(int row
, int col
) const
2148 wxGridCell
*cell
= GetCell(row
, col
);
2150 return cell
->GetBackgroundColour();
2152 return (wxColour
&) m_cellBackgroundColour
;
2155 void wxGenericGrid::SetCellTextColour(const wxColour
& val
, int row
, int col
)
2157 wxGridCell
*cell
= GetCell(row
, col
);
2160 cell
->SetTextColour(val
);
2161 RefreshCell(row
, col
);
2165 void wxGenericGrid::SetCellTextFont(const wxFont
& fnt
, int row
, int col
)
2167 wxGridCell
*cell
= GetCell(row
, col
);
2171 RefreshCell(row
, col
);
2175 wxFont
& wxGenericGrid::GetCellTextFont(int row
, int col
) const
2177 wxGridCell
*cell
= GetCell(row
, col
);
2179 return (wxFont
&) cell
->GetFont();
2181 return (wxFont
&) m_cellTextFont
;
2184 wxColour
& wxGenericGrid::GetCellTextColour(int row
, int col
) const
2186 wxGridCell
*cell
= GetCell(row
, col
);
2188 return (wxColour
&) cell
->GetTextColour();
2190 return (wxColour
&) m_cellTextColour
;
2193 void wxGenericGrid::SetCellTextColour(const wxColour
& val
)
2195 m_cellTextColour
= val
;
2197 for (i
= 0; i
< GetRows(); i
++)
2198 for (j
= 0; j
< GetCols(); j
++)
2200 GetCell(i
, j
)->SetTextColour(val
);
2203 void wxGenericGrid::SetCellTextFont(const wxFont
& fnt
)
2205 m_cellTextFont
= fnt
;
2207 for (i
= 0; i
< GetRows(); i
++)
2208 for (j
= 0; j
< GetCols(); j
++)
2210 GetCell(i
, j
)->SetFont(fnt
);
2213 void wxGenericGrid::SetCellBitmap(wxBitmap
*bitmap
, int row
, int col
)
2215 wxGridCell
*cell
= GetCell(row
, col
);
2218 cell
->SetCellBitmap(bitmap
);
2219 RefreshCell(row
, col
);
2223 wxBitmap
*wxGenericGrid::GetCellBitmap(int row
, int col
) const
2225 wxGridCell
*cell
= GetCell(row
, col
);
2228 return cell
->GetCellBitmap();
2231 return (wxBitmap
*) NULL
;
2234 bool wxGenericGrid::InsertCols(int pos
, int n
, bool updateLabels
)
2236 if (pos
> m_totalCols
)
2240 return CreateGrid(1, n
);
2245 for (i
= 0; i
< m_totalRows
; i
++)
2247 wxGridCell
**cols
= m_gridCells
[i
];
2248 wxGridCell
**newCols
= new wxGridCell
*[m_totalCols
+ n
];
2249 for (j
= 0; j
< pos
; j
++)
2250 newCols
[j
] = cols
[j
];
2251 for (j
= pos
; j
< pos
+ n
; j
++)
2252 newCols
[j
] = new wxGridCell(this);
2253 for (j
= pos
+ n
; j
< m_totalCols
+ n
; j
++)
2254 newCols
[j
] = cols
[j
- n
];
2257 m_gridCells
[i
] = newCols
;
2261 short *newColWidths
= new short[m_totalCols
+ n
];
2262 for (j
= 0; j
< pos
; j
++)
2263 newColWidths
[j
] = m_colWidths
[j
];
2264 for (j
= pos
; j
< pos
+ n
; j
++)
2265 newColWidths
[j
] = wxGRID_DEFAULT_CELL_WIDTH
;
2266 for (j
= pos
+ n
; j
< m_totalCols
+ n
; j
++)
2267 newColWidths
[j
] = m_colWidths
[j
- n
];
2268 delete[] m_colWidths
;
2269 m_colWidths
= newColWidths
;
2272 wxGridCell
**newLabels
= new wxGridCell
*[m_totalCols
+ n
];
2273 for (j
= 0; j
< pos
; j
++)
2274 newLabels
[j
] = m_colLabelCells
[j
];
2275 for (j
= pos
; j
< pos
+ n
; j
++)
2276 newLabels
[j
] = new wxGridCell(this);
2277 for (j
= pos
+ n
; j
< m_totalCols
+ n
; j
++)
2278 newLabels
[j
] = m_colLabelCells
[j
- n
];
2280 delete[] m_colLabelCells
;
2281 m_colLabelCells
= newLabels
;
2287 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2288 GetEventHandler()->ProcessEvent(g_evt
);
2297 bool wxGenericGrid::InsertRows(int pos
, int n
, bool updateLabels
)
2299 if (pos
> m_totalRows
)
2303 return CreateGrid(n
, 1);
2308 wxGridCell
***rows
= new wxGridCell
**[m_totalRows
+ n
];
2311 for (i
= 0; i
< pos
; i
++)
2312 rows
[i
] = m_gridCells
[i
];
2314 for (i
= pos
; i
< pos
+ n
; i
++)
2316 rows
[i
] = new wxGridCell
*[m_totalCols
];
2317 for (j
= 0; j
< m_totalCols
; j
++)
2318 rows
[i
][j
] = new wxGridCell(this);
2321 for (i
= pos
+ n
; i
< m_totalRows
+ n
; i
++)
2322 rows
[i
] = m_gridCells
[i
- n
];
2324 delete[] m_gridCells
;
2328 short *newRowHeights
= new short[m_totalRows
+ n
];
2329 for (i
= 0; i
< pos
; i
++)
2330 newRowHeights
[i
] = m_rowHeights
[i
];
2331 for (i
= pos
; i
< pos
+ n
; i
++)
2332 newRowHeights
[i
] = wxGRID_DEFAULT_CELL_HEIGHT
;
2333 for (i
= pos
+ n
; i
< m_totalRows
+ n
; i
++)
2334 newRowHeights
[i
] = m_rowHeights
[i
- n
];
2335 delete[] m_rowHeights
;
2336 m_rowHeights
= newRowHeights
;
2339 wxGridCell
**newLabels
= new wxGridCell
*[m_totalRows
+ n
];
2340 for (i
= 0; i
< pos
; i
++)
2341 newLabels
[i
] = m_rowLabelCells
[i
];
2342 for (i
= pos
; i
< pos
+ n
; i
++)
2343 newLabels
[i
] = new wxGridCell(this);
2344 for (i
= pos
+ n
; i
< m_totalRows
+ n
; i
++)
2345 newLabels
[i
] = m_rowLabelCells
[i
- n
];
2347 delete[] m_rowLabelCells
;
2348 m_rowLabelCells
= newLabels
;
2354 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2355 GetEventHandler()->ProcessEvent(g_evt
);
2364 bool wxGenericGrid::AppendCols(int n
, bool updateLabels
)
2366 return InsertCols(GetCols(), n
, updateLabels
);
2369 bool wxGenericGrid::AppendRows(int n
, bool updateLabels
)
2371 return InsertRows(GetRows(), n
, updateLabels
);
2374 bool wxGenericGrid::DeleteRows(int pos
, int n
, bool updateLabels
)
2376 if (pos
> m_totalRows
)
2383 wxGridCell
***rows
= new wxGridCell
**[m_totalRows
- n
];
2386 for (i
= 0; i
< pos
; i
++)
2387 rows
[i
] = m_gridCells
[i
];
2389 for (i
= pos
+ n
; i
< m_totalRows
; i
++)
2390 rows
[i
-n
] = m_gridCells
[i
];
2392 delete[] m_gridCells
;
2396 short *newRowHeights
= new short[m_totalRows
- n
];
2397 for (i
= 0; i
< pos
; i
++)
2398 newRowHeights
[i
] = m_rowHeights
[i
];
2399 for (i
= pos
+ n
; i
< m_totalRows
; i
++)
2400 newRowHeights
[i
-n
] = m_rowHeights
[i
];
2401 delete[] m_rowHeights
;
2402 m_rowHeights
= newRowHeights
;
2405 wxGridCell
**newLabels
= new wxGridCell
*[m_totalRows
- n
];
2406 for (i
= 0; i
< pos
; i
++)
2407 newLabels
[i
] = m_rowLabelCells
[i
];
2408 for (i
= pos
+ n
; i
< m_totalRows
; i
++)
2409 newLabels
[i
-n
] = m_rowLabelCells
[i
];
2411 delete[] m_rowLabelCells
;
2412 m_rowLabelCells
= newLabels
;
2418 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2419 GetEventHandler()->ProcessEvent(g_evt
);
2426 bool wxGenericGrid::DeleteCols(int pos
, int n
, bool updateLabels
)
2428 if (pos
+ n
> m_totalCols
)
2436 for (i
= 0; i
< m_totalRows
; i
++)
2438 wxGridCell
**cols
= m_gridCells
[i
];
2439 wxGridCell
**newCols
= new wxGridCell
*[m_totalCols
- n
];
2440 for (j
= 0; j
< pos
; j
++)
2441 newCols
[j
] = cols
[j
];
2442 for (j
= pos
; j
< pos
+ n
; j
++)
2444 for (j
= pos
+ n
; j
< m_totalCols
; j
++)
2445 newCols
[j
-n
] = cols
[j
];
2448 m_gridCells
[i
] = newCols
;
2452 short *newColWidths
= new short[m_totalCols
- n
];
2453 for (j
= 0; j
< pos
; j
++)
2454 newColWidths
[j
] = m_colWidths
[j
];
2455 for (j
= pos
+ n
; j
< m_totalCols
; j
++)
2456 newColWidths
[j
-n
] = m_colWidths
[j
];
2457 delete[] m_colWidths
;
2458 m_colWidths
= newColWidths
;
2461 wxGridCell
**newLabels
= new wxGridCell
*[m_totalCols
- n
];
2462 for (j
= 0; j
< pos
; j
++)
2463 newLabels
[j
] = m_colLabelCells
[j
];
2464 for (j
= pos
+ n
; j
< m_totalCols
; j
++)
2465 newLabels
[j
-n
] = m_colLabelCells
[j
];
2467 delete[] m_colLabelCells
;
2468 m_colLabelCells
= newLabels
;
2474 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2475 GetEventHandler()->ProcessEvent(g_evt
);
2482 void wxGenericGrid::SetGridCursor(int row
, int col
)
2484 if (row
>= m_totalRows
|| col
>= m_totalCols
)
2487 if (row
== GetCursorRow() && col
== GetCursorColumn())
2490 wxClientDC
dc(this);
2493 SetGridClippingRegion(& dc
);
2495 if (m_currentRectVisible
&& !(m_editable
&& m_editInPlace
) )
2496 HighlightCell(& dc
);
2499 m_wCursorColumn
= col
;
2502 GetClientSize(&cw
, &ch
);
2504 SetCurrentRect(row
, col
, cw
, ch
);
2506 if (m_currentRectVisible
&& !(m_editable
&& m_editInPlace
) )
2507 HighlightCell(& dc
);
2509 dc
.DestroyClippingRegion();
2517 wxGridCell::wxGridCell(wxGenericGrid
*window
)
2519 cellBitmap
= (wxBitmap
*) NULL
;
2521 backgroundBrush
= wxNullBrush
;
2523 textColour
= window
->GetCellTextColour();
2525 textColour
.Set(0,0,0);
2527 backgroundColour
= window
->GetCellBackgroundColour();
2529 backgroundColour
.Set(255,255,255);
2532 font
= window
->GetCellTextFont();
2534 font
= * wxTheFontList
->FindOrCreateFont(12, wxSWISS
, wxNORMAL
, wxNORMAL
);
2536 SetBackgroundColour(backgroundColour
);
2539 alignment
= window
->GetCellAlignment();
2544 wxGridCell::~wxGridCell(void)
2548 void wxGridCell::SetBackgroundColour(const wxColour
& colour
)
2550 backgroundColour
= colour
;
2551 backgroundBrush
= * wxTheBrushList
->FindOrCreateBrush(backgroundColour
, wxSOLID
);
2554 void wxGenericGrid::OnText(wxCommandEvent
& WXUNUSED(ev
) )
2556 // michael - added this conditional to prevent change to
2557 // grid cell text when edit control is hidden but still has
2562 wxGenericGrid
*grid
= this;
2563 wxGridCell
*cell
= grid
->GetCell(grid
->GetCursorRow(), grid
->GetCursorColumn());
2564 if (cell
&& grid
->CurrentCellVisible())
2566 cell
->SetTextValue(grid
->GetTextItem()->GetValue());
2567 if ( m_editInPlace
&& !m_inOnTextInPlace
)
2569 m_inPlaceTextItem
->SetValue( grid
->GetTextItem()->GetValue() );
2572 wxClientDC
dc(grid
);
2575 grid
->SetGridClippingRegion(& dc
);
2576 grid
->DrawCellBackground(& dc
, &grid
->GetCurrentRect(), grid
->GetCursorRow(), grid
->GetCursorColumn());
2577 grid
->DrawCellValue(& dc
, &grid
->GetCurrentRect(), grid
->GetCursorRow(), grid
->GetCursorColumn());
2578 if ( !(m_editable
&& m_editInPlace
) ) grid
->HighlightCell(& dc
);
2579 dc
.DestroyClippingRegion();
2582 //grid->OnCellChange(grid->GetCursorRow(), grid->GetCursorColumn());
2583 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CELL_CHANGE
, grid
,
2584 grid
->GetCursorRow(), grid
->GetCursorColumn());
2585 GetEventHandler()->ProcessEvent(g_evt
);
2587 // grid->DrawCellText();
2592 void wxGenericGrid::OnTextEnter(wxCommandEvent
& WXUNUSED(ev
) )
2594 // move the cursor down the current row (if possible)
2595 // when the enter key has been pressed
2599 if ( GetCursorRow() < GetRows()-1 )
2601 wxClientDC
dc( this );
2603 OnSelectCellImplementation(& dc
,
2605 GetCursorColumn() );
2611 void wxGenericGrid::OnTextInPlace(wxCommandEvent
& ev
)
2615 wxGenericGrid
*grid
= this;
2616 wxGridCell
*cell
= grid
->GetCell(grid
->GetCursorRow(), grid
->GetCursorColumn());
2617 if (cell
&& grid
->CurrentCellVisible())
2619 m_inOnTextInPlace
= TRUE
;
2620 grid
->GetTextItem()->SetValue( m_inPlaceTextItem
->GetValue() );
2622 m_inOnTextInPlace
= FALSE
;
2627 void wxGenericGrid::OnTextInPlaceEnter(wxCommandEvent
& WXUNUSED(ev
) )
2629 // move the cursor down the current row (if possible)
2630 // when the enter key has been pressed
2634 if ( GetCursorRow() < GetRows()-1 )
2636 wxClientDC
dc( this );
2638 OnSelectCellImplementation(& dc
,
2640 GetCursorColumn() );
2646 void wxGenericGrid::OnGridScroll(wxScrollEvent
& ev
)
2648 static bool inScroll
= FALSE
;
2653 if ( m_editInPlace
) m_inPlaceTextItem
->Show(FALSE
);
2656 wxGenericGrid
*win
= this;
2658 bool change
= FALSE
;
2660 if (ev
.GetEventObject() == win
->GetHorizScrollBar())
2662 change
= (ev
.GetPosition() != m_scrollPosX
);
2663 win
->SetScrollPosX(ev
.GetPosition());
2667 change
= (ev
.GetPosition() != m_scrollPosY
);
2668 win
->SetScrollPosY(ev
.GetPosition());
2671 win
->UpdateDimensions();
2673 win
->SetCurrentRect(win
->GetCursorRow(), win
->GetCursorColumn());
2675 // Because rows and columns can be arbitrary sizes,
2676 // the scrollbars will need to be adjusted to reflect the
2680 if (change
) win
->Refresh(FALSE
);
2682 if ( m_editInPlace
&& m_currentRectVisible
)
2684 m_inPlaceTextItem
->SetSize( m_currentRect
.x
-2, m_currentRect
.y
-2,
2685 m_currentRect
.width
+4, m_currentRect
.height
+4 );
2686 m_inPlaceTextItem
->Show( TRUE
);
2687 m_inPlaceTextItem
->SetFocus();
2695 //----------------------------------------------------------------------
2696 // Default wxGridEvent handlers
2697 // (just redirect to the pre-existing virtual methods)
2699 void wxGenericGrid::_OnSelectCell(wxGridEvent
& ev
)
2701 OnSelectCell(ev
.m_row
, ev
.m_col
);
2704 void wxGenericGrid::_OnCreateCell(wxGridEvent
& ev
)
2706 ev
.m_cell
= OnCreateCell();
2709 void wxGenericGrid::_OnChangeLabels(wxGridEvent
& WXUNUSED(ev
))
2714 void wxGenericGrid::_OnChangeSelectionLabel(wxGridEvent
& WXUNUSED(ev
))
2716 OnChangeSelectionLabel();
2719 void wxGenericGrid::_OnCellChange(wxGridEvent
& ev
)
2721 OnCellChange(ev
.m_row
, ev
.m_col
);
2724 void wxGenericGrid::_OnCellLeftClick(wxGridEvent
& ev
)
2726 OnCellLeftClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2729 void wxGenericGrid::_OnCellRightClick(wxGridEvent
& ev
)
2731 OnCellRightClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2734 void wxGenericGrid::_OnLabelLeftClick(wxGridEvent
& ev
)
2736 OnLabelLeftClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2739 void wxGenericGrid::_OnLabelRightClick(wxGridEvent
& ev
)
2741 OnLabelRightClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);