1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxGenericGrid
4 // Author: Julian Smart
5 // Modified by: Michael Bedward
6 // Added edit in place facility, 20 Apr 1999
7 // Added cursor key control, 29 Jun 1999
9 // Added keyboard navigation, client data, other fixes
12 // Copyright: (c) Julian Smart and Markus Holzem
13 // Licence: wxWindows license
14 /////////////////////////////////////////////////////////////////////////////
17 #pragma implementation "gridg.h"
21 // For compilers that support precompilation, includes "wx/wx.h".
22 #include "wx/wxprec.h"
30 #include "wx/dcclient.h"
31 #include "wx/dcmemory.h"
32 #include "wx/textctrl.h"
33 #include "wx/settings.h"
38 #include "wx/string.h"
40 #include "wx/generic/gridg.h"
43 // Values used to adjust the size of the in-place-edit control, and other
44 // goodies. Per-platform tweaks should be done here.
46 #define wxIPE_ADJUST -2
47 #define wxIPE_STYLE wxNO_BORDER
48 #define wxIPE_HIGHLIGHT 1
49 #define wxUSE_DOUBLE_BUFFERING 1
53 #define wxIPE_ADJUST -1
54 #define wxIPE_STYLE wxNO_BORDER
55 #define wxIPE_HIGHLIGHT 1
56 #define wxUSE_DOUBLE_BUFFERING 1
60 #define wxIPE_ADJUST -1
61 #define wxIPE_STYLE wxNO_BORDER
62 #define wxIPE_HIGHLIGHT 0
63 #define wxUSE_DOUBLE_BUFFERING 1
67 #define wxIPE_ADJUST 2
68 #define wxIPE_STYLE wxNO_BORDER
69 #define wxIPE_HIGHLIGHT 0
70 #define wxUSE_DOUBLE_BUFFERING 0
74 #define wxIPE_ADJUST 2
75 #define wxIPE_STYLE wxNO_BORDER
76 #define wxIPE_HIGHLIGHT 0
77 #define wxUSE_DOUBLE_BUFFERING 0
82 #define wxGRID_DRAG_NONE 0
83 #define wxGRID_DRAG_LEFT_RIGHT 1
84 #define wxGRID_DRAG_UP_DOWN 2
86 IMPLEMENT_DYNAMIC_CLASS(wxGenericGrid
, wxPanel
)
87 IMPLEMENT_DYNAMIC_CLASS(wxGridEvent
, wxEvent
)
89 BEGIN_EVENT_TABLE(wxGenericGrid
, wxPanel
)
90 EVT_SIZE(wxGenericGrid::OnSize
)
91 EVT_PAINT(wxGenericGrid::OnPaint
)
92 EVT_ERASE_BACKGROUND(wxGenericGrid::OnEraseBackground
)
93 EVT_MOUSE_EVENTS(wxGenericGrid::OnMouseEvent
)
94 EVT_TEXT(wxGRID_TEXT_CTRL
, wxGenericGrid::OnText
)
95 EVT_TEXT(wxGRID_EDIT_IN_PLACE_TEXT_CTRL
, wxGenericGrid::OnTextInPlace
)
96 EVT_TEXT_ENTER(wxGRID_TEXT_CTRL
, wxGenericGrid::OnTextEnter
)
97 EVT_TEXT_ENTER(wxGRID_EDIT_IN_PLACE_TEXT_CTRL
, wxGenericGrid::OnTextInPlaceEnter
)
98 EVT_COMMAND_SCROLL(wxGRID_HSCROLL
, wxGenericGrid::OnGridScroll
)
99 EVT_COMMAND_SCROLL(wxGRID_VSCROLL
, wxGenericGrid::OnGridScroll
)
101 // default wxGridEvent handlers
102 EVT_GRID_SELECT_CELL(wxGenericGrid::_OnSelectCell
)
103 EVT_GRID_CREATE_CELL(wxGenericGrid::_OnCreateCell
)
104 EVT_GRID_CHANGE_LABELS(wxGenericGrid::_OnChangeLabels
)
105 EVT_GRID_CHANGE_SEL_LABEL(wxGenericGrid::_OnChangeSelectionLabel
)
106 EVT_GRID_CELL_CHANGE(wxGenericGrid::_OnCellChange
)
107 EVT_GRID_CELL_LCLICK(wxGenericGrid::_OnCellLeftClick
)
108 EVT_GRID_CELL_RCLICK(wxGenericGrid::_OnCellRightClick
)
109 EVT_GRID_LABEL_LCLICK(wxGenericGrid::_OnLabelLeftClick
)
110 EVT_GRID_LABEL_RCLICK(wxGenericGrid::_OnLabelRightClick
)
115 wxGenericGrid::wxGenericGrid()
120 m_hScrollBar
= (wxScrollBar
*) NULL
;
121 m_vScrollBar
= (wxScrollBar
*) NULL
;
122 m_cellTextColour
= *wxBLACK
;
123 m_cellBackgroundColour
= *wxWHITE
;
124 m_labelTextColour
= *wxBLACK
;
125 // m_labelBackgroundColour = *wxLIGHT_GREY;
126 m_labelBackgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
127 m_labelBackgroundBrush
= wxNullBrush
;
128 m_labelTextFont
= wxNullFont
;
129 m_cellTextFont
= wxNullFont
;
130 m_textItem
= (wxTextCtrl
*) NULL
;
131 m_currentRectVisible
= FALSE
;
134 m_editInPlace
= FALSE
;
135 m_inOnTextInPlace
= FALSE
;
138 #if defined(__WIN95__)
139 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
140 #elif defined(__WXGTK__)
141 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
145 m_dragStatus
= wxGRID_DRAG_NONE
;
147 m_dragStartPosition
= 0;
148 m_dragLastPosition
= 0;
149 m_divisionPen
= wxNullPen
;
150 m_highlightPen
= wxNullPen
;
151 m_leftOfSheet
= wxGRID_DEFAULT_SHEET_LEFT
;
152 m_topOfSheet
= wxGRID_DEFAULT_SHEET_TOP
;
153 m_cellHeight
= wxGRID_DEFAULT_CELL_HEIGHT
;
154 m_totalGridWidth
= 0;
155 m_totalGridHeight
= 0;
156 m_colWidths
= (short *) NULL
;
157 m_rowHeights
= (short *) NULL
;
158 m_verticalLabelWidth
= wxGRID_DEFAULT_VERTICAL_LABEL_WIDTH
;
159 m_horizontalLabelHeight
= wxGRID_DEFAULT_HORIZONAL_LABEL_HEIGHT
;
160 m_verticalLabelAlignment
= wxCENTRE
;
161 m_horizontalLabelAlignment
= wxCENTRE
;
162 m_editControlPosition
.x
= wxGRID_DEFAULT_EDIT_X
;
163 m_editControlPosition
.y
= wxGRID_DEFAULT_EDIT_Y
;
164 m_editControlPosition
.width
= wxGRID_DEFAULT_EDIT_WIDTH
;
165 m_editControlPosition
.height
= wxGRID_DEFAULT_EDIT_HEIGHT
;
170 m_editCreated
= FALSE
;
173 m_gridCells
= (wxGridCell
***) NULL
;
174 m_rowLabelCells
= (wxGridCell
**) NULL
;
175 m_colLabelCells
= (wxGridCell
**) NULL
;
176 m_textItem
= (wxTextCtrl
*) NULL
;
179 bool wxGenericGrid::Create(wxWindow
*parent
,
184 const wxString
& name
)
189 m_editingPanel
= (wxPanel
*) NULL
;
190 m_hScrollBar
= (wxScrollBar
*) NULL
;
191 m_vScrollBar
= (wxScrollBar
*) NULL
;
192 m_cellTextColour
= *wxBLACK
;
193 m_cellBackgroundColour
= *wxWHITE
;
194 m_labelTextColour
= *wxBLACK
;
195 // m_labelBackgroundColour = *wxLIGHT_GREY;
196 m_labelBackgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
197 m_labelBackgroundBrush
= wxNullBrush
;
198 m_labelTextFont
= * wxTheFontList
->FindOrCreateFont(10, wxSWISS
, wxNORMAL
, wxBOLD
);
199 m_cellTextFont
= * wxTheFontList
->FindOrCreateFont(10, wxSWISS
, wxNORMAL
, wxNORMAL
);
200 m_textItem
= (wxTextCtrl
*) NULL
;
201 m_currentRectVisible
= FALSE
;
203 m_editInPlace
= FALSE
;
204 m_inOnTextInPlace
= FALSE
;
206 #if defined(__WIN95__)
207 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
208 #elif defined(__WXGTK__)
209 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
213 m_dragStatus
= wxGRID_DRAG_NONE
;
215 m_dragStartPosition
= 0;
216 m_dragLastPosition
= 0;
217 m_divisionPen
= * wxThePenList
->FindOrCreatePen("LIGHT GREY", 1, wxSOLID
);
218 m_highlightPen
= * wxBLACK_PEN
;
219 m_doubleBufferingBitmap
= (wxBitmap
*) NULL
;
221 if (!m_horizontalSashCursor
.Ok())
223 m_horizontalSashCursor
= wxCursor(wxCURSOR_SIZEWE
);
224 m_verticalSashCursor
= wxCursor(wxCURSOR_SIZENS
);
227 SetLabelBackgroundColour(m_labelBackgroundColour
);
229 m_leftOfSheet
= wxGRID_DEFAULT_SHEET_LEFT
;
230 m_topOfSheet
= wxGRID_DEFAULT_SHEET_TOP
;
231 m_cellHeight
= wxGRID_DEFAULT_CELL_HEIGHT
;
232 m_totalGridWidth
= 0;
233 m_totalGridHeight
= 0;
234 m_colWidths
= (short *) NULL
;
235 m_rowHeights
= (short *) NULL
;
237 m_verticalLabelWidth
= wxGRID_DEFAULT_VERTICAL_LABEL_WIDTH
;
238 m_horizontalLabelHeight
= wxGRID_DEFAULT_HORIZONAL_LABEL_HEIGHT
;
239 m_verticalLabelAlignment
= wxCENTRE
;
240 m_horizontalLabelAlignment
= wxCENTRE
;
241 m_editControlPosition
.x
= wxGRID_DEFAULT_EDIT_X
;
242 m_editControlPosition
.y
= wxGRID_DEFAULT_EDIT_Y
;
243 m_editControlPosition
.width
= wxGRID_DEFAULT_EDIT_WIDTH
;
244 m_editControlPosition
.height
= wxGRID_DEFAULT_EDIT_HEIGHT
;
252 /* Store the rect. coordinates for the current cell */
253 SetCurrentRect(m_wCursorRow
, m_wCursorColumn
);
255 m_editCreated
= FALSE
;
259 m_gridCells
= (wxGridCell
***) NULL
;
260 m_rowLabelCells
= (wxGridCell
**) NULL
;
261 m_colLabelCells
= (wxGridCell
**) NULL
;
262 m_textItem
= (wxTextCtrl
*) NULL
;
264 wxPanel::Create(parent
, id
, pos
, size
, style
, name
);
266 m_editingPanel
= new wxPanel(this);
268 m_textItem
= new wxTextCtrl(m_editingPanel
, wxGRID_TEXT_CTRL
, "",
269 wxPoint(m_editControlPosition
.x
, m_editControlPosition
.y
),
270 wxSize(m_editControlPosition
.width
, -1),
272 m_textItem
->Show(TRUE
);
273 m_textItem
->SetFocus();
274 int controlW
, controlH
;
276 m_textItem
->GetSize(&controlW
, &controlH
);
277 m_editControlPosition
.height
= controlH
;
279 m_topOfSheet
= m_editControlPosition
.y
+ controlH
+ 2;
281 m_editCreated
= TRUE
;
283 m_hScrollBar
= new wxScrollBar(this, wxGRID_HSCROLL
, wxPoint(0, 0), wxSize(20, 100), wxHORIZONTAL
);
284 m_vScrollBar
= new wxScrollBar(this, wxGRID_VSCROLL
, wxPoint(0, 0), wxSize(100, 20), wxVERTICAL
);
286 // SetSize(pos.x, pos.y, size.x, size.y);
288 m_inPlaceTextItem
= new wxTextCtrl( (wxPanel
*)this, wxGRID_EDIT_IN_PLACE_TEXT_CTRL
, "",
289 wxPoint( m_currentRect
.x
-wxIPE_ADJUST
, m_currentRect
.y
-wxIPE_ADJUST
),
290 wxSize( m_currentRect
.width
+wxIPE_ADJUST
*2, m_currentRect
.height
+wxIPE_ADJUST
*2 ),
291 wxNO_BORDER
| wxTE_PROCESS_ENTER
);
292 m_inPlaceTextItem
->Show(m_editInPlace
);
294 m_inPlaceTextItem
->SetFocus();
299 wxGenericGrid::~wxGenericGrid()
304 void wxGenericGrid::ClearGrid()
309 for (i
= 0; i
< m_totalRows
; i
++)
311 for (j
= 0; j
< m_totalCols
; j
++)
312 if (m_gridCells
[i
][j
])
313 delete m_gridCells
[i
][j
];
314 delete[] m_gridCells
[i
];
316 delete[] m_gridCells
;
317 m_gridCells
= (wxGridCell
***) NULL
;
320 delete[] m_colWidths
;
321 m_colWidths
= (short *) NULL
;
323 delete[] m_rowHeights
;
324 m_rowHeights
= (short *) NULL
;
328 for (i
= 0; i
< m_totalRows
; i
++)
329 delete m_rowLabelCells
[i
];
330 delete[] m_rowLabelCells
;
331 m_rowLabelCells
= (wxGridCell
**) NULL
;
335 for (i
= 0; i
< m_totalCols
; i
++)
336 delete m_colLabelCells
[i
];
337 delete[] m_colLabelCells
;
338 m_colLabelCells
= (wxGridCell
**) NULL
;
340 if (m_doubleBufferingBitmap
)
342 delete m_doubleBufferingBitmap
;
343 m_doubleBufferingBitmap
= (wxBitmap
*) NULL
;
347 bool wxGenericGrid::CreateGrid(int nRows
, int nCols
, wxString
**cellValues
, short *widths
,
348 short defaultWidth
, short defaultHeight
)
354 m_colWidths
= new short[nCols
];
355 m_rowHeights
= new short[nRows
];
356 for (i
= 0; i
< nCols
; i
++)
358 m_colWidths
[i
] = widths
[i
];
360 m_colWidths
[i
] = defaultWidth
;
361 for (i
= 0; i
< nRows
; i
++)
362 m_rowHeights
[i
] = defaultHeight
;
364 m_gridCells
= new wxGridCell
**[nRows
];
366 for (i
= 0; i
< nRows
; i
++)
367 m_gridCells
[i
] = new wxGridCell
*[nCols
];
369 for (i
= 0; i
< nRows
; i
++)
370 for (j
= 0; j
< nCols
; j
++)
373 //m_gridCells[i][j] = OnCreateCell();
374 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CREATE_CELL
, this, i
, j
);
375 GetEventHandler()->ProcessEvent(g_evt
);
376 m_gridCells
[i
][j
] = g_evt
.m_cell
;
377 m_gridCells
[i
][j
]->SetTextValue(cellValues
[i
][j
]);
380 m_gridCells
[i
][j
] = (wxGridCell
*) NULL
;
382 m_rowLabelCells
= new wxGridCell
*[nRows
];
383 for (i
= 0; i
< nRows
; i
++)
384 m_rowLabelCells
[i
] = new wxGridCell(this);
385 m_colLabelCells
= new wxGridCell
*[nCols
];
386 for (i
= 0; i
< nCols
; i
++)
387 m_colLabelCells
[i
] = new wxGridCell(this);
389 m_wCursorRow
= m_wCursorColumn
= 0;
390 SetCurrentRect(0, 0);
392 // Need to determine various dimensions
396 int objectSizeX
= m_totalCols
;
398 int viewLengthX
= m_totalCols
;
401 m_hScrollBar->SetViewLength(viewLengthX);
402 m_hScrollBar->SetObjectLength(objectSizeX);
403 m_hScrollBar->SetPageSize(pageSizeX);
405 m_hScrollBar
->SetScrollbar(m_hScrollBar
->GetThumbPosition(), pageSizeX
, objectSizeX
, viewLengthX
);
407 int objectSizeY
= m_totalRows
;
409 int viewLengthY
= m_totalRows
;
412 m_vScrollBar->SetViewLength(viewLengthY);
413 m_vScrollBar->SetObjectLength(objectSizeY);
414 m_vScrollBar->SetPageSize(pageSizeY);
417 m_vScrollBar
->SetScrollbar(m_vScrollBar
->GetThumbPosition(), pageSizeY
, objectSizeY
, viewLengthY
);
422 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
423 GetEventHandler()->ProcessEvent(g_evt
);
425 //OnChangeSelectionLabel();
426 wxGridEvent
g_evt2(GetId(), wxEVT_GRID_CHANGE_SEL_LABEL
, this);
427 GetEventHandler()->ProcessEvent(g_evt2
);
432 // Need to determine various dimensions
433 void wxGenericGrid::UpdateDimensions()
435 int canvasWidth
, canvasHeight
;
436 GetSize(&canvasWidth
, &canvasHeight
);
438 if (m_editCreated
&& m_editable
)
440 int controlW
, controlH
;
441 GetTextItem()->GetSize(&controlW
, &controlH
);
442 m_topOfSheet
= m_editControlPosition
.y
+ controlH
+ 2;
446 m_rightOfSheet
= m_leftOfSheet
+ m_verticalLabelWidth
;
448 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
450 if (m_rightOfSheet
> canvasWidth
)
453 m_rightOfSheet
+= m_colWidths
[i
];
455 m_bottomOfSheet
= m_topOfSheet
+ m_horizontalLabelHeight
;
456 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
458 if (m_bottomOfSheet
> canvasHeight
)
461 m_bottomOfSheet
+= m_rowHeights
[i
];
464 m_totalGridWidth
= m_leftOfSheet
+ m_verticalLabelWidth
;
465 for (i
= 0; i
< m_totalCols
; i
++)
467 m_totalGridWidth
+= m_colWidths
[i
];
469 m_totalGridHeight
= m_topOfSheet
+ m_horizontalLabelHeight
;
470 for (i
= 0; i
< m_totalRows
; i
++)
472 m_totalGridHeight
+= m_rowHeights
[i
];
476 wxGridCell
*wxGenericGrid::GetCell(int row
, int col
) const
479 return (wxGridCell
*) NULL
;
481 if ((row
>= m_totalRows
) || (col
>= m_totalCols
))
482 return (wxGridCell
*) NULL
;
484 wxGridCell
*cell
= m_gridCells
[row
][col
];
487 // m_gridCells[row][col] = OnCreateCell();
488 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CREATE_CELL
, (wxGenericGrid
*) this, row
, col
);
489 GetEventHandler()->ProcessEvent(g_evt
);
490 m_gridCells
[row
][col
] = g_evt
.m_cell
;
491 return m_gridCells
[row
][col
];
497 void wxGenericGrid::SetGridClippingRegion(wxDC
*dc
)
499 int m_scrollWidthHoriz
= 0;
500 int m_scrollWidthVert
= 0;
502 GetClientSize(&cw
, &ch
);
504 if (m_hScrollBar
&& m_hScrollBar
->IsShown())
505 m_scrollWidthHoriz
= m_scrollWidth
;
506 if (m_vScrollBar
&& m_vScrollBar
->IsShown())
507 m_scrollWidthVert
= m_scrollWidth
;
509 // Don't paint over the scrollbars
510 dc
->SetClippingRegion(m_leftOfSheet
, m_topOfSheet
,
511 cw
- m_scrollWidthVert
- m_leftOfSheet
, ch
- m_scrollWidthHoriz
- m_topOfSheet
);
514 void wxGenericGrid::OnPaint(wxPaintEvent
& WXUNUSED(event
))
517 GetClientSize(&w
, &h
);
519 bool useDoubleBuffering
= (bool) wxUSE_DOUBLE_BUFFERING
;
520 if (useDoubleBuffering
)
522 // Reuse the old bitmap if possible
524 if (!m_doubleBufferingBitmap
||
525 (m_doubleBufferingBitmap
->GetWidth() < w
|| m_doubleBufferingBitmap
->GetHeight() < h
))
527 if (m_doubleBufferingBitmap
)
528 delete m_doubleBufferingBitmap
;
529 m_doubleBufferingBitmap
= new wxBitmap(w
, h
);
531 if (!m_doubleBufferingBitmap
|| !m_doubleBufferingBitmap
->Ok())
533 // If we couldn't create a new bitmap, perhaps because resources were low,
534 // then don't complain, just don't double-buffer
535 if (m_doubleBufferingBitmap
)
536 delete m_doubleBufferingBitmap
;
537 m_doubleBufferingBitmap
= (wxBitmap
*) NULL
;
538 useDoubleBuffering
= FALSE
;
542 if (useDoubleBuffering
)
544 wxPaintDC
paintDC(this);
545 wxMemoryDC
dc(& paintDC
);
546 dc
.SelectObject(* m_doubleBufferingBitmap
);
550 int vertScrollBarWidth
= m_scrollWidth
;
551 int horizScrollBarHeight
= m_scrollWidth
;
552 if (m_vScrollBar
&& !m_vScrollBar
->IsShown())
553 vertScrollBarWidth
= 0;
554 if (m_hScrollBar
&& !m_hScrollBar
->IsShown())
555 horizScrollBarHeight
= 0;
557 paintDC
.Blit(m_leftOfSheet
, m_topOfSheet
, w
- vertScrollBarWidth
- m_leftOfSheet
, h
- horizScrollBarHeight
- m_topOfSheet
,
558 &dc
, m_leftOfSheet
, m_topOfSheet
, wxCOPY
);
560 dc
.SelectObject(wxNullBitmap
);
569 void wxGenericGrid::PaintGrid(wxDC
& dc
)
572 dc
.SetOptimization(FALSE
);
574 SetGridClippingRegion(& dc
);
576 DrawLabelAreas(& dc
);
578 DrawEditableArea(& dc
);
579 DrawColumnLabels(& dc
);
584 /* Hilight present cell */
585 SetCurrentRect(m_wCursorRow
, m_wCursorColumn
);
586 if (m_currentRectVisible
&& (wxIPE_HIGHLIGHT
|| !(m_editable
&& m_editInPlace
)))
587 HighlightCell(& dc
, TRUE
);
589 dc
.DestroyClippingRegion();
590 dc
.SetOptimization(TRUE
);
594 // Erase (some of) the background.
595 // Currently, a Windows-only optimisation.
596 void wxGenericGrid::OnEraseBackground(wxEraseEvent
& WXUNUSED(event
) )
600 dc
.SetOptimization(FALSE
);
603 GetClientSize(& w
, & h
);
604 dc
.SetBrush(*wxLIGHT_GREY_BRUSH
);
605 dc
.SetPen(*wxLIGHT_GREY_PEN
);
607 if (m_hScrollBar
&& m_hScrollBar
->IsShown() && m_vScrollBar
&& m_vScrollBar
->IsShown())
609 dc
.DrawRectangle(w
- m_scrollWidth
, h
- m_scrollWidth
, m_scrollWidth
, m_scrollWidth
);
612 dc
.SetOptimization(TRUE
);
617 void wxGenericGrid::DrawLabelAreas(wxDC
*dc
)
620 GetClientSize(&cw
, &ch
);
622 dc
->SetPen(*wxTRANSPARENT_PEN
);
623 // dc->SetBrush(*dc->GetBackground());
625 // Should blank out any area which isn't going to be painted over.
626 // dc->DrawRectangle(m_leftOfSheet, m_bottomOfSheet, cw - m_leftOfSheet, ch - m_bottomOfSheet);
627 // dc->DrawRectangle(m_rightOfSheet, m_topOfSheet, cw - m_rightOfSheet, ch - m_topOfSheet);
629 // Paint the label areas
630 dc
->SetBrush(m_labelBackgroundBrush
);
631 // dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, m_rightOfSheet - m_leftOfSheet + 1, m_horizontalLabelHeight + 1);
632 dc
->DrawRectangle(m_leftOfSheet
, m_topOfSheet
, cw
-m_leftOfSheet
, m_horizontalLabelHeight
+ 1);
633 // dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, m_verticalLabelWidth + 1, m_bottomOfSheet - m_topOfSheet + 1);
634 dc
->DrawRectangle(m_leftOfSheet
, m_topOfSheet
, m_verticalLabelWidth
+ 1, ch
-m_topOfSheet
);
637 void wxGenericGrid::DrawEditableArea(wxDC
*dc
)
640 GetClientSize(&cw
, &ch
);
642 dc
->SetPen(*wxTRANSPARENT_PEN
);
643 dc
->SetBrush(*wxTheBrushList
->FindOrCreateBrush(m_cellBackgroundColour
, wxSOLID
));
644 // dc->DrawRectangle(m_leftOfSheet+m_verticalLabelWidth, m_topOfSheet+m_horizontalLabelHeight,
645 // m_rightOfSheet-(m_leftOfSheet+m_verticalLabelWidth) + 1, m_bottomOfSheet - (m_topOfSheet+m_horizontalLabelHeight) + 1);
646 dc
->DrawRectangle(m_leftOfSheet
+m_verticalLabelWidth
, m_topOfSheet
+m_horizontalLabelHeight
,
647 cw
-(m_leftOfSheet
+m_verticalLabelWidth
), ch
- (m_topOfSheet
+m_horizontalLabelHeight
));
650 void wxGenericGrid::DrawGridLines(wxDC
*dc
)
653 GetClientSize(&cw
, &ch
);
657 if (m_divisionPen
.Ok())
659 dc
->SetPen(m_divisionPen
);
661 int heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
663 // Draw horizontal grey lines for cells
664 for (i
= m_scrollPosY
; i
< (m_totalRows
+1); i
++)
666 if (heightCount
> ch
)
670 dc
->DrawLine(m_leftOfSheet
, heightCount
,
673 heightCount
+= m_rowHeights
[i
];
678 if (m_verticalLabelWidth
> 0)
680 dc
->SetPen(*wxBLACK_PEN
);
682 // Draw horizontal black lines for row labels
683 int heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
684 for (i
= m_scrollPosY
; i
< (m_totalRows
+1); i
++)
686 if (heightCount
> ch
)
690 dc
->DrawLine(m_leftOfSheet
, heightCount
,
691 m_verticalLabelWidth
, heightCount
);
693 heightCount
+= m_rowHeights
[i
];
696 // Draw a black vertical line for row number cells
697 dc
->DrawLine(m_leftOfSheet
+ m_verticalLabelWidth
, m_topOfSheet
,
698 m_leftOfSheet
+ m_verticalLabelWidth
, ch
);
699 // First vertical line
700 dc
->DrawLine(m_leftOfSheet
, m_topOfSheet
, m_leftOfSheet
, ch
);
702 dc
->SetPen(*wxWHITE_PEN
);
704 // Draw highlights on row labels
705 heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
706 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
708 if (heightCount
> ch
)
712 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
713 m_verticalLabelWidth
, heightCount
+1);
714 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
715 m_leftOfSheet
+1, heightCount
+ m_rowHeights
[i
] - 1);
716 heightCount
+= m_rowHeights
[i
];
719 // Last one - down to the floor.
720 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
721 m_verticalLabelWidth
, heightCount
+1);
722 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
723 m_leftOfSheet
+1, ch
);
727 if (m_divisionPen
.Ok())
729 dc
->SetPen(m_divisionPen
);
731 // Draw vertical grey lines for cells
732 int widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
733 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
739 // Skip the first one
740 if (i
!= m_scrollPosX
)
742 dc
->DrawLine(widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
,
743 widthCount
, m_bottomOfSheet
);
745 widthCount
+= m_colWidths
[i
];
749 dc
->DrawLine(widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
,
750 widthCount
, m_bottomOfSheet
);
753 dc
->SetPen(*wxBLACK_PEN
);
755 // Draw two black horizontal lines for column number cells
757 m_leftOfSheet
, m_topOfSheet
,
759 dc
->DrawLine(m_leftOfSheet
, m_topOfSheet
+ m_horizontalLabelHeight
,
760 cw
, m_topOfSheet
+ m_horizontalLabelHeight
);
762 if (m_horizontalLabelHeight
> 0)
764 int widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
766 // Draw black vertical lines for column number cells
767 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
773 dc
->DrawLine(widthCount
, m_topOfSheet
,
774 widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
);
775 widthCount
+= m_colWidths
[i
];
780 dc
->DrawLine(widthCount
, m_topOfSheet
,
781 widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
);
784 dc
->SetPen(*wxWHITE_PEN
);
785 widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
787 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
793 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
794 widthCount
+m_colWidths
[i
], m_topOfSheet
+1);
795 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
796 widthCount
+1, m_topOfSheet
+m_horizontalLabelHeight
);
797 widthCount
+= m_colWidths
[i
];
800 // Last one - to the right side of the canvas.
801 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
803 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
804 widthCount
+1, m_topOfSheet
+m_horizontalLabelHeight
);
809 void wxGenericGrid::DrawColumnLabels(wxDC
*dc
)
812 GetClientSize(&cw
, &ch
);
814 if (m_horizontalLabelHeight
== 0)
820 // Draw letters for columns
821 rect
.y
= m_topOfSheet
+ 1;
822 rect
.height
= m_horizontalLabelHeight
- 1;
824 dc
->SetTextBackground(m_labelBackgroundColour
);
825 dc
->SetBackgroundMode(wxTRANSPARENT
);
826 // dc->SetTextForeground(m_labelTextColour);
828 int widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
829 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
835 rect
.x
= 1 + widthCount
;
836 rect
.width
= m_colWidths
[i
];
837 DrawColumnLabel(dc
, &rect
, i
);
839 widthCount
+= m_colWidths
[i
];
844 void wxGenericGrid::DrawColumnLabel(wxDC
*dc
, wxRect
*rect
, int col
)
846 wxGridCell
*cell
= GetLabelCell(wxHORIZONTAL
, col
);
855 dc
->SetTextForeground(GetLabelTextColour());
856 dc
->SetFont(GetLabelTextFont());
857 if ( !cell
->GetTextValue().IsNull() )
858 DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, GetLabelAlignment(wxHORIZONTAL
));
862 void wxGenericGrid::DrawRowLabels(wxDC
*dc
)
865 GetClientSize(&cw
, &ch
);
867 if (m_verticalLabelWidth
== 0)
873 // Draw numbers for rows
874 rect
.x
= m_leftOfSheet
;
875 rect
.width
= m_verticalLabelWidth
;
877 int heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
879 dc
->SetTextBackground(m_labelBackgroundColour
);
880 dc
->SetBackgroundMode(wxTRANSPARENT
);
882 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
884 if (heightCount
> ch
)
888 rect
.y
= 1 + heightCount
;
889 rect
.height
= m_rowHeights
[i
];
890 DrawRowLabel(dc
, &rect
, i
);
892 heightCount
+= m_rowHeights
[i
];
897 void wxGenericGrid::DrawRowLabel(wxDC
*dc
, wxRect
*rect
, int row
)
899 wxGridCell
*cell
= GetLabelCell(wxVERTICAL
, row
);
908 dc
->SetTextForeground(GetLabelTextColour());
909 dc
->SetFont(GetLabelTextFont());
910 if ( !cell
->GetTextValue().IsNull() )
911 DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, GetLabelAlignment(wxVERTICAL
));
915 void wxGenericGrid::DrawCells(wxDC
*dc
)
918 GetClientSize(&cw
, &ch
);
922 // Draw value corresponding to each cell
923 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
925 for (j
= m_scrollPosX
; j
< m_totalCols
; j
++)
927 SetCurrentRect(i
, j
, cw
, ch
);
928 if (m_currentRectVisible
)
930 DrawCellBackground(dc
, &m_currentRect
, i
, j
);
931 DrawCellValue(dc
, &m_currentRect
, i
, j
);
933 if (m_currentRect
.x
> cw
)
936 if (m_currentRect
.y
> ch
)
939 dc
->SetBackgroundMode(wxSOLID
);
940 dc
->SetPen(*wxBLACK_PEN
);
943 void wxGenericGrid::DrawCellBackground(wxDC
*dc
, wxRect
*rect
, int row
, int col
)
945 wxGridCell
*cell
= GetCell(row
, col
);
948 dc
->SetBrush(cell
->GetBackgroundBrush());
949 dc
->SetPen(*wxTRANSPARENT_PEN
);
951 #if 0 // In wxWin 2.0 the dc code is exact. RR.
953 dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
-1, rect
->height
-1);
955 dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
, rect
->height
);
959 dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
-1, rect
->height
-1);
961 dc
->SetPen(*wxBLACK_PEN
);
965 void wxGenericGrid::DrawCellValue(wxDC
*dc
, wxRect
*rect
, int row
, int col
)
967 wxGridCell
*cell
= GetCell(row
, col
);
970 wxBitmap
*bitmap
= cell
->GetCellBitmap();
980 DrawBitmapRect(dc
, bitmap
, &rect2
, cell
->GetAlignment());
984 dc
->SetBackgroundMode(wxTRANSPARENT
);
985 dc
->SetTextForeground(cell
->GetTextColour());
986 dc
->SetFont(cell
->GetFont());
988 if ( !cell
->GetTextValue().IsNull() )
989 DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, cell
->GetAlignment());
994 void wxGenericGrid::AdjustScrollbars()
997 GetClientSize(&cw
, &ch
);
999 // We find the view size by seeing how many rows/cols fit on
1000 // the current view.
1001 // BUT... this means that the scrollbar should be adjusted every time
1002 // it's scrolled, as well as when sized, because with variable size rows/cols,
1003 // the number of rows/col visible on the view differs according to what bit
1004 // you're looking at. The object length is always the same, but the
1005 // view length differs.
1007 // Since this may not be known until the end of this function, we should probably call AdjustScrollbars
1009 int vertScrollBarWidth
= m_scrollWidth
;
1010 int horizScrollBarHeight
= m_scrollWidth
;
1011 if (m_vScrollBar
&& !m_vScrollBar
->IsShown())
1012 vertScrollBarWidth
= 0;
1013 if (m_hScrollBar
&& !m_hScrollBar
->IsShown())
1014 horizScrollBarHeight
= 0;
1016 int noHorizSteps
= 0;
1017 int noVertSteps
= 0;
1019 if (m_totalGridWidth
+ vertScrollBarWidth
> cw
)
1025 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1027 widthCount
+= m_colWidths
[i
];
1028 // A partial bit doesn't count, we still have to scroll to see the
1030 if (widthCount
+ m_leftOfSheet
+ m_verticalLabelWidth
> (cw
-vertScrollBarWidth
))
1038 m_viewWidth
= noHorizSteps
;
1040 if (m_totalGridHeight
+ horizScrollBarHeight
> ch
)
1042 int heightCount
= 0;
1046 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1048 heightCount
+= m_rowHeights
[i
];
1049 // A partial bit doesn't count, we still have to scroll to see the
1051 if (heightCount
+ m_topOfSheet
+ m_horizontalLabelHeight
> (ch
-horizScrollBarHeight
))
1060 m_viewHeight
= noVertSteps
;
1062 if (m_totalGridWidth
+ vertScrollBarWidth
<= cw
)
1065 m_hScrollBar
->Show(FALSE
);
1071 m_hScrollBar
->Show(TRUE
);
1074 if (m_totalGridHeight
+ horizScrollBarHeight
<= ch
)
1077 m_vScrollBar
->Show(FALSE
);
1083 m_vScrollBar
->Show(TRUE
);
1086 UpdateDimensions(); // Necessary in case m_scrollPosX/Y changed
1088 vertScrollBarWidth
= m_scrollWidth
;
1089 horizScrollBarHeight
= m_scrollWidth
;
1090 if (m_vScrollBar
&& !m_vScrollBar
->IsShown())
1091 vertScrollBarWidth
= 0;
1092 if (m_hScrollBar
&& !m_hScrollBar
->IsShown())
1093 horizScrollBarHeight
= 0;
1095 if (m_hScrollBar
&& m_hScrollBar
->IsShown())
1097 int nCols
= GetCols();
1098 m_hScrollBar
->SetScrollbar(m_hScrollBar
->GetThumbPosition(), wxMax(noHorizSteps
, 1), (noHorizSteps
== 0) ? 1 : nCols
, wxMax(noHorizSteps
, 1));
1101 m_hScrollBar->SetSize(m_leftOfSheet, ch - m_scrollWidth -2, // why -2 ? Robert.
1102 cw - vertScrollBarWidth - m_leftOfSheet, m_scrollWidth);
1104 m_hScrollBar
->SetSize(m_leftOfSheet
, ch
- m_scrollWidth
,
1105 cw
- vertScrollBarWidth
- m_leftOfSheet
, m_scrollWidth
);
1109 if (m_vScrollBar
&& m_vScrollBar
->IsShown())
1111 int nRows
= GetRows();
1113 m_vScrollBar
->SetScrollbar(m_vScrollBar
->GetThumbPosition(), wxMax(noVertSteps
, 1), (noVertSteps
== 0) ? 1 : nRows
, wxMax(noVertSteps
, 1));
1114 m_vScrollBar
->SetSize(cw
- m_scrollWidth
, m_topOfSheet
,
1115 m_scrollWidth
, ch
- m_topOfSheet
- horizScrollBarHeight
);
1119 void wxGenericGrid::OnSize(wxSizeEvent
& WXUNUSED(event
) )
1121 if (!m_vScrollBar
|| !m_hScrollBar
)
1127 GetClientSize(&cw
, &ch
);
1129 if (m_editCreated
&& m_editingPanel
&& GetTextItem() && GetTextItem()->IsShown())
1131 m_editingPanel
->SetSize(0, 0, cw
, m_editControlPosition
.height
+ m_editControlPosition
.y
+ 2);
1132 GetTextItem()->SetSize(m_editControlPosition
.x
, m_editControlPosition
.y
,
1133 cw
- 2*m_editControlPosition
.x
, m_editControlPosition
.height
);
1137 bool wxGenericGrid::CellHitTest(int x
, int y
, int *row
, int *col
)
1139 // Find the selected cell and call OnSelectCell
1140 if (x
>= (m_leftOfSheet
+ m_verticalLabelWidth
) && y
>= (m_topOfSheet
+ m_horizontalLabelHeight
) &&
1141 x
<= m_rightOfSheet
&& y
<= m_bottomOfSheet
)
1143 // Calculate the cell number from x and y
1144 x
-= (m_verticalLabelWidth
+ m_leftOfSheet
);
1145 y
-= (m_topOfSheet
+ m_horizontalLabelHeight
);
1149 // Now we need to do a hit test for which row we're on
1150 int currentHeight
= 0;
1151 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1153 if (y
>= currentHeight
&& y
<= (currentHeight
+ m_rowHeights
[i
]))
1158 currentHeight
+= m_rowHeights
[i
];
1161 // Now we need to do a hit test for which column we're on
1162 int currentWidth
= 0;
1163 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1165 if (x
>= currentWidth
&& x
<= (currentWidth
+ m_colWidths
[i
]))
1170 currentWidth
+= m_colWidths
[i
];
1177 bool wxGenericGrid::LabelSashHitTest(int x
, int y
, int *orientation
, int *rowOrCol
, int *startPos
)
1182 if (x
>= (m_leftOfSheet
+ m_verticalLabelWidth
) && y
>= m_topOfSheet
&&
1183 x
<= m_rightOfSheet
&& y
<= (m_topOfSheet
+ m_horizontalLabelHeight
))
1185 // We may be on a column label sash.
1186 int currentWidth
= m_leftOfSheet
+ m_verticalLabelWidth
;
1187 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1189 if (x
>= (currentWidth
+ m_colWidths
[i
] - tolerance
) && x
<= (currentWidth
+ m_colWidths
[i
] + tolerance
))
1191 *orientation
= wxHORIZONTAL
;
1193 *startPos
= currentWidth
;
1196 currentWidth
+= m_colWidths
[i
];
1200 else if (x
>= m_leftOfSheet
&& y
>= (m_topOfSheet
+ m_horizontalLabelHeight
) &&
1201 x
<= (m_leftOfSheet
+ m_verticalLabelWidth
) && y
<= m_bottomOfSheet
)
1203 // We may be on a row label sash.
1204 int currentHeight
= m_topOfSheet
+ m_horizontalLabelHeight
;
1205 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1207 if (y
>= (currentHeight
+ m_rowHeights
[i
] - tolerance
) && y
<= (currentHeight
+ m_rowHeights
[i
] + tolerance
))
1209 *orientation
= wxVERTICAL
;
1211 *startPos
= currentHeight
;
1214 currentHeight
+= m_rowHeights
[i
];
1221 bool wxGenericGrid::LabelHitTest(int x
, int y
, int *row
, int *col
)
1223 // Find the selected label
1224 if (x
>= m_leftOfSheet
&& y
>= m_topOfSheet
&&
1225 x
<= m_rightOfSheet
&& y
<= m_bottomOfSheet
)
1227 // Calculate the cell number from x and y
1233 // Now we need to do a hit test for which row we're on
1234 int currentHeight
= m_horizontalLabelHeight
;
1235 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1237 if (y
>= currentHeight
&& y
<= (currentHeight
+ m_rowHeights
[i
]))
1242 currentHeight
+= m_rowHeights
[i
];
1244 if (y
>= 0 && y
<= m_horizontalLabelHeight
)
1249 // Now we need to do a hit test for which column we're on
1250 int currentWidth
= m_verticalLabelWidth
;
1251 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1253 if (x
>= currentWidth
&& x
<= (currentWidth
+ m_colWidths
[i
]))
1258 currentWidth
+= m_colWidths
[i
];
1260 if (x
>= 0 && x
<= m_verticalLabelWidth
)
1265 if ((*col
== -1) || (*row
== -1))
1273 void wxGenericGrid::OnMouseEvent(wxMouseEvent
& ev
)
1277 wxClientDC
dc(this);
1281 if (CellHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1283 OnSelectCellImplementation(& dc
, row
, col
);
1285 //OnCellLeftClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1286 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CELL_LCLICK
, this,
1287 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1288 ev
.ControlDown(), ev
.ShiftDown());
1289 GetEventHandler()->ProcessEvent(g_evt
);
1292 if (LabelHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1294 //OnLabelLeftClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1295 wxGridEvent
g_evt(GetId(), wxEVT_GRID_LABEL_LCLICK
, this,
1296 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1297 ev
.ControlDown(), ev
.ShiftDown());
1298 GetEventHandler()->ProcessEvent(g_evt
);
1303 else if (ev
.Dragging() && ev
.LeftIsDown())
1305 switch (m_dragStatus
)
1307 case wxGRID_DRAG_NONE
:
1310 if (LabelSashHitTest((int)ev
.GetX(), (int)ev
.GetY(), &orientation
, &m_dragRowOrCol
, &m_dragStartPosition
))
1312 if (orientation
== wxHORIZONTAL
)
1314 m_dragStatus
= wxGRID_DRAG_LEFT_RIGHT
;
1315 SetCursor(m_horizontalSashCursor
);
1316 m_dragLastPosition
= (int)ev
.GetX();
1320 m_dragStatus
= wxGRID_DRAG_UP_DOWN
;
1321 SetCursor(m_verticalSashCursor
);
1322 m_dragLastPosition
= (int)ev
.GetY();
1324 wxClientDC
dc(this);
1326 dc
.SetLogicalFunction(wxINVERT
);
1327 if (orientation
== wxHORIZONTAL
)
1328 dc
.DrawLine((int)ev
.GetX(), m_topOfSheet
, (int)ev
.GetX(), m_bottomOfSheet
);
1330 dc
.DrawLine(m_leftOfSheet
, (int)ev
.GetY(), m_rightOfSheet
, (int)ev
.GetY());
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
);
1344 dc
.DrawLine((int)ev
.GetX(), m_topOfSheet
, (int)ev
.GetX(), m_bottomOfSheet
);
1347 m_dragLastPosition
= (int)ev
.GetX();
1348 SetCursor(m_horizontalSashCursor
);
1351 case wxGRID_DRAG_UP_DOWN
:
1353 wxClientDC
dc(this);
1355 dc
.SetLogicalFunction(wxINVERT
);
1356 dc
.DrawLine(m_leftOfSheet
, m_dragLastPosition
, m_rightOfSheet
, m_dragLastPosition
);
1358 dc
.DrawLine(m_leftOfSheet
, (int)ev
.GetY(), m_rightOfSheet
, (int)ev
.GetY());
1361 m_dragLastPosition
= (int)ev
.GetY();
1362 SetCursor(m_verticalSashCursor
);
1367 else if (ev
.Moving())
1369 int rowOrCol
, orientation
, startPos
;
1370 if (LabelSashHitTest((int)ev
.GetX(), (int)ev
.GetY(), &orientation
, &rowOrCol
, &startPos
))
1372 if (orientation
== wxHORIZONTAL
)
1373 SetCursor(m_horizontalSashCursor
);
1375 SetCursor(m_verticalSashCursor
);
1378 SetCursor(*wxSTANDARD_CURSOR
);
1380 else if (ev
.LeftUp())
1382 switch (m_dragStatus
)
1384 case wxGRID_DRAG_LEFT_RIGHT
:
1386 wxClientDC
dc(this);
1388 dc
.SetLogicalFunction(wxINVERT
);
1389 dc
.DrawLine(m_dragLastPosition
, m_topOfSheet
, m_dragLastPosition
, m_bottomOfSheet
);
1390 dc
.SetLogicalFunction(wxCOPY
);
1394 if (ev
.GetX() > m_dragStartPosition
)
1396 m_colWidths
[m_dragRowOrCol
] = (short)(ev
.GetX() - m_dragStartPosition
);
1401 SetCursor(*wxSTANDARD_CURSOR
);
1403 GetClientSize(&cw
, &ch
);
1408 case wxGRID_DRAG_UP_DOWN
:
1410 wxClientDC
dc(this);
1412 dc
.SetLogicalFunction(wxINVERT
);
1413 dc
.DrawLine(m_leftOfSheet
, m_dragLastPosition
, m_rightOfSheet
, m_dragLastPosition
);
1414 dc
.SetLogicalFunction(wxCOPY
);
1418 if (ev
.GetY() > m_dragStartPosition
)
1420 m_rowHeights
[m_dragRowOrCol
] = (short)(ev
.GetY() - m_dragStartPosition
);
1425 SetCursor(*wxSTANDARD_CURSOR
);
1429 m_dragStatus
= wxGRID_DRAG_NONE
;
1431 else if (ev
.RightDown())
1434 if (CellHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1436 //OnCellRightClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1437 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CELL_RCLICK
, this,
1438 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1439 ev
.ControlDown(), ev
.ShiftDown());
1440 GetEventHandler()->ProcessEvent(g_evt
);
1443 if (LabelHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1445 //OnLabelRightClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1446 wxGridEvent
g_evt(GetId(), wxEVT_GRID_LABEL_RCLICK
, this,
1447 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1448 ev
.ControlDown(), ev
.ShiftDown());
1449 GetEventHandler()->ProcessEvent(g_evt
);
1454 void wxGenericGrid::OnSelectCellImplementation(wxDC
*dc
, int row
, int col
)
1456 m_wCursorColumn
= col
;
1459 //OnChangeSelectionLabel();
1460 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_SEL_LABEL
, this);
1461 GetEventHandler()->ProcessEvent(g_evt
);
1463 SetGridClippingRegion(dc
);
1465 // Remove the highlight from the old cell
1466 if ( m_currentRectVisible
&& (wxIPE_HIGHLIGHT
|| !(m_editable
&& m_editInPlace
)))
1468 HighlightCell(dc
, FALSE
);
1472 // Highlight the new cell and copy its content to the edit control
1473 SetCurrentRect(m_wCursorRow
, m_wCursorColumn
);
1474 wxGridCell
*cell
= GetCell(m_wCursorRow
, m_wCursorColumn
);
1477 if ( cell
->GetTextValue().IsNull() )
1478 m_textItem
->SetValue("");
1480 m_textItem
->SetValue(cell
->GetTextValue());
1483 SetGridClippingRegion(dc
);
1486 if ( m_editable
&& m_editInPlace
)
1488 int x
, y
, width
, height
;
1489 if ( m_currentRect
.x
<= 0 )
1492 width
= m_currentRect
.width
+ wxIPE_ADJUST
;
1496 x
= m_currentRect
.x
- wxIPE_ADJUST
;
1497 width
= m_currentRect
.width
+ wxIPE_ADJUST
*2;
1500 if ( m_currentRect
.y
<= 0 )
1503 height
= m_currentRect
.height
+ wxIPE_ADJUST
;
1507 y
= m_currentRect
.y
- wxIPE_ADJUST
;
1508 height
= m_currentRect
.height
+ wxIPE_ADJUST
*2;
1511 m_inPlaceTextItem
->SetSize( x
, y
, width
, height
);
1514 m_inPlaceTextItem
->SetFont( cell
->GetFont() );
1515 m_inPlaceTextItem
->SetBackgroundColour(cell
->GetBackgroundColour());
1516 m_inPlaceTextItem
->SetForegroundColour(cell
->GetTextColour());
1518 if ( cell
->GetTextValue().IsNull() ) {
1519 m_inPlaceTextItem
->SetValue( "" );
1522 m_inPlaceTextItem
->SetValue( cell
->GetTextValue() );
1526 m_inPlaceTextItem
->Show(TRUE
);
1527 m_inPlaceTextItem
->SetFocus();
1528 #if defined(__VISAGECPP__)
1530 int highlight
= wxIPE_HIGHLIGHT
;
1532 HighlightCell(dc
, TRUE
);
1535 if (wxIPE_HIGHLIGHT
!= 0)
1536 HighlightCell(dc
, TRUE
);
1541 // 1) Why isn't this needed for Windows??
1542 // Probably because of the SetValue?? JS.
1543 // 2) Arrrrrgh. This isn't needed anywhere,
1544 // of course. One hour of debugging... RR.
1546 // 3) It *is* needed for Motif - michael
1548 #if defined(__WXMOTIF__)
1549 if ((wxIPE_HIGHLIGHT
|| !(m_editable
&& m_editInPlace
)))
1550 HighlightCell(dc
, TRUE
);
1554 dc
->DestroyClippingRegion();
1556 OnSelectCell(row
, col
);
1557 wxGridEvent
g_evt2(GetId(), wxEVT_GRID_SELECT_CELL
, this, row
, col
);
1558 GetEventHandler()->ProcessEvent(g_evt2
);
1561 wxGridCell
*wxGenericGrid::OnCreateCell()
1563 return new wxGridCell(this);
1566 void wxGenericGrid::OnChangeLabels()
1570 for (i
= 0; i
< m_totalRows
; i
++)
1572 sprintf(buf
, "%d", i
+1);
1573 SetLabelValue(wxVERTICAL
, buf
, i
);
1575 // A...Z,AA...ZZ,AAA...ZZZ, etc.
1576 for (i
= 0; i
< m_totalCols
; i
++)
1579 int noTimes
= (i
/26 + 1);
1580 int ch
= (i
% 26) + 65;
1582 for (j
= 0; j
< noTimes
; j
++)
1585 sprintf(buf2
, "%c", (char)ch
);
1588 SetLabelValue(wxHORIZONTAL
, buf
, i
);
1592 void wxGenericGrid::OnChangeSelectionLabel()
1597 wxString
rowLabel(GetLabelValue(wxVERTICAL
, GetCursorRow()));
1598 wxString
colLabel(GetLabelValue(wxHORIZONTAL
, GetCursorColumn()));
1600 wxString newLabel
= colLabel
+ rowLabel
;
1601 if ((newLabel
.Length() > 0) && (newLabel
.Length() <= 8) && GetTextItem())
1603 // GetTextItem()->SetLabel(newLabel);
1607 void wxGenericGrid::HighlightCell(wxDC
*dc
, bool doHighlight
)
1609 wxPen savePen
= dc
->GetPen();
1611 dc
->SetPen(m_highlightPen
);
1613 dc
->SetPen(*wxThePenList
->FindOrCreatePen(m_cellBackgroundColour
, 1, wxSOLID
));
1616 dc
->DrawLine( m_currentRect
.x
+ 1,
1617 m_currentRect
.y
+ 1,
1618 m_currentRect
.x
+ m_currentRect
.width
- 1,
1619 m_currentRect
.y
+ 1);
1621 dc
->DrawLine( m_currentRect
.x
+ m_currentRect
.width
- 1,
1622 m_currentRect
.y
+ 1,
1623 m_currentRect
.x
+ m_currentRect
.width
- 1,
1624 m_currentRect
.y
+ m_currentRect
.height
- 1 );
1626 dc
->DrawLine( m_currentRect
.x
+ m_currentRect
.width
- 1,
1627 m_currentRect
.y
+ m_currentRect
.height
- 1,
1628 m_currentRect
.x
+ 1,
1629 m_currentRect
.y
+ m_currentRect
.height
- 1);
1631 dc
->DrawLine( m_currentRect
.x
+ 1,
1632 m_currentRect
.y
+ m_currentRect
.height
- 1,
1633 m_currentRect
.x
+ 1,
1634 m_currentRect
.y
+ 1);
1636 dc
->SetPen(savePen
);
1639 void wxGenericGrid::DrawCellText()
1641 if (!m_currentRectVisible
)
1644 wxGridCell
*cell
= GetCell(GetCursorRow(), GetCursorColumn());
1648 wxClientDC
dc(this);
1651 SetGridClippingRegion(& dc
);
1653 dc
.SetBackgroundMode(wxTRANSPARENT
);
1654 dc
.SetBrush(cell
->GetBackgroundBrush());
1656 wxString editValue
= m_textItem
->GetValue();
1659 rect
= m_currentRect
;
1665 // FIXME: what's this string of spaces supposed to represent?
1666 DrawTextRect(& dc
, " ", &rect
, wxLEFT
);
1667 DrawTextRect(& dc
, editValue
, &rect
, cell
->GetAlignment());
1669 dc
.DestroyClippingRegion();
1671 dc
.SetBackgroundMode(wxSOLID
);
1676 void wxGenericGrid::SetCurrentRect(int Row
, int Column
, int canvasW
, int canvasH
)
1678 int currentWidth
= m_leftOfSheet
+ m_verticalLabelWidth
;
1680 for (i
= m_scrollPosX
; i
< Column
; i
++)
1681 currentWidth
+= m_colWidths
[i
];
1683 int currentHeight
= m_topOfSheet
+ m_horizontalLabelHeight
;
1684 for (i
= m_scrollPosY
; i
< Row
; i
++)
1685 currentHeight
+= m_rowHeights
[i
];
1687 m_currentRect
.x
= currentWidth
;
1688 m_currentRect
.y
= currentHeight
;
1689 m_currentRect
.width
= m_colWidths
? (m_colWidths
[Column
]) : 0;
1690 m_currentRect
.height
= m_rowHeights
? (m_rowHeights
[Row
]) : 0;
1692 if (Row
< m_scrollPosY
|| Column
< m_scrollPosX
)
1693 m_currentRectVisible
= FALSE
;
1694 else if ((canvasW
!= -1 && canvasH
!= -1) && (m_currentRect
.x
> canvasW
|| m_currentRect
.y
> canvasH
))
1695 m_currentRectVisible
= FALSE
;
1696 else m_currentRectVisible
= TRUE
;
1699 static bool wxRectIntersection(wxRect
*rect1
, wxRect
*rect2
, wxRect
*rect3
)
1701 int x2_1
= rect1
->x
+ rect1
->width
;
1702 int y2_1
= rect1
->y
+ rect1
->height
;
1704 int x2_2
= rect2
->x
+ rect2
->width
;
1705 int y2_2
= rect2
->y
+ rect2
->height
;
1709 // Check for intersection
1710 if ((rect1
->x
> x2_2
) || (rect2
->x
> x2_1
) ||
1711 (rect1
->y
> y2_2
) || (rect2
->y
> y2_1
))
1714 rect3
->x
= rect3
->y
= rect3
->width
= rect3
->height
= 0;
1718 if (rect1
->x
> rect2
->x
)
1719 rect3
->x
= rect1
->x
;
1721 rect3
->x
= rect2
->x
;
1722 if (rect1
->y
> rect2
->y
)
1723 rect3
->y
= rect1
->y
;
1725 rect3
->y
= rect2
->y
;
1736 rect3
->width
= (int)(x2_3
- rect3
->x
);
1737 rect3
->height
= (int)(y2_3
- rect3
->y
);
1741 void wxGenericGrid::DrawTextRect(wxDC
*dc
, const wxString
& text
, wxRect
*rect
, int flag
)
1745 // Ultimately, this functionality should be built into wxWindows,
1746 // and optimized for each platform. E.g. on Windows, use DrawText
1747 // passing a clipping rectangle, so that the wxWindows clipping region
1748 // does not have to be used to implement this.
1750 // If we're already clipping, we need to find the intersection
1751 // between current clipping area and text clipping area.
1755 long clipX
, clipY
, clipW
, clipH
;
1756 dc
->GetClippingBox(&clipX
, &clipY
, &clipW
, &clipH
);
1757 clipRect
.x
= (int)clipX
; clipRect
.y
= (int)clipY
;
1758 clipRect
.width
= (int)clipW
; clipRect
.height
= (int)clipH
;
1760 bool alreadyClipping
= TRUE
;
1762 if (clipRect
.x
== 0 && clipRect
.y
== 0 && clipRect
.width
== 0 && clipRect
.height
== 0)
1764 alreadyClipping
= FALSE
;
1765 clipRect2
.x
= rect
->x
; clipRect2
.y
= rect
->y
;
1766 clipRect2
.width
= rect
->width
; clipRect2
.height
= rect
->height
;
1770 // Find intersection.
1771 if (!wxRectIntersection(rect
, &clipRect
, &clipRect2
))
1775 if (alreadyClipping
)
1776 dc
->DestroyClippingRegion();
1778 dc
->SetClippingRegion(clipRect2
.x
, clipRect2
.y
, clipRect2
.width
, clipRect2
.height
);
1779 long textWidth
, textHeight
;
1781 dc
->GetTextExtent(text
, &textWidth
, &textHeight
);
1789 x
= (rect
->x
+ rect
->width
- textWidth
- (float)1.0);
1790 y
= (rect
->y
+ (rect
->height
- textHeight
)/(float)2.0);
1795 x
= (rect
->x
+ (rect
->width
- textWidth
)/(float)2.0);
1796 y
= (rect
->y
+ (rect
->height
- textHeight
)/(float)2.0);
1802 x
= (rect
->x
+ (float)1.0);
1803 y
= (rect
->y
+ (rect
->height
- textHeight
)/(float)2.0);
1807 dc
->DrawText(text
, (long)x
, (long)y
);
1809 dc
->DestroyClippingRegion();
1811 // Restore old clipping
1812 if (alreadyClipping
)
1813 dc
->SetClippingRegion(clipRect
.x
, clipRect
.y
, clipRect
.width
, clipRect
.height
);
1818 void wxGenericGrid::DrawBitmapRect(wxDC
*dc
, wxBitmap
*bitmap
, wxRect
*rect
, int flag
)
1822 // Ultimately, this functionality should be built into wxWindows,
1823 // and optimized for each platform. E.g. on Windows, use DrawText
1824 // passing a clipping rectangle, so that the wxWindows clipping region
1825 // does not have to be used to implement this.
1827 // If we're already clipping, we need to find the intersection
1828 // between current clipping area and text clipping area.
1832 long clipX
, clipY
, clipW
, clipH
;
1833 dc
->GetClippingBox(&clipX
, &clipY
, &clipW
, &clipH
);
1834 clipRect
.x
= (int)clipX
; clipRect
.y
= (int)clipY
;
1835 clipRect
.width
= (int)clipW
; clipRect
.height
= (int)clipH
;
1837 bool alreadyClipping
= TRUE
;
1839 if (clipRect
.x
== 0 && clipRect
.y
== 0 && clipRect
.width
== 0 && clipRect
.height
== 0)
1841 alreadyClipping
= FALSE
;
1842 clipRect2
.x
= rect
->x
; clipRect2
.y
= rect
->y
;
1843 clipRect2
.width
= rect
->width
; clipRect2
.height
= rect
->height
;
1847 // Find intersection.
1848 if (!wxRectIntersection(rect
, &clipRect
, &clipRect2
))
1852 if (alreadyClipping
)
1853 dc
->DestroyClippingRegion();
1855 dc
->SetClippingRegion(clipRect2
.x
, clipRect2
.y
, clipRect2
.width
, clipRect2
.height
);
1856 float bitmapWidth
, bitmapHeight
;
1858 bitmapWidth
= bitmap
->GetWidth();
1859 bitmapHeight
= bitmap
->GetHeight();
1867 x
= (long)(rect
->x
+ rect
->width
- bitmapWidth
- 1);
1868 y
= (long)(rect
->y
+ (rect
->height
- bitmapHeight
)/2.0);
1873 x
= (long)(rect
->x
+ (rect
->width
- bitmapWidth
)/2.0);
1874 y
= (long)(rect
->y
+ (rect
->height
- bitmapHeight
)/2.0);
1880 x
= (long)(rect
->x
+ 1);
1881 y
= (long)(rect
->y
+ (rect
->height
- bitmapHeight
)/2.0);
1886 dcTemp
.SelectObject(*bitmap
);
1888 dc
->Blit( (long)x
, (long)y
, (long)bitmapWidth
, (long)bitmapHeight
, &dcTemp
, 0, 0);
1889 dcTemp
.SelectObject(wxNullBitmap
);
1891 dc
->DestroyClippingRegion();
1893 // Restore old clipping
1894 if (alreadyClipping
)
1895 dc
->SetClippingRegion(clipRect
.x
, clipRect
.y
, clipRect
.width
, clipRect
.height
);
1900 void wxGenericGrid::OnActivate(bool active
)
1904 // Edit control should always have the focus
1905 if (GetTextItem() && GetEditable())
1907 GetTextItem()->SetFocus();
1908 wxGridCell
*cell
= GetCell(GetCursorRow(), GetCursorColumn());
1910 GetTextItem()->SetValue(cell
->GetTextValue());
1915 void wxGenericGrid::SetCellValue(const wxString
& val
, int row
, int col
)
1917 wxGridCell
*cell
= GetCell(row
, col
);
1920 cell
->SetTextValue(val
);
1922 RefreshCell(row
, col
, TRUE
);
1926 void wxGenericGrid::RefreshCell(int row
, int col
, bool setText
)
1928 // Don't refresh within a pair of batch brackets
1929 if (GetBatchCount() > 0)
1933 GetClientSize(&cw
, &ch
);
1935 SetCurrentRect(row
, col
, cw
, ch
);
1936 if (m_currentRectVisible
)
1938 wxGridCell
*cell
= GetCell(row
, col
);
1940 bool currentPos
= FALSE
;
1941 if (row
== m_wCursorRow
&& col
== m_wCursorColumn
&& GetTextItem() && GetTextItem()->IsShown() && setText
)
1943 GetTextItem()->SetValue(cell
->GetTextValue());
1946 // Gets refreshed anyway in MSW
1951 wxClientDC
dc(this);
1953 DrawCellBackground(& dc
, &m_currentRect
, row
, col
);
1954 DrawCellValue(& dc
, &m_currentRect
, row
, col
);
1960 wxString
& wxGenericGrid::GetCellValue(int row
, int col
) const
1962 static wxString
emptyString("");
1964 wxGridCell
*cell
= GetCell(row
, col
);
1966 return cell
->GetTextValue();
1971 void wxGenericGrid::SetColumnWidth(int col
, int width
)
1973 if (col
<= m_totalCols
)
1974 m_colWidths
[col
] = width
;
1977 int wxGenericGrid::GetColumnWidth(int col
) const
1979 if (col
<= m_totalCols
)
1980 return m_colWidths
[col
];
1985 void wxGenericGrid::SetRowHeight(int row
, int height
)
1987 if (row
<= m_totalRows
)
1988 m_rowHeights
[row
] = height
;
1991 int wxGenericGrid::GetRowHeight(int row
) const
1993 if (row
<= m_totalRows
)
1994 return m_rowHeights
[row
];
1999 void wxGenericGrid::SetLabelSize(int orientation
, int sz
)
2001 if (orientation
== wxHORIZONTAL
)
2002 m_horizontalLabelHeight
= sz
;
2004 m_verticalLabelWidth
= sz
;
2006 SetCurrentRect(GetCursorRow(), GetCursorColumn());
2009 int wxGenericGrid::GetLabelSize(int orientation
) const
2011 if (orientation
== wxHORIZONTAL
)
2012 return m_horizontalLabelHeight
;
2014 return m_verticalLabelWidth
;
2017 wxGridCell
*wxGenericGrid::GetLabelCell(int orientation
, int pos
) const
2019 if (orientation
== wxHORIZONTAL
)
2021 if (m_colLabelCells
&& pos
< m_totalCols
)
2022 return m_colLabelCells
[pos
];
2024 return (wxGridCell
*) NULL
;
2028 if (m_rowLabelCells
&& pos
< m_totalRows
)
2029 return m_rowLabelCells
[pos
];
2031 return (wxGridCell
*) NULL
;
2035 void wxGenericGrid::SetLabelValue(int orientation
, const wxString
& val
, int pos
)
2037 wxGridCell
*cell
= GetLabelCell(orientation
, pos
);
2039 cell
->SetTextValue(val
);
2042 wxString
& wxGenericGrid::GetLabelValue(int orientation
, int pos
) const
2044 static wxString emptyString
= "";
2045 wxGridCell
*cell
= GetLabelCell(orientation
, pos
);
2047 return cell
->GetTextValue();
2052 void wxGenericGrid::SetLabelAlignment(int orientation
, int align
)
2054 if (orientation
== wxHORIZONTAL
)
2055 m_horizontalLabelAlignment
= align
;
2057 m_verticalLabelAlignment
= align
;
2059 SetCurrentRect(GetCursorRow(), GetCursorColumn());
2062 int wxGenericGrid::GetLabelAlignment(int orientation
) const
2064 if (orientation
== wxHORIZONTAL
)
2065 return m_horizontalLabelAlignment
;
2067 return m_verticalLabelAlignment
;
2070 void wxGenericGrid::SetLabelTextColour(const wxColour
& colour
)
2072 m_labelTextColour
= colour
;
2076 void wxGenericGrid::SetLabelBackgroundColour(const wxColour
& colour
)
2078 m_labelBackgroundColour
= colour
;
2079 m_labelBackgroundBrush
= * wxTheBrushList
->FindOrCreateBrush(m_labelBackgroundColour
, wxSOLID
);
2082 void wxGenericGrid::SetEditable(bool edit
)
2087 int controlW
, controlH
;
2088 m_textItem
->GetSize(&controlW
, &controlH
);
2089 m_editControlPosition
.height
= controlH
;
2091 m_topOfSheet
= m_editControlPosition
.x
+ controlH
+ 2;
2094 m_editingPanel
->Show(TRUE
);
2095 m_textItem
->Show(TRUE
);
2096 m_textItem
->SetFocus();
2099 if (m_inPlaceTextItem
)
2101 m_inPlaceTextItem
->Show(TRUE
);
2102 m_inPlaceTextItem
->SetFocus();
2110 m_textItem
->Show(FALSE
);
2111 m_editingPanel
->Show(FALSE
);
2114 if ( m_inPlaceTextItem
)
2116 m_inPlaceTextItem
->Show(FALSE
);
2120 SetCurrentRect(GetCursorRow(), GetCursorColumn());
2123 GetClientSize(&cw
, &ch
);
2128 int m_scrollWidth = 16;
2129 GetClientSize(&cw, &ch);
2132 m_vScrollBar->SetSize(cw - m_scrollWidth, m_topOfSheet,
2133 m_scrollWidth, ch - m_topOfSheet - m_scrollWidth);
2138 void wxGenericGrid::SetEditInPlace(bool edit
)
2140 if ( m_editInPlace
!= edit
)
2142 m_editInPlace
= edit
;
2144 if ( m_editInPlace
) // switched on
2146 if ( m_currentRectVisible
&& m_editable
)
2148 m_inPlaceTextItem
->SetSize( m_currentRect
.x
-wxIPE_ADJUST
,
2149 m_currentRect
.y
-wxIPE_ADJUST
,
2150 m_currentRect
.width
+wxIPE_ADJUST
*2,
2151 m_currentRect
.height
+wxIPE_ADJUST
*2 );
2153 wxGridCell
*cell
= GetCell(m_wCursorRow
, m_wCursorColumn
);
2156 m_inPlaceTextItem
->SetFont( cell
->GetFont() );
2157 m_inPlaceTextItem
->SetBackgroundColour(cell
->GetBackgroundColour());
2158 m_inPlaceTextItem
->SetForegroundColour(cell
->GetTextColour());
2160 if ( cell
->GetTextValue().IsNull() ) {
2161 m_inPlaceTextItem
->SetValue( "" );
2164 m_inPlaceTextItem
->SetValue( cell
->GetTextValue() );
2168 m_inPlaceTextItem
->Show( TRUE
);
2169 m_inPlaceTextItem
->SetFocus();
2172 else // switched off
2174 m_inPlaceTextItem
->Show( FALSE
);
2180 void wxGenericGrid::SetCellAlignment(int flag
, int row
, int col
)
2182 wxGridCell
*cell
= GetCell(row
, col
);
2184 cell
->SetAlignment(flag
);
2187 int wxGenericGrid::GetCellAlignment(int row
, int col
) const
2189 wxGridCell
*cell
= GetCell(row
, col
);
2191 return cell
->GetAlignment();
2193 return m_cellAlignment
;
2196 void wxGenericGrid::SetCellAlignment(int flag
)
2198 m_cellAlignment
= flag
;
2200 for (i
= 0; i
< GetRows(); i
++)
2201 for (j
= 0; j
< GetCols(); j
++)
2203 GetCell(i
, j
)->SetAlignment(flag
);
2206 int wxGenericGrid::GetCellAlignment(void) const
2208 return m_cellAlignment
;
2211 void wxGenericGrid::SetCellBackgroundColour(const wxColour
& col
)
2213 m_cellBackgroundColour
= col
;
2215 for (i
= 0; i
< GetRows(); i
++)
2216 for (j
= 0; j
< GetCols(); j
++)
2218 GetCell(i
, j
)->SetBackgroundColour(col
);
2221 void wxGenericGrid::SetCellBackgroundColour(const wxColour
& val
, int row
, int col
)
2223 wxGridCell
*cell
= GetCell(row
, col
);
2226 cell
->SetBackgroundColour(val
);
2227 RefreshCell(row
, col
);
2231 wxColour
& wxGenericGrid::GetCellBackgroundColour(int row
, int col
) const
2233 wxGridCell
*cell
= GetCell(row
, col
);
2235 return cell
->GetBackgroundColour();
2237 return (wxColour
&) m_cellBackgroundColour
;
2240 void wxGenericGrid::SetCellTextColour(const wxColour
& val
, int row
, int col
)
2242 wxGridCell
*cell
= GetCell(row
, col
);
2245 cell
->SetTextColour(val
);
2246 RefreshCell(row
, col
);
2250 void wxGenericGrid::SetCellTextFont(const wxFont
& fnt
, int row
, int col
)
2252 wxGridCell
*cell
= GetCell(row
, col
);
2256 RefreshCell(row
, col
);
2260 wxFont
& wxGenericGrid::GetCellTextFont(int row
, int col
) const
2262 wxGridCell
*cell
= GetCell(row
, col
);
2264 return (wxFont
&) cell
->GetFont();
2266 return (wxFont
&) m_cellTextFont
;
2269 wxColour
& wxGenericGrid::GetCellTextColour(int row
, int col
) const
2271 wxGridCell
*cell
= GetCell(row
, col
);
2273 return (wxColour
&) cell
->GetTextColour();
2275 return (wxColour
&) m_cellTextColour
;
2278 void wxGenericGrid::SetCellTextColour(const wxColour
& val
)
2280 m_cellTextColour
= val
;
2282 for (i
= 0; i
< GetRows(); i
++)
2283 for (j
= 0; j
< GetCols(); j
++)
2285 GetCell(i
, j
)->SetTextColour(val
);
2288 void wxGenericGrid::SetCellTextFont(const wxFont
& fnt
)
2290 m_cellTextFont
= fnt
;
2292 for (i
= 0; i
< GetRows(); i
++)
2293 for (j
= 0; j
< GetCols(); j
++)
2295 GetCell(i
, j
)->SetFont(fnt
);
2298 void wxGenericGrid::SetCellBitmap(wxBitmap
*bitmap
, int row
, int col
)
2300 wxGridCell
*cell
= GetCell(row
, col
);
2303 cell
->SetCellBitmap(bitmap
);
2304 RefreshCell(row
, col
);
2308 wxBitmap
*wxGenericGrid::GetCellBitmap(int row
, int col
) const
2310 wxGridCell
*cell
= GetCell(row
, col
);
2313 return cell
->GetCellBitmap();
2316 return (wxBitmap
*) NULL
;
2319 bool wxGenericGrid::InsertCols(int pos
, int n
, bool updateLabels
)
2321 if (pos
> m_totalCols
)
2325 return CreateGrid(1, n
);
2330 for (i
= 0; i
< m_totalRows
; i
++)
2332 wxGridCell
**cols
= m_gridCells
[i
];
2333 wxGridCell
**newCols
= new wxGridCell
*[m_totalCols
+ n
];
2334 for (j
= 0; j
< pos
; j
++)
2335 newCols
[j
] = cols
[j
];
2336 for (j
= pos
; j
< pos
+ n
; j
++)
2337 newCols
[j
] = new wxGridCell(this);
2338 for (j
= pos
+ n
; j
< m_totalCols
+ n
; j
++)
2339 newCols
[j
] = cols
[j
- n
];
2342 m_gridCells
[i
] = newCols
;
2346 short *newColWidths
= new short[m_totalCols
+ n
];
2347 for (j
= 0; j
< pos
; j
++)
2348 newColWidths
[j
] = m_colWidths
[j
];
2349 for (j
= pos
; j
< pos
+ n
; j
++)
2350 newColWidths
[j
] = wxGRID_DEFAULT_CELL_WIDTH
;
2351 for (j
= pos
+ n
; j
< m_totalCols
+ n
; j
++)
2352 newColWidths
[j
] = m_colWidths
[j
- n
];
2353 delete[] m_colWidths
;
2354 m_colWidths
= newColWidths
;
2357 wxGridCell
**newLabels
= new wxGridCell
*[m_totalCols
+ n
];
2358 for (j
= 0; j
< pos
; j
++)
2359 newLabels
[j
] = m_colLabelCells
[j
];
2360 for (j
= pos
; j
< pos
+ n
; j
++)
2361 newLabels
[j
] = new wxGridCell(this);
2362 for (j
= pos
+ n
; j
< m_totalCols
+ n
; j
++)
2363 newLabels
[j
] = m_colLabelCells
[j
- n
];
2365 delete[] m_colLabelCells
;
2366 m_colLabelCells
= newLabels
;
2372 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2373 GetEventHandler()->ProcessEvent(g_evt
);
2382 bool wxGenericGrid::InsertRows(int pos
, int n
, bool updateLabels
)
2384 if (pos
> m_totalRows
)
2388 return CreateGrid(n
, 1);
2393 wxGridCell
***rows
= new wxGridCell
**[m_totalRows
+ n
];
2396 for (i
= 0; i
< pos
; i
++)
2397 rows
[i
] = m_gridCells
[i
];
2399 for (i
= pos
; i
< pos
+ n
; i
++)
2401 rows
[i
] = new wxGridCell
*[m_totalCols
];
2402 for (j
= 0; j
< m_totalCols
; j
++)
2403 rows
[i
][j
] = new wxGridCell(this);
2406 for (i
= pos
+ n
; i
< m_totalRows
+ n
; i
++)
2407 rows
[i
] = m_gridCells
[i
- n
];
2409 delete[] m_gridCells
;
2413 short *newRowHeights
= new short[m_totalRows
+ n
];
2414 for (i
= 0; i
< pos
; i
++)
2415 newRowHeights
[i
] = m_rowHeights
[i
];
2416 for (i
= pos
; i
< pos
+ n
; i
++)
2417 newRowHeights
[i
] = wxGRID_DEFAULT_CELL_HEIGHT
;
2418 for (i
= pos
+ n
; i
< m_totalRows
+ n
; i
++)
2419 newRowHeights
[i
] = m_rowHeights
[i
- n
];
2420 delete[] m_rowHeights
;
2421 m_rowHeights
= newRowHeights
;
2424 wxGridCell
**newLabels
= new wxGridCell
*[m_totalRows
+ n
];
2425 for (i
= 0; i
< pos
; i
++)
2426 newLabels
[i
] = m_rowLabelCells
[i
];
2427 for (i
= pos
; i
< pos
+ n
; i
++)
2428 newLabels
[i
] = new wxGridCell(this);
2429 for (i
= pos
+ n
; i
< m_totalRows
+ n
; i
++)
2430 newLabels
[i
] = m_rowLabelCells
[i
- n
];
2432 delete[] m_rowLabelCells
;
2433 m_rowLabelCells
= newLabels
;
2439 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2440 GetEventHandler()->ProcessEvent(g_evt
);
2449 bool wxGenericGrid::AppendCols(int n
, bool updateLabels
)
2451 return InsertCols(GetCols(), n
, updateLabels
);
2454 bool wxGenericGrid::AppendRows(int n
, bool updateLabels
)
2456 return InsertRows(GetRows(), n
, updateLabels
);
2459 bool wxGenericGrid::DeleteRows(int pos
, int n
, bool updateLabels
)
2461 if (pos
> m_totalRows
)
2468 wxGridCell
***rows
= new wxGridCell
**[m_totalRows
- n
];
2471 for (i
= 0; i
< pos
; i
++)
2472 rows
[i
] = m_gridCells
[i
];
2474 for (i
= pos
+ n
; i
< m_totalRows
; i
++)
2475 rows
[i
-n
] = m_gridCells
[i
];
2477 delete[] m_gridCells
;
2481 short *newRowHeights
= new short[m_totalRows
- n
];
2482 for (i
= 0; i
< pos
; i
++)
2483 newRowHeights
[i
] = m_rowHeights
[i
];
2484 for (i
= pos
+ n
; i
< m_totalRows
; i
++)
2485 newRowHeights
[i
-n
] = m_rowHeights
[i
];
2486 delete[] m_rowHeights
;
2487 m_rowHeights
= newRowHeights
;
2490 wxGridCell
**newLabels
= new wxGridCell
*[m_totalRows
- n
];
2491 for (i
= 0; i
< pos
; i
++)
2492 newLabels
[i
] = m_rowLabelCells
[i
];
2493 for (i
= pos
+ n
; i
< m_totalRows
; i
++)
2494 newLabels
[i
-n
] = m_rowLabelCells
[i
];
2496 delete[] m_rowLabelCells
;
2497 m_rowLabelCells
= newLabels
;
2503 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2504 GetEventHandler()->ProcessEvent(g_evt
);
2511 bool wxGenericGrid::DeleteCols(int pos
, int n
, bool updateLabels
)
2513 if (pos
+ n
> m_totalCols
)
2521 for (i
= 0; i
< m_totalRows
; i
++)
2523 wxGridCell
**cols
= m_gridCells
[i
];
2524 wxGridCell
**newCols
= new wxGridCell
*[m_totalCols
- n
];
2525 for (j
= 0; j
< pos
; j
++)
2526 newCols
[j
] = cols
[j
];
2527 for (j
= pos
; j
< pos
+ n
; j
++)
2529 for (j
= pos
+ n
; j
< m_totalCols
; j
++)
2530 newCols
[j
-n
] = cols
[j
];
2533 m_gridCells
[i
] = newCols
;
2537 short *newColWidths
= new short[m_totalCols
- n
];
2538 for (j
= 0; j
< pos
; j
++)
2539 newColWidths
[j
] = m_colWidths
[j
];
2540 for (j
= pos
+ n
; j
< m_totalCols
; j
++)
2541 newColWidths
[j
-n
] = m_colWidths
[j
];
2542 delete[] m_colWidths
;
2543 m_colWidths
= newColWidths
;
2546 wxGridCell
**newLabels
= new wxGridCell
*[m_totalCols
- n
];
2547 for (j
= 0; j
< pos
; j
++)
2548 newLabels
[j
] = m_colLabelCells
[j
];
2549 for (j
= pos
+ n
; j
< m_totalCols
; j
++)
2550 newLabels
[j
-n
] = m_colLabelCells
[j
];
2552 delete[] m_colLabelCells
;
2553 m_colLabelCells
= newLabels
;
2559 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2560 GetEventHandler()->ProcessEvent(g_evt
);
2567 void wxGenericGrid::SetGridCursor(int row
, int col
)
2569 if (row
>= m_totalRows
|| col
>= m_totalCols
)
2572 if (row
== GetCursorRow() && col
== GetCursorColumn())
2575 wxClientDC
dc(this);
2578 SetGridClippingRegion(& dc
);
2580 if (m_currentRectVisible
&& (wxIPE_HIGHLIGHT
|| !(m_editable
&& m_editInPlace
)))
2581 HighlightCell(& dc
, FALSE
);
2584 m_wCursorColumn
= col
;
2587 GetClientSize(&cw
, &ch
);
2589 SetCurrentRect(row
, col
, cw
, ch
);
2591 if (m_currentRectVisible
&& (wxIPE_HIGHLIGHT
|| !(m_editable
&& m_editInPlace
)))
2592 HighlightCell(& dc
, TRUE
);
2594 dc
.DestroyClippingRegion();
2598 // ----------------------------------------------------------------------------
2600 // ----------------------------------------------------------------------------
2602 wxGridCell::wxGridCell(wxGenericGrid
*window
)
2604 cellBitmap
= (wxBitmap
*) NULL
;
2606 backgroundBrush
= wxNullBrush
;
2608 textColour
= window
->GetCellTextColour();
2610 textColour
.Set(0,0,0);
2612 backgroundColour
= window
->GetCellBackgroundColour();
2614 backgroundColour
.Set(255,255,255);
2617 font
= window
->GetCellTextFont();
2619 font
= * wxTheFontList
->FindOrCreateFont(12, wxSWISS
, wxNORMAL
, wxNORMAL
);
2621 SetBackgroundColour(backgroundColour
);
2624 alignment
= window
->GetCellAlignment();
2628 cellData
= (void *)NULL
;
2631 wxGridCell::~wxGridCell()
2635 void wxGridCell::SetBackgroundColour(const wxColour
& colour
)
2637 backgroundColour
= colour
;
2638 backgroundBrush
= * wxTheBrushList
->FindOrCreateBrush(backgroundColour
, wxSOLID
);
2641 void wxGenericGrid::OnText(wxCommandEvent
& WXUNUSED(ev
) )
2643 // michael - added this conditional to prevent change to
2644 // grid cell text when edit control is hidden but still has
2649 wxGenericGrid
*grid
= this;
2650 wxGridCell
*cell
= grid
->GetCell(grid
->GetCursorRow(), grid
->GetCursorColumn());
2651 if (cell
&& grid
->CurrentCellVisible())
2653 cell
->SetTextValue(grid
->GetTextItem()->GetValue());
2654 if ( m_editInPlace
&& !m_inOnTextInPlace
)
2656 m_inPlaceTextItem
->SetValue( grid
->GetTextItem()->GetValue() );
2659 if (!m_editInPlace
) {
2660 wxClientDC
dc(grid
);
2663 grid
->SetGridClippingRegion(& dc
);
2664 grid
->DrawCellBackground(& dc
, &grid
->GetCurrentRect(), grid
->GetCursorRow(), grid
->GetCursorColumn());
2665 grid
->DrawCellValue(& dc
, &grid
->GetCurrentRect(), grid
->GetCursorRow(), grid
->GetCursorColumn());
2666 grid
->HighlightCell(& dc
, TRUE
);
2667 dc
.DestroyClippingRegion();
2671 //grid->OnCellChange(grid->GetCursorRow(), grid->GetCursorColumn());
2672 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CELL_CHANGE
, grid
,
2673 grid
->GetCursorRow(), grid
->GetCursorColumn());
2674 GetEventHandler()->ProcessEvent(g_evt
);
2676 // grid->DrawCellText();
2681 void wxGenericGrid::OnTextEnter(wxCommandEvent
& WXUNUSED(ev
) )
2683 // move the cursor down the current row (if possible)
2684 // when the enter key has been pressed
2688 if ( GetCursorRow() < GetRows()-1 )
2690 wxClientDC
dc( this );
2692 OnSelectCellImplementation(& dc
,
2694 GetCursorColumn() );
2700 void wxGenericGrid::OnTextInPlace(wxCommandEvent
& ev
)
2704 wxGenericGrid
*grid
= this;
2705 wxGridCell
*cell
= grid
->GetCell(grid
->GetCursorRow(), grid
->GetCursorColumn());
2706 if (cell
&& grid
->CurrentCellVisible())
2708 m_inOnTextInPlace
= TRUE
;
2709 grid
->GetTextItem()->SetValue( m_inPlaceTextItem
->GetValue() );
2711 m_inOnTextInPlace
= FALSE
;
2716 void wxGenericGrid::OnTextInPlaceEnter(wxCommandEvent
& WXUNUSED(ev
) )
2718 // move the cursor down the current row (if possible)
2719 // when the enter key has been pressed
2723 if ( GetCursorRow() < GetRows()-1 )
2725 wxClientDC
dc( this );
2727 OnSelectCellImplementation(& dc
,
2729 GetCursorColumn() );
2735 void wxGenericGrid::OnGridScroll(wxScrollEvent
& ev
)
2740 if ( m_editInPlace
) m_inPlaceTextItem
->Show(FALSE
);
2743 wxGenericGrid
*win
= this;
2745 bool change
= FALSE
;
2747 if (ev
.GetEventObject() == win
->GetHorizScrollBar())
2749 change
= (ev
.GetPosition() != m_scrollPosX
);
2750 win
->SetScrollPosX(ev
.GetPosition());
2754 change
= (ev
.GetPosition() != m_scrollPosY
);
2755 win
->SetScrollPosY(ev
.GetPosition());
2758 win
->UpdateDimensions();
2760 win
->SetCurrentRect(win
->GetCursorRow(), win
->GetCursorColumn());
2762 // Because rows and columns can be arbitrary sizes,
2763 // the scrollbars will need to be adjusted to reflect the
2767 if (change
) win
->Refresh(FALSE
);
2769 if ( m_editInPlace
&& m_currentRectVisible
)
2771 m_inPlaceTextItem
->SetSize( m_currentRect
.x
-wxIPE_ADJUST
,
2772 m_currentRect
.y
-wxIPE_ADJUST
,
2773 m_currentRect
.width
+wxIPE_ADJUST
*2,
2774 m_currentRect
.height
+wxIPE_ADJUST
*2 );
2775 m_inPlaceTextItem
->Show( TRUE
);
2776 m_inPlaceTextItem
->SetFocus();
2784 //----------------------------------------------------------------------
2785 // Default wxGridEvent handlers
2786 // (just redirect to the pre-existing virtual methods)
2788 void wxGenericGrid::_OnSelectCell(wxGridEvent
& ev
)
2790 OnSelectCell(ev
.m_row
, ev
.m_col
);
2793 void wxGenericGrid::_OnCreateCell(wxGridEvent
& ev
)
2795 ev
.m_cell
= OnCreateCell();
2798 void wxGenericGrid::_OnChangeLabels(wxGridEvent
& WXUNUSED(ev
))
2803 void wxGenericGrid::_OnChangeSelectionLabel(wxGridEvent
& WXUNUSED(ev
))
2805 OnChangeSelectionLabel();
2808 void wxGenericGrid::_OnCellChange(wxGridEvent
& ev
)
2810 OnCellChange(ev
.m_row
, ev
.m_col
);
2813 void wxGenericGrid::_OnCellLeftClick(wxGridEvent
& ev
)
2815 OnCellLeftClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2818 void wxGenericGrid::_OnCellRightClick(wxGridEvent
& ev
)
2820 OnCellRightClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2823 void wxGenericGrid::_OnLabelLeftClick(wxGridEvent
& ev
)
2825 OnLabelLeftClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2828 void wxGenericGrid::_OnLabelRightClick(wxGridEvent
& ev
)
2830 OnLabelRightClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2833 void *wxGenericGrid::SetCellData(void *data
, int row
, int col
)
2837 wxGridCell
*cell
= GetCell(row
, col
);
2839 rc
= cell
->SetCellData(data
);
2844 void *wxGenericGrid::GetCellData(int row
, int col
)
2848 wxGridCell
*cell
= GetCell(row
, col
);
2850 rc
= cell
->GetCellData();