1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxGenericGrid
4 // Author: Julian Smart
5 // Modified by: Michael Bedward 20 Apr 1999
6 // Added edit in place facility
9 // Copyright: (c) Julian Smart and Markus Holzem
10 // Licence: wxWindows license
11 /////////////////////////////////////////////////////////////////////////////
14 #pragma implementation "gridg.h"
18 // For compilers that support precompilation, includes "wx/wx.h".
19 #include "wx/wxprec.h"
27 #include "wx/dcclient.h"
28 #include "wx/dcmemory.h"
29 #include "wx/textctrl.h"
34 #include "wx/string.h"
35 #include "wx/generic/gridg.h"
36 #include "wx/settings.h"
38 // Set to zero to use no double-buffering
40 #define wxUSE_DOUBLE_BUFFERING 1
42 #define wxUSE_DOUBLE_BUFFERING 0
45 #define wxGRID_DRAG_NONE 0
46 #define wxGRID_DRAG_LEFT_RIGHT 1
47 #define wxGRID_DRAG_UP_DOWN 2
49 IMPLEMENT_DYNAMIC_CLASS(wxGenericGrid
, wxPanel
)
50 IMPLEMENT_DYNAMIC_CLASS(wxGridEvent
, wxEvent
)
52 BEGIN_EVENT_TABLE(wxGenericGrid
, wxPanel
)
53 EVT_SIZE(wxGenericGrid::OnSize
)
54 EVT_PAINT(wxGenericGrid::OnPaint
)
55 EVT_ERASE_BACKGROUND(wxGenericGrid::OnEraseBackground
)
56 EVT_MOUSE_EVENTS(wxGenericGrid::OnMouseEvent
)
57 EVT_TEXT(wxGRID_TEXT_CTRL
, wxGenericGrid::OnText
)
58 EVT_TEXT(wxGRID_EDIT_IN_PLACE_TEXT_CTRL
, wxGenericGrid::OnTextInPlace
)
59 EVT_COMMAND_SCROLL(wxGRID_HSCROLL
, wxGenericGrid::OnGridScroll
)
60 EVT_COMMAND_SCROLL(wxGRID_VSCROLL
, wxGenericGrid::OnGridScroll
)
62 // default wxGridEvent handlers
63 EVT_GRID_SELECT_CELL(wxGenericGrid::_OnSelectCell
)
64 EVT_GRID_CREATE_CELL(wxGenericGrid::_OnCreateCell
)
65 EVT_GRID_CHANGE_LABELS(wxGenericGrid::_OnChangeLabels
)
66 EVT_GRID_CHANGE_SEL_LABEL(wxGenericGrid::_OnChangeSelectionLabel
)
67 EVT_GRID_CELL_CHANGE(wxGenericGrid::_OnCellChange
)
68 EVT_GRID_CELL_LCLICK(wxGenericGrid::_OnCellLeftClick
)
69 EVT_GRID_CELL_RCLICK(wxGenericGrid::_OnCellRightClick
)
70 EVT_GRID_LABEL_LCLICK(wxGenericGrid::_OnLabelLeftClick
)
71 EVT_GRID_LABEL_RCLICK(wxGenericGrid::_OnLabelRightClick
)
76 wxGenericGrid::wxGenericGrid(void)
79 m_hScrollBar
= (wxScrollBar
*) NULL
;
80 m_vScrollBar
= (wxScrollBar
*) NULL
;
81 m_cellTextColour
= *wxBLACK
;
82 m_cellBackgroundColour
= *wxWHITE
;
83 m_labelTextColour
= *wxBLACK
;
84 // m_labelBackgroundColour = *wxLIGHT_GREY;
85 m_labelBackgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
86 m_labelBackgroundBrush
= wxNullBrush
;
87 m_labelTextFont
= wxNullFont
;
88 m_cellTextFont
= wxNullFont
;
89 m_textItem
= (wxTextCtrl
*) NULL
;
90 m_currentRectVisible
= FALSE
;
94 m_inOnTextInPlace
= FALSE
;
96 #if defined(__WIN95__)
97 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
98 #elif defined(__WXGTK__)
99 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
103 m_dragStatus
= wxGRID_DRAG_NONE
;
105 m_dragStartPosition
= 0;
106 m_dragLastPosition
= 0;
107 m_divisionPen
= wxNullPen
;
108 m_leftOfSheet
= wxGRID_DEFAULT_SHEET_LEFT
;
109 m_topOfSheet
= wxGRID_DEFAULT_SHEET_TOP
;
110 m_cellHeight
= wxGRID_DEFAULT_CELL_HEIGHT
;
111 m_totalGridWidth
= 0;
112 m_totalGridHeight
= 0;
113 m_colWidths
= (short *) NULL
;
114 m_rowHeights
= (short *) NULL
;
115 m_verticalLabelWidth
= wxGRID_DEFAULT_VERTICAL_LABEL_WIDTH
;
116 m_horizontalLabelHeight
= wxGRID_DEFAULT_HORIZONAL_LABEL_HEIGHT
;
117 m_verticalLabelAlignment
= wxCENTRE
;
118 m_horizontalLabelAlignment
= wxCENTRE
;
119 m_editControlPosition
.x
= wxGRID_DEFAULT_EDIT_X
;
120 m_editControlPosition
.y
= wxGRID_DEFAULT_EDIT_Y
;
121 m_editControlPosition
.width
= wxGRID_DEFAULT_EDIT_WIDTH
;
122 m_editControlPosition
.height
= wxGRID_DEFAULT_EDIT_HEIGHT
;
127 m_editCreated
= FALSE
;
130 m_gridCells
= (wxGridCell
***) NULL
;
131 m_rowLabelCells
= (wxGridCell
**) NULL
;
132 m_colLabelCells
= (wxGridCell
**) NULL
;
133 m_textItem
= (wxTextCtrl
*) NULL
;
136 bool wxGenericGrid::Create(wxWindow
*parent
, wxWindowID id
, const wxPoint
& pos
, const wxSize
& size
,
137 long style
, const wxString
& name
)
140 m_editingPanel
= (wxPanel
*) NULL
;
141 m_hScrollBar
= (wxScrollBar
*) NULL
;
142 m_vScrollBar
= (wxScrollBar
*) NULL
;
143 m_cellTextColour
= *wxBLACK
;
144 m_cellBackgroundColour
= *wxWHITE
;
145 m_labelTextColour
= *wxBLACK
;
146 // m_labelBackgroundColour = *wxLIGHT_GREY;
147 m_labelBackgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
148 m_labelBackgroundBrush
= wxNullBrush
;
149 m_labelTextFont
= * wxTheFontList
->FindOrCreateFont(10, wxSWISS
, wxNORMAL
, wxBOLD
);
150 m_cellTextFont
= * wxTheFontList
->FindOrCreateFont(10, wxSWISS
, wxNORMAL
, wxNORMAL
);
151 m_textItem
= (wxTextCtrl
*) NULL
;
152 m_currentRectVisible
= FALSE
;
154 #if defined(__WIN95__)
155 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
156 #elif defined(__WXGTK__)
157 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
161 m_dragStatus
= wxGRID_DRAG_NONE
;
163 m_dragStartPosition
= 0;
164 m_dragLastPosition
= 0;
165 m_divisionPen
= * wxThePenList
->FindOrCreatePen("LIGHT GREY", 1, wxSOLID
);
166 m_doubleBufferingBitmap
= (wxBitmap
*) NULL
;
168 if (!m_horizontalSashCursor
.Ok())
170 m_horizontalSashCursor
= wxCursor(wxCURSOR_SIZEWE
);
171 m_verticalSashCursor
= wxCursor(wxCURSOR_SIZENS
);
174 SetLabelBackgroundColour(m_labelBackgroundColour
);
176 m_leftOfSheet
= wxGRID_DEFAULT_SHEET_LEFT
;
177 m_topOfSheet
= wxGRID_DEFAULT_SHEET_TOP
;
178 m_cellHeight
= wxGRID_DEFAULT_CELL_HEIGHT
;
179 m_totalGridWidth
= 0;
180 m_totalGridHeight
= 0;
181 m_colWidths
= (short *) NULL
;
182 m_rowHeights
= (short *) NULL
;
184 m_verticalLabelWidth
= wxGRID_DEFAULT_VERTICAL_LABEL_WIDTH
;
185 m_horizontalLabelHeight
= wxGRID_DEFAULT_HORIZONAL_LABEL_HEIGHT
;
186 m_verticalLabelAlignment
= wxCENTRE
;
187 m_horizontalLabelAlignment
= wxCENTRE
;
188 m_editControlPosition
.x
= wxGRID_DEFAULT_EDIT_X
;
189 m_editControlPosition
.y
= wxGRID_DEFAULT_EDIT_Y
;
190 m_editControlPosition
.width
= wxGRID_DEFAULT_EDIT_WIDTH
;
191 m_editControlPosition
.height
= wxGRID_DEFAULT_EDIT_HEIGHT
;
199 /* Store the rect. coordinates for the current cell */
200 SetCurrentRect(m_wCursorRow
, m_wCursorColumn
);
202 m_editCreated
= FALSE
;
206 m_gridCells
= (wxGridCell
***) NULL
;
207 m_rowLabelCells
= (wxGridCell
**) NULL
;
208 m_colLabelCells
= (wxGridCell
**) NULL
;
209 m_textItem
= (wxTextCtrl
*) NULL
;
211 wxPanel::Create(parent
, id
, pos
, size
, style
, name
);
213 m_editingPanel
= new wxPanel(this);
215 m_textItem
= new wxTextCtrl(m_editingPanel
, wxGRID_TEXT_CTRL
, "",
216 wxPoint(m_editControlPosition
.x
, m_editControlPosition
.y
),
217 wxSize(m_editControlPosition
.width
, -1),
219 m_textItem
->Show(TRUE
);
220 m_textItem
->SetFocus();
221 int controlW
, controlH
;
223 m_textItem
->GetSize(&controlW
, &controlH
);
224 m_editControlPosition
.height
= controlH
;
226 m_topOfSheet
= m_editControlPosition
.y
+ controlH
+ 2;
228 m_editCreated
= TRUE
;
230 m_hScrollBar
= new wxScrollBar(this, wxGRID_HSCROLL
, wxPoint(0, 0), wxSize(20, 100), wxHORIZONTAL
);
231 m_vScrollBar
= new wxScrollBar(this, wxGRID_VSCROLL
, wxPoint(0, 0), wxSize(100, 20), wxVERTICAL
);
233 // SetSize(pos.x, pos.y, size.x, size.y);
235 m_inPlaceTextItem
= new wxTextCtrl( (wxPanel
*)this, wxGRID_EDIT_IN_PLACE_TEXT_CTRL
, "",
236 wxPoint( m_currentRect
.x
-2, m_currentRect
.y
-2 ),
237 wxSize( m_currentRect
.width
+4, m_currentRect
.height
+4 ),
239 m_inPlaceTextItem
->Show(TRUE
);
240 m_inPlaceTextItem
->SetFocus();
245 wxGenericGrid::~wxGenericGrid(void)
250 void wxGenericGrid::ClearGrid(void)
255 for (i
= 0; i
< m_totalRows
; i
++)
257 for (j
= 0; j
< m_totalCols
; j
++)
258 if (m_gridCells
[i
][j
])
259 delete m_gridCells
[i
][j
];
260 delete[] m_gridCells
[i
];
262 delete[] m_gridCells
;
263 m_gridCells
= (wxGridCell
***) NULL
;
266 delete[] m_colWidths
;
267 m_colWidths
= (short *) NULL
;
269 delete[] m_rowHeights
;
270 m_rowHeights
= (short *) NULL
;
274 for (i
= 0; i
< m_totalRows
; i
++)
275 delete m_rowLabelCells
[i
];
276 delete[] m_rowLabelCells
;
277 m_rowLabelCells
= (wxGridCell
**) NULL
;
281 for (i
= 0; i
< m_totalCols
; i
++)
282 delete m_colLabelCells
[i
];
283 delete[] m_colLabelCells
;
284 m_colLabelCells
= (wxGridCell
**) NULL
;
286 if (m_doubleBufferingBitmap
)
288 delete m_doubleBufferingBitmap
;
289 m_doubleBufferingBitmap
= (wxBitmap
*) NULL
;
293 bool wxGenericGrid::CreateGrid(int nRows
, int nCols
, wxString
**cellValues
, short *widths
,
294 short defaultWidth
, short defaultHeight
)
300 m_colWidths
= new short[nCols
];
301 m_rowHeights
= new short[nRows
];
302 for (i
= 0; i
< nCols
; i
++)
304 m_colWidths
[i
] = widths
[i
];
306 m_colWidths
[i
] = defaultWidth
;
307 for (i
= 0; i
< nRows
; i
++)
308 m_rowHeights
[i
] = defaultHeight
;
310 m_gridCells
= new wxGridCell
**[nRows
];
312 for (i
= 0; i
< nRows
; i
++)
313 m_gridCells
[i
] = new wxGridCell
*[nCols
];
315 for (i
= 0; i
< nRows
; i
++)
316 for (j
= 0; j
< nCols
; j
++)
319 //m_gridCells[i][j] = OnCreateCell();
320 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CREATE_CELL
, this, i
, j
);
321 GetEventHandler()->ProcessEvent(g_evt
);
322 m_gridCells
[i
][j
] = g_evt
.m_cell
;
323 m_gridCells
[i
][j
]->SetTextValue(cellValues
[i
][j
]);
326 m_gridCells
[i
][j
] = (wxGridCell
*) NULL
;
328 m_rowLabelCells
= new wxGridCell
*[nRows
];
329 for (i
= 0; i
< nRows
; i
++)
330 m_rowLabelCells
[i
] = new wxGridCell(this);
331 m_colLabelCells
= new wxGridCell
*[nCols
];
332 for (i
= 0; i
< nCols
; i
++)
333 m_colLabelCells
[i
] = new wxGridCell(this);
335 m_wCursorRow
= m_wCursorColumn
= 0;
336 SetCurrentRect(0, 0);
338 // Need to determine various dimensions
342 int objectSizeX
= m_totalCols
;
344 int viewLengthX
= m_totalCols
;
347 m_hScrollBar->SetViewLength(viewLengthX);
348 m_hScrollBar->SetObjectLength(objectSizeX);
349 m_hScrollBar->SetPageSize(pageSizeX);
351 m_hScrollBar
->SetScrollbar(m_hScrollBar
->GetThumbPosition(), pageSizeX
, objectSizeX
, viewLengthX
);
353 int objectSizeY
= m_totalRows
;
355 int viewLengthY
= m_totalRows
;
358 m_vScrollBar->SetViewLength(viewLengthY);
359 m_vScrollBar->SetObjectLength(objectSizeY);
360 m_vScrollBar->SetPageSize(pageSizeY);
363 m_vScrollBar
->SetScrollbar(m_vScrollBar
->GetThumbPosition(), pageSizeY
, objectSizeY
, viewLengthY
);
368 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
369 GetEventHandler()->ProcessEvent(g_evt
);
371 //OnChangeSelectionLabel();
372 wxGridEvent
g_evt2(GetId(), wxEVT_GRID_CHANGE_SEL_LABEL
, this);
373 GetEventHandler()->ProcessEvent(g_evt2
);
378 // Need to determine various dimensions
379 void wxGenericGrid::UpdateDimensions(void)
381 int canvasWidth
, canvasHeight
;
382 GetSize(&canvasWidth
, &canvasHeight
);
384 if (m_editCreated
&& m_editable
)
386 int controlW
, controlH
;
387 GetTextItem()->GetSize(&controlW
, &controlH
);
388 m_topOfSheet
= m_editControlPosition
.y
+ controlH
+ 2;
392 m_rightOfSheet
= m_leftOfSheet
+ m_verticalLabelWidth
;
394 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
396 if (m_rightOfSheet
> canvasWidth
)
399 m_rightOfSheet
+= m_colWidths
[i
];
401 m_bottomOfSheet
= m_topOfSheet
+ m_horizontalLabelHeight
;
402 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
404 if (m_bottomOfSheet
> canvasHeight
)
407 m_bottomOfSheet
+= m_rowHeights
[i
];
410 m_totalGridWidth
= m_leftOfSheet
+ m_verticalLabelWidth
;
411 for (i
= 0; i
< m_totalCols
; i
++)
413 m_totalGridWidth
+= m_colWidths
[i
];
415 m_totalGridHeight
= m_topOfSheet
+ m_horizontalLabelHeight
;
416 for (i
= 0; i
< m_totalRows
; i
++)
418 m_totalGridHeight
+= m_rowHeights
[i
];
422 wxGridCell
*wxGenericGrid::GetCell(int row
, int col
) const
425 return (wxGridCell
*) NULL
;
427 if ((row
>= m_totalRows
) || (col
>= m_totalCols
))
428 return (wxGridCell
*) NULL
;
430 wxGridCell
*cell
= m_gridCells
[row
][col
];
433 // m_gridCells[row][col] = OnCreateCell();
434 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CREATE_CELL
, (wxGenericGrid
*) this, row
, col
);
435 GetEventHandler()->ProcessEvent(g_evt
);
436 m_gridCells
[row
][col
] = g_evt
.m_cell
;
437 return m_gridCells
[row
][col
];
443 void wxGenericGrid::SetGridClippingRegion(wxDC
*dc
)
445 int m_scrollWidthHoriz
= 0;
446 int m_scrollWidthVert
= 0;
448 GetClientSize(&cw
, &ch
);
450 if (m_hScrollBar
&& m_hScrollBar
->IsShown())
451 m_scrollWidthHoriz
= m_scrollWidth
;
452 if (m_vScrollBar
&& m_vScrollBar
->IsShown())
453 m_scrollWidthVert
= m_scrollWidth
;
455 // Don't paint over the scrollbars
456 dc
->SetClippingRegion(m_leftOfSheet
, m_topOfSheet
,
457 cw
- m_scrollWidthVert
- m_leftOfSheet
, ch
- m_scrollWidthHoriz
- m_topOfSheet
);
460 void wxGenericGrid::OnPaint(wxPaintEvent
& WXUNUSED(event
))
463 GetClientSize(&w
, &h
);
465 bool useDoubleBuffering
= (bool) wxUSE_DOUBLE_BUFFERING
;
466 if (useDoubleBuffering
)
468 // Reuse the old bitmap if possible
470 if (!m_doubleBufferingBitmap
||
471 (m_doubleBufferingBitmap
->GetWidth() < w
|| m_doubleBufferingBitmap
->GetHeight() < h
))
473 if (m_doubleBufferingBitmap
)
474 delete m_doubleBufferingBitmap
;
475 m_doubleBufferingBitmap
= new wxBitmap(w
, h
);
477 if (!m_doubleBufferingBitmap
|| !m_doubleBufferingBitmap
->Ok())
479 // If we couldn't create a new bitmap, perhaps because resources were low,
480 // then don't complain, just don't double-buffer
481 if (m_doubleBufferingBitmap
)
482 delete m_doubleBufferingBitmap
;
483 m_doubleBufferingBitmap
= (wxBitmap
*) NULL
;
484 useDoubleBuffering
= FALSE
;
488 if (useDoubleBuffering
)
490 wxPaintDC
paintDC(this);
491 wxMemoryDC
dc(& paintDC
);
492 dc
.SelectObject(* m_doubleBufferingBitmap
);
496 int vertScrollBarWidth
= m_scrollWidth
;
497 int horizScrollBarHeight
= m_scrollWidth
;
498 if (m_vScrollBar
&& !m_vScrollBar
->IsShown())
499 vertScrollBarWidth
= 0;
500 if (m_hScrollBar
&& !m_hScrollBar
->IsShown())
501 horizScrollBarHeight
= 0;
503 paintDC
.Blit(m_leftOfSheet
, m_topOfSheet
, w
- vertScrollBarWidth
- m_leftOfSheet
, h
- horizScrollBarHeight
- m_topOfSheet
,
504 &dc
, m_leftOfSheet
, m_topOfSheet
, wxCOPY
);
506 dc
.SelectObject(wxNullBitmap
);
515 void wxGenericGrid::PaintGrid(wxDC
& dc
)
518 dc
.SetOptimization(FALSE
);
520 SetGridClippingRegion(& dc
);
522 DrawLabelAreas(& dc
);
524 DrawEditableArea(& dc
);
525 DrawColumnLabels(& dc
);
530 /* Hilight present cell */
531 SetCurrentRect(m_wCursorRow
, m_wCursorColumn
);
532 if (m_currentRectVisible
&& !(m_editable
&& m_editInPlace
))
535 dc
.DestroyClippingRegion();
536 dc
.SetOptimization(TRUE
);
540 // Erase (some of) the background.
541 // Currently, a Windows-only optimisation.
542 void wxGenericGrid::OnEraseBackground(wxEraseEvent
& WXUNUSED(event
) )
546 dc
.SetOptimization(FALSE
);
549 GetClientSize(& w
, & h
);
550 dc
.SetBrush(*wxLIGHT_GREY_BRUSH
);
551 dc
.SetPen(*wxLIGHT_GREY_PEN
);
553 if (m_hScrollBar
&& m_hScrollBar
->IsShown() && m_vScrollBar
&& m_vScrollBar
->IsShown())
555 dc
.DrawRectangle(w
- m_scrollWidth
, h
- m_scrollWidth
, m_scrollWidth
, m_scrollWidth
);
558 dc
.SetOptimization(TRUE
);
563 void wxGenericGrid::DrawLabelAreas(wxDC
*dc
)
566 GetClientSize(&cw
, &ch
);
568 dc
->SetPen(*wxTRANSPARENT_PEN
);
569 // dc->SetBrush(*dc->GetBackground());
571 // Should blank out any area which isn't going to be painted over.
572 // dc->DrawRectangle(m_leftOfSheet, m_bottomOfSheet, cw - m_leftOfSheet, ch - m_bottomOfSheet);
573 // dc->DrawRectangle(m_rightOfSheet, m_topOfSheet, cw - m_rightOfSheet, ch - m_topOfSheet);
575 // Paint the label areas
576 dc
->SetBrush(m_labelBackgroundBrush
);
577 // dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, m_rightOfSheet - m_leftOfSheet + 1, m_horizontalLabelHeight + 1);
578 dc
->DrawRectangle(m_leftOfSheet
, m_topOfSheet
, cw
-m_leftOfSheet
, m_horizontalLabelHeight
+ 1);
579 // dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, m_verticalLabelWidth + 1, m_bottomOfSheet - m_topOfSheet + 1);
580 dc
->DrawRectangle(m_leftOfSheet
, m_topOfSheet
, m_verticalLabelWidth
+ 1, ch
-m_topOfSheet
);
583 void wxGenericGrid::DrawEditableArea(wxDC
*dc
)
586 GetClientSize(&cw
, &ch
);
588 dc
->SetPen(*wxTRANSPARENT_PEN
);
589 dc
->SetBrush(*wxTheBrushList
->FindOrCreateBrush(m_cellBackgroundColour
, wxSOLID
));
590 // dc->DrawRectangle(m_leftOfSheet+m_verticalLabelWidth, m_topOfSheet+m_horizontalLabelHeight,
591 // m_rightOfSheet-(m_leftOfSheet+m_verticalLabelWidth) + 1, m_bottomOfSheet - (m_topOfSheet+m_horizontalLabelHeight) + 1);
592 dc
->DrawRectangle(m_leftOfSheet
+m_verticalLabelWidth
, m_topOfSheet
+m_horizontalLabelHeight
,
593 cw
-(m_leftOfSheet
+m_verticalLabelWidth
), ch
- (m_topOfSheet
+m_horizontalLabelHeight
));
596 void wxGenericGrid::DrawGridLines(wxDC
*dc
)
599 GetClientSize(&cw
, &ch
);
603 if (m_divisionPen
.Ok())
605 dc
->SetPen(m_divisionPen
);
607 int heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
609 // Draw horizontal grey lines for cells
610 for (i
= m_scrollPosY
; i
< (m_totalRows
+1); i
++)
612 if (heightCount
> ch
)
616 dc
->DrawLine(m_leftOfSheet
, heightCount
,
619 heightCount
+= m_rowHeights
[i
];
624 if (m_verticalLabelWidth
> 0)
626 dc
->SetPen(*wxBLACK_PEN
);
628 // Draw horizontal black lines for row labels
629 int heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
630 for (i
= m_scrollPosY
; i
< (m_totalRows
+1); i
++)
632 if (heightCount
> ch
)
636 dc
->DrawLine(m_leftOfSheet
, heightCount
,
637 m_verticalLabelWidth
, heightCount
);
639 heightCount
+= m_rowHeights
[i
];
642 // Draw a black vertical line for row number cells
643 dc
->DrawLine(m_leftOfSheet
+ m_verticalLabelWidth
, m_topOfSheet
,
644 m_leftOfSheet
+ m_verticalLabelWidth
, ch
);
645 // First vertical line
646 dc
->DrawLine(m_leftOfSheet
, m_topOfSheet
, m_leftOfSheet
, ch
);
648 dc
->SetPen(*wxWHITE_PEN
);
650 // Draw highlights on row labels
651 heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
652 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
654 if (heightCount
> ch
)
658 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
659 m_verticalLabelWidth
, heightCount
+1);
660 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
661 m_leftOfSheet
+1, heightCount
+ m_rowHeights
[i
] - 1);
662 heightCount
+= m_rowHeights
[i
];
665 // Last one - down to the floor.
666 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
667 m_verticalLabelWidth
, heightCount
+1);
668 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
669 m_leftOfSheet
+1, ch
);
673 if (m_divisionPen
.Ok())
675 dc
->SetPen(m_divisionPen
);
677 // Draw vertical grey lines for cells
678 int widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
679 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
685 // Skip the first one
686 if (i
!= m_scrollPosX
)
688 dc
->DrawLine(widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
,
689 widthCount
, m_bottomOfSheet
);
691 widthCount
+= m_colWidths
[i
];
695 dc
->DrawLine(widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
,
696 widthCount
, m_bottomOfSheet
);
699 dc
->SetPen(*wxBLACK_PEN
);
701 // Draw two black horizontal lines for column number cells
703 m_leftOfSheet
, m_topOfSheet
,
705 dc
->DrawLine(m_leftOfSheet
, m_topOfSheet
+ m_horizontalLabelHeight
,
706 cw
, m_topOfSheet
+ m_horizontalLabelHeight
);
708 if (m_horizontalLabelHeight
> 0)
710 int widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
712 // Draw black vertical lines for column number cells
713 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
719 dc
->DrawLine(widthCount
, m_topOfSheet
,
720 widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
);
721 widthCount
+= m_colWidths
[i
];
726 dc
->DrawLine(widthCount
, m_topOfSheet
,
727 widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
);
730 dc
->SetPen(*wxWHITE_PEN
);
731 widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
733 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
739 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
740 widthCount
+m_colWidths
[i
], m_topOfSheet
+1);
741 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
742 widthCount
+1, m_topOfSheet
+m_horizontalLabelHeight
);
743 widthCount
+= m_colWidths
[i
];
746 // Last one - to the right side of the canvas.
747 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
749 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
750 widthCount
+1, m_topOfSheet
+m_horizontalLabelHeight
);
755 void wxGenericGrid::DrawColumnLabels(wxDC
*dc
)
758 GetClientSize(&cw
, &ch
);
760 if (m_horizontalLabelHeight
== 0)
766 // Draw letters for columns
767 rect
.y
= m_topOfSheet
+ 1;
768 rect
.height
= m_horizontalLabelHeight
- 1;
770 dc
->SetTextBackground(m_labelBackgroundColour
);
771 dc
->SetBackgroundMode(wxTRANSPARENT
);
772 // dc->SetTextForeground(m_labelTextColour);
774 int widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
775 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
781 rect
.x
= 1 + widthCount
;
782 rect
.width
= m_colWidths
[i
];
783 DrawColumnLabel(dc
, &rect
, i
);
785 widthCount
+= m_colWidths
[i
];
790 void wxGenericGrid::DrawColumnLabel(wxDC
*dc
, wxRect
*rect
, int col
)
792 wxGridCell
*cell
= GetLabelCell(wxHORIZONTAL
, col
);
801 dc
->SetTextForeground(GetLabelTextColour());
802 dc
->SetFont(GetLabelTextFont());
803 if ( !cell
->GetTextValue().IsNull() )
804 DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, GetLabelAlignment(wxHORIZONTAL
));
808 void wxGenericGrid::DrawRowLabels(wxDC
*dc
)
811 GetClientSize(&cw
, &ch
);
813 if (m_verticalLabelWidth
== 0)
819 // Draw numbers for rows
820 rect
.x
= m_leftOfSheet
;
821 rect
.width
= m_verticalLabelWidth
;
823 int heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
825 dc
->SetTextBackground(m_labelBackgroundColour
);
826 dc
->SetBackgroundMode(wxTRANSPARENT
);
828 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
830 if (heightCount
> ch
)
834 rect
.y
= 1 + heightCount
;
835 rect
.height
= m_rowHeights
[i
];
836 DrawRowLabel(dc
, &rect
, i
);
838 heightCount
+= m_rowHeights
[i
];
843 void wxGenericGrid::DrawRowLabel(wxDC
*dc
, wxRect
*rect
, int row
)
845 wxGridCell
*cell
= GetLabelCell(wxVERTICAL
, row
);
854 dc
->SetTextForeground(GetLabelTextColour());
855 dc
->SetFont(GetLabelTextFont());
856 if ( !cell
->GetTextValue().IsNull() )
857 DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, GetLabelAlignment(wxVERTICAL
));
861 void wxGenericGrid::DrawCells(wxDC
*dc
)
864 GetClientSize(&cw
, &ch
);
868 // Draw value corresponding to each cell
869 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
871 for (j
= m_scrollPosX
; j
< m_totalCols
; j
++)
873 SetCurrentRect(i
, j
, cw
, ch
);
874 if (m_currentRectVisible
)
876 DrawCellBackground(dc
, &m_currentRect
, i
, j
);
877 DrawCellValue(dc
, &m_currentRect
, i
, j
);
879 if (m_currentRect
.x
> cw
)
882 if (m_currentRect
.y
> ch
)
885 dc
->SetBackgroundMode(wxSOLID
);
886 dc
->SetPen(*wxBLACK_PEN
);
889 void wxGenericGrid::DrawCellBackground(wxDC
*dc
, wxRect
*rect
, int row
, int col
)
891 wxGridCell
*cell
= GetCell(row
, col
);
894 dc
->SetBrush(cell
->GetBackgroundBrush());
895 dc
->SetPen(*wxTRANSPARENT_PEN
);
897 #if 0 // In wxWin 2.0 the dc code is exact. RR.
899 dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
-1, rect
->height
-1);
901 dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
, rect
->height
);
905 dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
-1, rect
->height
-1);
907 dc
->SetPen(*wxBLACK_PEN
);
911 void wxGenericGrid::DrawCellValue(wxDC
*dc
, wxRect
*rect
, int row
, int col
)
913 wxGridCell
*cell
= GetCell(row
, col
);
916 wxBitmap
*bitmap
= cell
->GetCellBitmap();
926 DrawBitmapRect(dc
, bitmap
, &rect2
, cell
->GetAlignment());
930 dc
->SetBackgroundMode(wxTRANSPARENT
);
931 dc
->SetTextForeground(cell
->GetTextColour());
932 dc
->SetFont(cell
->GetFont());
934 if ( !cell
->GetTextValue().IsNull() )
935 DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, cell
->GetAlignment());
940 void wxGenericGrid::AdjustScrollbars(void)
943 GetClientSize(&cw
, &ch
);
945 // We find the view size by seeing how many rows/cols fit on
947 // BUT... this means that the scrollbar should be adjusted every time
948 // it's scrolled, as well as when sized, because with variable size rows/cols,
949 // the number of rows/col visible on the view differs according to what bit
950 // you're looking at. The object length is always the same, but the
951 // view length differs.
953 // Since this may not be known until the end of this function, we should probably call AdjustScrollbars
955 int vertScrollBarWidth
= m_scrollWidth
;
956 int horizScrollBarHeight
= m_scrollWidth
;
957 if (m_vScrollBar
&& !m_vScrollBar
->IsShown())
958 vertScrollBarWidth
= 0;
959 if (m_hScrollBar
&& !m_hScrollBar
->IsShown())
960 horizScrollBarHeight
= 0;
962 int noHorizSteps
= 0;
965 if (m_totalGridWidth
+ vertScrollBarWidth
<= cw
)
974 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
976 widthCount
+= m_colWidths
[i
];
977 // A partial bit doesn't count, we still have to scroll to see the
979 if (widthCount
+ m_leftOfSheet
+ m_verticalLabelWidth
> (cw
-vertScrollBarWidth
))
988 if (m_totalGridHeight
+ horizScrollBarHeight
<= ch
)
997 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
999 heightCount
+= m_rowHeights
[i
];
1000 // A partial bit doesn't count, we still have to scroll to see the
1002 if (heightCount
+ m_topOfSheet
+ m_horizontalLabelHeight
> (ch
-horizScrollBarHeight
))
1011 if (m_totalGridWidth
+ vertScrollBarWidth
<= cw
)
1014 m_hScrollBar
->Show(FALSE
);
1020 m_hScrollBar
->Show(TRUE
);
1023 if (m_totalGridHeight
+ horizScrollBarHeight
<= ch
)
1026 m_vScrollBar
->Show(FALSE
);
1032 m_vScrollBar
->Show(TRUE
);
1035 UpdateDimensions(); // Necessary in case m_scrollPosX/Y changed
1037 vertScrollBarWidth
= m_scrollWidth
;
1038 horizScrollBarHeight
= m_scrollWidth
;
1039 if (m_vScrollBar
&& !m_vScrollBar
->IsShown())
1040 vertScrollBarWidth
= 0;
1041 if (m_hScrollBar
&& !m_hScrollBar
->IsShown())
1042 horizScrollBarHeight
= 0;
1044 if (m_hScrollBar
&& m_hScrollBar
->IsShown())
1046 int nCols
= GetCols();
1047 m_hScrollBar
->SetScrollbar(m_hScrollBar
->GetThumbPosition(), wxMax(noHorizSteps
, 1), (noHorizSteps
== 0) ? 1 : nCols
, wxMax(noHorizSteps
, 1));
1050 m_hScrollBar->SetSize(m_leftOfSheet, ch - m_scrollWidth -2, // why -2 ? Robert.
1051 cw - vertScrollBarWidth - m_leftOfSheet, m_scrollWidth);
1053 m_hScrollBar
->SetSize(m_leftOfSheet
, ch
- m_scrollWidth
,
1054 cw
- vertScrollBarWidth
- m_leftOfSheet
, m_scrollWidth
);
1058 if (m_vScrollBar
&& m_vScrollBar
->IsShown())
1060 int nRows
= GetRows();
1062 m_vScrollBar
->SetScrollbar(m_vScrollBar
->GetThumbPosition(), wxMax(noVertSteps
, 1), (noVertSteps
== 0) ? 1 : nRows
, wxMax(noVertSteps
, 1));
1063 m_vScrollBar
->SetSize(cw
- m_scrollWidth
, m_topOfSheet
,
1064 m_scrollWidth
, ch
- m_topOfSheet
- horizScrollBarHeight
);
1068 void wxGenericGrid::OnSize(wxSizeEvent
& WXUNUSED(event
) )
1070 if (!m_vScrollBar
|| !m_hScrollBar
)
1076 GetClientSize(&cw
, &ch
);
1078 if (m_editCreated
&& m_editingPanel
&& GetTextItem() && GetTextItem()->IsShown())
1080 m_editingPanel
->SetSize(0, 0, cw
, m_editControlPosition
.height
+ m_editControlPosition
.y
+ 2);
1081 GetTextItem()->SetSize(m_editControlPosition
.x
, m_editControlPosition
.y
,
1082 cw
- 2*m_editControlPosition
.x
, m_editControlPosition
.height
);
1086 bool wxGenericGrid::CellHitTest(int x
, int y
, int *row
, int *col
)
1088 // Find the selected cell and call OnSelectCell
1089 if (x
>= (m_leftOfSheet
+ m_verticalLabelWidth
) && y
>= (m_topOfSheet
+ m_horizontalLabelHeight
) &&
1090 x
<= m_rightOfSheet
&& y
<= m_bottomOfSheet
)
1092 // Calculate the cell number from x and y
1093 x
-= (m_verticalLabelWidth
+ m_leftOfSheet
);
1094 y
-= (m_topOfSheet
+ m_horizontalLabelHeight
);
1098 // Now we need to do a hit test for which row we're on
1099 int currentHeight
= 0;
1100 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1102 if (y
>= currentHeight
&& y
<= (currentHeight
+ m_rowHeights
[i
]))
1107 currentHeight
+= m_rowHeights
[i
];
1110 // Now we need to do a hit test for which column we're on
1111 int currentWidth
= 0;
1112 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1114 if (x
>= currentWidth
&& x
<= (currentWidth
+ m_colWidths
[i
]))
1119 currentWidth
+= m_colWidths
[i
];
1126 bool wxGenericGrid::LabelSashHitTest(int x
, int y
, int *orientation
, int *rowOrCol
, int *startPos
)
1131 if (x
>= (m_leftOfSheet
+ m_verticalLabelWidth
) && y
>= m_topOfSheet
&&
1132 x
<= m_rightOfSheet
&& y
<= (m_topOfSheet
+ m_horizontalLabelHeight
))
1134 // We may be on a column label sash.
1135 int currentWidth
= m_leftOfSheet
+ m_verticalLabelWidth
;
1136 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1138 if (x
>= (currentWidth
+ m_colWidths
[i
] - tolerance
) && x
<= (currentWidth
+ m_colWidths
[i
] + tolerance
))
1140 *orientation
= wxHORIZONTAL
;
1142 *startPos
= currentWidth
;
1145 currentWidth
+= m_colWidths
[i
];
1149 else if (x
>= m_leftOfSheet
&& y
>= (m_topOfSheet
+ m_horizontalLabelHeight
) &&
1150 x
<= (m_leftOfSheet
+ m_verticalLabelWidth
) && y
<= m_bottomOfSheet
)
1152 // We may be on a row label sash.
1153 int currentHeight
= m_topOfSheet
+ m_horizontalLabelHeight
;
1154 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1156 if (y
>= (currentHeight
+ m_rowHeights
[i
] - tolerance
) && y
<= (currentHeight
+ m_rowHeights
[i
] + tolerance
))
1158 *orientation
= wxVERTICAL
;
1160 *startPos
= currentHeight
;
1163 currentHeight
+= m_rowHeights
[i
];
1170 bool wxGenericGrid::LabelHitTest(int x
, int y
, int *row
, int *col
)
1172 // Find the selected label
1173 if (x
>= m_leftOfSheet
&& y
>= m_topOfSheet
&&
1174 x
<= m_rightOfSheet
&& y
<= m_bottomOfSheet
)
1176 // Calculate the cell number from x and y
1182 // Now we need to do a hit test for which row we're on
1183 int currentHeight
= m_horizontalLabelHeight
;
1184 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1186 if (y
>= currentHeight
&& y
<= (currentHeight
+ m_rowHeights
[i
]))
1191 currentHeight
+= m_rowHeights
[i
];
1193 if (y
>= 0 && y
<= m_horizontalLabelHeight
)
1198 // Now we need to do a hit test for which column we're on
1199 int currentWidth
= m_verticalLabelWidth
;
1200 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1202 if (x
>= currentWidth
&& x
<= (currentWidth
+ m_colWidths
[i
]))
1207 currentWidth
+= m_colWidths
[i
];
1209 if (x
>= 0 && x
<= m_verticalLabelWidth
)
1214 if ((*col
== -1) || (*row
== -1))
1222 void wxGenericGrid::OnMouseEvent(wxMouseEvent
& ev
)
1226 wxClientDC
dc(this);
1230 if (CellHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1232 OnSelectCellImplementation(& dc
, row
, col
);
1234 //OnCellLeftClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1235 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CELL_LCLICK
, this,
1236 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1237 ev
.ControlDown(), ev
.ShiftDown());
1238 GetEventHandler()->ProcessEvent(g_evt
);
1241 if (LabelHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1243 //OnLabelLeftClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1244 wxGridEvent
g_evt(GetId(), wxEVT_GRID_LABEL_LCLICK
, this,
1245 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1246 ev
.ControlDown(), ev
.ShiftDown());
1247 GetEventHandler()->ProcessEvent(g_evt
);
1252 else if (ev
.Dragging() && ev
.LeftIsDown())
1254 switch (m_dragStatus
)
1256 case wxGRID_DRAG_NONE
:
1259 if (LabelSashHitTest((int)ev
.GetX(), (int)ev
.GetY(), &orientation
, &m_dragRowOrCol
, &m_dragStartPosition
))
1261 if (orientation
== wxHORIZONTAL
)
1263 m_dragStatus
= wxGRID_DRAG_LEFT_RIGHT
;
1264 SetCursor(m_horizontalSashCursor
);
1265 m_dragLastPosition
= (int)ev
.GetX();
1269 m_dragStatus
= wxGRID_DRAG_UP_DOWN
;
1270 SetCursor(m_verticalSashCursor
);
1271 m_dragLastPosition
= (int)ev
.GetY();
1273 wxClientDC
dc(this);
1275 dc
.SetLogicalFunction(wxINVERT
);
1276 if (orientation
== wxHORIZONTAL
)
1277 dc
.DrawLine((int)ev
.GetX(), m_topOfSheet
, (int)ev
.GetX(), m_bottomOfSheet
);
1279 dc
.DrawLine(m_leftOfSheet
, (int)ev
.GetY(), m_rightOfSheet
, (int)ev
.GetY());
1286 case wxGRID_DRAG_LEFT_RIGHT
:
1288 wxClientDC
dc(this);
1290 dc
.SetLogicalFunction(wxINVERT
);
1291 dc
.DrawLine(m_dragLastPosition
, m_topOfSheet
, m_dragLastPosition
, m_bottomOfSheet
);
1293 dc
.DrawLine((int)ev
.GetX(), m_topOfSheet
, (int)ev
.GetX(), m_bottomOfSheet
);
1296 m_dragLastPosition
= (int)ev
.GetX();
1297 SetCursor(m_horizontalSashCursor
);
1300 case wxGRID_DRAG_UP_DOWN
:
1302 wxClientDC
dc(this);
1304 dc
.SetLogicalFunction(wxINVERT
);
1305 dc
.DrawLine(m_leftOfSheet
, m_dragLastPosition
, m_rightOfSheet
, m_dragLastPosition
);
1307 dc
.DrawLine(m_leftOfSheet
, (int)ev
.GetY(), m_rightOfSheet
, (int)ev
.GetY());
1310 m_dragLastPosition
= (int)ev
.GetY();
1311 SetCursor(m_verticalSashCursor
);
1316 else if (ev
.Moving())
1318 int rowOrCol
, orientation
, startPos
;
1319 if (LabelSashHitTest((int)ev
.GetX(), (int)ev
.GetY(), &orientation
, &rowOrCol
, &startPos
))
1321 if (orientation
== wxHORIZONTAL
)
1322 SetCursor(m_horizontalSashCursor
);
1324 SetCursor(m_verticalSashCursor
);
1327 SetCursor(*wxSTANDARD_CURSOR
);
1329 else if (ev
.LeftUp())
1331 switch (m_dragStatus
)
1333 case wxGRID_DRAG_LEFT_RIGHT
:
1335 wxClientDC
dc(this);
1337 dc
.SetLogicalFunction(wxINVERT
);
1338 dc
.DrawLine(m_dragLastPosition
, m_topOfSheet
, m_dragLastPosition
, m_bottomOfSheet
);
1339 dc
.SetLogicalFunction(wxCOPY
);
1343 if (ev
.GetX() > m_dragStartPosition
)
1345 m_colWidths
[m_dragRowOrCol
] = (short)(ev
.GetX() - m_dragStartPosition
);
1350 SetCursor(*wxSTANDARD_CURSOR
);
1352 GetClientSize(&cw
, &ch
);
1357 case wxGRID_DRAG_UP_DOWN
:
1359 wxClientDC
dc(this);
1361 dc
.SetLogicalFunction(wxINVERT
);
1362 dc
.DrawLine(m_leftOfSheet
, m_dragLastPosition
, m_rightOfSheet
, m_dragLastPosition
);
1363 dc
.SetLogicalFunction(wxCOPY
);
1367 if (ev
.GetY() > m_dragStartPosition
)
1369 m_rowHeights
[m_dragRowOrCol
] = (short)(ev
.GetY() - m_dragStartPosition
);
1374 SetCursor(*wxSTANDARD_CURSOR
);
1378 m_dragStatus
= wxGRID_DRAG_NONE
;
1380 else if (ev
.RightDown())
1383 if (CellHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1385 //OnCellRightClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1386 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CELL_RCLICK
, this,
1387 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1388 ev
.ControlDown(), ev
.ShiftDown());
1389 GetEventHandler()->ProcessEvent(g_evt
);
1392 if (LabelHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1394 //OnLabelRightClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1395 wxGridEvent
g_evt(GetId(), wxEVT_GRID_LABEL_RCLICK
, this,
1396 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1397 ev
.ControlDown(), ev
.ShiftDown());
1398 GetEventHandler()->ProcessEvent(g_evt
);
1403 void wxGenericGrid::OnSelectCellImplementation(wxDC
*dc
, int row
, int col
)
1405 m_wCursorColumn
= col
;
1408 //OnChangeSelectionLabel();
1409 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_SEL_LABEL
, this);
1410 GetEventHandler()->ProcessEvent(g_evt
);
1412 SetGridClippingRegion(dc
);
1414 // Remove the highlight from the old cell
1415 if ( m_currentRectVisible
&& !(m_editable
&& m_editInPlace
) )
1421 // Highlight the new cell and copy its content to the edit control
1422 SetCurrentRect(m_wCursorRow
, m_wCursorColumn
);
1423 wxGridCell
*cell
= GetCell(m_wCursorRow
, m_wCursorColumn
);
1426 if ( cell
->GetTextValue().IsNull() )
1427 m_textItem
->SetValue("");
1429 m_textItem
->SetValue(cell
->GetTextValue());
1432 SetGridClippingRegion(dc
);
1435 if ( m_editable
&& m_editInPlace
)
1437 m_inPlaceTextItem
->SetSize( m_currentRect
.x
-2, m_currentRect
.y
-2,
1438 m_currentRect
.width
+4, m_currentRect
.height
+4 );
1442 if ( cell
->GetTextValue().IsNull() )
1444 m_inPlaceTextItem
->SetValue( "" );
1448 m_inPlaceTextItem
->SetFont( cell
->GetFont() );
1449 m_inPlaceTextItem
->SetValue( cell
->GetTextValue() );
1453 m_inPlaceTextItem
->Show(TRUE
);
1454 m_inPlaceTextItem
->SetFocus();
1458 // 1) Why isn't this needed for Windows??
1459 // Probably because of the SetValue?? JS.
1460 // 2) Arrrrrgh. This isn't needed anywhere,
1461 // of course. One hour of debugging... RR.
1463 // 3) It *is* needed for Motif - michael
1466 if ( !(m_editable
&& m_editInPlace
) )
1471 dc
->DestroyClippingRegion();
1473 OnSelectCell(row
, col
);
1474 wxGridEvent
g_evt2(GetId(), wxEVT_GRID_SELECT_CELL
, this, row
, col
);
1475 GetEventHandler()->ProcessEvent(g_evt2
);
1478 wxGridCell
*wxGenericGrid::OnCreateCell(void)
1480 return new wxGridCell(this);
1483 void wxGenericGrid::OnChangeLabels(void)
1487 for (i
= 0; i
< m_totalRows
; i
++)
1489 sprintf(buf
, "%d", i
+1);
1490 SetLabelValue(wxVERTICAL
, buf
, i
);
1492 // A...Z,AA...ZZ,AAA...ZZZ, etc.
1493 for (i
= 0; i
< m_totalCols
; i
++)
1496 int noTimes
= (i
/26 + 1);
1497 int ch
= (i
% 26) + 65;
1499 for (j
= 0; j
< noTimes
; j
++)
1502 sprintf(buf2
, "%c", (char)ch
);
1505 SetLabelValue(wxHORIZONTAL
, buf
, i
);
1509 void wxGenericGrid::OnChangeSelectionLabel(void)
1514 wxString
rowLabel(GetLabelValue(wxVERTICAL
, GetCursorRow()));
1515 wxString
colLabel(GetLabelValue(wxHORIZONTAL
, GetCursorColumn()));
1517 wxString newLabel
= colLabel
+ rowLabel
;
1518 if ((newLabel
.Length() > 0) && (newLabel
.Length() <= 8) && GetTextItem())
1520 // GetTextItem()->SetLabel(newLabel);
1524 void wxGenericGrid::HighlightCell(wxDC
*dc
)
1526 dc
->SetLogicalFunction(wxINVERT
);
1529 dc
->DrawLine( m_currentRect
.x
+ 1,
1530 m_currentRect
.y
+ 1,
1531 m_currentRect
.x
+ m_currentRect
.width
- 1,
1532 m_currentRect
.y
+ 1);
1534 dc
->DrawLine( m_currentRect
.x
+ m_currentRect
.width
- 1,
1535 m_currentRect
.y
+ 1,
1536 m_currentRect
.x
+ m_currentRect
.width
- 1,
1537 m_currentRect
.y
+m_currentRect
.height
- 1 );
1539 dc
->DrawLine( m_currentRect
.x
+ m_currentRect
.width
- 1,
1540 m_currentRect
.y
+ m_currentRect
.height
- 1,
1541 m_currentRect
.x
+ 1,
1542 m_currentRect
.y
+ m_currentRect
.height
- 1);
1544 dc
->DrawLine( m_currentRect
.x
+ 1,
1545 m_currentRect
.y
+ m_currentRect
.height
- 1,
1546 m_currentRect
.x
+ 1,
1547 m_currentRect
.y
+ 1);
1549 dc
->SetLogicalFunction(wxCOPY
);
1552 void wxGenericGrid::DrawCellText(void)
1554 if (!m_currentRectVisible
)
1557 wxGridCell
*cell
= GetCell(GetCursorRow(), GetCursorColumn());
1561 wxClientDC
dc(this);
1564 SetGridClippingRegion(& dc
);
1566 dc
.SetBackgroundMode(wxTRANSPARENT
);
1567 dc
.SetBrush(cell
->GetBackgroundBrush());
1569 wxString editValue
= m_textItem
->GetValue();
1572 rect
= m_currentRect
;
1578 // FIXME: what's this string of spaces supposed to represent?
1579 DrawTextRect(& dc
, " ", &rect
, wxLEFT
);
1580 DrawTextRect(& dc
, editValue
, &rect
, cell
->GetAlignment());
1582 dc
.DestroyClippingRegion();
1584 dc
.SetBackgroundMode(wxSOLID
);
1589 void wxGenericGrid::SetCurrentRect(int Row
, int Column
, int canvasW
, int canvasH
)
1591 int currentWidth
= m_leftOfSheet
+ m_verticalLabelWidth
;
1593 for (i
= m_scrollPosX
; i
< Column
; i
++)
1594 currentWidth
+= m_colWidths
[i
];
1596 int currentHeight
= m_topOfSheet
+ m_horizontalLabelHeight
;
1597 for (i
= m_scrollPosY
; i
< Row
; i
++)
1598 currentHeight
+= m_rowHeights
[i
];
1600 m_currentRect
.x
= currentWidth
;
1601 m_currentRect
.y
= currentHeight
;
1602 m_currentRect
.width
= m_colWidths
? (m_colWidths
[Column
]) : 0;
1603 m_currentRect
.height
= m_rowHeights
? (m_rowHeights
[Row
]) : 0;
1605 if (Row
< m_scrollPosY
|| Column
< m_scrollPosX
)
1606 m_currentRectVisible
= FALSE
;
1607 else if ((canvasW
!= -1 && canvasH
!= -1) && (m_currentRect
.x
> canvasW
|| m_currentRect
.y
> canvasH
))
1608 m_currentRectVisible
= FALSE
;
1609 else m_currentRectVisible
= TRUE
;
1612 static bool wxRectIntersection(wxRect
*rect1
, wxRect
*rect2
, wxRect
*rect3
)
1614 int x2_1
= rect1
->x
+ rect1
->width
;
1615 int y2_1
= rect1
->y
+ rect1
->height
;
1617 int x2_2
= rect2
->x
+ rect2
->width
;
1618 int y2_2
= rect2
->y
+ rect2
->height
;
1622 // Check for intersection
1623 if ((rect1
->x
> x2_2
) || (rect2
->x
> x2_1
) ||
1624 (rect1
->y
> y2_2
) || (rect2
->y
> y2_1
))
1627 rect3
->x
= rect3
->y
= rect3
->width
= rect3
->height
= 0;
1631 if (rect1
->x
> rect2
->x
)
1632 rect3
->x
= rect1
->x
;
1634 rect3
->x
= rect2
->x
;
1635 if (rect1
->y
> rect2
->y
)
1636 rect3
->y
= rect1
->y
;
1638 rect3
->y
= rect2
->y
;
1649 rect3
->width
= (int)(x2_3
- rect3
->x
);
1650 rect3
->height
= (int)(y2_3
- rect3
->y
);
1654 void wxGenericGrid::DrawTextRect(wxDC
*dc
, const wxString
& text
, wxRect
*rect
, int flag
)
1658 // Ultimately, this functionality should be built into wxWindows,
1659 // and optimized for each platform. E.g. on Windows, use DrawText
1660 // passing a clipping rectangle, so that the wxWindows clipping region
1661 // does not have to be used to implement this.
1663 // If we're already clipping, we need to find the intersection
1664 // between current clipping area and text clipping area.
1668 long clipX
, clipY
, clipW
, clipH
;
1669 dc
->GetClippingBox(&clipX
, &clipY
, &clipW
, &clipH
);
1670 clipRect
.x
= (int)clipX
; clipRect
.y
= (int)clipY
;
1671 clipRect
.width
= (int)clipW
; clipRect
.height
= (int)clipH
;
1673 bool alreadyClipping
= TRUE
;
1675 if (clipRect
.x
== 0 && clipRect
.y
== 0 && clipRect
.width
== 0 && clipRect
.height
== 0)
1677 alreadyClipping
= FALSE
;
1678 clipRect2
.x
= rect
->x
; clipRect2
.y
= rect
->y
;
1679 clipRect2
.width
= rect
->width
; clipRect2
.height
= rect
->height
;
1683 // Find intersection.
1684 if (!wxRectIntersection(rect
, &clipRect
, &clipRect2
))
1688 if (alreadyClipping
)
1689 dc
->DestroyClippingRegion();
1691 dc
->SetClippingRegion(clipRect2
.x
, clipRect2
.y
, clipRect2
.width
, clipRect2
.height
);
1692 long textWidth
, textHeight
;
1694 dc
->GetTextExtent(text
, &textWidth
, &textHeight
);
1702 x
= (rect
->x
+ rect
->width
- textWidth
- 1.0);
1703 y
= (rect
->y
+ (rect
->height
- textHeight
)/2.0);
1708 x
= (rect
->x
+ (rect
->width
- textWidth
)/2.0);
1709 y
= (rect
->y
+ (rect
->height
- textHeight
)/2.0);
1715 x
= (rect
->x
+ 1.0);
1716 y
= (rect
->y
+ (rect
->height
- textHeight
)/2.0);
1720 dc
->DrawText(text
, (long)x
, (long)y
);
1722 dc
->DestroyClippingRegion();
1724 // Restore old clipping
1725 if (alreadyClipping
)
1726 dc
->SetClippingRegion(clipRect
.x
, clipRect
.y
, clipRect
.width
, clipRect
.height
);
1731 void wxGenericGrid::DrawBitmapRect(wxDC
*dc
, wxBitmap
*bitmap
, wxRect
*rect
, int flag
)
1735 // Ultimately, this functionality should be built into wxWindows,
1736 // and optimized for each platform. E.g. on Windows, use DrawText
1737 // passing a clipping rectangle, so that the wxWindows clipping region
1738 // does not have to be used to implement this.
1740 // If we're already clipping, we need to find the intersection
1741 // between current clipping area and text clipping area.
1745 long clipX
, clipY
, clipW
, clipH
;
1746 dc
->GetClippingBox(&clipX
, &clipY
, &clipW
, &clipH
);
1747 clipRect
.x
= (int)clipX
; clipRect
.y
= (int)clipY
;
1748 clipRect
.width
= (int)clipW
; clipRect
.height
= (int)clipH
;
1750 bool alreadyClipping
= TRUE
;
1752 if (clipRect
.x
== 0 && clipRect
.y
== 0 && clipRect
.width
== 0 && clipRect
.height
== 0)
1754 alreadyClipping
= FALSE
;
1755 clipRect2
.x
= rect
->x
; clipRect2
.y
= rect
->y
;
1756 clipRect2
.width
= rect
->width
; clipRect2
.height
= rect
->height
;
1760 // Find intersection.
1761 if (!wxRectIntersection(rect
, &clipRect
, &clipRect2
))
1765 if (alreadyClipping
)
1766 dc
->DestroyClippingRegion();
1768 dc
->SetClippingRegion(clipRect2
.x
, clipRect2
.y
, clipRect2
.width
, clipRect2
.height
);
1769 float bitmapWidth
, bitmapHeight
;
1771 bitmapWidth
= bitmap
->GetWidth();
1772 bitmapHeight
= bitmap
->GetHeight();
1780 x
= (long)(rect
->x
+ rect
->width
- bitmapWidth
- 1);
1781 y
= (long)(rect
->y
+ (rect
->height
- bitmapHeight
)/2.0);
1786 x
= (long)(rect
->x
+ (rect
->width
- bitmapWidth
)/2.0);
1787 y
= (long)(rect
->y
+ (rect
->height
- bitmapHeight
)/2.0);
1793 x
= (long)(rect
->x
+ 1);
1794 y
= (long)(rect
->y
+ (rect
->height
- bitmapHeight
)/2.0);
1799 dcTemp
.SelectObject(*bitmap
);
1801 dc
->Blit( (long)x
, (long)y
, (long)bitmapWidth
, (long)bitmapHeight
, &dcTemp
, 0, 0);
1802 dcTemp
.SelectObject(wxNullBitmap
);
1804 dc
->DestroyClippingRegion();
1806 // Restore old clipping
1807 if (alreadyClipping
)
1808 dc
->SetClippingRegion(clipRect
.x
, clipRect
.y
, clipRect
.width
, clipRect
.height
);
1813 void wxGenericGrid::OnActivate(bool active
)
1817 // Edit control should always have the focus
1818 if (GetTextItem() && GetEditable())
1820 GetTextItem()->SetFocus();
1821 wxGridCell
*cell
= GetCell(GetCursorRow(), GetCursorColumn());
1823 GetTextItem()->SetValue(cell
->GetTextValue());
1828 void wxGenericGrid::SetCellValue(const wxString
& val
, int row
, int col
)
1830 wxGridCell
*cell
= GetCell(row
, col
);
1833 cell
->SetTextValue(val
);
1835 RefreshCell(row
, col
, TRUE
);
1839 void wxGenericGrid::RefreshCell(int row
, int col
, bool setText
)
1841 // Don't refresh within a pair of batch brackets
1842 if (GetBatchCount() > 0)
1846 GetClientSize(&cw
, &ch
);
1848 SetCurrentRect(row
, col
, cw
, ch
);
1849 if (m_currentRectVisible
)
1851 wxGridCell
*cell
= GetCell(row
, col
);
1853 bool currentPos
= FALSE
;
1854 if (row
== m_wCursorRow
&& col
== m_wCursorColumn
&& GetTextItem() && GetTextItem()->IsShown() && setText
)
1856 GetTextItem()->SetValue(cell
->GetTextValue());
1859 // Gets refreshed anyway in MSW
1864 wxClientDC
dc(this);
1866 DrawCellBackground(& dc
, &m_currentRect
, row
, col
);
1867 DrawCellValue(& dc
, &m_currentRect
, row
, col
);
1873 wxString
& wxGenericGrid::GetCellValue(int row
, int col
) const
1875 static wxString
emptyString("");
1877 wxGridCell
*cell
= GetCell(row
, col
);
1879 return cell
->GetTextValue();
1884 void wxGenericGrid::SetColumnWidth(int col
, int width
)
1886 if (col
<= m_totalCols
)
1887 m_colWidths
[col
] = width
;
1890 int wxGenericGrid::GetColumnWidth(int col
) const
1892 if (col
<= m_totalCols
)
1893 return m_colWidths
[col
];
1898 void wxGenericGrid::SetRowHeight(int row
, int height
)
1900 if (row
<= m_totalRows
)
1901 m_rowHeights
[row
] = height
;
1904 int wxGenericGrid::GetRowHeight(int row
) const
1906 if (row
<= m_totalRows
)
1907 return m_rowHeights
[row
];
1912 void wxGenericGrid::SetLabelSize(int orientation
, int sz
)
1914 if (orientation
== wxHORIZONTAL
)
1915 m_horizontalLabelHeight
= sz
;
1917 m_verticalLabelWidth
= sz
;
1919 SetCurrentRect(GetCursorRow(), GetCursorColumn());
1922 int wxGenericGrid::GetLabelSize(int orientation
) const
1924 if (orientation
== wxHORIZONTAL
)
1925 return m_horizontalLabelHeight
;
1927 return m_verticalLabelWidth
;
1930 wxGridCell
*wxGenericGrid::GetLabelCell(int orientation
, int pos
) const
1932 if (orientation
== wxHORIZONTAL
)
1934 if (m_colLabelCells
&& pos
< m_totalCols
)
1935 return m_colLabelCells
[pos
];
1937 return (wxGridCell
*) NULL
;
1941 if (m_rowLabelCells
&& pos
< m_totalRows
)
1942 return m_rowLabelCells
[pos
];
1944 return (wxGridCell
*) NULL
;
1948 void wxGenericGrid::SetLabelValue(int orientation
, const wxString
& val
, int pos
)
1950 wxGridCell
*cell
= GetLabelCell(orientation
, pos
);
1952 cell
->SetTextValue(val
);
1955 wxString
& wxGenericGrid::GetLabelValue(int orientation
, int pos
) const
1957 static wxString emptyString
= "";
1958 wxGridCell
*cell
= GetLabelCell(orientation
, pos
);
1960 return cell
->GetTextValue();
1965 void wxGenericGrid::SetLabelAlignment(int orientation
, int align
)
1967 if (orientation
== wxHORIZONTAL
)
1968 m_horizontalLabelAlignment
= align
;
1970 m_verticalLabelAlignment
= align
;
1972 SetCurrentRect(GetCursorRow(), GetCursorColumn());
1975 int wxGenericGrid::GetLabelAlignment(int orientation
) const
1977 if (orientation
== wxHORIZONTAL
)
1978 return m_horizontalLabelAlignment
;
1980 return m_verticalLabelAlignment
;
1983 void wxGenericGrid::SetLabelTextColour(const wxColour
& colour
)
1985 m_labelTextColour
= colour
;
1989 void wxGenericGrid::SetLabelBackgroundColour(const wxColour
& colour
)
1991 m_labelBackgroundColour
= colour
;
1992 m_labelBackgroundBrush
= * wxTheBrushList
->FindOrCreateBrush(m_labelBackgroundColour
, wxSOLID
);
1995 void wxGenericGrid::SetEditable(bool edit
)
2000 int controlW
, controlH
;
2001 m_textItem
->GetSize(&controlW
, &controlH
);
2002 m_editControlPosition
.height
= controlH
;
2004 m_topOfSheet
= m_editControlPosition
.x
+ controlH
+ 2;
2007 m_editingPanel
->Show(TRUE
);
2008 m_textItem
->Show(TRUE
);
2009 m_textItem
->SetFocus();
2012 if (m_inPlaceTextItem
)
2014 m_inPlaceTextItem
->Show(TRUE
);
2015 m_inPlaceTextItem
->SetFocus();
2023 m_textItem
->Show(FALSE
);
2024 m_editingPanel
->Show(FALSE
);
2027 if ( m_inPlaceTextItem
)
2029 m_inPlaceTextItem
->Show(FALSE
);
2033 SetCurrentRect(GetCursorRow(), GetCursorColumn());
2036 GetClientSize(&cw
, &ch
);
2041 int m_scrollWidth = 16;
2042 GetClientSize(&cw, &ch);
2045 m_vScrollBar->SetSize(cw - m_scrollWidth, m_topOfSheet,
2046 m_scrollWidth, ch - m_topOfSheet - m_scrollWidth);
2051 void wxGenericGrid::SetEditInPlace(bool edit
)
2053 if ( m_editInPlace
!= edit
)
2055 m_editInPlace
= edit
;
2057 if ( m_editInPlace
) // switched on
2059 if ( m_currentRectVisible
&& m_editable
)
2061 m_inPlaceTextItem
->SetSize( m_currentRect
.x
-2, m_currentRect
.y
-2,
2062 m_currentRect
.width
+4, m_currentRect
.height
+4 );
2064 wxGridCell
*cell
= GetCell(m_wCursorRow
, m_wCursorColumn
);
2068 if ( cell
->GetTextValue().IsNull() )
2070 m_inPlaceTextItem
->SetValue( "" );
2074 m_inPlaceTextItem
->SetFont( cell
->GetFont() );
2075 m_inPlaceTextItem
->SetValue( cell
->GetTextValue() );
2079 m_inPlaceTextItem
->Show( TRUE
);
2080 m_inPlaceTextItem
->SetFocus();
2083 else // switched off
2085 m_inPlaceTextItem
->Show( FALSE
);
2091 void wxGenericGrid::SetCellAlignment(int flag
, int row
, int col
)
2093 wxGridCell
*cell
= GetCell(row
, col
);
2095 cell
->SetAlignment(flag
);
2098 int wxGenericGrid::GetCellAlignment(int row
, int col
) const
2100 wxGridCell
*cell
= GetCell(row
, col
);
2102 return cell
->GetAlignment();
2104 return m_cellAlignment
;
2107 void wxGenericGrid::SetCellAlignment(int flag
)
2109 m_cellAlignment
= flag
;
2111 for (i
= 0; i
< GetRows(); i
++)
2112 for (j
= 0; j
< GetCols(); j
++)
2114 GetCell(i
, j
)->SetAlignment(flag
);
2117 int wxGenericGrid::GetCellAlignment(void) const
2119 return m_cellAlignment
;
2122 void wxGenericGrid::SetCellBackgroundColour(const wxColour
& col
)
2124 m_cellBackgroundColour
= col
;
2126 for (i
= 0; i
< GetRows(); i
++)
2127 for (j
= 0; j
< GetCols(); j
++)
2129 GetCell(i
, j
)->SetBackgroundColour(col
);
2132 void wxGenericGrid::SetCellBackgroundColour(const wxColour
& val
, int row
, int col
)
2134 wxGridCell
*cell
= GetCell(row
, col
);
2137 cell
->SetBackgroundColour(val
);
2138 RefreshCell(row
, col
);
2142 wxColour
& wxGenericGrid::GetCellBackgroundColour(int row
, int col
) const
2144 wxGridCell
*cell
= GetCell(row
, col
);
2146 return cell
->GetBackgroundColour();
2148 return (wxColour
&) m_cellBackgroundColour
;
2151 void wxGenericGrid::SetCellTextColour(const wxColour
& val
, int row
, int col
)
2153 wxGridCell
*cell
= GetCell(row
, col
);
2156 cell
->SetTextColour(val
);
2157 RefreshCell(row
, col
);
2161 void wxGenericGrid::SetCellTextFont(const wxFont
& fnt
, int row
, int col
)
2163 wxGridCell
*cell
= GetCell(row
, col
);
2167 RefreshCell(row
, col
);
2171 wxFont
& wxGenericGrid::GetCellTextFont(int row
, int col
) const
2173 wxGridCell
*cell
= GetCell(row
, col
);
2175 return (wxFont
&) cell
->GetFont();
2177 return (wxFont
&) m_cellTextFont
;
2180 wxColour
& wxGenericGrid::GetCellTextColour(int row
, int col
) const
2182 wxGridCell
*cell
= GetCell(row
, col
);
2184 return (wxColour
&) cell
->GetTextColour();
2186 return (wxColour
&) m_cellTextColour
;
2189 void wxGenericGrid::SetCellTextColour(const wxColour
& val
)
2191 m_cellTextColour
= val
;
2193 for (i
= 0; i
< GetRows(); i
++)
2194 for (j
= 0; j
< GetCols(); j
++)
2196 GetCell(i
, j
)->SetTextColour(val
);
2199 void wxGenericGrid::SetCellTextFont(const wxFont
& fnt
)
2201 m_cellTextFont
= fnt
;
2203 for (i
= 0; i
< GetRows(); i
++)
2204 for (j
= 0; j
< GetCols(); j
++)
2206 GetCell(i
, j
)->SetFont(fnt
);
2209 void wxGenericGrid::SetCellBitmap(wxBitmap
*bitmap
, int row
, int col
)
2211 wxGridCell
*cell
= GetCell(row
, col
);
2214 cell
->SetCellBitmap(bitmap
);
2215 RefreshCell(row
, col
);
2219 wxBitmap
*wxGenericGrid::GetCellBitmap(int row
, int col
) const
2221 wxGridCell
*cell
= GetCell(row
, col
);
2224 return cell
->GetCellBitmap();
2227 return (wxBitmap
*) NULL
;
2230 bool wxGenericGrid::InsertCols(int pos
, int n
, bool updateLabels
)
2232 if (pos
> m_totalCols
)
2236 return CreateGrid(1, n
);
2241 for (i
= 0; i
< m_totalRows
; i
++)
2243 wxGridCell
**cols
= m_gridCells
[i
];
2244 wxGridCell
**newCols
= new wxGridCell
*[m_totalCols
+ n
];
2245 for (j
= 0; j
< pos
; j
++)
2246 newCols
[j
] = cols
[j
];
2247 for (j
= pos
; j
< pos
+ n
; j
++)
2248 newCols
[j
] = new wxGridCell(this);
2249 for (j
= pos
+ n
; j
< m_totalCols
+ n
; j
++)
2250 newCols
[j
] = cols
[j
- n
];
2253 m_gridCells
[i
] = newCols
;
2257 short *newColWidths
= new short[m_totalCols
+ n
];
2258 for (j
= 0; j
< pos
; j
++)
2259 newColWidths
[j
] = m_colWidths
[j
];
2260 for (j
= pos
; j
< pos
+ n
; j
++)
2261 newColWidths
[j
] = wxGRID_DEFAULT_CELL_WIDTH
;
2262 for (j
= pos
+ n
; j
< m_totalCols
+ n
; j
++)
2263 newColWidths
[j
] = m_colWidths
[j
- n
];
2264 delete[] m_colWidths
;
2265 m_colWidths
= newColWidths
;
2268 wxGridCell
**newLabels
= new wxGridCell
*[m_totalCols
+ n
];
2269 for (j
= 0; j
< pos
; j
++)
2270 newLabels
[j
] = m_colLabelCells
[j
];
2271 for (j
= pos
; j
< pos
+ n
; j
++)
2272 newLabels
[j
] = new wxGridCell(this);
2273 for (j
= pos
+ n
; j
< m_totalCols
+ n
; j
++)
2274 newLabels
[j
] = m_colLabelCells
[j
- n
];
2276 delete[] m_colLabelCells
;
2277 m_colLabelCells
= newLabels
;
2283 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2284 GetEventHandler()->ProcessEvent(g_evt
);
2293 bool wxGenericGrid::InsertRows(int pos
, int n
, bool updateLabels
)
2295 if (pos
> m_totalRows
)
2299 return CreateGrid(n
, 1);
2304 wxGridCell
***rows
= new wxGridCell
**[m_totalRows
+ n
];
2307 for (i
= 0; i
< pos
; i
++)
2308 rows
[i
] = m_gridCells
[i
];
2310 for (i
= pos
; i
< pos
+ n
; i
++)
2312 rows
[i
] = new wxGridCell
*[m_totalCols
];
2313 for (j
= 0; j
< m_totalCols
; j
++)
2314 rows
[i
][j
] = new wxGridCell(this);
2317 for (i
= pos
+ n
; i
< m_totalRows
+ n
; i
++)
2318 rows
[i
] = m_gridCells
[i
- n
];
2320 delete[] m_gridCells
;
2324 short *newRowHeights
= new short[m_totalRows
+ n
];
2325 for (i
= 0; i
< pos
; i
++)
2326 newRowHeights
[i
] = m_rowHeights
[i
];
2327 for (i
= pos
; i
< pos
+ n
; i
++)
2328 newRowHeights
[i
] = wxGRID_DEFAULT_CELL_HEIGHT
;
2329 for (i
= pos
+ n
; i
< m_totalRows
+ n
; i
++)
2330 newRowHeights
[i
] = m_rowHeights
[i
- n
];
2331 delete[] m_rowHeights
;
2332 m_rowHeights
= newRowHeights
;
2335 wxGridCell
**newLabels
= new wxGridCell
*[m_totalRows
+ n
];
2336 for (i
= 0; i
< pos
; i
++)
2337 newLabels
[i
] = m_rowLabelCells
[i
];
2338 for (i
= pos
; i
< pos
+ n
; i
++)
2339 newLabels
[i
] = new wxGridCell(this);
2340 for (i
= pos
+ n
; i
< m_totalRows
+ n
; i
++)
2341 newLabels
[i
] = m_rowLabelCells
[i
- n
];
2343 delete[] m_rowLabelCells
;
2344 m_rowLabelCells
= newLabels
;
2350 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2351 GetEventHandler()->ProcessEvent(g_evt
);
2360 bool wxGenericGrid::AppendCols(int n
, bool updateLabels
)
2362 return InsertCols(GetCols(), n
, updateLabels
);
2365 bool wxGenericGrid::AppendRows(int n
, bool updateLabels
)
2367 return InsertRows(GetRows(), n
, updateLabels
);
2370 bool wxGenericGrid::DeleteRows(int pos
, int n
, bool updateLabels
)
2372 if (pos
> m_totalRows
)
2379 wxGridCell
***rows
= new wxGridCell
**[m_totalRows
- n
];
2382 for (i
= 0; i
< pos
; i
++)
2383 rows
[i
] = m_gridCells
[i
];
2385 for (i
= pos
+ n
; i
< m_totalRows
; i
++)
2386 rows
[i
-n
] = m_gridCells
[i
];
2388 delete[] m_gridCells
;
2392 short *newRowHeights
= new short[m_totalRows
- n
];
2393 for (i
= 0; i
< pos
; i
++)
2394 newRowHeights
[i
] = m_rowHeights
[i
];
2395 for (i
= pos
+ n
; i
< m_totalRows
; i
++)
2396 newRowHeights
[i
-n
] = m_rowHeights
[i
];
2397 delete[] m_rowHeights
;
2398 m_rowHeights
= newRowHeights
;
2401 wxGridCell
**newLabels
= new wxGridCell
*[m_totalRows
- n
];
2402 for (i
= 0; i
< pos
; i
++)
2403 newLabels
[i
] = m_rowLabelCells
[i
];
2404 for (i
= pos
+ n
; i
< m_totalRows
; i
++)
2405 newLabels
[i
-n
] = m_rowLabelCells
[i
];
2407 delete[] m_rowLabelCells
;
2408 m_rowLabelCells
= newLabels
;
2414 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2415 GetEventHandler()->ProcessEvent(g_evt
);
2422 bool wxGenericGrid::DeleteCols(int pos
, int n
, bool updateLabels
)
2424 if (pos
+ n
> m_totalCols
)
2432 for (i
= 0; i
< m_totalRows
; i
++)
2434 wxGridCell
**cols
= m_gridCells
[i
];
2435 wxGridCell
**newCols
= new wxGridCell
*[m_totalCols
- n
];
2436 for (j
= 0; j
< pos
; j
++)
2437 newCols
[j
] = cols
[j
];
2438 for (j
= pos
; j
< pos
+ n
; j
++)
2440 for (j
= pos
+ n
; j
< m_totalCols
; j
++)
2441 newCols
[j
-n
] = cols
[j
];
2444 m_gridCells
[i
] = newCols
;
2448 short *newColWidths
= new short[m_totalCols
- n
];
2449 for (j
= 0; j
< pos
; j
++)
2450 newColWidths
[j
] = m_colWidths
[j
];
2451 for (j
= pos
+ n
; j
< m_totalCols
; j
++)
2452 newColWidths
[j
-n
] = m_colWidths
[j
];
2453 delete[] m_colWidths
;
2454 m_colWidths
= newColWidths
;
2457 wxGridCell
**newLabels
= new wxGridCell
*[m_totalCols
- n
];
2458 for (j
= 0; j
< pos
; j
++)
2459 newLabels
[j
] = m_colLabelCells
[j
];
2460 for (j
= pos
+ n
; j
< m_totalCols
; j
++)
2461 newLabels
[j
-n
] = m_colLabelCells
[j
];
2463 delete[] m_colLabelCells
;
2464 m_colLabelCells
= newLabels
;
2470 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2471 GetEventHandler()->ProcessEvent(g_evt
);
2478 void wxGenericGrid::SetGridCursor(int row
, int col
)
2480 if (row
>= m_totalRows
|| col
>= m_totalCols
)
2483 if (row
== GetCursorRow() && col
== GetCursorColumn())
2486 wxClientDC
dc(this);
2489 SetGridClippingRegion(& dc
);
2491 if (m_currentRectVisible
&& !(m_editable
&& m_editInPlace
) )
2492 HighlightCell(& dc
);
2495 m_wCursorColumn
= col
;
2498 GetClientSize(&cw
, &ch
);
2500 SetCurrentRect(row
, col
, cw
, ch
);
2502 if (m_currentRectVisible
&& !(m_editable
&& m_editInPlace
) )
2503 HighlightCell(& dc
);
2505 dc
.DestroyClippingRegion();
2513 wxGridCell::wxGridCell(wxGenericGrid
*window
)
2515 cellBitmap
= (wxBitmap
*) NULL
;
2517 backgroundBrush
= wxNullBrush
;
2519 textColour
= window
->GetCellTextColour();
2521 textColour
.Set(0,0,0);
2523 backgroundColour
= window
->GetCellBackgroundColour();
2525 backgroundColour
.Set(255,255,255);
2528 font
= window
->GetCellTextFont();
2530 font
= * wxTheFontList
->FindOrCreateFont(12, wxSWISS
, wxNORMAL
, wxNORMAL
);
2532 SetBackgroundColour(backgroundColour
);
2535 alignment
= window
->GetCellAlignment();
2540 wxGridCell::~wxGridCell(void)
2544 void wxGridCell::SetBackgroundColour(const wxColour
& colour
)
2546 backgroundColour
= colour
;
2547 backgroundBrush
= * wxTheBrushList
->FindOrCreateBrush(backgroundColour
, wxSOLID
);
2550 void wxGenericGrid::OnText(wxCommandEvent
& WXUNUSED(ev
) )
2552 // michael - added this conditional to prevent change to
2553 // grid cell text when edit control is hidden but still has
2558 wxGenericGrid
*grid
= this;
2559 wxGridCell
*cell
= grid
->GetCell(grid
->GetCursorRow(), grid
->GetCursorColumn());
2560 if (cell
&& grid
->CurrentCellVisible())
2562 cell
->SetTextValue(grid
->GetTextItem()->GetValue());
2563 if ( m_editInPlace
&& !m_inOnTextInPlace
)
2565 m_inPlaceTextItem
->SetValue( grid
->GetTextItem()->GetValue() );
2568 wxClientDC
dc(grid
);
2571 grid
->SetGridClippingRegion(& dc
);
2572 grid
->DrawCellBackground(& dc
, &grid
->GetCurrentRect(), grid
->GetCursorRow(), grid
->GetCursorColumn());
2573 grid
->DrawCellValue(& dc
, &grid
->GetCurrentRect(), grid
->GetCursorRow(), grid
->GetCursorColumn());
2574 if ( !(m_editable
&& m_editInPlace
) ) grid
->HighlightCell(& dc
);
2575 dc
.DestroyClippingRegion();
2578 //grid->OnCellChange(grid->GetCursorRow(), grid->GetCursorColumn());
2579 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CELL_CHANGE
, grid
,
2580 grid
->GetCursorRow(), grid
->GetCursorColumn());
2581 GetEventHandler()->ProcessEvent(g_evt
);
2583 // grid->DrawCellText();
2588 void wxGenericGrid::OnTextInPlace(wxCommandEvent
& ev
)
2592 wxGenericGrid
*grid
= this;
2593 wxGridCell
*cell
= grid
->GetCell(grid
->GetCursorRow(), grid
->GetCursorColumn());
2594 if (cell
&& grid
->CurrentCellVisible())
2596 m_inOnTextInPlace
= TRUE
;
2597 grid
->GetTextItem()->SetValue( m_inPlaceTextItem
->GetValue() );
2599 m_inOnTextInPlace
= FALSE
;
2604 void wxGenericGrid::OnGridScroll(wxScrollEvent
& ev
)
2606 static bool inScroll
= FALSE
;
2611 if ( m_editInPlace
) m_inPlaceTextItem
->Show(FALSE
);
2614 wxGenericGrid
*win
= this;
2616 bool change
= FALSE
;
2618 if (ev
.GetEventObject() == win
->GetHorizScrollBar())
2620 change
= (ev
.GetPosition() != m_scrollPosX
);
2621 win
->SetScrollPosX(ev
.GetPosition());
2625 change
= (ev
.GetPosition() != m_scrollPosY
);
2626 win
->SetScrollPosY(ev
.GetPosition());
2629 win
->UpdateDimensions();
2631 win
->SetCurrentRect(win
->GetCursorRow(), win
->GetCursorColumn());
2633 // Because rows and columns can be arbitrary sizes,
2634 // the scrollbars will need to be adjusted to reflect the
2638 if (change
) win
->Refresh(FALSE
);
2640 if ( m_editInPlace
&& m_currentRectVisible
)
2642 m_inPlaceTextItem
->SetSize( m_currentRect
.x
-2, m_currentRect
.y
-2,
2643 m_currentRect
.width
+4, m_currentRect
.height
+4 );
2644 m_inPlaceTextItem
->Show( TRUE
);
2645 m_inPlaceTextItem
->SetFocus();
2653 //----------------------------------------------------------------------
2654 // Default wxGridEvent handlers
2655 // (just redirect to the pre-existing virtual methods)
2657 void wxGenericGrid::_OnSelectCell(wxGridEvent
& ev
)
2659 OnSelectCell(ev
.m_row
, ev
.m_col
);
2662 void wxGenericGrid::_OnCreateCell(wxGridEvent
& ev
)
2664 ev
.m_cell
= OnCreateCell();
2667 void wxGenericGrid::_OnChangeLabels(wxGridEvent
& WXUNUSED(ev
))
2672 void wxGenericGrid::_OnChangeSelectionLabel(wxGridEvent
& WXUNUSED(ev
))
2674 OnChangeSelectionLabel();
2677 void wxGenericGrid::_OnCellChange(wxGridEvent
& ev
)
2679 OnCellChange(ev
.m_row
, ev
.m_col
);
2682 void wxGenericGrid::_OnCellLeftClick(wxGridEvent
& ev
)
2684 OnCellLeftClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2687 void wxGenericGrid::_OnCellRightClick(wxGridEvent
& ev
)
2689 OnCellRightClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2692 void wxGenericGrid::_OnLabelLeftClick(wxGridEvent
& ev
)
2694 OnLabelLeftClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2697 void wxGenericGrid::_OnLabelRightClick(wxGridEvent
& ev
)
2699 OnLabelRightClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);