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 0
56 #define wxUSE_DOUBLE_BUFFERING 1
60 #define wxIPE_ADJUST 2
61 #define wxIPE_STYLE wxNO_BORDER
62 #define wxIPE_HIGHLIGHT 0
63 #define wxUSE_DOUBLE_BUFFERING 0
67 #define wxIPE_ADJUST 2
68 #define wxIPE_STYLE wxNO_BORDER
69 #define wxIPE_HIGHLIGHT 0
70 #define wxUSE_DOUBLE_BUFFERING 0
75 #define wxGRID_DRAG_NONE 0
76 #define wxGRID_DRAG_LEFT_RIGHT 1
77 #define wxGRID_DRAG_UP_DOWN 2
79 IMPLEMENT_DYNAMIC_CLASS(wxGenericGrid
, wxPanel
)
80 IMPLEMENT_DYNAMIC_CLASS(wxGridEvent
, wxEvent
)
82 BEGIN_EVENT_TABLE(wxGenericGrid
, wxPanel
)
83 EVT_SIZE(wxGenericGrid::OnSize
)
84 EVT_PAINT(wxGenericGrid::OnPaint
)
85 EVT_ERASE_BACKGROUND(wxGenericGrid::OnEraseBackground
)
86 EVT_MOUSE_EVENTS(wxGenericGrid::OnMouseEvent
)
87 EVT_TEXT(wxGRID_TEXT_CTRL
, wxGenericGrid::OnText
)
88 EVT_TEXT(wxGRID_EDIT_IN_PLACE_TEXT_CTRL
, wxGenericGrid::OnTextInPlace
)
89 EVT_TEXT_ENTER(wxGRID_TEXT_CTRL
, wxGenericGrid::OnTextEnter
)
90 EVT_TEXT_ENTER(wxGRID_EDIT_IN_PLACE_TEXT_CTRL
, wxGenericGrid::OnTextInPlaceEnter
)
91 EVT_COMMAND_SCROLL(wxGRID_HSCROLL
, wxGenericGrid::OnGridScroll
)
92 EVT_COMMAND_SCROLL(wxGRID_VSCROLL
, wxGenericGrid::OnGridScroll
)
94 // default wxGridEvent handlers
95 EVT_GRID_SELECT_CELL(wxGenericGrid::_OnSelectCell
)
96 EVT_GRID_CREATE_CELL(wxGenericGrid::_OnCreateCell
)
97 EVT_GRID_CHANGE_LABELS(wxGenericGrid::_OnChangeLabels
)
98 EVT_GRID_CHANGE_SEL_LABEL(wxGenericGrid::_OnChangeSelectionLabel
)
99 EVT_GRID_CELL_CHANGE(wxGenericGrid::_OnCellChange
)
100 EVT_GRID_CELL_LCLICK(wxGenericGrid::_OnCellLeftClick
)
101 EVT_GRID_CELL_RCLICK(wxGenericGrid::_OnCellRightClick
)
102 EVT_GRID_LABEL_LCLICK(wxGenericGrid::_OnLabelLeftClick
)
103 EVT_GRID_LABEL_RCLICK(wxGenericGrid::_OnLabelRightClick
)
108 wxGenericGrid::wxGenericGrid()
113 m_hScrollBar
= (wxScrollBar
*) NULL
;
114 m_vScrollBar
= (wxScrollBar
*) NULL
;
115 m_cellTextColour
= *wxBLACK
;
116 m_cellBackgroundColour
= *wxWHITE
;
117 m_labelTextColour
= *wxBLACK
;
118 // m_labelBackgroundColour = *wxLIGHT_GREY;
119 m_labelBackgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
120 m_labelBackgroundBrush
= wxNullBrush
;
121 m_labelTextFont
= wxNullFont
;
122 m_cellTextFont
= wxNullFont
;
123 m_textItem
= (wxTextCtrl
*) NULL
;
124 m_currentRectVisible
= FALSE
;
127 m_editInPlace
= FALSE
;
128 m_inOnTextInPlace
= FALSE
;
131 #if defined(__WIN95__)
132 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
133 #elif defined(__WXGTK__)
134 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
138 m_dragStatus
= wxGRID_DRAG_NONE
;
140 m_dragStartPosition
= 0;
141 m_dragLastPosition
= 0;
142 m_divisionPen
= wxNullPen
;
143 m_highlightPen
= wxNullPen
;
144 m_leftOfSheet
= wxGRID_DEFAULT_SHEET_LEFT
;
145 m_topOfSheet
= wxGRID_DEFAULT_SHEET_TOP
;
146 m_cellHeight
= wxGRID_DEFAULT_CELL_HEIGHT
;
147 m_totalGridWidth
= 0;
148 m_totalGridHeight
= 0;
149 m_colWidths
= (short *) NULL
;
150 m_rowHeights
= (short *) NULL
;
151 m_verticalLabelWidth
= wxGRID_DEFAULT_VERTICAL_LABEL_WIDTH
;
152 m_horizontalLabelHeight
= wxGRID_DEFAULT_HORIZONAL_LABEL_HEIGHT
;
153 m_verticalLabelAlignment
= wxCENTRE
;
154 m_horizontalLabelAlignment
= wxCENTRE
;
155 m_editControlPosition
.x
= wxGRID_DEFAULT_EDIT_X
;
156 m_editControlPosition
.y
= wxGRID_DEFAULT_EDIT_Y
;
157 m_editControlPosition
.width
= wxGRID_DEFAULT_EDIT_WIDTH
;
158 m_editControlPosition
.height
= wxGRID_DEFAULT_EDIT_HEIGHT
;
163 m_editCreated
= FALSE
;
166 m_gridCells
= (wxGridCell
***) NULL
;
167 m_rowLabelCells
= (wxGridCell
**) NULL
;
168 m_colLabelCells
= (wxGridCell
**) NULL
;
169 m_textItem
= (wxTextCtrl
*) NULL
;
172 bool wxGenericGrid::Create(wxWindow
*parent
,
177 const wxString
& name
)
182 m_editingPanel
= (wxPanel
*) NULL
;
183 m_hScrollBar
= (wxScrollBar
*) NULL
;
184 m_vScrollBar
= (wxScrollBar
*) NULL
;
185 m_cellTextColour
= *wxBLACK
;
186 m_cellBackgroundColour
= *wxWHITE
;
187 m_labelTextColour
= *wxBLACK
;
188 // m_labelBackgroundColour = *wxLIGHT_GREY;
189 m_labelBackgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
190 m_labelBackgroundBrush
= wxNullBrush
;
191 m_labelTextFont
= * wxTheFontList
->FindOrCreateFont(10, wxSWISS
, wxNORMAL
, wxBOLD
);
192 m_cellTextFont
= * wxTheFontList
->FindOrCreateFont(10, wxSWISS
, wxNORMAL
, wxNORMAL
);
193 m_textItem
= (wxTextCtrl
*) NULL
;
194 m_currentRectVisible
= FALSE
;
196 m_editInPlace
= FALSE
;
197 m_inOnTextInPlace
= FALSE
;
199 #if defined(__WIN95__)
200 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
201 #elif defined(__WXGTK__)
202 m_scrollWidth
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
);
206 m_dragStatus
= wxGRID_DRAG_NONE
;
208 m_dragStartPosition
= 0;
209 m_dragLastPosition
= 0;
210 m_divisionPen
= * wxThePenList
->FindOrCreatePen("LIGHT GREY", 1, wxSOLID
);
211 m_highlightPen
= * wxBLACK_PEN
;
212 m_doubleBufferingBitmap
= (wxBitmap
*) NULL
;
214 if (!m_horizontalSashCursor
.Ok())
216 m_horizontalSashCursor
= wxCursor(wxCURSOR_SIZEWE
);
217 m_verticalSashCursor
= wxCursor(wxCURSOR_SIZENS
);
220 SetLabelBackgroundColour(m_labelBackgroundColour
);
222 m_leftOfSheet
= wxGRID_DEFAULT_SHEET_LEFT
;
223 m_topOfSheet
= wxGRID_DEFAULT_SHEET_TOP
;
224 m_cellHeight
= wxGRID_DEFAULT_CELL_HEIGHT
;
225 m_totalGridWidth
= 0;
226 m_totalGridHeight
= 0;
227 m_colWidths
= (short *) NULL
;
228 m_rowHeights
= (short *) NULL
;
230 m_verticalLabelWidth
= wxGRID_DEFAULT_VERTICAL_LABEL_WIDTH
;
231 m_horizontalLabelHeight
= wxGRID_DEFAULT_HORIZONAL_LABEL_HEIGHT
;
232 m_verticalLabelAlignment
= wxCENTRE
;
233 m_horizontalLabelAlignment
= wxCENTRE
;
234 m_editControlPosition
.x
= wxGRID_DEFAULT_EDIT_X
;
235 m_editControlPosition
.y
= wxGRID_DEFAULT_EDIT_Y
;
236 m_editControlPosition
.width
= wxGRID_DEFAULT_EDIT_WIDTH
;
237 m_editControlPosition
.height
= wxGRID_DEFAULT_EDIT_HEIGHT
;
245 /* Store the rect. coordinates for the current cell */
246 SetCurrentRect(m_wCursorRow
, m_wCursorColumn
);
248 m_editCreated
= FALSE
;
252 m_gridCells
= (wxGridCell
***) NULL
;
253 m_rowLabelCells
= (wxGridCell
**) NULL
;
254 m_colLabelCells
= (wxGridCell
**) NULL
;
255 m_textItem
= (wxTextCtrl
*) NULL
;
257 wxPanel::Create(parent
, id
, pos
, size
, style
, name
);
259 m_editingPanel
= new wxPanel(this);
261 m_textItem
= new wxTextCtrl(m_editingPanel
, wxGRID_TEXT_CTRL
, "",
262 wxPoint(m_editControlPosition
.x
, m_editControlPosition
.y
),
263 wxSize(m_editControlPosition
.width
, -1),
265 m_textItem
->Show(TRUE
);
266 m_textItem
->SetFocus();
267 int controlW
, controlH
;
269 m_textItem
->GetSize(&controlW
, &controlH
);
270 m_editControlPosition
.height
= controlH
;
272 m_topOfSheet
= m_editControlPosition
.y
+ controlH
+ 2;
274 m_editCreated
= TRUE
;
276 m_hScrollBar
= new wxScrollBar(this, wxGRID_HSCROLL
, wxPoint(0, 0), wxSize(20, 100), wxHORIZONTAL
);
277 m_vScrollBar
= new wxScrollBar(this, wxGRID_VSCROLL
, wxPoint(0, 0), wxSize(100, 20), wxVERTICAL
);
279 // SetSize(pos.x, pos.y, size.x, size.y);
281 m_inPlaceTextItem
= new wxTextCtrl( (wxPanel
*)this, wxGRID_EDIT_IN_PLACE_TEXT_CTRL
, "",
282 wxPoint( m_currentRect
.x
-wxIPE_ADJUST
, m_currentRect
.y
-wxIPE_ADJUST
),
283 wxSize( m_currentRect
.width
+wxIPE_ADJUST
*2, m_currentRect
.height
+wxIPE_ADJUST
*2 ),
284 wxNO_BORDER
| wxTE_PROCESS_ENTER
);
285 m_inPlaceTextItem
->Show(m_editInPlace
);
287 m_inPlaceTextItem
->SetFocus();
292 wxGenericGrid::~wxGenericGrid()
297 void wxGenericGrid::ClearGrid()
302 for (i
= 0; i
< m_totalRows
; i
++)
304 for (j
= 0; j
< m_totalCols
; j
++)
305 if (m_gridCells
[i
][j
])
306 delete m_gridCells
[i
][j
];
307 delete[] m_gridCells
[i
];
309 delete[] m_gridCells
;
310 m_gridCells
= (wxGridCell
***) NULL
;
313 delete[] m_colWidths
;
314 m_colWidths
= (short *) NULL
;
316 delete[] m_rowHeights
;
317 m_rowHeights
= (short *) NULL
;
321 for (i
= 0; i
< m_totalRows
; i
++)
322 delete m_rowLabelCells
[i
];
323 delete[] m_rowLabelCells
;
324 m_rowLabelCells
= (wxGridCell
**) NULL
;
328 for (i
= 0; i
< m_totalCols
; i
++)
329 delete m_colLabelCells
[i
];
330 delete[] m_colLabelCells
;
331 m_colLabelCells
= (wxGridCell
**) NULL
;
333 if (m_doubleBufferingBitmap
)
335 delete m_doubleBufferingBitmap
;
336 m_doubleBufferingBitmap
= (wxBitmap
*) NULL
;
340 bool wxGenericGrid::CreateGrid(int nRows
, int nCols
, wxString
**cellValues
, short *widths
,
341 short defaultWidth
, short defaultHeight
)
347 m_colWidths
= new short[nCols
];
348 m_rowHeights
= new short[nRows
];
349 for (i
= 0; i
< nCols
; i
++)
351 m_colWidths
[i
] = widths
[i
];
353 m_colWidths
[i
] = defaultWidth
;
354 for (i
= 0; i
< nRows
; i
++)
355 m_rowHeights
[i
] = defaultHeight
;
357 m_gridCells
= new wxGridCell
**[nRows
];
359 for (i
= 0; i
< nRows
; i
++)
360 m_gridCells
[i
] = new wxGridCell
*[nCols
];
362 for (i
= 0; i
< nRows
; i
++)
363 for (j
= 0; j
< nCols
; j
++)
366 //m_gridCells[i][j] = OnCreateCell();
367 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CREATE_CELL
, this, i
, j
);
368 GetEventHandler()->ProcessEvent(g_evt
);
369 m_gridCells
[i
][j
] = g_evt
.m_cell
;
370 m_gridCells
[i
][j
]->SetTextValue(cellValues
[i
][j
]);
373 m_gridCells
[i
][j
] = (wxGridCell
*) NULL
;
375 m_rowLabelCells
= new wxGridCell
*[nRows
];
376 for (i
= 0; i
< nRows
; i
++)
377 m_rowLabelCells
[i
] = new wxGridCell(this);
378 m_colLabelCells
= new wxGridCell
*[nCols
];
379 for (i
= 0; i
< nCols
; i
++)
380 m_colLabelCells
[i
] = new wxGridCell(this);
382 m_wCursorRow
= m_wCursorColumn
= 0;
383 SetCurrentRect(0, 0);
385 // Need to determine various dimensions
389 int objectSizeX
= m_totalCols
;
391 int viewLengthX
= m_totalCols
;
394 m_hScrollBar->SetViewLength(viewLengthX);
395 m_hScrollBar->SetObjectLength(objectSizeX);
396 m_hScrollBar->SetPageSize(pageSizeX);
398 m_hScrollBar
->SetScrollbar(m_hScrollBar
->GetThumbPosition(), pageSizeX
, objectSizeX
, viewLengthX
);
400 int objectSizeY
= m_totalRows
;
402 int viewLengthY
= m_totalRows
;
405 m_vScrollBar->SetViewLength(viewLengthY);
406 m_vScrollBar->SetObjectLength(objectSizeY);
407 m_vScrollBar->SetPageSize(pageSizeY);
410 m_vScrollBar
->SetScrollbar(m_vScrollBar
->GetThumbPosition(), pageSizeY
, objectSizeY
, viewLengthY
);
415 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
416 GetEventHandler()->ProcessEvent(g_evt
);
418 //OnChangeSelectionLabel();
419 wxGridEvent
g_evt2(GetId(), wxEVT_GRID_CHANGE_SEL_LABEL
, this);
420 GetEventHandler()->ProcessEvent(g_evt2
);
425 // Need to determine various dimensions
426 void wxGenericGrid::UpdateDimensions()
428 int canvasWidth
, canvasHeight
;
429 GetSize(&canvasWidth
, &canvasHeight
);
431 if (m_editCreated
&& m_editable
)
433 int controlW
, controlH
;
434 GetTextItem()->GetSize(&controlW
, &controlH
);
435 m_topOfSheet
= m_editControlPosition
.y
+ controlH
+ 2;
439 m_rightOfSheet
= m_leftOfSheet
+ m_verticalLabelWidth
;
441 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
443 if (m_rightOfSheet
> canvasWidth
)
446 m_rightOfSheet
+= m_colWidths
[i
];
448 m_bottomOfSheet
= m_topOfSheet
+ m_horizontalLabelHeight
;
449 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
451 if (m_bottomOfSheet
> canvasHeight
)
454 m_bottomOfSheet
+= m_rowHeights
[i
];
457 m_totalGridWidth
= m_leftOfSheet
+ m_verticalLabelWidth
;
458 for (i
= 0; i
< m_totalCols
; i
++)
460 m_totalGridWidth
+= m_colWidths
[i
];
462 m_totalGridHeight
= m_topOfSheet
+ m_horizontalLabelHeight
;
463 for (i
= 0; i
< m_totalRows
; i
++)
465 m_totalGridHeight
+= m_rowHeights
[i
];
469 wxGridCell
*wxGenericGrid::GetCell(int row
, int col
) const
472 return (wxGridCell
*) NULL
;
474 if ((row
>= m_totalRows
) || (col
>= m_totalCols
))
475 return (wxGridCell
*) NULL
;
477 wxGridCell
*cell
= m_gridCells
[row
][col
];
480 // m_gridCells[row][col] = OnCreateCell();
481 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CREATE_CELL
, (wxGenericGrid
*) this, row
, col
);
482 GetEventHandler()->ProcessEvent(g_evt
);
483 m_gridCells
[row
][col
] = g_evt
.m_cell
;
484 return m_gridCells
[row
][col
];
490 void wxGenericGrid::SetGridClippingRegion(wxDC
*dc
)
492 int m_scrollWidthHoriz
= 0;
493 int m_scrollWidthVert
= 0;
495 GetClientSize(&cw
, &ch
);
497 if (m_hScrollBar
&& m_hScrollBar
->IsShown())
498 m_scrollWidthHoriz
= m_scrollWidth
;
499 if (m_vScrollBar
&& m_vScrollBar
->IsShown())
500 m_scrollWidthVert
= m_scrollWidth
;
502 // Don't paint over the scrollbars
503 dc
->SetClippingRegion(m_leftOfSheet
, m_topOfSheet
,
504 cw
- m_scrollWidthVert
- m_leftOfSheet
, ch
- m_scrollWidthHoriz
- m_topOfSheet
);
507 void wxGenericGrid::OnPaint(wxPaintEvent
& WXUNUSED(event
))
510 GetClientSize(&w
, &h
);
512 bool useDoubleBuffering
= (bool) wxUSE_DOUBLE_BUFFERING
;
513 if (useDoubleBuffering
)
515 // Reuse the old bitmap if possible
517 if (!m_doubleBufferingBitmap
||
518 (m_doubleBufferingBitmap
->GetWidth() < w
|| m_doubleBufferingBitmap
->GetHeight() < h
))
520 if (m_doubleBufferingBitmap
)
521 delete m_doubleBufferingBitmap
;
522 m_doubleBufferingBitmap
= new wxBitmap(w
, h
);
524 if (!m_doubleBufferingBitmap
|| !m_doubleBufferingBitmap
->Ok())
526 // If we couldn't create a new bitmap, perhaps because resources were low,
527 // then don't complain, just don't double-buffer
528 if (m_doubleBufferingBitmap
)
529 delete m_doubleBufferingBitmap
;
530 m_doubleBufferingBitmap
= (wxBitmap
*) NULL
;
531 useDoubleBuffering
= FALSE
;
535 if (useDoubleBuffering
)
537 wxPaintDC
paintDC(this);
538 wxMemoryDC
dc(& paintDC
);
539 dc
.SelectObject(* m_doubleBufferingBitmap
);
543 int vertScrollBarWidth
= m_scrollWidth
;
544 int horizScrollBarHeight
= m_scrollWidth
;
545 if (m_vScrollBar
&& !m_vScrollBar
->IsShown())
546 vertScrollBarWidth
= 0;
547 if (m_hScrollBar
&& !m_hScrollBar
->IsShown())
548 horizScrollBarHeight
= 0;
550 paintDC
.Blit(m_leftOfSheet
, m_topOfSheet
, w
- vertScrollBarWidth
- m_leftOfSheet
, h
- horizScrollBarHeight
- m_topOfSheet
,
551 &dc
, m_leftOfSheet
, m_topOfSheet
, wxCOPY
);
553 dc
.SelectObject(wxNullBitmap
);
562 void wxGenericGrid::PaintGrid(wxDC
& dc
)
565 dc
.SetOptimization(FALSE
);
567 SetGridClippingRegion(& dc
);
569 DrawLabelAreas(& dc
);
571 DrawEditableArea(& dc
);
572 DrawColumnLabels(& dc
);
577 /* Hilight present cell */
578 SetCurrentRect(m_wCursorRow
, m_wCursorColumn
);
579 if (m_currentRectVisible
&& (wxIPE_HIGHLIGHT
|| !(m_editable
&& m_editInPlace
)))
580 HighlightCell(& dc
, TRUE
);
582 dc
.DestroyClippingRegion();
583 dc
.SetOptimization(TRUE
);
587 // Erase (some of) the background.
588 // Currently, a Windows-only optimisation.
589 void wxGenericGrid::OnEraseBackground(wxEraseEvent
& WXUNUSED(event
) )
593 dc
.SetOptimization(FALSE
);
596 GetClientSize(& w
, & h
);
597 dc
.SetBrush(*wxLIGHT_GREY_BRUSH
);
598 dc
.SetPen(*wxLIGHT_GREY_PEN
);
600 if (m_hScrollBar
&& m_hScrollBar
->IsShown() && m_vScrollBar
&& m_vScrollBar
->IsShown())
602 dc
.DrawRectangle(w
- m_scrollWidth
, h
- m_scrollWidth
, m_scrollWidth
, m_scrollWidth
);
605 dc
.SetOptimization(TRUE
);
610 void wxGenericGrid::DrawLabelAreas(wxDC
*dc
)
613 GetClientSize(&cw
, &ch
);
615 dc
->SetPen(*wxTRANSPARENT_PEN
);
616 // dc->SetBrush(*dc->GetBackground());
618 // Should blank out any area which isn't going to be painted over.
619 // dc->DrawRectangle(m_leftOfSheet, m_bottomOfSheet, cw - m_leftOfSheet, ch - m_bottomOfSheet);
620 // dc->DrawRectangle(m_rightOfSheet, m_topOfSheet, cw - m_rightOfSheet, ch - m_topOfSheet);
622 // Paint the label areas
623 dc
->SetBrush(m_labelBackgroundBrush
);
624 // dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, m_rightOfSheet - m_leftOfSheet + 1, m_horizontalLabelHeight + 1);
625 dc
->DrawRectangle(m_leftOfSheet
, m_topOfSheet
, cw
-m_leftOfSheet
, m_horizontalLabelHeight
+ 1);
626 // dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, m_verticalLabelWidth + 1, m_bottomOfSheet - m_topOfSheet + 1);
627 dc
->DrawRectangle(m_leftOfSheet
, m_topOfSheet
, m_verticalLabelWidth
+ 1, ch
-m_topOfSheet
);
630 void wxGenericGrid::DrawEditableArea(wxDC
*dc
)
633 GetClientSize(&cw
, &ch
);
635 dc
->SetPen(*wxTRANSPARENT_PEN
);
636 dc
->SetBrush(*wxTheBrushList
->FindOrCreateBrush(m_cellBackgroundColour
, wxSOLID
));
637 // dc->DrawRectangle(m_leftOfSheet+m_verticalLabelWidth, m_topOfSheet+m_horizontalLabelHeight,
638 // m_rightOfSheet-(m_leftOfSheet+m_verticalLabelWidth) + 1, m_bottomOfSheet - (m_topOfSheet+m_horizontalLabelHeight) + 1);
639 dc
->DrawRectangle(m_leftOfSheet
+m_verticalLabelWidth
, m_topOfSheet
+m_horizontalLabelHeight
,
640 cw
-(m_leftOfSheet
+m_verticalLabelWidth
), ch
- (m_topOfSheet
+m_horizontalLabelHeight
));
643 void wxGenericGrid::DrawGridLines(wxDC
*dc
)
646 GetClientSize(&cw
, &ch
);
650 if (m_divisionPen
.Ok())
652 dc
->SetPen(m_divisionPen
);
654 int heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
656 // Draw horizontal grey lines for cells
657 for (i
= m_scrollPosY
; i
< (m_totalRows
+1); i
++)
659 if (heightCount
> ch
)
663 dc
->DrawLine(m_leftOfSheet
, heightCount
,
666 heightCount
+= m_rowHeights
[i
];
671 if (m_verticalLabelWidth
> 0)
673 dc
->SetPen(*wxBLACK_PEN
);
675 // Draw horizontal black lines for row labels
676 int heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
677 for (i
= m_scrollPosY
; i
< (m_totalRows
+1); i
++)
679 if (heightCount
> ch
)
683 dc
->DrawLine(m_leftOfSheet
, heightCount
,
684 m_verticalLabelWidth
, heightCount
);
686 heightCount
+= m_rowHeights
[i
];
689 // Draw a black vertical line for row number cells
690 dc
->DrawLine(m_leftOfSheet
+ m_verticalLabelWidth
, m_topOfSheet
,
691 m_leftOfSheet
+ m_verticalLabelWidth
, ch
);
692 // First vertical line
693 dc
->DrawLine(m_leftOfSheet
, m_topOfSheet
, m_leftOfSheet
, ch
);
695 dc
->SetPen(*wxWHITE_PEN
);
697 // Draw highlights on row labels
698 heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
699 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
701 if (heightCount
> ch
)
705 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
706 m_verticalLabelWidth
, heightCount
+1);
707 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
708 m_leftOfSheet
+1, heightCount
+ m_rowHeights
[i
] - 1);
709 heightCount
+= m_rowHeights
[i
];
712 // Last one - down to the floor.
713 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
714 m_verticalLabelWidth
, heightCount
+1);
715 dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1,
716 m_leftOfSheet
+1, ch
);
720 if (m_divisionPen
.Ok())
722 dc
->SetPen(m_divisionPen
);
724 // Draw vertical grey lines for cells
725 int widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
726 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
732 // Skip the first one
733 if (i
!= m_scrollPosX
)
735 dc
->DrawLine(widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
,
736 widthCount
, m_bottomOfSheet
);
738 widthCount
+= m_colWidths
[i
];
742 dc
->DrawLine(widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
,
743 widthCount
, m_bottomOfSheet
);
746 dc
->SetPen(*wxBLACK_PEN
);
748 // Draw two black horizontal lines for column number cells
750 m_leftOfSheet
, m_topOfSheet
,
752 dc
->DrawLine(m_leftOfSheet
, m_topOfSheet
+ m_horizontalLabelHeight
,
753 cw
, m_topOfSheet
+ m_horizontalLabelHeight
);
755 if (m_horizontalLabelHeight
> 0)
757 int widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
759 // Draw black vertical lines for column number cells
760 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
766 dc
->DrawLine(widthCount
, m_topOfSheet
,
767 widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
);
768 widthCount
+= m_colWidths
[i
];
773 dc
->DrawLine(widthCount
, m_topOfSheet
,
774 widthCount
, m_topOfSheet
+ m_horizontalLabelHeight
);
777 dc
->SetPen(*wxWHITE_PEN
);
778 widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
780 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
786 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
787 widthCount
+m_colWidths
[i
], m_topOfSheet
+1);
788 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
789 widthCount
+1, m_topOfSheet
+m_horizontalLabelHeight
);
790 widthCount
+= m_colWidths
[i
];
793 // Last one - to the right side of the canvas.
794 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
796 dc
->DrawLine(widthCount
+1, m_topOfSheet
+1,
797 widthCount
+1, m_topOfSheet
+m_horizontalLabelHeight
);
802 void wxGenericGrid::DrawColumnLabels(wxDC
*dc
)
805 GetClientSize(&cw
, &ch
);
807 if (m_horizontalLabelHeight
== 0)
813 // Draw letters for columns
814 rect
.y
= m_topOfSheet
+ 1;
815 rect
.height
= m_horizontalLabelHeight
- 1;
817 dc
->SetTextBackground(m_labelBackgroundColour
);
818 dc
->SetBackgroundMode(wxTRANSPARENT
);
819 // dc->SetTextForeground(m_labelTextColour);
821 int widthCount
= m_leftOfSheet
+ m_verticalLabelWidth
;
822 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
828 rect
.x
= 1 + widthCount
;
829 rect
.width
= m_colWidths
[i
];
830 DrawColumnLabel(dc
, &rect
, i
);
832 widthCount
+= m_colWidths
[i
];
837 void wxGenericGrid::DrawColumnLabel(wxDC
*dc
, wxRect
*rect
, int col
)
839 wxGridCell
*cell
= GetLabelCell(wxHORIZONTAL
, col
);
848 dc
->SetTextForeground(GetLabelTextColour());
849 dc
->SetFont(GetLabelTextFont());
850 if ( !cell
->GetTextValue().IsNull() )
851 DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, GetLabelAlignment(wxHORIZONTAL
));
855 void wxGenericGrid::DrawRowLabels(wxDC
*dc
)
858 GetClientSize(&cw
, &ch
);
860 if (m_verticalLabelWidth
== 0)
866 // Draw numbers for rows
867 rect
.x
= m_leftOfSheet
;
868 rect
.width
= m_verticalLabelWidth
;
870 int heightCount
= m_topOfSheet
+ m_horizontalLabelHeight
;
872 dc
->SetTextBackground(m_labelBackgroundColour
);
873 dc
->SetBackgroundMode(wxTRANSPARENT
);
875 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
877 if (heightCount
> ch
)
881 rect
.y
= 1 + heightCount
;
882 rect
.height
= m_rowHeights
[i
];
883 DrawRowLabel(dc
, &rect
, i
);
885 heightCount
+= m_rowHeights
[i
];
890 void wxGenericGrid::DrawRowLabel(wxDC
*dc
, wxRect
*rect
, int row
)
892 wxGridCell
*cell
= GetLabelCell(wxVERTICAL
, row
);
901 dc
->SetTextForeground(GetLabelTextColour());
902 dc
->SetFont(GetLabelTextFont());
903 if ( !cell
->GetTextValue().IsNull() )
904 DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, GetLabelAlignment(wxVERTICAL
));
908 void wxGenericGrid::DrawCells(wxDC
*dc
)
911 GetClientSize(&cw
, &ch
);
915 // Draw value corresponding to each cell
916 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
918 for (j
= m_scrollPosX
; j
< m_totalCols
; j
++)
920 SetCurrentRect(i
, j
, cw
, ch
);
921 if (m_currentRectVisible
)
923 DrawCellBackground(dc
, &m_currentRect
, i
, j
);
924 DrawCellValue(dc
, &m_currentRect
, i
, j
);
926 if (m_currentRect
.x
> cw
)
929 if (m_currentRect
.y
> ch
)
932 dc
->SetBackgroundMode(wxSOLID
);
933 dc
->SetPen(*wxBLACK_PEN
);
936 void wxGenericGrid::DrawCellBackground(wxDC
*dc
, wxRect
*rect
, int row
, int col
)
938 wxGridCell
*cell
= GetCell(row
, col
);
941 dc
->SetBrush(cell
->GetBackgroundBrush());
942 dc
->SetPen(*wxTRANSPARENT_PEN
);
944 #if 0 // In wxWin 2.0 the dc code is exact. RR.
946 dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
-1, rect
->height
-1);
948 dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
, rect
->height
);
952 dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
-1, rect
->height
-1);
954 dc
->SetPen(*wxBLACK_PEN
);
958 void wxGenericGrid::DrawCellValue(wxDC
*dc
, wxRect
*rect
, int row
, int col
)
960 wxGridCell
*cell
= GetCell(row
, col
);
963 wxBitmap
*bitmap
= cell
->GetCellBitmap();
973 DrawBitmapRect(dc
, bitmap
, &rect2
, cell
->GetAlignment());
977 dc
->SetBackgroundMode(wxTRANSPARENT
);
978 dc
->SetTextForeground(cell
->GetTextColour());
979 dc
->SetFont(cell
->GetFont());
981 if ( !cell
->GetTextValue().IsNull() )
982 DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, cell
->GetAlignment());
987 void wxGenericGrid::AdjustScrollbars()
990 GetClientSize(&cw
, &ch
);
992 // We find the view size by seeing how many rows/cols fit on
994 // BUT... this means that the scrollbar should be adjusted every time
995 // it's scrolled, as well as when sized, because with variable size rows/cols,
996 // the number of rows/col visible on the view differs according to what bit
997 // you're looking at. The object length is always the same, but the
998 // view length differs.
1000 // Since this may not be known until the end of this function, we should probably call AdjustScrollbars
1002 int vertScrollBarWidth
= m_scrollWidth
;
1003 int horizScrollBarHeight
= m_scrollWidth
;
1004 if (m_vScrollBar
&& !m_vScrollBar
->IsShown())
1005 vertScrollBarWidth
= 0;
1006 if (m_hScrollBar
&& !m_hScrollBar
->IsShown())
1007 horizScrollBarHeight
= 0;
1009 int noHorizSteps
= 0;
1010 int noVertSteps
= 0;
1012 if (m_totalGridWidth
+ vertScrollBarWidth
> cw
)
1018 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1020 widthCount
+= m_colWidths
[i
];
1021 // A partial bit doesn't count, we still have to scroll to see the
1023 if (widthCount
+ m_leftOfSheet
+ m_verticalLabelWidth
> (cw
-vertScrollBarWidth
))
1031 m_viewWidth
= noHorizSteps
;
1033 if (m_totalGridHeight
+ horizScrollBarHeight
> ch
)
1035 int heightCount
= 0;
1039 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1041 heightCount
+= m_rowHeights
[i
];
1042 // A partial bit doesn't count, we still have to scroll to see the
1044 if (heightCount
+ m_topOfSheet
+ m_horizontalLabelHeight
> (ch
-horizScrollBarHeight
))
1053 m_viewHeight
= noVertSteps
;
1055 if (m_totalGridWidth
+ vertScrollBarWidth
<= cw
)
1058 m_hScrollBar
->Show(FALSE
);
1064 m_hScrollBar
->Show(TRUE
);
1067 if (m_totalGridHeight
+ horizScrollBarHeight
<= ch
)
1070 m_vScrollBar
->Show(FALSE
);
1076 m_vScrollBar
->Show(TRUE
);
1079 UpdateDimensions(); // Necessary in case m_scrollPosX/Y changed
1081 vertScrollBarWidth
= m_scrollWidth
;
1082 horizScrollBarHeight
= m_scrollWidth
;
1083 if (m_vScrollBar
&& !m_vScrollBar
->IsShown())
1084 vertScrollBarWidth
= 0;
1085 if (m_hScrollBar
&& !m_hScrollBar
->IsShown())
1086 horizScrollBarHeight
= 0;
1088 if (m_hScrollBar
&& m_hScrollBar
->IsShown())
1090 int nCols
= GetCols();
1091 m_hScrollBar
->SetScrollbar(m_hScrollBar
->GetThumbPosition(), wxMax(noHorizSteps
, 1), (noHorizSteps
== 0) ? 1 : nCols
, wxMax(noHorizSteps
, 1));
1094 m_hScrollBar->SetSize(m_leftOfSheet, ch - m_scrollWidth -2, // why -2 ? Robert.
1095 cw - vertScrollBarWidth - m_leftOfSheet, m_scrollWidth);
1097 m_hScrollBar
->SetSize(m_leftOfSheet
, ch
- m_scrollWidth
,
1098 cw
- vertScrollBarWidth
- m_leftOfSheet
, m_scrollWidth
);
1102 if (m_vScrollBar
&& m_vScrollBar
->IsShown())
1104 int nRows
= GetRows();
1106 m_vScrollBar
->SetScrollbar(m_vScrollBar
->GetThumbPosition(), wxMax(noVertSteps
, 1), (noVertSteps
== 0) ? 1 : nRows
, wxMax(noVertSteps
, 1));
1107 m_vScrollBar
->SetSize(cw
- m_scrollWidth
, m_topOfSheet
,
1108 m_scrollWidth
, ch
- m_topOfSheet
- horizScrollBarHeight
);
1112 void wxGenericGrid::OnSize(wxSizeEvent
& WXUNUSED(event
) )
1114 if (!m_vScrollBar
|| !m_hScrollBar
)
1120 GetClientSize(&cw
, &ch
);
1122 if (m_editCreated
&& m_editingPanel
&& GetTextItem() && GetTextItem()->IsShown())
1124 m_editingPanel
->SetSize(0, 0, cw
, m_editControlPosition
.height
+ m_editControlPosition
.y
+ 2);
1125 GetTextItem()->SetSize(m_editControlPosition
.x
, m_editControlPosition
.y
,
1126 cw
- 2*m_editControlPosition
.x
, m_editControlPosition
.height
);
1130 bool wxGenericGrid::CellHitTest(int x
, int y
, int *row
, int *col
)
1132 // Find the selected cell and call OnSelectCell
1133 if (x
>= (m_leftOfSheet
+ m_verticalLabelWidth
) && y
>= (m_topOfSheet
+ m_horizontalLabelHeight
) &&
1134 x
<= m_rightOfSheet
&& y
<= m_bottomOfSheet
)
1136 // Calculate the cell number from x and y
1137 x
-= (m_verticalLabelWidth
+ m_leftOfSheet
);
1138 y
-= (m_topOfSheet
+ m_horizontalLabelHeight
);
1142 // Now we need to do a hit test for which row we're on
1143 int currentHeight
= 0;
1144 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1146 if (y
>= currentHeight
&& y
<= (currentHeight
+ m_rowHeights
[i
]))
1151 currentHeight
+= m_rowHeights
[i
];
1154 // Now we need to do a hit test for which column we're on
1155 int currentWidth
= 0;
1156 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1158 if (x
>= currentWidth
&& x
<= (currentWidth
+ m_colWidths
[i
]))
1163 currentWidth
+= m_colWidths
[i
];
1170 bool wxGenericGrid::LabelSashHitTest(int x
, int y
, int *orientation
, int *rowOrCol
, int *startPos
)
1175 if (x
>= (m_leftOfSheet
+ m_verticalLabelWidth
) && y
>= m_topOfSheet
&&
1176 x
<= m_rightOfSheet
&& y
<= (m_topOfSheet
+ m_horizontalLabelHeight
))
1178 // We may be on a column label sash.
1179 int currentWidth
= m_leftOfSheet
+ m_verticalLabelWidth
;
1180 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1182 if (x
>= (currentWidth
+ m_colWidths
[i
] - tolerance
) && x
<= (currentWidth
+ m_colWidths
[i
] + tolerance
))
1184 *orientation
= wxHORIZONTAL
;
1186 *startPos
= currentWidth
;
1189 currentWidth
+= m_colWidths
[i
];
1193 else if (x
>= m_leftOfSheet
&& y
>= (m_topOfSheet
+ m_horizontalLabelHeight
) &&
1194 x
<= (m_leftOfSheet
+ m_verticalLabelWidth
) && y
<= m_bottomOfSheet
)
1196 // We may be on a row label sash.
1197 int currentHeight
= m_topOfSheet
+ m_horizontalLabelHeight
;
1198 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1200 if (y
>= (currentHeight
+ m_rowHeights
[i
] - tolerance
) && y
<= (currentHeight
+ m_rowHeights
[i
] + tolerance
))
1202 *orientation
= wxVERTICAL
;
1204 *startPos
= currentHeight
;
1207 currentHeight
+= m_rowHeights
[i
];
1214 bool wxGenericGrid::LabelHitTest(int x
, int y
, int *row
, int *col
)
1216 // Find the selected label
1217 if (x
>= m_leftOfSheet
&& y
>= m_topOfSheet
&&
1218 x
<= m_rightOfSheet
&& y
<= m_bottomOfSheet
)
1220 // Calculate the cell number from x and y
1226 // Now we need to do a hit test for which row we're on
1227 int currentHeight
= m_horizontalLabelHeight
;
1228 for (i
= m_scrollPosY
; i
< m_totalRows
; i
++)
1230 if (y
>= currentHeight
&& y
<= (currentHeight
+ m_rowHeights
[i
]))
1235 currentHeight
+= m_rowHeights
[i
];
1237 if (y
>= 0 && y
<= m_horizontalLabelHeight
)
1242 // Now we need to do a hit test for which column we're on
1243 int currentWidth
= m_verticalLabelWidth
;
1244 for (i
= m_scrollPosX
; i
< m_totalCols
; i
++)
1246 if (x
>= currentWidth
&& x
<= (currentWidth
+ m_colWidths
[i
]))
1251 currentWidth
+= m_colWidths
[i
];
1253 if (x
>= 0 && x
<= m_verticalLabelWidth
)
1258 if ((*col
== -1) || (*row
== -1))
1266 void wxGenericGrid::OnMouseEvent(wxMouseEvent
& ev
)
1270 wxClientDC
dc(this);
1274 if (CellHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1276 OnSelectCellImplementation(& dc
, row
, col
);
1278 //OnCellLeftClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1279 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CELL_LCLICK
, this,
1280 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1281 ev
.ControlDown(), ev
.ShiftDown());
1282 GetEventHandler()->ProcessEvent(g_evt
);
1285 if (LabelHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1287 //OnLabelLeftClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1288 wxGridEvent
g_evt(GetId(), wxEVT_GRID_LABEL_LCLICK
, this,
1289 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1290 ev
.ControlDown(), ev
.ShiftDown());
1291 GetEventHandler()->ProcessEvent(g_evt
);
1296 else if (ev
.Dragging() && ev
.LeftIsDown())
1298 switch (m_dragStatus
)
1300 case wxGRID_DRAG_NONE
:
1303 if (LabelSashHitTest((int)ev
.GetX(), (int)ev
.GetY(), &orientation
, &m_dragRowOrCol
, &m_dragStartPosition
))
1305 if (orientation
== wxHORIZONTAL
)
1307 m_dragStatus
= wxGRID_DRAG_LEFT_RIGHT
;
1308 SetCursor(m_horizontalSashCursor
);
1309 m_dragLastPosition
= (int)ev
.GetX();
1313 m_dragStatus
= wxGRID_DRAG_UP_DOWN
;
1314 SetCursor(m_verticalSashCursor
);
1315 m_dragLastPosition
= (int)ev
.GetY();
1317 wxClientDC
dc(this);
1319 dc
.SetLogicalFunction(wxINVERT
);
1320 if (orientation
== wxHORIZONTAL
)
1321 dc
.DrawLine((int)ev
.GetX(), m_topOfSheet
, (int)ev
.GetX(), m_bottomOfSheet
);
1323 dc
.DrawLine(m_leftOfSheet
, (int)ev
.GetY(), m_rightOfSheet
, (int)ev
.GetY());
1330 case wxGRID_DRAG_LEFT_RIGHT
:
1332 wxClientDC
dc(this);
1334 dc
.SetLogicalFunction(wxINVERT
);
1335 dc
.DrawLine(m_dragLastPosition
, m_topOfSheet
, m_dragLastPosition
, m_bottomOfSheet
);
1337 dc
.DrawLine((int)ev
.GetX(), m_topOfSheet
, (int)ev
.GetX(), m_bottomOfSheet
);
1340 m_dragLastPosition
= (int)ev
.GetX();
1341 SetCursor(m_horizontalSashCursor
);
1344 case wxGRID_DRAG_UP_DOWN
:
1346 wxClientDC
dc(this);
1348 dc
.SetLogicalFunction(wxINVERT
);
1349 dc
.DrawLine(m_leftOfSheet
, m_dragLastPosition
, m_rightOfSheet
, m_dragLastPosition
);
1351 dc
.DrawLine(m_leftOfSheet
, (int)ev
.GetY(), m_rightOfSheet
, (int)ev
.GetY());
1354 m_dragLastPosition
= (int)ev
.GetY();
1355 SetCursor(m_verticalSashCursor
);
1360 else if (ev
.Moving())
1362 int rowOrCol
, orientation
, startPos
;
1363 if (LabelSashHitTest((int)ev
.GetX(), (int)ev
.GetY(), &orientation
, &rowOrCol
, &startPos
))
1365 if (orientation
== wxHORIZONTAL
)
1366 SetCursor(m_horizontalSashCursor
);
1368 SetCursor(m_verticalSashCursor
);
1371 SetCursor(*wxSTANDARD_CURSOR
);
1373 else if (ev
.LeftUp())
1375 switch (m_dragStatus
)
1377 case wxGRID_DRAG_LEFT_RIGHT
:
1379 wxClientDC
dc(this);
1381 dc
.SetLogicalFunction(wxINVERT
);
1382 dc
.DrawLine(m_dragLastPosition
, m_topOfSheet
, m_dragLastPosition
, m_bottomOfSheet
);
1383 dc
.SetLogicalFunction(wxCOPY
);
1387 if (ev
.GetX() > m_dragStartPosition
)
1389 m_colWidths
[m_dragRowOrCol
] = (short)(ev
.GetX() - m_dragStartPosition
);
1394 SetCursor(*wxSTANDARD_CURSOR
);
1396 GetClientSize(&cw
, &ch
);
1401 case wxGRID_DRAG_UP_DOWN
:
1403 wxClientDC
dc(this);
1405 dc
.SetLogicalFunction(wxINVERT
);
1406 dc
.DrawLine(m_leftOfSheet
, m_dragLastPosition
, m_rightOfSheet
, m_dragLastPosition
);
1407 dc
.SetLogicalFunction(wxCOPY
);
1411 if (ev
.GetY() > m_dragStartPosition
)
1413 m_rowHeights
[m_dragRowOrCol
] = (short)(ev
.GetY() - m_dragStartPosition
);
1418 SetCursor(*wxSTANDARD_CURSOR
);
1422 m_dragStatus
= wxGRID_DRAG_NONE
;
1424 else if (ev
.RightDown())
1427 if (CellHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1429 //OnCellRightClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1430 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CELL_RCLICK
, this,
1431 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1432 ev
.ControlDown(), ev
.ShiftDown());
1433 GetEventHandler()->ProcessEvent(g_evt
);
1436 if (LabelHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
))
1438 //OnLabelRightClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1439 wxGridEvent
g_evt(GetId(), wxEVT_GRID_LABEL_RCLICK
, this,
1440 row
, col
, (int)ev
.GetX(), (int)ev
.GetY(),
1441 ev
.ControlDown(), ev
.ShiftDown());
1442 GetEventHandler()->ProcessEvent(g_evt
);
1447 void wxGenericGrid::OnSelectCellImplementation(wxDC
*dc
, int row
, int col
)
1449 m_wCursorColumn
= col
;
1452 //OnChangeSelectionLabel();
1453 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_SEL_LABEL
, this);
1454 GetEventHandler()->ProcessEvent(g_evt
);
1456 SetGridClippingRegion(dc
);
1458 // Remove the highlight from the old cell
1459 if ( m_currentRectVisible
&& (wxIPE_HIGHLIGHT
|| !(m_editable
&& m_editInPlace
)))
1461 HighlightCell(dc
, FALSE
);
1465 // Highlight the new cell and copy its content to the edit control
1466 SetCurrentRect(m_wCursorRow
, m_wCursorColumn
);
1467 wxGridCell
*cell
= GetCell(m_wCursorRow
, m_wCursorColumn
);
1470 if ( cell
->GetTextValue().IsNull() )
1471 m_textItem
->SetValue("");
1473 m_textItem
->SetValue(cell
->GetTextValue());
1476 SetGridClippingRegion(dc
);
1479 if ( m_editable
&& m_editInPlace
)
1481 int x
, y
, width
, height
;
1482 if ( m_currentRect
.x
<= 0 )
1485 width
= m_currentRect
.width
+ wxIPE_ADJUST
;
1489 x
= m_currentRect
.x
- wxIPE_ADJUST
;
1490 width
= m_currentRect
.width
+ wxIPE_ADJUST
*2;
1493 if ( m_currentRect
.y
<= 0 )
1496 height
= m_currentRect
.height
+ wxIPE_ADJUST
;
1500 y
= m_currentRect
.y
- wxIPE_ADJUST
;
1501 height
= m_currentRect
.height
+ wxIPE_ADJUST
*2;
1504 m_inPlaceTextItem
->SetSize( x
, y
, width
, height
);
1507 m_inPlaceTextItem
->SetFont( cell
->GetFont() );
1508 m_inPlaceTextItem
->SetBackgroundColour(cell
->GetBackgroundColour());
1509 m_inPlaceTextItem
->SetForegroundColour(cell
->GetTextColour());
1511 if ( cell
->GetTextValue().IsNull() ) {
1512 m_inPlaceTextItem
->SetValue( "" );
1515 m_inPlaceTextItem
->SetValue( cell
->GetTextValue() );
1519 m_inPlaceTextItem
->Show(TRUE
);
1520 m_inPlaceTextItem
->SetFocus();
1521 if (wxIPE_HIGHLIGHT
)
1522 HighlightCell(dc
, TRUE
);
1526 // 1) Why isn't this needed for Windows??
1527 // Probably because of the SetValue?? JS.
1528 // 2) Arrrrrgh. This isn't needed anywhere,
1529 // of course. One hour of debugging... RR.
1531 // 3) It *is* needed for Motif - michael
1533 #if defined(__WXMOTIF__)
1534 if ((wxIPE_HIGHLIGHT
|| !(m_editable
&& m_editInPlace
)))
1535 HighlightCell(dc
, TRUE
);
1539 dc
->DestroyClippingRegion();
1541 OnSelectCell(row
, col
);
1542 wxGridEvent
g_evt2(GetId(), wxEVT_GRID_SELECT_CELL
, this, row
, col
);
1543 GetEventHandler()->ProcessEvent(g_evt2
);
1546 wxGridCell
*wxGenericGrid::OnCreateCell()
1548 return new wxGridCell(this);
1551 void wxGenericGrid::OnChangeLabels()
1555 for (i
= 0; i
< m_totalRows
; i
++)
1557 sprintf(buf
, "%d", i
+1);
1558 SetLabelValue(wxVERTICAL
, buf
, i
);
1560 // A...Z,AA...ZZ,AAA...ZZZ, etc.
1561 for (i
= 0; i
< m_totalCols
; i
++)
1564 int noTimes
= (i
/26 + 1);
1565 int ch
= (i
% 26) + 65;
1567 for (j
= 0; j
< noTimes
; j
++)
1570 sprintf(buf2
, "%c", (char)ch
);
1573 SetLabelValue(wxHORIZONTAL
, buf
, i
);
1577 void wxGenericGrid::OnChangeSelectionLabel()
1582 wxString
rowLabel(GetLabelValue(wxVERTICAL
, GetCursorRow()));
1583 wxString
colLabel(GetLabelValue(wxHORIZONTAL
, GetCursorColumn()));
1585 wxString newLabel
= colLabel
+ rowLabel
;
1586 if ((newLabel
.Length() > 0) && (newLabel
.Length() <= 8) && GetTextItem())
1588 // GetTextItem()->SetLabel(newLabel);
1592 void wxGenericGrid::HighlightCell(wxDC
*dc
, bool doHighlight
)
1594 wxPen savePen
= dc
->GetPen();
1596 dc
->SetPen(m_highlightPen
);
1598 dc
->SetPen(*wxThePenList
->FindOrCreatePen(m_cellBackgroundColour
, 1, wxSOLID
));
1601 dc
->DrawLine( m_currentRect
.x
+ 1,
1602 m_currentRect
.y
+ 1,
1603 m_currentRect
.x
+ m_currentRect
.width
- 1,
1604 m_currentRect
.y
+ 1);
1606 dc
->DrawLine( m_currentRect
.x
+ m_currentRect
.width
- 1,
1607 m_currentRect
.y
+ 1,
1608 m_currentRect
.x
+ m_currentRect
.width
- 1,
1609 m_currentRect
.y
+ m_currentRect
.height
- 1 );
1611 dc
->DrawLine( m_currentRect
.x
+ m_currentRect
.width
- 1,
1612 m_currentRect
.y
+ m_currentRect
.height
- 1,
1613 m_currentRect
.x
+ 1,
1614 m_currentRect
.y
+ m_currentRect
.height
- 1);
1616 dc
->DrawLine( m_currentRect
.x
+ 1,
1617 m_currentRect
.y
+ m_currentRect
.height
- 1,
1618 m_currentRect
.x
+ 1,
1619 m_currentRect
.y
+ 1);
1621 dc
->SetPen(savePen
);
1624 void wxGenericGrid::DrawCellText()
1626 if (!m_currentRectVisible
)
1629 wxGridCell
*cell
= GetCell(GetCursorRow(), GetCursorColumn());
1633 wxClientDC
dc(this);
1636 SetGridClippingRegion(& dc
);
1638 dc
.SetBackgroundMode(wxTRANSPARENT
);
1639 dc
.SetBrush(cell
->GetBackgroundBrush());
1641 wxString editValue
= m_textItem
->GetValue();
1644 rect
= m_currentRect
;
1650 // FIXME: what's this string of spaces supposed to represent?
1651 DrawTextRect(& dc
, " ", &rect
, wxLEFT
);
1652 DrawTextRect(& dc
, editValue
, &rect
, cell
->GetAlignment());
1654 dc
.DestroyClippingRegion();
1656 dc
.SetBackgroundMode(wxSOLID
);
1661 void wxGenericGrid::SetCurrentRect(int Row
, int Column
, int canvasW
, int canvasH
)
1663 int currentWidth
= m_leftOfSheet
+ m_verticalLabelWidth
;
1665 for (i
= m_scrollPosX
; i
< Column
; i
++)
1666 currentWidth
+= m_colWidths
[i
];
1668 int currentHeight
= m_topOfSheet
+ m_horizontalLabelHeight
;
1669 for (i
= m_scrollPosY
; i
< Row
; i
++)
1670 currentHeight
+= m_rowHeights
[i
];
1672 m_currentRect
.x
= currentWidth
;
1673 m_currentRect
.y
= currentHeight
;
1674 m_currentRect
.width
= m_colWidths
? (m_colWidths
[Column
]) : 0;
1675 m_currentRect
.height
= m_rowHeights
? (m_rowHeights
[Row
]) : 0;
1677 if (Row
< m_scrollPosY
|| Column
< m_scrollPosX
)
1678 m_currentRectVisible
= FALSE
;
1679 else if ((canvasW
!= -1 && canvasH
!= -1) && (m_currentRect
.x
> canvasW
|| m_currentRect
.y
> canvasH
))
1680 m_currentRectVisible
= FALSE
;
1681 else m_currentRectVisible
= TRUE
;
1684 static bool wxRectIntersection(wxRect
*rect1
, wxRect
*rect2
, wxRect
*rect3
)
1686 int x2_1
= rect1
->x
+ rect1
->width
;
1687 int y2_1
= rect1
->y
+ rect1
->height
;
1689 int x2_2
= rect2
->x
+ rect2
->width
;
1690 int y2_2
= rect2
->y
+ rect2
->height
;
1694 // Check for intersection
1695 if ((rect1
->x
> x2_2
) || (rect2
->x
> x2_1
) ||
1696 (rect1
->y
> y2_2
) || (rect2
->y
> y2_1
))
1699 rect3
->x
= rect3
->y
= rect3
->width
= rect3
->height
= 0;
1703 if (rect1
->x
> rect2
->x
)
1704 rect3
->x
= rect1
->x
;
1706 rect3
->x
= rect2
->x
;
1707 if (rect1
->y
> rect2
->y
)
1708 rect3
->y
= rect1
->y
;
1710 rect3
->y
= rect2
->y
;
1721 rect3
->width
= (int)(x2_3
- rect3
->x
);
1722 rect3
->height
= (int)(y2_3
- rect3
->y
);
1726 void wxGenericGrid::DrawTextRect(wxDC
*dc
, const wxString
& text
, wxRect
*rect
, int flag
)
1730 // Ultimately, this functionality should be built into wxWindows,
1731 // and optimized for each platform. E.g. on Windows, use DrawText
1732 // passing a clipping rectangle, so that the wxWindows clipping region
1733 // does not have to be used to implement this.
1735 // If we're already clipping, we need to find the intersection
1736 // between current clipping area and text clipping area.
1740 long clipX
, clipY
, clipW
, clipH
;
1741 dc
->GetClippingBox(&clipX
, &clipY
, &clipW
, &clipH
);
1742 clipRect
.x
= (int)clipX
; clipRect
.y
= (int)clipY
;
1743 clipRect
.width
= (int)clipW
; clipRect
.height
= (int)clipH
;
1745 bool alreadyClipping
= TRUE
;
1747 if (clipRect
.x
== 0 && clipRect
.y
== 0 && clipRect
.width
== 0 && clipRect
.height
== 0)
1749 alreadyClipping
= FALSE
;
1750 clipRect2
.x
= rect
->x
; clipRect2
.y
= rect
->y
;
1751 clipRect2
.width
= rect
->width
; clipRect2
.height
= rect
->height
;
1755 // Find intersection.
1756 if (!wxRectIntersection(rect
, &clipRect
, &clipRect2
))
1760 if (alreadyClipping
)
1761 dc
->DestroyClippingRegion();
1763 dc
->SetClippingRegion(clipRect2
.x
, clipRect2
.y
, clipRect2
.width
, clipRect2
.height
);
1764 long textWidth
, textHeight
;
1766 dc
->GetTextExtent(text
, &textWidth
, &textHeight
);
1774 x
= (rect
->x
+ rect
->width
- textWidth
- 1.0);
1775 y
= (rect
->y
+ (rect
->height
- textHeight
)/2.0);
1780 x
= (rect
->x
+ (rect
->width
- textWidth
)/2.0);
1781 y
= (rect
->y
+ (rect
->height
- textHeight
)/2.0);
1787 x
= (rect
->x
+ 1.0);
1788 y
= (rect
->y
+ (rect
->height
- textHeight
)/2.0);
1792 dc
->DrawText(text
, (long)x
, (long)y
);
1794 dc
->DestroyClippingRegion();
1796 // Restore old clipping
1797 if (alreadyClipping
)
1798 dc
->SetClippingRegion(clipRect
.x
, clipRect
.y
, clipRect
.width
, clipRect
.height
);
1803 void wxGenericGrid::DrawBitmapRect(wxDC
*dc
, wxBitmap
*bitmap
, wxRect
*rect
, int flag
)
1807 // Ultimately, this functionality should be built into wxWindows,
1808 // and optimized for each platform. E.g. on Windows, use DrawText
1809 // passing a clipping rectangle, so that the wxWindows clipping region
1810 // does not have to be used to implement this.
1812 // If we're already clipping, we need to find the intersection
1813 // between current clipping area and text clipping area.
1817 long clipX
, clipY
, clipW
, clipH
;
1818 dc
->GetClippingBox(&clipX
, &clipY
, &clipW
, &clipH
);
1819 clipRect
.x
= (int)clipX
; clipRect
.y
= (int)clipY
;
1820 clipRect
.width
= (int)clipW
; clipRect
.height
= (int)clipH
;
1822 bool alreadyClipping
= TRUE
;
1824 if (clipRect
.x
== 0 && clipRect
.y
== 0 && clipRect
.width
== 0 && clipRect
.height
== 0)
1826 alreadyClipping
= FALSE
;
1827 clipRect2
.x
= rect
->x
; clipRect2
.y
= rect
->y
;
1828 clipRect2
.width
= rect
->width
; clipRect2
.height
= rect
->height
;
1832 // Find intersection.
1833 if (!wxRectIntersection(rect
, &clipRect
, &clipRect2
))
1837 if (alreadyClipping
)
1838 dc
->DestroyClippingRegion();
1840 dc
->SetClippingRegion(clipRect2
.x
, clipRect2
.y
, clipRect2
.width
, clipRect2
.height
);
1841 float bitmapWidth
, bitmapHeight
;
1843 bitmapWidth
= bitmap
->GetWidth();
1844 bitmapHeight
= bitmap
->GetHeight();
1852 x
= (long)(rect
->x
+ rect
->width
- bitmapWidth
- 1);
1853 y
= (long)(rect
->y
+ (rect
->height
- bitmapHeight
)/2.0);
1858 x
= (long)(rect
->x
+ (rect
->width
- bitmapWidth
)/2.0);
1859 y
= (long)(rect
->y
+ (rect
->height
- bitmapHeight
)/2.0);
1865 x
= (long)(rect
->x
+ 1);
1866 y
= (long)(rect
->y
+ (rect
->height
- bitmapHeight
)/2.0);
1871 dcTemp
.SelectObject(*bitmap
);
1873 dc
->Blit( (long)x
, (long)y
, (long)bitmapWidth
, (long)bitmapHeight
, &dcTemp
, 0, 0);
1874 dcTemp
.SelectObject(wxNullBitmap
);
1876 dc
->DestroyClippingRegion();
1878 // Restore old clipping
1879 if (alreadyClipping
)
1880 dc
->SetClippingRegion(clipRect
.x
, clipRect
.y
, clipRect
.width
, clipRect
.height
);
1885 void wxGenericGrid::OnActivate(bool active
)
1889 // Edit control should always have the focus
1890 if (GetTextItem() && GetEditable())
1892 GetTextItem()->SetFocus();
1893 wxGridCell
*cell
= GetCell(GetCursorRow(), GetCursorColumn());
1895 GetTextItem()->SetValue(cell
->GetTextValue());
1900 void wxGenericGrid::SetCellValue(const wxString
& val
, int row
, int col
)
1902 wxGridCell
*cell
= GetCell(row
, col
);
1905 cell
->SetTextValue(val
);
1907 RefreshCell(row
, col
, TRUE
);
1911 void wxGenericGrid::RefreshCell(int row
, int col
, bool setText
)
1913 // Don't refresh within a pair of batch brackets
1914 if (GetBatchCount() > 0)
1918 GetClientSize(&cw
, &ch
);
1920 SetCurrentRect(row
, col
, cw
, ch
);
1921 if (m_currentRectVisible
)
1923 wxGridCell
*cell
= GetCell(row
, col
);
1925 bool currentPos
= FALSE
;
1926 if (row
== m_wCursorRow
&& col
== m_wCursorColumn
&& GetTextItem() && GetTextItem()->IsShown() && setText
)
1928 GetTextItem()->SetValue(cell
->GetTextValue());
1931 // Gets refreshed anyway in MSW
1936 wxClientDC
dc(this);
1938 DrawCellBackground(& dc
, &m_currentRect
, row
, col
);
1939 DrawCellValue(& dc
, &m_currentRect
, row
, col
);
1945 wxString
& wxGenericGrid::GetCellValue(int row
, int col
) const
1947 static wxString
emptyString("");
1949 wxGridCell
*cell
= GetCell(row
, col
);
1951 return cell
->GetTextValue();
1956 void wxGenericGrid::SetColumnWidth(int col
, int width
)
1958 if (col
<= m_totalCols
)
1959 m_colWidths
[col
] = width
;
1962 int wxGenericGrid::GetColumnWidth(int col
) const
1964 if (col
<= m_totalCols
)
1965 return m_colWidths
[col
];
1970 void wxGenericGrid::SetRowHeight(int row
, int height
)
1972 if (row
<= m_totalRows
)
1973 m_rowHeights
[row
] = height
;
1976 int wxGenericGrid::GetRowHeight(int row
) const
1978 if (row
<= m_totalRows
)
1979 return m_rowHeights
[row
];
1984 void wxGenericGrid::SetLabelSize(int orientation
, int sz
)
1986 if (orientation
== wxHORIZONTAL
)
1987 m_horizontalLabelHeight
= sz
;
1989 m_verticalLabelWidth
= sz
;
1991 SetCurrentRect(GetCursorRow(), GetCursorColumn());
1994 int wxGenericGrid::GetLabelSize(int orientation
) const
1996 if (orientation
== wxHORIZONTAL
)
1997 return m_horizontalLabelHeight
;
1999 return m_verticalLabelWidth
;
2002 wxGridCell
*wxGenericGrid::GetLabelCell(int orientation
, int pos
) const
2004 if (orientation
== wxHORIZONTAL
)
2006 if (m_colLabelCells
&& pos
< m_totalCols
)
2007 return m_colLabelCells
[pos
];
2009 return (wxGridCell
*) NULL
;
2013 if (m_rowLabelCells
&& pos
< m_totalRows
)
2014 return m_rowLabelCells
[pos
];
2016 return (wxGridCell
*) NULL
;
2020 void wxGenericGrid::SetLabelValue(int orientation
, const wxString
& val
, int pos
)
2022 wxGridCell
*cell
= GetLabelCell(orientation
, pos
);
2024 cell
->SetTextValue(val
);
2027 wxString
& wxGenericGrid::GetLabelValue(int orientation
, int pos
) const
2029 static wxString emptyString
= "";
2030 wxGridCell
*cell
= GetLabelCell(orientation
, pos
);
2032 return cell
->GetTextValue();
2037 void wxGenericGrid::SetLabelAlignment(int orientation
, int align
)
2039 if (orientation
== wxHORIZONTAL
)
2040 m_horizontalLabelAlignment
= align
;
2042 m_verticalLabelAlignment
= align
;
2044 SetCurrentRect(GetCursorRow(), GetCursorColumn());
2047 int wxGenericGrid::GetLabelAlignment(int orientation
) const
2049 if (orientation
== wxHORIZONTAL
)
2050 return m_horizontalLabelAlignment
;
2052 return m_verticalLabelAlignment
;
2055 void wxGenericGrid::SetLabelTextColour(const wxColour
& colour
)
2057 m_labelTextColour
= colour
;
2061 void wxGenericGrid::SetLabelBackgroundColour(const wxColour
& colour
)
2063 m_labelBackgroundColour
= colour
;
2064 m_labelBackgroundBrush
= * wxTheBrushList
->FindOrCreateBrush(m_labelBackgroundColour
, wxSOLID
);
2067 void wxGenericGrid::SetEditable(bool edit
)
2072 int controlW
, controlH
;
2073 m_textItem
->GetSize(&controlW
, &controlH
);
2074 m_editControlPosition
.height
= controlH
;
2076 m_topOfSheet
= m_editControlPosition
.x
+ controlH
+ 2;
2079 m_editingPanel
->Show(TRUE
);
2080 m_textItem
->Show(TRUE
);
2081 m_textItem
->SetFocus();
2084 if (m_inPlaceTextItem
)
2086 m_inPlaceTextItem
->Show(TRUE
);
2087 m_inPlaceTextItem
->SetFocus();
2095 m_textItem
->Show(FALSE
);
2096 m_editingPanel
->Show(FALSE
);
2099 if ( m_inPlaceTextItem
)
2101 m_inPlaceTextItem
->Show(FALSE
);
2105 SetCurrentRect(GetCursorRow(), GetCursorColumn());
2108 GetClientSize(&cw
, &ch
);
2113 int m_scrollWidth = 16;
2114 GetClientSize(&cw, &ch);
2117 m_vScrollBar->SetSize(cw - m_scrollWidth, m_topOfSheet,
2118 m_scrollWidth, ch - m_topOfSheet - m_scrollWidth);
2123 void wxGenericGrid::SetEditInPlace(bool edit
)
2125 if ( m_editInPlace
!= edit
)
2127 m_editInPlace
= edit
;
2129 if ( m_editInPlace
) // switched on
2131 if ( m_currentRectVisible
&& m_editable
)
2133 m_inPlaceTextItem
->SetSize( m_currentRect
.x
-wxIPE_ADJUST
,
2134 m_currentRect
.y
-wxIPE_ADJUST
,
2135 m_currentRect
.width
+wxIPE_ADJUST
*2,
2136 m_currentRect
.height
+wxIPE_ADJUST
*2 );
2138 wxGridCell
*cell
= GetCell(m_wCursorRow
, m_wCursorColumn
);
2141 m_inPlaceTextItem
->SetFont( cell
->GetFont() );
2142 m_inPlaceTextItem
->SetBackgroundColour(cell
->GetBackgroundColour());
2143 m_inPlaceTextItem
->SetForegroundColour(cell
->GetTextColour());
2145 if ( cell
->GetTextValue().IsNull() ) {
2146 m_inPlaceTextItem
->SetValue( "" );
2149 m_inPlaceTextItem
->SetValue( cell
->GetTextValue() );
2153 m_inPlaceTextItem
->Show( TRUE
);
2154 m_inPlaceTextItem
->SetFocus();
2157 else // switched off
2159 m_inPlaceTextItem
->Show( FALSE
);
2165 void wxGenericGrid::SetCellAlignment(int flag
, int row
, int col
)
2167 wxGridCell
*cell
= GetCell(row
, col
);
2169 cell
->SetAlignment(flag
);
2172 int wxGenericGrid::GetCellAlignment(int row
, int col
) const
2174 wxGridCell
*cell
= GetCell(row
, col
);
2176 return cell
->GetAlignment();
2178 return m_cellAlignment
;
2181 void wxGenericGrid::SetCellAlignment(int flag
)
2183 m_cellAlignment
= flag
;
2185 for (i
= 0; i
< GetRows(); i
++)
2186 for (j
= 0; j
< GetCols(); j
++)
2188 GetCell(i
, j
)->SetAlignment(flag
);
2191 int wxGenericGrid::GetCellAlignment(void) const
2193 return m_cellAlignment
;
2196 void wxGenericGrid::SetCellBackgroundColour(const wxColour
& col
)
2198 m_cellBackgroundColour
= col
;
2200 for (i
= 0; i
< GetRows(); i
++)
2201 for (j
= 0; j
< GetCols(); j
++)
2203 GetCell(i
, j
)->SetBackgroundColour(col
);
2206 void wxGenericGrid::SetCellBackgroundColour(const wxColour
& val
, int row
, int col
)
2208 wxGridCell
*cell
= GetCell(row
, col
);
2211 cell
->SetBackgroundColour(val
);
2212 RefreshCell(row
, col
);
2216 wxColour
& wxGenericGrid::GetCellBackgroundColour(int row
, int col
) const
2218 wxGridCell
*cell
= GetCell(row
, col
);
2220 return cell
->GetBackgroundColour();
2222 return (wxColour
&) m_cellBackgroundColour
;
2225 void wxGenericGrid::SetCellTextColour(const wxColour
& val
, int row
, int col
)
2227 wxGridCell
*cell
= GetCell(row
, col
);
2230 cell
->SetTextColour(val
);
2231 RefreshCell(row
, col
);
2235 void wxGenericGrid::SetCellTextFont(const wxFont
& fnt
, int row
, int col
)
2237 wxGridCell
*cell
= GetCell(row
, col
);
2241 RefreshCell(row
, col
);
2245 wxFont
& wxGenericGrid::GetCellTextFont(int row
, int col
) const
2247 wxGridCell
*cell
= GetCell(row
, col
);
2249 return (wxFont
&) cell
->GetFont();
2251 return (wxFont
&) m_cellTextFont
;
2254 wxColour
& wxGenericGrid::GetCellTextColour(int row
, int col
) const
2256 wxGridCell
*cell
= GetCell(row
, col
);
2258 return (wxColour
&) cell
->GetTextColour();
2260 return (wxColour
&) m_cellTextColour
;
2263 void wxGenericGrid::SetCellTextColour(const wxColour
& val
)
2265 m_cellTextColour
= val
;
2267 for (i
= 0; i
< GetRows(); i
++)
2268 for (j
= 0; j
< GetCols(); j
++)
2270 GetCell(i
, j
)->SetTextColour(val
);
2273 void wxGenericGrid::SetCellTextFont(const wxFont
& fnt
)
2275 m_cellTextFont
= fnt
;
2277 for (i
= 0; i
< GetRows(); i
++)
2278 for (j
= 0; j
< GetCols(); j
++)
2280 GetCell(i
, j
)->SetFont(fnt
);
2283 void wxGenericGrid::SetCellBitmap(wxBitmap
*bitmap
, int row
, int col
)
2285 wxGridCell
*cell
= GetCell(row
, col
);
2288 cell
->SetCellBitmap(bitmap
);
2289 RefreshCell(row
, col
);
2293 wxBitmap
*wxGenericGrid::GetCellBitmap(int row
, int col
) const
2295 wxGridCell
*cell
= GetCell(row
, col
);
2298 return cell
->GetCellBitmap();
2301 return (wxBitmap
*) NULL
;
2304 bool wxGenericGrid::InsertCols(int pos
, int n
, bool updateLabels
)
2306 if (pos
> m_totalCols
)
2310 return CreateGrid(1, n
);
2315 for (i
= 0; i
< m_totalRows
; i
++)
2317 wxGridCell
**cols
= m_gridCells
[i
];
2318 wxGridCell
**newCols
= new wxGridCell
*[m_totalCols
+ n
];
2319 for (j
= 0; j
< pos
; j
++)
2320 newCols
[j
] = cols
[j
];
2321 for (j
= pos
; j
< pos
+ n
; j
++)
2322 newCols
[j
] = new wxGridCell(this);
2323 for (j
= pos
+ n
; j
< m_totalCols
+ n
; j
++)
2324 newCols
[j
] = cols
[j
- n
];
2327 m_gridCells
[i
] = newCols
;
2331 short *newColWidths
= new short[m_totalCols
+ n
];
2332 for (j
= 0; j
< pos
; j
++)
2333 newColWidths
[j
] = m_colWidths
[j
];
2334 for (j
= pos
; j
< pos
+ n
; j
++)
2335 newColWidths
[j
] = wxGRID_DEFAULT_CELL_WIDTH
;
2336 for (j
= pos
+ n
; j
< m_totalCols
+ n
; j
++)
2337 newColWidths
[j
] = m_colWidths
[j
- n
];
2338 delete[] m_colWidths
;
2339 m_colWidths
= newColWidths
;
2342 wxGridCell
**newLabels
= new wxGridCell
*[m_totalCols
+ n
];
2343 for (j
= 0; j
< pos
; j
++)
2344 newLabels
[j
] = m_colLabelCells
[j
];
2345 for (j
= pos
; j
< pos
+ n
; j
++)
2346 newLabels
[j
] = new wxGridCell(this);
2347 for (j
= pos
+ n
; j
< m_totalCols
+ n
; j
++)
2348 newLabels
[j
] = m_colLabelCells
[j
- n
];
2350 delete[] m_colLabelCells
;
2351 m_colLabelCells
= newLabels
;
2357 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2358 GetEventHandler()->ProcessEvent(g_evt
);
2367 bool wxGenericGrid::InsertRows(int pos
, int n
, bool updateLabels
)
2369 if (pos
> m_totalRows
)
2373 return CreateGrid(n
, 1);
2378 wxGridCell
***rows
= new wxGridCell
**[m_totalRows
+ n
];
2381 for (i
= 0; i
< pos
; i
++)
2382 rows
[i
] = m_gridCells
[i
];
2384 for (i
= pos
; i
< pos
+ n
; i
++)
2386 rows
[i
] = new wxGridCell
*[m_totalCols
];
2387 for (j
= 0; j
< m_totalCols
; j
++)
2388 rows
[i
][j
] = new wxGridCell(this);
2391 for (i
= pos
+ n
; i
< m_totalRows
+ n
; i
++)
2392 rows
[i
] = m_gridCells
[i
- n
];
2394 delete[] m_gridCells
;
2398 short *newRowHeights
= new short[m_totalRows
+ n
];
2399 for (i
= 0; i
< pos
; i
++)
2400 newRowHeights
[i
] = m_rowHeights
[i
];
2401 for (i
= pos
; i
< pos
+ n
; i
++)
2402 newRowHeights
[i
] = wxGRID_DEFAULT_CELL_HEIGHT
;
2403 for (i
= pos
+ n
; i
< m_totalRows
+ n
; i
++)
2404 newRowHeights
[i
] = m_rowHeights
[i
- n
];
2405 delete[] m_rowHeights
;
2406 m_rowHeights
= newRowHeights
;
2409 wxGridCell
**newLabels
= new wxGridCell
*[m_totalRows
+ n
];
2410 for (i
= 0; i
< pos
; i
++)
2411 newLabels
[i
] = m_rowLabelCells
[i
];
2412 for (i
= pos
; i
< pos
+ n
; i
++)
2413 newLabels
[i
] = new wxGridCell(this);
2414 for (i
= pos
+ n
; i
< m_totalRows
+ n
; i
++)
2415 newLabels
[i
] = m_rowLabelCells
[i
- n
];
2417 delete[] m_rowLabelCells
;
2418 m_rowLabelCells
= newLabels
;
2424 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2425 GetEventHandler()->ProcessEvent(g_evt
);
2434 bool wxGenericGrid::AppendCols(int n
, bool updateLabels
)
2436 return InsertCols(GetCols(), n
, updateLabels
);
2439 bool wxGenericGrid::AppendRows(int n
, bool updateLabels
)
2441 return InsertRows(GetRows(), n
, updateLabels
);
2444 bool wxGenericGrid::DeleteRows(int pos
, int n
, bool updateLabels
)
2446 if (pos
> m_totalRows
)
2453 wxGridCell
***rows
= new wxGridCell
**[m_totalRows
- n
];
2456 for (i
= 0; i
< pos
; i
++)
2457 rows
[i
] = m_gridCells
[i
];
2459 for (i
= pos
+ n
; i
< m_totalRows
; i
++)
2460 rows
[i
-n
] = m_gridCells
[i
];
2462 delete[] m_gridCells
;
2466 short *newRowHeights
= new short[m_totalRows
- n
];
2467 for (i
= 0; i
< pos
; i
++)
2468 newRowHeights
[i
] = m_rowHeights
[i
];
2469 for (i
= pos
+ n
; i
< m_totalRows
; i
++)
2470 newRowHeights
[i
-n
] = m_rowHeights
[i
];
2471 delete[] m_rowHeights
;
2472 m_rowHeights
= newRowHeights
;
2475 wxGridCell
**newLabels
= new wxGridCell
*[m_totalRows
- n
];
2476 for (i
= 0; i
< pos
; i
++)
2477 newLabels
[i
] = m_rowLabelCells
[i
];
2478 for (i
= pos
+ n
; i
< m_totalRows
; i
++)
2479 newLabels
[i
-n
] = m_rowLabelCells
[i
];
2481 delete[] m_rowLabelCells
;
2482 m_rowLabelCells
= newLabels
;
2488 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2489 GetEventHandler()->ProcessEvent(g_evt
);
2496 bool wxGenericGrid::DeleteCols(int pos
, int n
, bool updateLabels
)
2498 if (pos
+ n
> m_totalCols
)
2506 for (i
= 0; i
< m_totalRows
; i
++)
2508 wxGridCell
**cols
= m_gridCells
[i
];
2509 wxGridCell
**newCols
= new wxGridCell
*[m_totalCols
- n
];
2510 for (j
= 0; j
< pos
; j
++)
2511 newCols
[j
] = cols
[j
];
2512 for (j
= pos
; j
< pos
+ n
; j
++)
2514 for (j
= pos
+ n
; j
< m_totalCols
; j
++)
2515 newCols
[j
-n
] = cols
[j
];
2518 m_gridCells
[i
] = newCols
;
2522 short *newColWidths
= new short[m_totalCols
- n
];
2523 for (j
= 0; j
< pos
; j
++)
2524 newColWidths
[j
] = m_colWidths
[j
];
2525 for (j
= pos
+ n
; j
< m_totalCols
; j
++)
2526 newColWidths
[j
-n
] = m_colWidths
[j
];
2527 delete[] m_colWidths
;
2528 m_colWidths
= newColWidths
;
2531 wxGridCell
**newLabels
= new wxGridCell
*[m_totalCols
- n
];
2532 for (j
= 0; j
< pos
; j
++)
2533 newLabels
[j
] = m_colLabelCells
[j
];
2534 for (j
= pos
+ n
; j
< m_totalCols
; j
++)
2535 newLabels
[j
-n
] = m_colLabelCells
[j
];
2537 delete[] m_colLabelCells
;
2538 m_colLabelCells
= newLabels
;
2544 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this);
2545 GetEventHandler()->ProcessEvent(g_evt
);
2552 void wxGenericGrid::SetGridCursor(int row
, int col
)
2554 if (row
>= m_totalRows
|| col
>= m_totalCols
)
2557 if (row
== GetCursorRow() && col
== GetCursorColumn())
2560 wxClientDC
dc(this);
2563 SetGridClippingRegion(& dc
);
2565 if (m_currentRectVisible
&& (wxIPE_HIGHLIGHT
|| !(m_editable
&& m_editInPlace
)))
2566 HighlightCell(& dc
, FALSE
);
2569 m_wCursorColumn
= col
;
2572 GetClientSize(&cw
, &ch
);
2574 SetCurrentRect(row
, col
, cw
, ch
);
2576 if (m_currentRectVisible
&& (wxIPE_HIGHLIGHT
|| !(m_editable
&& m_editInPlace
)))
2577 HighlightCell(& dc
, TRUE
);
2579 dc
.DestroyClippingRegion();
2583 // ----------------------------------------------------------------------------
2585 // ----------------------------------------------------------------------------
2587 wxGridCell::wxGridCell(wxGenericGrid
*window
)
2589 cellBitmap
= (wxBitmap
*) NULL
;
2591 backgroundBrush
= wxNullBrush
;
2593 textColour
= window
->GetCellTextColour();
2595 textColour
.Set(0,0,0);
2597 backgroundColour
= window
->GetCellBackgroundColour();
2599 backgroundColour
.Set(255,255,255);
2602 font
= window
->GetCellTextFont();
2604 font
= * wxTheFontList
->FindOrCreateFont(12, wxSWISS
, wxNORMAL
, wxNORMAL
);
2606 SetBackgroundColour(backgroundColour
);
2609 alignment
= window
->GetCellAlignment();
2613 cellData
= (void *)NULL
;
2616 wxGridCell::~wxGridCell()
2620 void wxGridCell::SetBackgroundColour(const wxColour
& colour
)
2622 backgroundColour
= colour
;
2623 backgroundBrush
= * wxTheBrushList
->FindOrCreateBrush(backgroundColour
, wxSOLID
);
2626 void wxGenericGrid::OnText(wxCommandEvent
& WXUNUSED(ev
) )
2628 // michael - added this conditional to prevent change to
2629 // grid cell text when edit control is hidden but still has
2634 wxGenericGrid
*grid
= this;
2635 wxGridCell
*cell
= grid
->GetCell(grid
->GetCursorRow(), grid
->GetCursorColumn());
2636 if (cell
&& grid
->CurrentCellVisible())
2638 cell
->SetTextValue(grid
->GetTextItem()->GetValue());
2639 if ( m_editInPlace
&& !m_inOnTextInPlace
)
2641 m_inPlaceTextItem
->SetValue( grid
->GetTextItem()->GetValue() );
2644 if (!m_editInPlace
) {
2645 wxClientDC
dc(grid
);
2648 grid
->SetGridClippingRegion(& dc
);
2649 grid
->DrawCellBackground(& dc
, &grid
->GetCurrentRect(), grid
->GetCursorRow(), grid
->GetCursorColumn());
2650 grid
->DrawCellValue(& dc
, &grid
->GetCurrentRect(), grid
->GetCursorRow(), grid
->GetCursorColumn());
2651 grid
->HighlightCell(& dc
, TRUE
);
2652 dc
.DestroyClippingRegion();
2656 //grid->OnCellChange(grid->GetCursorRow(), grid->GetCursorColumn());
2657 wxGridEvent
g_evt(GetId(), wxEVT_GRID_CELL_CHANGE
, grid
,
2658 grid
->GetCursorRow(), grid
->GetCursorColumn());
2659 GetEventHandler()->ProcessEvent(g_evt
);
2661 // grid->DrawCellText();
2666 void wxGenericGrid::OnTextEnter(wxCommandEvent
& WXUNUSED(ev
) )
2668 // move the cursor down the current row (if possible)
2669 // when the enter key has been pressed
2673 if ( GetCursorRow() < GetRows()-1 )
2675 wxClientDC
dc( this );
2677 OnSelectCellImplementation(& dc
,
2679 GetCursorColumn() );
2685 void wxGenericGrid::OnTextInPlace(wxCommandEvent
& ev
)
2689 wxGenericGrid
*grid
= this;
2690 wxGridCell
*cell
= grid
->GetCell(grid
->GetCursorRow(), grid
->GetCursorColumn());
2691 if (cell
&& grid
->CurrentCellVisible())
2693 m_inOnTextInPlace
= TRUE
;
2694 grid
->GetTextItem()->SetValue( m_inPlaceTextItem
->GetValue() );
2696 m_inOnTextInPlace
= FALSE
;
2701 void wxGenericGrid::OnTextInPlaceEnter(wxCommandEvent
& WXUNUSED(ev
) )
2703 // move the cursor down the current row (if possible)
2704 // when the enter key has been pressed
2708 if ( GetCursorRow() < GetRows()-1 )
2710 wxClientDC
dc( this );
2712 OnSelectCellImplementation(& dc
,
2714 GetCursorColumn() );
2720 void wxGenericGrid::OnGridScroll(wxScrollEvent
& ev
)
2725 if ( m_editInPlace
) m_inPlaceTextItem
->Show(FALSE
);
2728 wxGenericGrid
*win
= this;
2730 bool change
= FALSE
;
2732 if (ev
.GetEventObject() == win
->GetHorizScrollBar())
2734 change
= (ev
.GetPosition() != m_scrollPosX
);
2735 win
->SetScrollPosX(ev
.GetPosition());
2739 change
= (ev
.GetPosition() != m_scrollPosY
);
2740 win
->SetScrollPosY(ev
.GetPosition());
2743 win
->UpdateDimensions();
2745 win
->SetCurrentRect(win
->GetCursorRow(), win
->GetCursorColumn());
2747 // Because rows and columns can be arbitrary sizes,
2748 // the scrollbars will need to be adjusted to reflect the
2752 if (change
) win
->Refresh(FALSE
);
2754 if ( m_editInPlace
&& m_currentRectVisible
)
2756 m_inPlaceTextItem
->SetSize( m_currentRect
.x
-wxIPE_ADJUST
,
2757 m_currentRect
.y
-wxIPE_ADJUST
,
2758 m_currentRect
.width
+wxIPE_ADJUST
*2,
2759 m_currentRect
.height
+wxIPE_ADJUST
*2 );
2760 m_inPlaceTextItem
->Show( TRUE
);
2761 m_inPlaceTextItem
->SetFocus();
2769 //----------------------------------------------------------------------
2770 // Default wxGridEvent handlers
2771 // (just redirect to the pre-existing virtual methods)
2773 void wxGenericGrid::_OnSelectCell(wxGridEvent
& ev
)
2775 OnSelectCell(ev
.m_row
, ev
.m_col
);
2778 void wxGenericGrid::_OnCreateCell(wxGridEvent
& ev
)
2780 ev
.m_cell
= OnCreateCell();
2783 void wxGenericGrid::_OnChangeLabels(wxGridEvent
& WXUNUSED(ev
))
2788 void wxGenericGrid::_OnChangeSelectionLabel(wxGridEvent
& WXUNUSED(ev
))
2790 OnChangeSelectionLabel();
2793 void wxGenericGrid::_OnCellChange(wxGridEvent
& ev
)
2795 OnCellChange(ev
.m_row
, ev
.m_col
);
2798 void wxGenericGrid::_OnCellLeftClick(wxGridEvent
& ev
)
2800 OnCellLeftClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2803 void wxGenericGrid::_OnCellRightClick(wxGridEvent
& ev
)
2805 OnCellRightClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2808 void wxGenericGrid::_OnLabelLeftClick(wxGridEvent
& ev
)
2810 OnLabelLeftClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2813 void wxGenericGrid::_OnLabelRightClick(wxGridEvent
& ev
)
2815 OnLabelRightClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);
2818 void *wxGenericGrid::SetCellData(void *data
, int row
, int col
)
2822 wxGridCell
*cell
= GetCell(row
, col
);
2824 rc
= cell
->SetCellData(data
);
2829 void *wxGenericGrid::GetCellData(int row
, int col
)
2833 wxGridCell
*cell
= GetCell(row
, col
);
2835 rc
= cell
->GetCellData();