1 ////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxGrid and related classes
4 // Author: Michael Bedward (based on code by Julian Smart, Robin Dunn)
8 // Copyright: (c) Michael Bedward (mbedward@ozemail.com.au)
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "grid.h"
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
25 #if !defined(wxUSE_NEW_GRID) || !(wxUSE_NEW_GRID)
31 #include "wx/dcclient.h"
32 #include "wx/settings.h"
36 #include "wx/generic/grid.h"
39 //////////////////////////////////////////////////////////////////////
41 wxGridCellCoords
wxGridNoCellCoords( -1, -1 );
42 wxRect
wxGridNoCellRect( -1, -1, -1, -1 );
46 //////////////////////////////////////////////////////////////////////
48 // Abstract base class for grid data (the model)
50 IMPLEMENT_ABSTRACT_CLASS( wxGridTableBase
, wxObject
)
53 wxGridTableBase::wxGridTableBase()
56 m_view
= (wxGrid
*) NULL
;
59 wxGridTableBase::~wxGridTableBase()
64 bool wxGridTableBase::InsertRows( size_t pos
, size_t numRows
)
66 wxLogWarning( wxT("Called grid table class function InsertRows(pos=%d, N=%d)\n"
67 "but your derived table class does not override this function"),
73 bool wxGridTableBase::AppendRows( size_t numRows
)
75 wxLogWarning( wxT("Called grid table class function AppendRows(N=%d)\n"
76 "but your derived table class does not override this function"),
82 bool wxGridTableBase::DeleteRows( size_t pos
, size_t numRows
)
84 wxLogWarning( wxT("Called grid table class function DeleteRows(pos=%d, N=%d)\n"
85 "but your derived table class does not override this function"),
91 bool wxGridTableBase::InsertCols( size_t pos
, size_t numCols
)
93 wxLogWarning( wxT("Called grid table class function InsertCols(pos=%d, N=%d)\n"
94 "but your derived table class does not override this function"),
100 bool wxGridTableBase::AppendCols( size_t numCols
)
102 wxLogWarning( wxT("Called grid table class function AppendCols(N=%d)\n"
103 "but your derived table class does not override this function"),
109 bool wxGridTableBase::DeleteCols( size_t pos
, size_t numCols
)
111 wxLogWarning( wxT("Called grid table class function DeleteCols(pos=%d, N=%d)\n"
112 "but your derived table class does not override this function"),
119 wxString
wxGridTableBase::GetRowLabelValue( int row
)
126 wxString
wxGridTableBase::GetColLabelValue( int col
)
128 // default col labels are:
129 // cols 0 to 25 : A-Z
130 // cols 26 to 675 : AA-ZZ
137 s
+= ('A' + (char)( col%26
));
139 if ( col
< 0 ) break;
142 // reverse the string...
144 for ( i
= 0; i
< n
; i
++ )
154 //////////////////////////////////////////////////////////////////////
156 // Message class for the grid table to send requests and notifications
160 wxGridTableMessage::wxGridTableMessage()
162 m_table
= (wxGridTableBase
*) NULL
;
168 wxGridTableMessage::wxGridTableMessage( wxGridTableBase
*table
, int id
,
169 int commandInt1
, int commandInt2
)
173 m_comInt1
= commandInt1
;
174 m_comInt2
= commandInt2
;
179 //////////////////////////////////////////////////////////////////////
181 // A basic grid table for string data. An object of this class will
182 // created by wxGrid if you don't specify an alternative table class.
186 // this is a magic incantation which must be done!
187 #include <wx/arrimpl.cpp>
189 WX_DEFINE_OBJARRAY(wxGridStringArray
)
191 IMPLEMENT_DYNAMIC_CLASS( wxGridStringTable
, wxGridTableBase
)
193 wxGridStringTable::wxGridStringTable()
198 wxGridStringTable::wxGridStringTable( int numRows
, int numCols
)
203 m_data
.Alloc( numRows
);
207 for ( col
= 0; col
< numCols
; col
++ )
209 sa
.Add( wxEmptyString
);
212 for ( row
= 0; row
< numRows
; row
++ )
218 wxGridStringTable::~wxGridStringTable()
222 long wxGridStringTable::GetNumberRows()
224 return m_data
.GetCount();
227 long wxGridStringTable::GetNumberCols()
229 if ( m_data
.GetCount() > 0 )
230 return m_data
[0].GetCount();
235 wxString
wxGridStringTable::GetValue( int row
, int col
)
237 // TODO: bounds checking
239 return m_data
[row
][col
];
242 void wxGridStringTable::SetValue( int row
, int col
, const wxString
& s
)
244 // TODO: bounds checking
246 m_data
[row
][col
] = s
;
249 bool wxGridStringTable::IsEmptyCell( int row
, int col
)
251 // TODO: bounds checking
253 return (m_data
[row
][col
] == wxEmptyString
);
257 void wxGridStringTable::Clear()
260 int numRows
, numCols
;
262 numRows
= m_data
.GetCount();
265 numCols
= m_data
[0].GetCount();
267 for ( row
= 0; row
< numRows
; row
++ )
269 for ( col
= 0; col
< numCols
; col
++ )
271 m_data
[row
][col
] = wxEmptyString
;
278 bool wxGridStringTable::InsertRows( size_t pos
, size_t numRows
)
282 size_t curNumRows
= m_data
.GetCount();
283 size_t curNumCols
= ( curNumRows
> 0 ? m_data
[0].GetCount() : 0 );
285 if ( pos
>= curNumRows
)
287 return AppendRows( numRows
);
291 sa
.Alloc( curNumCols
);
292 for ( col
= 0; col
< curNumCols
; col
++ )
294 sa
.Add( wxEmptyString
);
297 for ( row
= pos
; row
< pos
+ numRows
; row
++ )
299 m_data
.Insert( sa
, row
);
304 wxGridTableMessage
msg( this,
305 wxGRIDTABLE_NOTIFY_ROWS_INSERTED
,
309 GetView()->ProcessTableMessage( msg
);
315 bool wxGridStringTable::AppendRows( size_t numRows
)
319 size_t curNumRows
= m_data
.GetCount();
320 size_t curNumCols
= ( curNumRows
> 0 ? m_data
[0].GetCount() : 0 );
323 if ( curNumCols
> 0 )
325 sa
.Alloc( curNumCols
);
326 for ( col
= 0; col
< curNumCols
; col
++ )
328 sa
.Add( wxEmptyString
);
332 for ( row
= 0; row
< numRows
; row
++ )
339 wxGridTableMessage
msg( this,
340 wxGRIDTABLE_NOTIFY_ROWS_APPENDED
,
343 GetView()->ProcessTableMessage( msg
);
349 bool wxGridStringTable::DeleteRows( size_t pos
, size_t numRows
)
353 size_t curNumRows
= m_data
.GetCount();
355 if ( pos
>= curNumRows
)
357 wxLogError( wxT("Called wxGridStringTable::DeleteRows(pos=%d, N=%d)...\n"
358 "Pos value is invalid for present table with %d rows"),
359 pos
, numRows
, curNumRows
);
363 if ( numRows
> curNumRows
- pos
)
365 numRows
= curNumRows
- pos
;
368 if ( numRows
>= curNumRows
)
370 m_data
.Empty(); // don't release memory just yet
374 for ( n
= 0; n
< numRows
; n
++ )
376 m_data
.Remove( pos
);
382 wxGridTableMessage
msg( this,
383 wxGRIDTABLE_NOTIFY_ROWS_DELETED
,
387 GetView()->ProcessTableMessage( msg
);
393 bool wxGridStringTable::InsertCols( size_t pos
, size_t numCols
)
397 size_t curNumRows
= m_data
.GetCount();
398 size_t curNumCols
= ( curNumRows
> 0 ? m_data
[0].GetCount() : 0 );
400 if ( pos
>= curNumCols
)
402 return AppendCols( numCols
);
405 for ( row
= 0; row
< curNumRows
; row
++ )
407 for ( col
= pos
; col
< pos
+ numCols
; col
++ )
409 m_data
[row
].Insert( wxEmptyString
, col
);
415 wxGridTableMessage
msg( this,
416 wxGRIDTABLE_NOTIFY_COLS_INSERTED
,
420 GetView()->ProcessTableMessage( msg
);
426 bool wxGridStringTable::AppendCols( size_t numCols
)
430 size_t curNumRows
= m_data
.GetCount();
433 // TODO: something better than this ?
435 wxLogError( wxT("Unable to append cols to a grid table with no rows.\n"
436 "Call AppendRows() first") );
440 for ( row
= 0; row
< curNumRows
; row
++ )
442 for ( n
= 0; n
< numCols
; n
++ )
444 m_data
[row
].Add( wxEmptyString
);
450 wxGridTableMessage
msg( this,
451 wxGRIDTABLE_NOTIFY_COLS_APPENDED
,
454 GetView()->ProcessTableMessage( msg
);
460 bool wxGridStringTable::DeleteCols( size_t pos
, size_t numCols
)
464 size_t curNumRows
= m_data
.GetCount();
465 size_t curNumCols
= ( curNumRows
> 0 ? m_data
[0].GetCount() : 0 );
467 if ( pos
>= curNumCols
)
469 wxLogError( wxT("Called wxGridStringTable::DeleteCols(pos=%d, N=%d)...\n"
470 "Pos value is invalid for present table with %d cols"),
471 pos
, numCols
, curNumCols
);
475 if ( numCols
> curNumCols
- pos
)
477 numCols
= curNumCols
- pos
;
480 for ( row
= 0; row
< curNumRows
; row
++ )
482 if ( numCols
>= curNumCols
)
488 for ( n
= 0; n
< numCols
; n
++ )
490 m_data
[row
].Remove( pos
);
497 wxGridTableMessage
msg( this,
498 wxGRIDTABLE_NOTIFY_COLS_DELETED
,
502 GetView()->ProcessTableMessage( msg
);
508 wxString
wxGridStringTable::GetRowLabelValue( int row
)
510 if ( row
> (int)(m_rowLabels
.GetCount()) - 1 )
512 // using default label
514 return wxGridTableBase::GetRowLabelValue( row
);
518 return m_rowLabels
[ row
];
522 wxString
wxGridStringTable::GetColLabelValue( int col
)
524 if ( col
> (int)(m_colLabels
.GetCount()) - 1 )
526 // using default label
528 return wxGridTableBase::GetColLabelValue( col
);
532 return m_colLabels
[ col
];
536 void wxGridStringTable::SetRowLabelValue( int row
, const wxString
& value
)
538 if ( row
> (int)(m_rowLabels
.GetCount()) - 1 )
540 int n
= m_rowLabels
.GetCount();
542 for ( i
= n
; i
<= row
; i
++ )
544 m_rowLabels
.Add( wxGridTableBase::GetRowLabelValue(i
) );
548 m_rowLabels
[row
] = value
;
551 void wxGridStringTable::SetColLabelValue( int col
, const wxString
& value
)
553 if ( col
> (int)(m_colLabels
.GetCount()) - 1 )
555 int n
= m_colLabels
.GetCount();
557 for ( i
= n
; i
<= col
; i
++ )
559 m_colLabels
.Add( wxGridTableBase::GetColLabelValue(i
) );
563 m_colLabels
[col
] = value
;
569 //////////////////////////////////////////////////////////////////////
571 IMPLEMENT_DYNAMIC_CLASS( wxGridTextCtrl
, wxTextCtrl
)
573 BEGIN_EVENT_TABLE( wxGridTextCtrl
, wxTextCtrl
)
574 EVT_KEY_DOWN( wxGridTextCtrl::OnKeyDown
)
578 wxGridTextCtrl::wxGridTextCtrl( wxWindow
*par
,
581 const wxString
& value
,
585 : wxTextCtrl( par
, id
, value
, pos
, size
, style
)
587 m_isCellControl
= isCellControl
;
591 void wxGridTextCtrl::OnKeyDown( wxKeyEvent
& ev
)
593 switch ( ev
.KeyCode() )
596 ((wxGrid
*)GetParent())->SetEditControlValue( startValue
);
597 SetInsertionPointEnd();
607 if ( m_isCellControl
)
609 // send the event to the parent grid, skipping the
610 // event if nothing happens
612 ev
.Skip( !GetParent()->ProcessEvent( ev
) );
616 // default text control response within the top edit
625 if ( m_isCellControl
)
627 // send the event to the parent grid, skipping the
628 // event if nothing happens
630 ev
.Skip( !GetParent()->ProcessEvent( ev
) );
634 // default text control response within the top edit
646 void wxGridTextCtrl::SetStartValue( const wxString
& s
)
649 wxTextCtrl::SetValue( s
.c_str() );
653 //////////////////////////////////////////////////////////////////////
655 IMPLEMENT_DYNAMIC_CLASS( wxGrid
, wxPanel
)
658 BEGIN_EVENT_TABLE( wxGrid
, wxPanel
)
659 EVT_PAINT( wxGrid::OnPaint
)
660 EVT_SIZE( wxGrid::OnSize
)
661 EVT_MOUSE_EVENTS( wxGrid::OnMouse
)
662 EVT_KEY_DOWN( wxGrid::OnKeyDown
)
663 EVT_TEXT( wxGRID_CELLCTRL
, wxGrid::OnText
)
664 EVT_TEXT( wxGRID_TOPCTRL
, wxGrid::OnText
)
665 EVT_COMMAND_SCROLL( wxGRID_HORIZSCROLL
, wxGrid::OnGridScroll
)
666 EVT_COMMAND_SCROLL( wxGRID_VERTSCROLL
, wxGrid::OnGridScroll
)
677 // ----- internal init and update functions
680 void wxGrid::Create()
682 m_table
= (wxGridTableBase
*) NULL
;
683 m_topEditCtrl
= (wxWindow
*) NULL
;
684 m_cellEditCtrl
= (wxWindow
*) NULL
;
685 m_horizScrollBar
= (wxScrollBar
*) NULL
;
686 m_vertScrollBar
= (wxScrollBar
*) NULL
;
700 // TODO: perhaps have a style flag for control panel
702 m_topEditCtrlEnabled
= FALSE
;
703 m_topEditCtrl
= new wxGridTextCtrl( this,
708 wxSize(WXGRID_DEFAULT_TOPEDIT_WIDTH
,
709 WXGRID_DEFAULT_TOPEDIT_HEIGHT
),
711 m_topEditCtrl
->Show( FALSE
);
713 if ( m_numRows
<= 0 )
714 m_numRows
= WXGRID_DEFAULT_NUMBER_ROWS
;
716 if ( m_numCols
<= 0 )
717 m_numCols
= WXGRID_DEFAULT_NUMBER_COLS
;
719 m_rowLabelWidth
= WXGRID_DEFAULT_ROW_LABEL_WIDTH
;
720 m_colLabelHeight
= WXGRID_DEFAULT_COL_LABEL_HEIGHT
;
722 // default labels are pale grey with black text
724 m_labelBackgroundColour
= wxColour( 192, 192, 192 );
725 m_labelTextColour
= wxColour( 0, 0, 0 );
727 // TODO: something better than this ?
729 m_labelFont
= this->GetFont();
730 m_labelFont
.SetWeight( m_labelFont
.GetWeight() + 2 );
732 m_rowLabelHorizAlign
= wxLEFT
;
733 m_rowLabelVertAlign
= wxCENTRE
;
735 m_colLabelHorizAlign
= wxCENTRE
;
736 m_colLabelVertAlign
= wxTOP
;
738 m_defaultRowHeight
= WXGRID_DEFAULT_ROW_HEIGHT
;
739 m_defaultColWidth
= WXGRID_DEFAULT_COL_WIDTH
;
741 m_rowHeights
.Alloc( m_numRows
);
742 m_rowBottoms
.Alloc( m_numRows
);
743 for ( i
= 0; i
< m_numRows
; i
++ )
745 m_rowHeights
.Add( m_defaultRowHeight
);
746 m_rowBottoms
.Add( 0 ); // set by CalcDimensions()
749 m_colWidths
.Alloc( m_numCols
);
750 m_colRights
.Alloc( m_numRows
);
751 for ( i
= 0; i
< m_numCols
; i
++ )
753 m_colWidths
.Add( m_defaultColWidth
);
754 m_colRights
.Add( 0 ); // set by CalcDimensions()
757 // TODO: improve this ?
759 m_defaultCellFont
= this->GetFont();
761 m_gridLineColour
= wxColour( 0, 0, 255 );
762 m_gridLinesEnabled
= TRUE
;
764 m_scrollBarWidth
= WXGRID_DEFAULT_SCROLLBAR_WIDTH
;
766 m_horizScrollBar
= new wxScrollBar( this,
772 m_vertScrollBar
= new wxScrollBar( this,
779 m_wholeColsVisible
= 0;
780 m_wholeRowsVisible
= 0;
783 m_inOnKeyDown
= FALSE
;
786 m_cursorMode
= WXGRID_CURSOR_DEFAULT
;
789 m_isDragging
= FALSE
;
791 m_rowResizeCursor
= wxCursor( wxCURSOR_SIZENS
);
792 m_colResizeCursor
= wxCursor( wxCURSOR_SIZEWE
);
794 m_currentCellCoords
= wxGridNoCellCoords
;
795 m_currentCellHighlighted
= FALSE
;
797 m_selectedTopLeft
= wxGridNoCellCoords
;
798 m_selectedBottomRight
= wxGridNoCellCoords
;
800 m_editable
= TRUE
; // default for whole grid
802 // TODO: extend this to other types of controls
804 m_cellEditCtrl
= new wxGridTextCtrl( this,
811 , wxTE_MULTILINE
| wxTE_NO_VSCROLL
815 m_cellEditCtrl
->Show( FALSE
);
816 m_cellEditCtrlEnabled
= TRUE
;
817 m_editCtrlType
= wxGRID_TEXTCTRL
;
819 // This is here in case OnSize does not get called when the grid is
826 void wxGrid::CalcDimensions()
830 if ( IsTopEditControlEnabled() )
833 m_topEditCtrl
->GetSize( &ctrlW
, &ctrlH
);
842 int bottom
= m_top
+ m_colLabelHeight
;
843 for ( i
= m_scrollPosY
; i
< m_numRows
; i
++ )
845 bottom
+= m_rowHeights
[i
];
846 m_rowBottoms
[i
] = bottom
;
849 int right
= m_left
+ m_rowLabelWidth
;
850 for ( i
= m_scrollPosX
; i
< m_numCols
; i
++ )
852 right
+= m_colWidths
[i
];
853 m_colRights
[i
] = right
;
856 // adjust the scroll bars
860 GetClientSize(&cw
, &ch
);
862 // begin by assuming that we don't need either scroll bar
864 int vertScrollBarWidth
= 0;
865 int horizScrollBarHeight
= 0;
867 // Each scroll bar needs to eventually know if the other one is
868 // required in deciding whether or not it is also required - hence
869 // this loop. A bit inelegant but simple and it works.
872 for ( check
= 0; check
< 2; check
++ )
874 if ( m_numRows
> 0 &&
875 m_rowBottoms
[m_numRows
-1] + horizScrollBarHeight
> ch
)
877 vertScrollBarWidth
= m_scrollBarWidth
;
879 m_wholeRowsVisible
= 0;
880 for ( i
= m_scrollPosY
; i
< m_numRows
; i
++ )
882 // A partial row doesn't count, we still have to scroll to
883 // see the rest of it
884 if ( m_rowBottoms
[i
] + horizScrollBarHeight
> ch
) break;
886 m_wholeRowsVisible
++ ;
891 m_wholeRowsVisible
= m_numRows
- m_scrollPosY
;
894 vertScrollBarWidth
= m_scrollBarWidth
;
900 m_colRights
[m_numCols
-1] + vertScrollBarWidth
> cw
)
902 horizScrollBarHeight
= m_scrollBarWidth
;
904 m_wholeColsVisible
= 0;
905 for ( i
= m_scrollPosX
; i
< m_numCols
; i
++ )
907 // A partial col doesn't count, we still have to scroll to
908 // see the rest of it
909 if ( m_colRights
[i
] + vertScrollBarWidth
> cw
) break;
911 m_wholeColsVisible
++ ;
916 // we can see the right-most column
918 m_wholeColsVisible
= m_numCols
- m_scrollPosX
;
921 horizScrollBarHeight
= m_scrollBarWidth
;
927 if ( m_vertScrollBar
)
929 if ( !vertScrollBarWidth
)
931 m_vertScrollBar
->Show(FALSE
);
935 m_vertScrollBar
->Show(TRUE
);
936 m_vertScrollBar
->SetScrollbar(
938 wxMax(m_wholeRowsVisible
, 1),
939 (m_wholeRowsVisible
== 0 ? 1 : m_numRows
),
940 wxMax(m_wholeRowsVisible
, 1) );
942 m_vertScrollBar
->SetSize( cw
- m_scrollBarWidth
,
945 ch
- m_top
- horizScrollBarHeight
);
949 if ( m_horizScrollBar
)
951 if ( !horizScrollBarHeight
)
953 m_horizScrollBar
->Show(FALSE
);
957 m_horizScrollBar
->Show(TRUE
);
959 m_horizScrollBar
->SetScrollbar(
961 wxMax(m_wholeColsVisible
, 1),
962 (m_wholeColsVisible
== 0) ? 1 : m_numCols
,
963 wxMax(m_wholeColsVisible
, 1) );
965 m_horizScrollBar
->SetSize( m_left
,
966 ch
- m_scrollBarWidth
,
967 cw
- m_left
- vertScrollBarWidth
,
972 m_bottom
= m_right
= 0;
975 m_bottom
= wxMin( m_rowBottoms
[m_numRows
-1],
976 ch
- horizScrollBarHeight
);
980 m_right
= wxMin( m_colRights
[m_numCols
-1],
981 cw
- vertScrollBarWidth
);
986 bool wxGrid::IsOnScreen()
989 GetClientSize( &cw
, &ch
);
994 // this is called when the grid table sends a message to say that it
995 // has been redimensioned
997 bool wxGrid::Redimension( wxGridTableMessage
& msg
)
1001 switch ( msg
.GetId() )
1003 case wxGRIDTABLE_NOTIFY_ROWS_INSERTED
:
1005 size_t pos
= msg
.GetCommandInt();
1006 int numRows
= msg
.GetCommandInt2();
1007 for ( i
= 0; i
< numRows
; i
++ )
1009 m_rowHeights
.Insert( m_defaultRowHeight
, pos
);
1010 m_rowBottoms
.Insert( 0, pos
);
1012 m_numRows
+= numRows
;
1017 case wxGRIDTABLE_NOTIFY_ROWS_APPENDED
:
1019 int numRows
= msg
.GetCommandInt();
1020 for ( i
= 0; i
< numRows
; i
++ )
1022 m_rowHeights
.Add( m_defaultRowHeight
);
1023 m_rowBottoms
.Add( 0 );
1025 m_numRows
+= numRows
;
1030 case wxGRIDTABLE_NOTIFY_ROWS_DELETED
:
1032 size_t pos
= msg
.GetCommandInt();
1033 int numRows
= msg
.GetCommandInt2();
1034 for ( i
= 0; i
< numRows
; i
++ )
1036 m_rowHeights
.Remove( pos
);
1037 m_rowBottoms
.Remove( pos
);
1039 m_numRows
-= numRows
;
1041 // TODO: improve these adjustments...
1043 if ( m_scrollPosY
>= m_numRows
)
1049 m_colWidths
.Clear();
1050 m_colRights
.Clear();
1051 m_currentCellCoords
= wxGridNoCellCoords
;
1053 else if ( m_currentCellCoords
.GetRow() >= m_numRows
)
1055 m_currentCellCoords
.Set( 0, 0 );
1061 case wxGRIDTABLE_NOTIFY_COLS_INSERTED
:
1063 size_t pos
= msg
.GetCommandInt();
1064 int numCols
= msg
.GetCommandInt2();
1065 for ( i
= 0; i
< numCols
; i
++ )
1067 m_colWidths
.Insert( m_defaultColWidth
, pos
);
1068 m_colRights
.Insert( 0, pos
);
1070 m_numCols
+= numCols
;
1075 case wxGRIDTABLE_NOTIFY_COLS_APPENDED
:
1077 int numCols
= msg
.GetCommandInt();
1078 for ( i
= 0; i
< numCols
; i
++ )
1080 m_colWidths
.Add( m_defaultColWidth
);
1081 m_colRights
.Add( 0 );
1083 m_numCols
+= numCols
;
1088 case wxGRIDTABLE_NOTIFY_COLS_DELETED
:
1090 size_t pos
= msg
.GetCommandInt();
1091 int numCols
= msg
.GetCommandInt2();
1092 for ( i
= 0; i
< numCols
; i
++ )
1094 m_colWidths
.Remove( pos
);
1095 m_colRights
.Remove( pos
);
1097 m_numCols
-= numCols
;
1099 // TODO: improve these adjustments...
1101 if ( m_scrollPosX
>= m_numCols
)
1106 #if 0 // leave the row alone here so that AppendCols will work subsequently
1108 m_rowHeights
.Clear();
1109 m_rowBottoms
.Clear();
1111 m_currentCellCoords
= wxGridNoCellCoords
;
1113 else if ( m_currentCellCoords
.GetCol() >= m_numCols
)
1115 m_currentCellCoords
.Set( 0, 0 );
1127 // ----- event handlers
1130 // Generate a grid event based on a mouse event and
1131 // return the result of ProcessEvent()
1133 bool wxGrid::SendEvent( const wxEventType type
,
1135 wxMouseEvent
& mouseEv
)
1137 if ( type
== EVT_GRID_ROW_SIZE
||
1138 type
== EVT_GRID_COL_SIZE
)
1140 int rowOrCol
= (row
== -1 ? col
: row
);
1142 wxGridSizeEvent
gridEvt( GetId(),
1146 mouseEv
.GetX(), mouseEv
.GetY(),
1147 mouseEv
.ControlDown(),
1148 mouseEv
.ShiftDown(),
1150 mouseEv
.MetaDown() );
1152 return GetEventHandler()->ProcessEvent(gridEvt
);
1154 else if ( type
== EVT_GRID_RANGE_SELECT
)
1156 wxGridRangeSelectEvent
gridEvt( GetId(),
1160 m_selectedBottomRight
,
1161 mouseEv
.ControlDown(),
1162 mouseEv
.ShiftDown(),
1164 mouseEv
.MetaDown() );
1166 return GetEventHandler()->ProcessEvent(gridEvt
);
1170 wxGridEvent
gridEvt( GetId(),
1174 mouseEv
.GetX(), mouseEv
.GetY(),
1175 mouseEv
.ControlDown(),
1176 mouseEv
.ShiftDown(),
1178 mouseEv
.MetaDown() );
1180 return GetEventHandler()->ProcessEvent(gridEvt
);
1185 // Generate a grid event of specified type and return the result
1186 // of ProcessEvent().
1188 bool wxGrid::SendEvent( const wxEventType type
,
1191 if ( type
== EVT_GRID_ROW_SIZE
||
1192 type
== EVT_GRID_COL_SIZE
)
1194 int rowOrCol
= (row
== -1 ? col
: row
);
1196 wxGridSizeEvent
gridEvt( GetId(),
1201 return GetEventHandler()->ProcessEvent(gridEvt
);
1205 wxGridEvent
gridEvt( GetId(),
1210 return GetEventHandler()->ProcessEvent(gridEvt
);
1215 void wxGrid::OnPaint( wxPaintEvent
& WXUNUSED(ev
) )
1217 wxPaintDC
dc( this );
1219 if ( !m_batchCount
)
1221 // define a clipping region to avoid painting over the scroll bars
1224 if ( m_vertScrollBar
&& m_vertScrollBar
->IsShown() )
1225 vs
= m_scrollBarWidth
;
1228 if ( m_horizScrollBar
&& m_horizScrollBar
->IsShown() )
1229 hs
= m_scrollBarWidth
;
1232 GetClientSize( &cw
, &ch
);
1233 dc
.SetClippingRegion( 0, 0, cw
- vs
, ch
- hs
);
1235 HideCurrentCellHighlight( dc
);
1237 DrawLabelAreas( dc
);
1238 DrawColLabels( dc
);
1239 DrawRowLabels( dc
);
1241 DrawGridLines( dc
);
1244 // TODO: something more elegant than this...
1248 if ( m_currentCellCoords
== wxGridNoCellCoords
)
1249 m_currentCellCoords
.Set(0, 0);
1251 SetEditControlValue();
1252 ShowCellEditControl();
1253 m_firstPaint
= FALSE
;
1256 ShowCurrentCellHighlight( dc
);
1258 dc
.DestroyClippingRegion();
1263 void wxGrid::OnSize( wxSizeEvent
& WXUNUSED(ev
) )
1265 if ( m_created
) CalcDimensions();
1269 void wxGrid::OnMouse( wxMouseEvent
& ev
)
1275 // ------------------------------------------------------------
1279 if ( ev
.Dragging() )
1281 m_isDragging
= TRUE
;
1283 if ( ev
.LeftIsDown() )
1285 switch( m_cursorMode
)
1287 case WXGRID_CURSOR_SELECT_CELL
:
1289 wxGridCellCoords cellCoords
;
1290 XYToCell( x
, y
, cellCoords
);
1291 if ( cellCoords
!= wxGridNoCellCoords
)
1293 if ( !IsSelection() )
1295 SelectBlock( cellCoords
, cellCoords
);
1299 // check for the mouse being outside the cell area
1300 // (we still want to let the user grow the selected block)
1302 if ( cellCoords
.GetCol() == -1 )
1305 cellCoords
.SetCol( m_numCols
-1 );
1307 cellCoords
.SetCol( m_scrollPosX
);
1310 if ( cellCoords
.GetRow() == -1 )
1312 if ( y
>= m_bottom
)
1313 cellCoords
.SetRow( m_numRows
-1 );
1315 cellCoords
.SetRow( m_scrollPosY
);
1318 if ( !IsInSelection( cellCoords
) )
1319 SelectBlock( m_currentCellCoords
, cellCoords
);
1325 case WXGRID_CURSOR_RESIZE_ROW
:
1327 wxClientDC
dc(this);
1328 dc
.SetLogicalFunction(wxXOR
);
1329 if ( m_dragLastPos
>= 0 )
1331 dc
.DrawLine( m_left
, m_dragLastPos
,
1332 m_right
, m_dragLastPos
);
1334 dc
.DrawLine( m_left
, ev
.GetY(),
1335 m_right
, ev
.GetY());
1337 m_dragLastPos
= ev
.GetY();
1341 case WXGRID_CURSOR_RESIZE_COL
:
1343 wxClientDC
dc(this);
1344 dc
.SetLogicalFunction(wxINVERT
);
1345 if ( m_dragLastPos
>= 0 )
1347 dc
.DrawLine( m_dragLastPos
, m_top
,
1348 m_dragLastPos
, m_bottom
);
1350 dc
.DrawLine( ev
.GetX(), m_top
,
1351 ev
.GetX(), m_bottom
);
1353 m_dragLastPos
= ev
.GetX();
1357 case WXGRID_CURSOR_SELECT_ROW
:
1359 if ( (row
= YToRow( y
)) >= 0 &&
1360 !IsInSelection( row
, 0 ) )
1362 SelectRow( row
, TRUE
);
1367 case WXGRID_CURSOR_SELECT_COL
:
1369 if ( (col
= XToCol( x
)) >= 0 &&
1370 !IsInSelection( 0, col
) )
1372 SelectCol( col
, TRUE
);
1381 m_isDragging
= FALSE
;
1383 // ------------------------------------------------------------
1385 // Left mouse button down
1387 if ( ev
.LeftDown() )
1391 wxGridCellCoords cellCoords
;
1393 switch( XYToArea( x
, y
) )
1395 case WXGRID_ROWLABEL
:
1397 // don't send a label click event for a hit on the
1398 // edge of the row label - this is probably the user
1399 // wanting to resize the row
1401 if ( YToEdgeOfRow(y
) < 0 )
1404 if ( !SendEvent( EVT_GRID_LABEL_LEFT_CLICK
, row
, col
, ev
) )
1406 SelectRow( row
, ev
.ShiftDown() );
1407 m_cursorMode
= WXGRID_CURSOR_SELECT_ROW
;
1413 case WXGRID_COLLABEL
:
1415 // don't send a label click event for a hit on the
1416 // edge of the col label - this is probably the user
1417 // wanting to resize the col
1419 if ( XToEdgeOfCol(x
) < 0 )
1422 if ( !SendEvent( EVT_GRID_LABEL_LEFT_CLICK
, row
, col
, ev
) )
1424 SelectCol( col
, ev
.ShiftDown() );
1425 m_cursorMode
= WXGRID_CURSOR_SELECT_COL
;
1431 case WXGRID_CORNERLABEL
:
1433 // leave both row and col as -1
1435 if ( !SendEvent( EVT_GRID_LABEL_LEFT_CLICK
, row
, col
, ev
) )
1444 XYToCell( x
, y
, cellCoords
);
1445 if ( !SendEvent( EVT_GRID_CELL_LEFT_CLICK
,
1446 cellCoords
.GetRow(),
1447 cellCoords
.GetCol(),
1450 MakeCellVisible( cellCoords
);
1451 SelectCell( cellCoords
);
1458 wxLogMessage( "outside grid area" );
1463 // ------------------------------------------------------------
1465 // Left mouse button double click
1467 else if ( ev
.LeftDClick() )
1471 wxGridCellCoords cellCoords
;
1473 switch( XYToArea( x
, y
) )
1475 case WXGRID_ROWLABEL
:
1477 // don't send a label click event for a hit on the
1478 // edge of the row label - this is probably the user
1479 // wanting to resize the row
1481 if ( YToEdgeOfRow(y
) < 0 )
1484 SendEvent( EVT_GRID_LABEL_LEFT_DCLICK
, row
, col
, ev
);
1489 case WXGRID_COLLABEL
:
1491 // don't send a label click event for a hit on the
1492 // edge of the col label - this is probably the user
1493 // wanting to resize the col
1495 if ( XToEdgeOfCol(x
) < 0 )
1498 SendEvent( EVT_GRID_LABEL_LEFT_DCLICK
, row
, col
, ev
);
1503 case WXGRID_CORNERLABEL
:
1505 // leave both row and col as -1
1507 SendEvent( EVT_GRID_LABEL_LEFT_DCLICK
, row
, col
, ev
);
1513 XYToCell( x
, y
, cellCoords
);
1514 SendEvent( EVT_GRID_CELL_LEFT_DCLICK
,
1515 cellCoords
.GetRow(),
1516 cellCoords
.GetCol(),
1523 wxLogMessage( "outside grid area" );
1528 // ------------------------------------------------------------
1530 // Left mouse button released
1532 else if ( ev
.LeftUp() )
1534 switch ( m_cursorMode
)
1536 case WXGRID_CURSOR_RESIZE_ROW
:
1538 if ( m_dragLastPos
>= 0 )
1540 // erase the last line and resize the row
1542 wxClientDC
dc( this );
1543 dc
.SetLogicalFunction( wxINVERT
);
1544 dc
.DrawLine( m_left
, m_dragLastPos
,
1545 m_right
, m_dragLastPos
);
1546 HideCellEditControl();
1547 int top
= m_top
+ m_colLabelHeight
;
1548 if ( m_dragRowOrCol
> 0 )
1549 top
= m_rowBottoms
[m_dragRowOrCol
-1];
1550 m_rowHeights
[m_dragRowOrCol
] = wxMax( ev
.GetY() - top
,
1551 WXGRID_MIN_ROW_HEIGHT
);
1553 ShowCellEditControl();
1556 // Note: we are ending the event *after* doing
1557 // default processing in this case
1559 SendEvent( EVT_GRID_ROW_SIZE
, m_dragRowOrCol
, -1, ev
);
1564 case WXGRID_CURSOR_RESIZE_COL
:
1566 if ( m_dragLastPos
>= 0 )
1568 // erase the last line and resize the col
1570 wxClientDC
dc( this );
1571 dc
.SetLogicalFunction( wxINVERT
);
1572 dc
.DrawLine( m_left
, m_dragLastPos
,
1573 m_right
, m_dragLastPos
);
1574 HideCellEditControl();
1575 int left
= m_left
+ m_rowLabelWidth
;
1576 if ( m_dragRowOrCol
> 0 )
1577 left
= m_colRights
[m_dragRowOrCol
-1];
1578 m_colWidths
[m_dragRowOrCol
] = wxMax( ev
.GetX() - left
,
1579 WXGRID_MIN_COL_WIDTH
);
1581 ShowCellEditControl();
1584 // Note: we are ending the event *after* doing
1585 // default processing in this case
1587 SendEvent( EVT_GRID_COL_SIZE
, -1, m_dragRowOrCol
, ev
);
1592 case WXGRID_CURSOR_SELECT_CELL
:
1594 if ( IsSelection() )
1596 // Note: we are ending the event *after* doing
1597 // default processing in this case
1599 SendEvent( EVT_GRID_RANGE_SELECT
, -1, -1, ev
);
1607 // ------------------------------------------------------------
1609 // Right mouse button down
1611 else if ( ev
.RightDown() )
1615 wxGridCellCoords cellCoords
;
1617 switch( XYToArea( x
, y
) )
1620 case WXGRID_ROWLABEL
:
1623 if ( !SendEvent( EVT_GRID_LABEL_RIGHT_CLICK
, row
, col
, ev
) )
1625 // TODO: default processing ?
1630 case WXGRID_COLLABEL
:
1633 if ( !SendEvent( EVT_GRID_LABEL_RIGHT_CLICK
, row
, col
, ev
) )
1635 // TODO: default processing ?
1640 case WXGRID_CORNERLABEL
:
1642 // leave both row and col as -1
1644 if ( !SendEvent( EVT_GRID_LABEL_RIGHT_CLICK
, row
, col
, ev
) )
1646 // TODO: default processing ?
1653 XYToCell( x
, y
, cellCoords
);
1654 if ( !SendEvent( EVT_GRID_CELL_RIGHT_CLICK
,
1655 cellCoords
.GetRow(),
1656 cellCoords
.GetCol(),
1659 // TODO: default processing ?
1666 wxLogMessage( "outside grid area" );
1671 // ------------------------------------------------------------
1673 // Right mouse button double click
1675 else if ( ev
.RightDClick() )
1679 wxGridCellCoords cellCoords
;
1681 switch( XYToArea( x
, y
) )
1684 case WXGRID_ROWLABEL
:
1687 SendEvent( EVT_GRID_LABEL_RIGHT_DCLICK
, row
, col
, ev
);
1691 case WXGRID_COLLABEL
:
1694 SendEvent( EVT_GRID_LABEL_RIGHT_DCLICK
, row
, col
, ev
);
1698 case WXGRID_CORNERLABEL
:
1700 // leave both row and col as -1
1702 SendEvent( EVT_GRID_LABEL_RIGHT_DCLICK
, row
, col
, ev
);
1708 XYToCell( x
, y
, cellCoords
);
1709 SendEvent( EVT_GRID_CELL_RIGHT_DCLICK
,
1710 cellCoords
.GetRow(),
1711 cellCoords
.GetCol(),
1718 wxLogMessage( "outside grid area" );
1723 // ------------------------------------------------------------
1725 // No buttons down and mouse moving
1727 else if ( ev
.Moving() )
1729 switch( XYToArea( x
, y
) )
1731 case WXGRID_ROWLABEL
:
1733 m_dragRowOrCol
= YToEdgeOfRow( y
);
1734 if ( m_dragRowOrCol
>= 0 )
1736 if ( m_cursorMode
== WXGRID_CURSOR_SELECT_CELL
)
1738 m_cursorMode
= WXGRID_CURSOR_RESIZE_ROW
;
1739 SetCursor( m_rowResizeCursor
);
1744 if ( m_cursorMode
!= WXGRID_CURSOR_SELECT_CELL
)
1746 m_cursorMode
= WXGRID_CURSOR_SELECT_CELL
;
1747 SetCursor( *wxSTANDARD_CURSOR
);
1753 case WXGRID_COLLABEL
:
1755 m_dragRowOrCol
= XToEdgeOfCol( x
);
1756 if ( m_dragRowOrCol
>= 0 )
1758 if ( m_cursorMode
== WXGRID_CURSOR_SELECT_CELL
)
1760 m_cursorMode
= WXGRID_CURSOR_RESIZE_COL
;
1761 SetCursor( m_colResizeCursor
);
1766 if ( m_cursorMode
!= WXGRID_CURSOR_SELECT_CELL
)
1768 m_cursorMode
= WXGRID_CURSOR_SELECT_CELL
;
1769 SetCursor( *wxSTANDARD_CURSOR
);
1777 if ( m_cursorMode
!= WXGRID_CURSOR_SELECT_CELL
)
1779 m_cursorMode
= WXGRID_CURSOR_SELECT_CELL
;
1780 SetCursor( *wxSTANDARD_CURSOR
);
1789 void wxGrid::OnKeyDown( wxKeyEvent
& ev
)
1791 if ( m_inOnKeyDown
)
1793 // shouldn't be here - we are going round in circles...
1795 wxLogFatalError( wxT("wxGrid::OnKeyDown called while alread active") );
1798 m_inOnKeyDown
= TRUE
;
1800 // propagate the event up and see if it gets processed
1802 wxWindow
*parent
= GetParent();
1803 wxKeyEvent
keyEvt( ev
);
1804 keyEvt
.SetEventObject( parent
);
1806 if ( !parent
->GetEventHandler()->ProcessEvent( keyEvt
) )
1808 // try local handlers
1810 switch ( ev
.KeyCode() )
1813 if ( ev
.ControlDown() )
1815 MoveCursorUpBlock();
1824 if ( ev
.ControlDown() )
1826 MoveCursorDownBlock();
1835 if ( ev
.ControlDown() )
1837 MoveCursorLeftBlock();
1846 if ( ev
.ControlDown() )
1848 MoveCursorRightBlock();
1861 if ( ev
.ControlDown() )
1863 MakeCellVisible( 0, 0 );
1873 if ( ev
.ControlDown() )
1875 MakeCellVisible( m_numRows
-1, m_numCols
-1 );
1876 SelectCell( m_numRows
-1, m_numCols
-1 );
1893 // now try the cell edit control
1895 if ( IsCellEditControlEnabled() )
1897 ev
.SetEventObject( m_cellEditCtrl
);
1898 m_cellEditCtrl
->GetEventHandler()->ProcessEvent( ev
);
1904 m_inOnKeyDown
= FALSE
;
1908 // Text updated in an edit control - either a text control or a
1911 void wxGrid::OnText( wxKeyEvent
& ev
)
1916 wxWindow
*ctrl
= (wxWindow
*)ev
.GetEventObject();
1918 if ( ctrl
== m_cellEditCtrl
&&
1919 IsTopEditControlEnabled() )
1921 // set the value of the top edit control
1923 switch ( m_editCtrlType
)
1925 case wxGRID_TEXTCTRL
:
1926 ((wxTextCtrl
*)m_topEditCtrl
)->
1927 SetValue(((wxTextCtrl
*)ctrl
)->GetValue());
1930 case wxGRID_COMBOBOX
:
1931 ((wxComboBox
*)m_topEditCtrl
)->
1932 SetValue(((wxComboBox
*)ctrl
)->GetValue());
1936 else if ( ctrl
== m_topEditCtrl
)
1938 if ( IsCellEditControlEnabled() )
1940 switch ( m_editCtrlType
)
1942 case wxGRID_TEXTCTRL
:
1943 ((wxTextCtrl
*)m_cellEditCtrl
)->
1944 SetValue(((wxTextCtrl
*)ctrl
)->GetValue());
1947 case wxGRID_COMBOBOX
:
1948 ((wxComboBox
*)m_cellEditCtrl
)->
1949 SetValue(((wxComboBox
*)ctrl
)->GetValue());
1955 // in the case when in-place editing is turned off we just want to
1956 // echo the text changes in the cell but not yet update the grid table
1958 switch ( m_editCtrlType
)
1960 case wxGRID_TEXTCTRL
:
1961 DrawCellValue( m_currentCellCoords
, ((wxTextCtrl
*)ctrl
)->GetValue() );
1964 case wxGRID_COMBOBOX
:
1965 DrawCellValue( m_currentCellCoords
, ((wxComboBox
*)ctrl
)->GetValue() );
1975 void wxGrid::OnGridScroll( wxScrollEvent
& ev
)
1977 // propagate the event up and see if it gets processed
1979 wxWindow
*parent
= GetParent();
1980 wxScrollEvent
scrollEvt( ev
);
1981 if (parent
->GetEventHandler()->ProcessEvent( scrollEvt
)) return;
1983 HideCellEditControl();
1985 if ( ev
.GetEventObject() == m_horizScrollBar
)
1987 if ( ev
.GetPosition() != m_scrollPosX
)
1989 SetHorizontalScrollPos( ev
.GetPosition() );
1994 if ( ev
.GetPosition() != m_scrollPosY
)
1996 SetVerticalScrollPos( ev
.GetPosition() );
2000 ShowCellEditControl();
2004 void wxGrid::SelectCell( const wxGridCellCoords
& coords
)
2006 if ( SendEvent( EVT_GRID_SELECT_CELL
, coords
.GetRow(), coords
.GetCol() ) )
2008 // the event has been intercepted - do nothing
2012 wxClientDC
dc( this );
2014 if ( m_currentCellCoords
!= wxGridNoCellCoords
)
2016 HideCurrentCellHighlight( dc
);
2017 HideCellEditControl();
2018 SaveEditControlValue();
2021 m_currentCellCoords
= coords
;
2023 SetEditControlValue();
2026 ShowCellEditControl();
2027 ShowCurrentCellHighlight( dc
);
2030 if ( IsSelection() )
2033 if ( !GetBatchCount() ) Refresh();
2038 void wxGrid::ShowCellEditControl()
2042 if ( IsCellEditControlEnabled() )
2044 if ( !IsVisible( m_currentCellCoords
) )
2050 rect
= CellToRect( m_currentCellCoords
);
2052 m_cellEditCtrl
->SetSize( rect
);
2053 m_cellEditCtrl
->Show( TRUE
);
2055 switch ( m_editCtrlType
)
2057 case wxGRID_TEXTCTRL
:
2058 ((wxTextCtrl
*) m_cellEditCtrl
)->SetInsertionPointEnd();
2061 case wxGRID_CHECKBOX
:
2062 // TODO: anything ???
2067 // TODO: anything ???
2071 case wxGRID_COMBOBOX
:
2072 // TODO: anything ???
2077 m_cellEditCtrl
->SetFocus();
2083 void wxGrid::HideCellEditControl()
2085 if ( IsCellEditControlEnabled() )
2087 m_cellEditCtrl
->Show( FALSE
);
2091 void wxGrid::SetEditControlValue( const wxString
& value
)
2097 s
= GetCellValue(m_currentCellCoords
);
2101 if ( IsTopEditControlEnabled() )
2103 switch ( m_editCtrlType
)
2105 case wxGRID_TEXTCTRL
:
2106 ((wxGridTextCtrl
*)m_topEditCtrl
)->SetStartValue(s
);
2109 case wxGRID_CHECKBOX
:
2110 // TODO: implement this
2115 // TODO: implement this
2119 case wxGRID_COMBOBOX
:
2120 // TODO: implement this
2126 if ( IsCellEditControlEnabled() )
2128 switch ( m_editCtrlType
)
2130 case wxGRID_TEXTCTRL
:
2131 ((wxGridTextCtrl
*)m_cellEditCtrl
)->SetStartValue(s
);
2134 case wxGRID_CHECKBOX
:
2135 // TODO: implement this
2140 // TODO: implement this
2144 case wxGRID_COMBOBOX
:
2145 // TODO: implement this
2153 void wxGrid::SaveEditControlValue()
2157 wxWindow
*ctrl
= (wxWindow
*)NULL
;
2159 if ( IsCellEditControlEnabled() )
2161 ctrl
= m_cellEditCtrl
;
2163 else if ( IsTopEditControlEnabled() )
2165 ctrl
= m_topEditCtrl
;
2172 bool valueChanged
= FALSE
;
2174 switch ( m_editCtrlType
)
2176 case wxGRID_TEXTCTRL
:
2177 valueChanged
= (((wxGridTextCtrl
*)ctrl
)->GetValue() !=
2178 ((wxGridTextCtrl
*)ctrl
)->GetStartValue());
2179 SetCellValue( m_currentCellCoords
,
2180 ((wxTextCtrl
*) ctrl
)->GetValue() );
2183 case wxGRID_CHECKBOX
:
2184 // TODO: implement this
2189 // TODO: implement this
2193 case wxGRID_COMBOBOX
:
2194 // TODO: implement this
2201 SendEvent( EVT_GRID_CELL_CHANGE
,
2202 m_currentCellCoords
.GetRow(),
2203 m_currentCellCoords
.GetCol() );
2209 int wxGrid::XYToArea( int x
, int y
)
2211 if ( x
> m_left
&& x
< m_right
&&
2212 y
> m_top
&& y
< m_bottom
)
2214 if ( y
< m_top
+ m_colLabelHeight
)
2216 if ( x
> m_left
+ m_rowLabelWidth
)
2218 return WXGRID_COLLABEL
;
2222 return WXGRID_CORNERLABEL
;
2225 else if ( x
<= m_left
+ m_rowLabelWidth
)
2227 return WXGRID_ROWLABEL
;
2235 return WXGRID_NOAREA
;
2239 void wxGrid::XYToCell( int x
, int y
, wxGridCellCoords
& coords
)
2241 coords
.SetRow( YToRow(y
) );
2242 coords
.SetCol( XToCol(x
) );
2246 int wxGrid::YToRow( int y
)
2250 if ( y
> m_top
+ m_colLabelHeight
)
2252 for ( i
= m_scrollPosY
; i
< m_numRows
; i
++ )
2254 if ( y
< m_rowBottoms
[i
] )
2265 int wxGrid::XToCol( int x
)
2269 if ( x
> m_left
+ m_rowLabelWidth
)
2271 for ( i
= m_scrollPosX
; i
< m_numCols
; i
++ )
2273 if ( x
< m_colRights
[i
] )
2284 // return the row number that that the y coord is near the edge of, or
2285 // -1 if not near an edge
2287 int wxGrid::YToEdgeOfRow( int y
)
2291 if ( y
> m_top
+ m_colLabelHeight
)
2293 for ( i
= m_scrollPosY
; i
< m_numRows
; i
++ )
2295 if ( m_rowHeights
[i
] > WXGRID_LABEL_EDGE_ZONE
)
2297 d
= abs( y
- m_rowBottoms
[i
] );
2299 if ( d
< WXGRID_LABEL_EDGE_ZONE
) return i
;
2310 // return the col number that that the x coord is near the edge of, or
2311 // -1 if not near an edge
2313 int wxGrid::XToEdgeOfCol( int x
)
2317 if ( x
> m_left
+ m_rowLabelWidth
)
2319 for ( i
= m_scrollPosX
; i
< m_numCols
; i
++ )
2321 if ( m_colWidths
[i
] > WXGRID_LABEL_EDGE_ZONE
)
2323 d
= abs( x
- m_colRights
[i
] );
2325 if ( d
< WXGRID_LABEL_EDGE_ZONE
) return i
;
2336 wxRect
wxGrid::CellToRect( int row
, int col
)
2338 wxRect
rect( -1, -1, -1, -1 );
2340 if ( row
>= m_scrollPosY
&& col
>= m_scrollPosX
)
2342 rect
.x
= m_colRights
[col
] - m_colWidths
[col
];
2343 rect
.y
= m_rowBottoms
[row
] - m_rowHeights
[row
];
2344 rect
.width
= m_colWidths
[col
];
2345 rect
.height
= m_rowHeights
[ row
];
2352 bool wxGrid::MoveCursorUp()
2354 if ( m_currentCellCoords
!= wxGridNoCellCoords
&&
2355 m_currentCellCoords
.GetRow() > 0 )
2357 SelectCell( m_currentCellCoords
.GetRow() - 1,
2358 m_currentCellCoords
.GetCol() );
2360 if ( !IsVisible( m_currentCellCoords
) )
2361 MakeCellVisible( m_currentCellCoords
);
2369 bool wxGrid::MoveCursorDown()
2371 // TODO: allow for scrolling
2373 if ( m_currentCellCoords
!= wxGridNoCellCoords
&&
2374 m_currentCellCoords
.GetRow() < m_numRows
-1 )
2376 SelectCell( m_currentCellCoords
.GetRow() + 1,
2377 m_currentCellCoords
.GetCol() );
2379 if ( !IsVisible( m_currentCellCoords
) )
2380 MakeCellVisible( m_currentCellCoords
);
2388 bool wxGrid::MoveCursorLeft()
2390 if ( m_currentCellCoords
!= wxGridNoCellCoords
&&
2391 m_currentCellCoords
.GetCol() > 0 )
2393 SelectCell( m_currentCellCoords
.GetRow(),
2394 m_currentCellCoords
.GetCol() - 1 );
2396 if ( !IsVisible( m_currentCellCoords
) )
2397 MakeCellVisible( m_currentCellCoords
);
2405 bool wxGrid::MoveCursorRight()
2407 if ( m_currentCellCoords
!= wxGridNoCellCoords
&&
2408 m_currentCellCoords
.GetCol() < m_numCols
- 1 )
2410 SelectCell( m_currentCellCoords
.GetRow(),
2411 m_currentCellCoords
.GetCol() + 1 );
2413 if ( !IsVisible( m_currentCellCoords
) )
2414 MakeCellVisible( m_currentCellCoords
);
2422 bool wxGrid::MovePageUp()
2424 if ( m_currentCellCoords
!= wxGridNoCellCoords
&&
2427 int row
= m_currentCellCoords
.GetRow();
2428 int y
= m_rowBottoms
[ row
] - m_rowHeights
[ row
];
2431 if ( y
+ m_rowHeights
[row
-1] > m_bottom
) break;
2432 y
+= m_rowHeights
[ --row
];
2434 SetVerticalScrollPos( row
);
2436 SelectCell( row
, m_currentCellCoords
.GetCol() );
2443 bool wxGrid::MovePageDown()
2445 if ( m_currentCellCoords
!= wxGridNoCellCoords
&&
2446 m_scrollPosY
+ m_wholeRowsVisible
< m_numRows
)
2448 if ( m_wholeRowsVisible
> 0 )
2450 SetVerticalScrollPos( m_scrollPosY
+ m_wholeRowsVisible
);
2452 else if ( m_scrollPosY
< m_numRows
- 1 )
2454 SetVerticalScrollPos( m_scrollPosY
+ 1 );
2461 // m_scrollPosY will have been updated
2463 SelectCell( m_scrollPosY
, m_currentCellCoords
.GetCol() );
2470 bool wxGrid::MoveCursorUpBlock()
2473 m_currentCellCoords
!= wxGridNoCellCoords
&&
2474 m_currentCellCoords
.GetRow() > 0 )
2476 int row
= m_currentCellCoords
.GetRow();
2477 int col
= m_currentCellCoords
.GetCol();
2479 if ( m_table
->IsEmptyCell(row
, col
) )
2481 // starting in an empty cell: find the next block of
2487 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break;
2490 else if ( m_table
->IsEmptyCell(row
-1, col
) )
2492 // starting at the top of a block: find the next block
2498 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break;
2503 // starting within a block: find the top of the block
2508 if ( m_table
->IsEmptyCell(row
, col
) )
2516 SelectCell( row
, col
);
2518 if ( !IsVisible( m_currentCellCoords
) )
2519 MakeCellVisible( m_currentCellCoords
);
2527 bool wxGrid::MoveCursorDownBlock()
2530 m_currentCellCoords
!= wxGridNoCellCoords
&&
2531 m_currentCellCoords
.GetRow() < m_numRows
-1 )
2533 int row
= m_currentCellCoords
.GetRow();
2534 int col
= m_currentCellCoords
.GetCol();
2536 if ( m_table
->IsEmptyCell(row
, col
) )
2538 // starting in an empty cell: find the next block of
2541 while ( row
< m_numRows
-1 )
2544 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break;
2547 else if ( m_table
->IsEmptyCell(row
+1, col
) )
2549 // starting at the bottom of a block: find the next block
2552 while ( row
< m_numRows
-1 )
2555 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break;
2560 // starting within a block: find the bottom of the block
2562 while ( row
< m_numRows
-1 )
2565 if ( m_table
->IsEmptyCell(row
, col
) )
2573 SelectCell( row
, col
);
2575 if ( !IsVisible( m_currentCellCoords
) )
2576 MakeCellVisible( m_currentCellCoords
);
2584 bool wxGrid::MoveCursorLeftBlock()
2587 m_currentCellCoords
!= wxGridNoCellCoords
&&
2588 m_currentCellCoords
.GetCol() > 0 )
2590 int row
= m_currentCellCoords
.GetRow();
2591 int col
= m_currentCellCoords
.GetCol();
2593 if ( m_table
->IsEmptyCell(row
, col
) )
2595 // starting in an empty cell: find the next block of
2601 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break;
2604 else if ( m_table
->IsEmptyCell(row
, col
-1) )
2606 // starting at the left of a block: find the next block
2612 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break;
2617 // starting within a block: find the left of the block
2622 if ( m_table
->IsEmptyCell(row
, col
) )
2630 SelectCell( row
, col
);
2632 if ( !IsVisible( m_currentCellCoords
) )
2633 MakeCellVisible( m_currentCellCoords
);
2641 bool wxGrid::MoveCursorRightBlock()
2644 m_currentCellCoords
!= wxGridNoCellCoords
&&
2645 m_currentCellCoords
.GetCol() < m_numCols
-1 )
2647 int row
= m_currentCellCoords
.GetRow();
2648 int col
= m_currentCellCoords
.GetCol();
2650 if ( m_table
->IsEmptyCell(row
, col
) )
2652 // starting in an empty cell: find the next block of
2655 while ( col
< m_numCols
-1 )
2658 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break;
2661 else if ( m_table
->IsEmptyCell(row
, col
+1) )
2663 // starting at the right of a block: find the next block
2666 while ( col
< m_numCols
-1 )
2669 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break;
2674 // starting within a block: find the right of the block
2676 while ( col
< m_numCols
-1 )
2679 if ( m_table
->IsEmptyCell(row
, col
) )
2687 SelectCell( row
, col
);
2689 if ( !IsVisible( m_currentCellCoords
) )
2690 MakeCellVisible( m_currentCellCoords
);
2701 // ----- grid drawing functions
2704 void wxGrid::DrawLabelAreas( wxDC
& dc
)
2707 GetClientSize(&cw
, &ch
);
2709 dc
.SetPen(*wxTRANSPARENT_PEN
);
2710 dc
.SetBrush( wxBrush(GetLabelBackgroundColour(), wxSOLID
) );
2712 dc
.DrawRectangle( m_left
, m_top
,
2713 cw
- m_left
, m_colLabelHeight
);
2715 dc
.DrawRectangle( m_left
, m_top
,
2716 m_rowLabelWidth
, ch
- m_top
);
2720 void wxGrid::DrawColLabels( wxDC
& dc
)
2723 GetClientSize(&cw
, &ch
);
2725 if (m_colLabelHeight
== 0) return;
2727 DrawColLabelBorders( dc
);
2731 rect
.height
= m_colLabelHeight
- 1;
2733 int labelLeft
= m_left
+ m_rowLabelWidth
;
2736 for ( i
= m_scrollPosX
; i
< m_numCols
; i
++ )
2738 if ( labelLeft
> cw
) break;
2740 rect
.x
= 1 + labelLeft
;
2741 rect
.width
= m_colWidths
[i
];
2742 DrawColLabel( dc
, rect
, i
);
2744 labelLeft
+= m_colWidths
[i
];
2749 void wxGrid::DrawColLabelBorders( wxDC
& dc
)
2751 if ( m_colLabelHeight
<= 0 ) return;
2755 GetClientSize( &cw
, &ch
);
2757 dc
.SetPen( *wxBLACK_PEN
);
2761 dc
.DrawLine( m_left
, m_top
, cw
, m_top
);
2763 dc
.DrawLine( m_left
, m_top
+ m_colLabelHeight
,
2764 cw
, m_top
+ m_colLabelHeight
);
2768 int colLeft
= m_left
+ m_rowLabelWidth
;
2769 for ( i
= m_scrollPosX
; i
<= m_numCols
; i
++ )
2771 if (colLeft
> cw
) break;
2773 dc
.DrawLine( colLeft
, m_top
,
2774 colLeft
, m_top
+ m_colLabelHeight
);
2776 if ( i
< m_numCols
) colLeft
+= m_colWidths
[i
];
2779 // Draw white highlights for a 3d effect
2781 dc
.SetPen( *wxWHITE_PEN
);
2783 colLeft
= m_left
+ m_rowLabelWidth
;
2784 for ( i
= m_scrollPosX
; i
< m_numCols
; i
++ )
2786 if (colLeft
> cw
) break;
2788 dc
.DrawLine(colLeft
+ 1, m_top
+ 1,
2789 colLeft
+ m_colWidths
[i
], m_top
+ 1);
2791 dc
.DrawLine(colLeft
+ 1, m_top
+ 1,
2792 colLeft
+ 1, m_top
+ m_colLabelHeight
);
2794 colLeft
+= m_colWidths
[i
];
2799 void wxGrid::DrawColLabel( wxDC
& dc
, const wxRect
& rect
, int col
)
2808 dc
.SetBackgroundMode( wxTRANSPARENT
);
2809 dc
.SetTextBackground( GetLabelBackgroundColour() );
2810 dc
.SetTextForeground( GetLabelTextColour() );
2811 dc
.SetFont( GetLabelFont() );
2814 GetColLabelAlignment( &hAlign
, &vAlign
);
2815 DrawTextRectangle( dc
, GetColLabelValue( col
), rect2
, hAlign
, vAlign
);
2819 void wxGrid::DrawRowLabels( wxDC
& dc
)
2822 GetClientSize(&cw
, &ch
);
2824 if (m_rowLabelWidth
== 0) return;
2826 DrawRowLabelBorders( dc
);
2829 rect
.x
= m_left
+ 1;
2830 rect
.width
= m_rowLabelWidth
- 1;
2832 int labelTop
= m_top
+ m_colLabelHeight
;
2835 for ( i
= m_scrollPosY
; i
< m_numRows
; i
++ )
2837 if ( labelTop
> ch
) break;
2839 rect
.y
= 1 + labelTop
;
2840 rect
.height
= m_rowHeights
[i
];
2841 DrawRowLabel( dc
, rect
, i
);
2843 labelTop
+= m_rowHeights
[i
];
2848 void wxGrid::DrawRowLabelBorders( wxDC
& dc
)
2850 if ( m_rowLabelWidth
<= 0 ) return;
2854 GetClientSize( &cw
, &ch
);
2856 dc
.SetPen( *wxBLACK_PEN
);
2860 dc
.DrawLine( m_left
, m_top
, m_left
, ch
);
2862 dc
.DrawLine( m_left
+ m_rowLabelWidth
, m_top
,
2863 m_left
+ m_rowLabelWidth
, ch
);
2867 int rowTop
= m_top
+ m_colLabelHeight
;
2868 for ( i
= m_scrollPosY
; i
<= m_numRows
; i
++ )
2870 if ( rowTop
> ch
) break;
2872 dc
.DrawLine( m_left
, rowTop
,
2873 m_left
+ m_rowLabelWidth
, rowTop
);
2875 if ( i
< m_numRows
) rowTop
+= m_rowHeights
[i
];
2878 // Draw white highlights for a 3d effect
2880 dc
.SetPen( *wxWHITE_PEN
);
2882 rowTop
= m_top
+ m_colLabelHeight
;
2883 for ( i
= m_scrollPosY
; i
< m_numRows
; i
++ )
2885 if ( rowTop
> ch
) break;
2887 dc
.DrawLine( m_left
+ 1, rowTop
+ 1,
2888 m_left
+ m_rowLabelWidth
, rowTop
+ 1 );
2890 dc
.DrawLine( m_left
+ 1, rowTop
+ 1,
2891 m_left
+ 1, rowTop
+ m_rowHeights
[i
] );
2893 rowTop
+= m_rowHeights
[i
];
2898 void wxGrid::DrawRowLabel( wxDC
& dc
, const wxRect
& rect
, int row
)
2907 dc
.SetBackgroundMode( wxTRANSPARENT
);
2908 dc
.SetTextBackground( GetLabelBackgroundColour() );
2909 dc
.SetTextForeground( GetLabelTextColour() );
2910 dc
.SetFont( GetLabelFont() );
2913 GetRowLabelAlignment( &hAlign
, &vAlign
);
2914 DrawTextRectangle( dc
, GetRowLabelValue( row
), rect2
, hAlign
, vAlign
);
2918 void wxGrid::DrawCellArea( wxDC
& dc
)
2921 GetClientSize(&cw
, &ch
);
2923 dc
.SetPen( *wxTRANSPARENT_PEN
);
2924 dc
.SetBrush( wxBrush(GetDefaultCellBackgroundColour(), wxSOLID
) );
2926 int left
= m_left
+ m_rowLabelWidth
+ 1;
2927 int top
= m_top
+ m_colLabelHeight
+ 1;
2929 dc
.DrawRectangle( left
, top
, cw
- left
, ch
- top
);
2933 void wxGrid::DrawGridLines( wxDC
& dc
)
2935 if ( !m_gridLinesEnabled
|| !m_numRows
|| !m_numCols
) return;
2939 GetClientSize(&cw
, &ch
);
2941 dc
.SetPen( wxPen(GetGridLineColour(), 1, wxSOLID
) );
2943 // horizontal grid lines
2945 int rowTop
= m_top
+ m_colLabelHeight
+ m_rowHeights
[m_scrollPosY
];
2946 for ( i
= m_scrollPosY
+ 1; i
<= m_numRows
; i
++ )
2948 if ( rowTop
> ch
) break;
2950 dc
.DrawLine( m_left
+ m_rowLabelWidth
+ 1, rowTop
,
2953 if ( i
< m_numRows
) rowTop
+= m_rowHeights
[i
];
2957 // vertical grid lines
2959 int colLeft
= m_left
+ m_rowLabelWidth
+ m_colWidths
[m_scrollPosX
];
2960 for ( i
= m_scrollPosX
+ 1; i
<= m_numCols
; i
++ )
2962 if ( colLeft
> cw
) break;
2964 dc
.DrawLine( colLeft
, m_top
+ m_colLabelHeight
+ 1,
2965 colLeft
, m_bottom
);
2967 if ( i
< m_numCols
) colLeft
+= m_colWidths
[i
];
2972 void wxGrid::DrawCells( wxDC
& dc
)
2974 if ( !m_numRows
|| !m_numCols
) return;
2979 GetClientSize( &cw
, &ch
);
2985 rect
.y
= m_top
+ m_colLabelHeight
;
2986 for ( row
= m_scrollPosY
; row
< m_numRows
; row
++ )
2988 if ( rect
.y
> ch
) break;
2990 rect
.height
= m_rowHeights
[ row
];
2991 rect
.x
= m_left
+ m_rowLabelWidth
;
2993 for ( col
= m_scrollPosX
; col
< m_numCols
; col
++ )
2995 if ( rect
.x
> cw
) break;
2997 rect
.width
= m_colWidths
[col
];
2998 DrawCellBackground( dc
, rect
, row
, col
);
2999 DrawCellValue( dc
, rect
, row
, col
);
3000 rect
.x
+= rect
.width
;
3002 rect
.y
+= rect
.height
;
3008 void wxGrid::DrawCellBackground( wxDC
& dc
, const wxRect
& rect
, int row
, int col
)
3017 dc
.SetBackgroundMode( wxSOLID
);
3019 if ( IsInSelection( row
, col
) )
3021 // TODO: improve this
3023 dc
.SetBrush( *wxBLACK_BRUSH
);
3027 dc
.SetBrush( wxBrush(GetCellBackgroundColour(row
, col
), wxSOLID
) );
3029 dc
.SetPen( *wxTRANSPARENT_PEN
);
3030 dc
.DrawRectangle( rect2
);
3034 // This draws a text value in the given cell. If useValueArg is FALSE
3035 // (the default) then the grid table value will be used
3037 void wxGrid::DrawCellValue( wxDC
& dc
, const wxRect
& rect
, int row
, int col
,
3038 const wxString
& value
, bool useValueArg
)
3047 dc
.SetBackgroundMode( wxTRANSPARENT
);
3049 if ( IsInSelection( row
, col
) )
3051 // TODO: improve this
3053 dc
.SetTextBackground( wxColour(0, 0, 0) );
3054 dc
.SetTextForeground( wxColour(255, 255, 255) );
3058 dc
.SetTextBackground( GetCellBackgroundColour(row
, col
) );
3059 dc
.SetTextForeground( GetCellTextColour(row
, col
) );
3061 dc
.SetFont( GetCellFont(row
, col
) );
3064 GetCellAlignment( row
, col
, &hAlign
, &vAlign
);
3068 DrawTextRectangle( dc
, value
, rect2
, hAlign
, vAlign
);
3072 DrawTextRectangle( dc
, GetCellValue( row
, col
), rect2
, hAlign
, vAlign
);
3077 // this is used to echo text being entered into the top edit control when
3078 // in-place editing is turned off
3080 void wxGrid::DrawCellValue( const wxGridCellCoords
& coords
, const wxString
& value
)
3082 if ( IsVisible( coords
) )
3084 int row
= coords
.GetRow();
3085 int col
= coords
.GetCol();
3087 rect
.x
= m_colRights
[ col
] - m_colWidths
[ col
];
3088 rect
.y
= m_rowBottoms
[ row
] - m_rowHeights
[ row
];
3089 rect
.width
= m_colWidths
[ col
];
3090 rect
.height
= m_rowHeights
[ row
];
3092 wxClientDC
dc( this );
3093 DrawCellBackground( dc
, rect
, row
, col
);
3094 DrawCellValue( dc
, rect
, row
, col
, value
, TRUE
);
3099 void wxGrid::DrawCellHighlight( wxDC
& dc
, int row
, int col
)
3101 // TODO: bounds checking on row, col ?
3104 if ( row
>= m_scrollPosY
&& col
>= m_scrollPosX
)
3109 GetClientSize( &cw
, &ch
);
3111 x
= m_colRights
[col
] - m_colWidths
[col
];
3112 if ( x
>= cw
) return;
3114 y
= m_rowBottoms
[row
] - m_rowHeights
[row
];
3115 if ( y
>= ch
) return;
3117 dc
.SetLogicalFunction( wxINVERT
);
3118 dc
.SetPen( wxPen(GetCellHighlightColour(), 2, wxSOLID
) );
3119 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
3121 dc
.DrawRectangle( x
-2, y
-2,
3122 m_colWidths
[col
] + 6,
3123 m_rowHeights
[row
] + 6 );
3125 dc
.SetLogicalFunction( wxCOPY
);
3130 // This function is handy when you just want to update one or a few
3131 // cells. For example, it is used by SetCellValue()
3133 void wxGrid::DrawCell( int row
, int col
)
3135 if ( !GetBatchCount() )
3137 if ( !IsVisible( wxGridCellCoords(row
, col
) ) ) return;
3140 GetClientSize( &cw
, &ch
);
3142 wxRect
rect( CellToRect( row
, col
) );
3146 wxClientDC
dc( this );
3147 DrawCellBackground( dc
, rect
, row
, col
);
3148 DrawCellValue( dc
, rect
, row
, col
);
3154 // this is just to make other code more obvious
3156 void wxGrid::HideCurrentCellHighlight( wxDC
& dc
)
3158 if ( m_currentCellHighlighted
&&
3159 m_currentCellCoords
!= wxGridNoCellCoords
)
3161 DrawCellHighlight( dc
, m_currentCellCoords
);
3162 m_currentCellHighlighted
= FALSE
;
3167 // this is just to make other code more obvious
3169 void wxGrid::ShowCurrentCellHighlight( wxDC
& dc
)
3171 if ( !m_currentCellHighlighted
&&
3172 m_currentCellCoords
!= wxGridNoCellCoords
)
3174 DrawCellHighlight( dc
, m_currentCellCoords
);
3175 m_currentCellHighlighted
= TRUE
;
3180 void wxGrid::DrawTextRectangle( wxDC
& dc
,
3181 const wxString
& value
,
3186 long textWidth
, textHeight
;
3187 long lineWidth
, lineHeight
;
3188 wxArrayString lines
;
3190 // see if we are already clipping
3193 dc
.GetClippingBox( clipRect
);
3195 bool alreadyClipping
= TRUE
;
3196 wxRect intersectRect
;
3198 if ( clipRect
.x
== 0 && clipRect
.y
== 0 &&
3199 clipRect
.width
== 0 && clipRect
.height
== 0)
3201 alreadyClipping
= FALSE
;
3202 intersectRect
= rect
;
3206 // Find the intersection of the clipping rectangle and our
3209 wxRegion
region( rect
);
3210 region
.Intersect( clipRect
);
3211 if ( region
.IsEmpty() )
3217 intersectRect
= region
.GetBox();
3220 if ( alreadyClipping
) dc
.DestroyClippingRegion();
3222 dc
.SetClippingRegion( intersectRect
);
3224 StringToLines( value
, lines
);
3225 if ( lines
.GetCount() )
3227 GetTextBoxSize( dc
, lines
, &textWidth
, &textHeight
);
3228 dc
.GetTextExtent( lines
[0], &lineWidth
, &lineHeight
);
3231 switch ( horizAlign
)
3234 x
= rect
.x
+ (rect
.width
- textWidth
- 1.0);
3238 x
= rect
.x
+ ((rect
.width
- textWidth
)/2.0);
3247 switch ( vertAlign
)
3250 y
= rect
.y
+ (rect
.height
- textHeight
- 1);
3254 y
= rect
.y
+ ((rect
.height
- textHeight
)/2.0);
3263 for ( size_t i
= 0; i
< lines
.GetCount(); i
++ )
3265 dc
.DrawText( lines
[i
], (long)x
, (long)y
);
3270 dc
.DestroyClippingRegion();
3271 if (alreadyClipping
) dc
.SetClippingRegion( clipRect
);
3275 // Split multi line text up into an array of strings. Any existing
3276 // contents of the string array are preserved.
3278 void wxGrid::StringToLines( const wxString
& value
, wxArrayString
& lines
)
3280 // TODO: this won't work for WXMAC ? (lines end with '\r')
3281 // => use wxTextFile functions then (VZ)
3284 while ( startPos
< (int)value
.Length() )
3286 pos
= value
.Mid(startPos
).Find( '\n' );
3291 else if ( pos
== 0 )
3293 lines
.Add( wxEmptyString
);
3297 if ( value
[startPos
+pos
-1] == '\r' )
3299 lines
.Add( value
.Mid(startPos
, pos
-1) );
3303 lines
.Add( value
.Mid(startPos
, pos
) );
3308 if ( startPos
< (int)value
.Length() )
3310 lines
.Add( value
.Mid( startPos
) );
3315 void wxGrid::GetTextBoxSize( wxDC
& dc
,
3316 wxArrayString
& lines
,
3317 long *width
, long *height
)
3324 for ( i
= 0; i
< lines
.GetCount(); i
++ )
3326 dc
.GetTextExtent( lines
[i
], &lineW
, &lineH
);
3327 w
= wxMax( w
, lineW
);
3337 // ------ functions to get/send data (see also public functions)
3340 bool wxGrid::GetModelValues()
3344 // all we need to do is repaint the grid
3354 bool wxGrid::SetModelValues()
3360 for ( row
= m_scrollPosY
; row
< m_numRows
; row
++ )
3362 for ( col
= m_scrollPosX
; col
< m_numCols
; col
++ )
3364 m_table
->SetValue( row
, col
, GetCellValue(row
, col
) );
3376 // ------ public functions
3379 bool wxGrid::CreateGrid( int numRows
, int numCols
)
3383 wxLogError( wxT("wxGrid::CreateGrid(numRows, numCols) called more than once") );
3388 m_numRows
= numRows
;
3389 m_numCols
= numCols
;
3391 m_table
= new wxGridStringTable( m_numRows
, m_numCols
);
3392 m_table
->SetView( this );
3401 // The behaviour of this function depends on the grid table class
3402 // Clear() function. For the default wxGridStringTable class the
3403 // behavious is to replace all cell contents with wxEmptyString but
3404 // not to change the number of rows or cols.
3406 void wxGrid::ClearGrid()
3411 SetEditControlValue();
3412 if ( !GetBatchCount() ) Refresh();
3417 bool wxGrid::InsertRows( int pos
, int numRows
, bool WXUNUSED(updateLabels
) )
3419 // TODO: something with updateLabels flag
3423 wxLogError( wxT("Called wxGrid::InsertRows() before calling CreateGrid()") );
3429 bool ok
= m_table
->InsertRows( pos
, numRows
);
3431 // the table will have sent the results of the insert row
3432 // operation to this view object as a grid table message
3436 if ( m_numCols
== 0 )
3438 m_table
->AppendCols( WXGRID_DEFAULT_NUMBER_COLS
);
3440 // TODO: perhaps instead of appending the default number of cols
3441 // we should remember what the last non-zero number of cols was ?
3445 if ( m_currentCellCoords
== wxGridNoCellCoords
)
3447 // if we have just inserted cols into an empty grid the current
3448 // cell will be undefined...
3453 if ( !GetBatchCount() ) Refresh();
3456 SetEditControlValue();
3465 bool wxGrid::AppendRows( int numRows
, bool WXUNUSED(updateLabels
) )
3467 // TODO: something with updateLabels flag
3471 wxLogError( wxT("Called wxGrid::AppendRows() before calling CreateGrid()") );
3475 if ( m_table
&& m_table
->AppendRows( numRows
) )
3477 if ( m_currentCellCoords
== wxGridNoCellCoords
)
3479 // if we have just inserted cols into an empty grid the current
3480 // cell will be undefined...
3485 // the table will have sent the results of the append row
3486 // operation to this view object as a grid table message
3488 if ( !GetBatchCount() ) Refresh();
3497 bool wxGrid::DeleteRows( int pos
, int numRows
, bool WXUNUSED(updateLabels
) )
3499 // TODO: something with updateLabels flag
3503 wxLogError( wxT("Called wxGrid::DeleteRows() before calling CreateGrid()") );
3507 if ( m_table
&& m_table
->DeleteRows( pos
, numRows
) )
3509 // the table will have sent the results of the delete row
3510 // operation to this view object as a grid table message
3512 if ( m_numRows
> 0 )
3513 SetEditControlValue();
3515 HideCellEditControl();
3517 if ( !GetBatchCount() ) Refresh();
3526 bool wxGrid::InsertCols( int pos
, int numCols
, bool WXUNUSED(updateLabels
) )
3528 // TODO: something with updateLabels flag
3532 wxLogError( wxT("Called wxGrid::InsertCols() before calling CreateGrid()") );
3538 HideCellEditControl();
3539 bool ok
= m_table
->InsertCols( pos
, numCols
);
3541 // the table will have sent the results of the insert col
3542 // operation to this view object as a grid table message
3546 if ( m_currentCellCoords
== wxGridNoCellCoords
)
3548 // if we have just inserted cols into an empty grid the current
3549 // cell will be undefined...
3554 if ( !GetBatchCount() ) Refresh();
3557 SetEditControlValue();
3566 bool wxGrid::AppendCols( int numCols
, bool WXUNUSED(updateLabels
) )
3568 // TODO: something with updateLabels flag
3572 wxLogError( wxT("Called wxGrid::AppendCols() before calling CreateGrid()") );
3576 if ( m_table
&& m_table
->AppendCols( numCols
) )
3578 // the table will have sent the results of the append col
3579 // operation to this view object as a grid table message
3581 if ( m_currentCellCoords
== wxGridNoCellCoords
)
3583 // if we have just inserted cols into an empty grid the current
3584 // cell will be undefined...
3588 if ( !GetBatchCount() ) Refresh();
3597 bool wxGrid::DeleteCols( int pos
, int numCols
, bool WXUNUSED(updateLabels
) )
3599 // TODO: something with updateLabels flag
3603 wxLogError( wxT("Called wxGrid::DeleteCols() before calling CreateGrid()") );
3607 if ( m_table
&& m_table
->DeleteCols( pos
, numCols
) )
3609 // the table will have sent the results of the delete col
3610 // operation to this view object as a grid table message
3612 if ( m_numCols
> 0 )
3613 SetEditControlValue();
3615 HideCellEditControl();
3617 if ( !GetBatchCount() ) Refresh();
3629 // ------ control panel and cell edit control
3632 void wxGrid::EnableEditing( bool edit
)
3634 // TODO: improve this ?
3636 if ( edit
!= m_editable
)
3639 if ( !m_editable
) HideCellEditControl();
3640 m_topEditCtrlEnabled
= m_editable
;
3641 m_cellEditCtrlEnabled
= m_editable
;
3642 if ( !m_editable
) ShowCellEditControl();
3647 void wxGrid::EnableTopEditControl( bool enable
)
3649 if ( enable
!= m_topEditCtrlEnabled
)
3651 HideCellEditControl();
3652 m_topEditCtrlEnabled
= enable
;
3654 m_topEditCtrl
->Show( enable
);
3656 if ( m_currentCellCoords
!= wxGridNoCellCoords
)
3657 SetEditControlValue();
3659 ShowCellEditControl();
3660 if ( !GetBatchCount() ) Refresh();
3664 void wxGrid::EnableCellEditControl( bool enable
)
3666 if ( m_cellEditCtrl
&&
3667 enable
!= m_cellEditCtrlEnabled
)
3669 wxClientDC
dc( this );
3671 HideCurrentCellHighlight( dc
);
3672 HideCellEditControl();
3673 SaveEditControlValue();
3675 m_cellEditCtrlEnabled
= enable
;
3677 SetEditControlValue();
3678 ShowCellEditControl();
3679 ShowCurrentCellHighlight( dc
);
3685 // ------ grid formatting functions
3688 void wxGrid::GetRowLabelAlignment( int *horiz
, int *vert
)
3690 *horiz
= m_rowLabelHorizAlign
;
3691 *vert
= m_rowLabelVertAlign
;
3694 void wxGrid::GetColLabelAlignment( int *horiz
, int *vert
)
3696 *horiz
= m_colLabelHorizAlign
;
3697 *vert
= m_colLabelVertAlign
;
3700 wxString
wxGrid::GetRowLabelValue( int row
)
3704 return m_table
->GetRowLabelValue( row
);
3714 wxString
wxGrid::GetColLabelValue( int col
)
3718 return m_table
->GetColLabelValue( col
);
3728 void wxGrid::SetRowLabelSize( int width
)
3730 m_rowLabelWidth
= wxMax( 0, width
);
3732 ShowCellEditControl();
3733 if ( !GetBatchCount() ) Refresh();
3736 void wxGrid::SetColLabelSize( int height
)
3738 m_colLabelHeight
= wxMax( 0, height
);
3740 ShowCellEditControl();
3741 if ( !GetBatchCount() ) Refresh();
3744 void wxGrid::SetLabelBackgroundColour( const wxColour
& colour
)
3746 m_labelBackgroundColour
= colour
;
3747 if ( !GetBatchCount() ) Refresh();
3750 void wxGrid::SetLabelTextColour( const wxColour
& colour
)
3752 m_labelTextColour
= colour
;
3753 if ( !GetBatchCount() ) Refresh();
3756 void wxGrid::SetLabelFont( const wxFont
& font
)
3759 if ( !GetBatchCount() ) Refresh();
3762 void wxGrid::SetRowLabelAlignment( int horiz
, int vert
)
3764 if ( horiz
== wxLEFT
|| horiz
== wxCENTRE
|| horiz
== wxRIGHT
)
3766 m_rowLabelHorizAlign
= horiz
;
3769 if ( vert
== wxTOP
|| vert
== wxCENTRE
|| vert
== wxBOTTOM
)
3771 m_rowLabelVertAlign
= vert
;
3774 if ( !GetBatchCount() ) Refresh();
3777 void wxGrid::SetColLabelAlignment( int horiz
, int vert
)
3779 if ( horiz
== wxLEFT
|| horiz
== wxCENTRE
|| horiz
== wxRIGHT
)
3781 m_colLabelHorizAlign
= horiz
;
3784 if ( vert
== wxTOP
|| vert
== wxCENTRE
|| vert
== wxBOTTOM
)
3786 m_colLabelVertAlign
= vert
;
3789 if ( !GetBatchCount() ) Refresh();
3792 void wxGrid::SetRowLabelValue( int row
, const wxString
& s
)
3796 m_table
->SetRowLabelValue( row
, s
);
3797 if ( !GetBatchCount() ) Refresh();
3801 void wxGrid::SetColLabelValue( int col
, const wxString
& s
)
3805 m_table
->SetColLabelValue( col
, s
);
3806 if ( !GetBatchCount() ) Refresh();
3810 void wxGrid::SetGridLineColour( const wxColour
& colour
)
3812 m_gridLineColour
= colour
;
3814 wxClientDC
dc( this );
3815 DrawGridLines( dc
);
3818 void wxGrid::EnableGridLines( bool enable
)
3820 if ( enable
!= m_gridLinesEnabled
)
3822 m_gridLinesEnabled
= enable
;
3823 if ( !GetBatchCount() ) Refresh();
3828 int wxGrid::GetDefaultRowSize()
3830 return m_defaultRowHeight
;
3833 int wxGrid::GetRowSize( int row
)
3835 if ( row
>= 0 && row
< m_numRows
)
3836 return m_rowHeights
[row
];
3838 return 0; // TODO: log an error here
3841 int wxGrid::GetDefaultColSize()
3843 return m_defaultColWidth
;
3846 int wxGrid::GetColSize( int col
)
3848 if ( col
>= 0 && col
< m_numCols
)
3849 return m_colWidths
[col
];
3851 return 0; // TODO: log an error here
3854 wxColour
wxGrid::GetDefaultCellBackgroundColour()
3856 // TODO: replace this temp test code
3858 return wxColour( 255, 255, 255 );
3861 wxColour
wxGrid::GetCellBackgroundColour( int WXUNUSED(row
), int WXUNUSED(col
) )
3863 // TODO: replace this temp test code
3865 return wxColour( 255, 255, 255 );
3868 wxColour
wxGrid::GetDefaultCellTextColour()
3870 // TODO: replace this temp test code
3872 return wxColour( 0, 0, 0 );
3875 wxColour
wxGrid::GetCellTextColour( int WXUNUSED(row
), int WXUNUSED(col
) )
3877 // TODO: replace this temp test code
3879 return wxColour( 0, 0, 0 );
3883 wxColour
wxGrid::GetCellHighlightColour()
3885 // TODO: replace this temp test code
3887 return wxColour( 0, 0, 0 );
3891 wxFont
wxGrid::GetDefaultCellFont()
3893 return m_defaultCellFont
;
3896 wxFont
wxGrid::GetCellFont( int WXUNUSED(row
), int WXUNUSED(col
) )
3898 // TODO: replace this temp test code
3900 return m_defaultCellFont
;
3903 void wxGrid::GetDefaultCellAlignment( int *horiz
, int *vert
)
3905 // TODO: replace this temp test code
3911 void wxGrid::GetCellAlignment( int WXUNUSED(row
), int WXUNUSED(col
), int *horiz
, int *vert
)
3913 // TODO: replace this temp test code
3919 void wxGrid::SetDefaultRowSize( int height
, bool resizeExistingRows
)
3921 m_defaultRowHeight
= wxMax( height
, WXGRID_MIN_ROW_HEIGHT
);
3923 if ( resizeExistingRows
)
3925 // TODO: what do we do about events here ?
3926 // Generate an event for each resize ?
3929 for ( row
= 0; row
< m_numRows
; row
++ )
3931 m_rowHeights
[row
] = m_defaultRowHeight
;
3934 if ( !GetBatchCount() ) Refresh();
3938 void wxGrid::SetRowSize( int row
, int height
)
3940 if ( row
>= 0 && row
< m_numRows
)
3942 m_rowHeights
[row
] = wxMax( 0, height
);
3944 if ( !GetBatchCount() ) Refresh();
3946 // Note: we are ending the event *after* doing
3947 // default processing in this case
3949 SendEvent( EVT_GRID_ROW_SIZE
,
3954 // TODO: log an error here
3958 void wxGrid::SetDefaultColSize( int width
, bool resizeExistingCols
)
3960 m_defaultColWidth
= wxMax( width
, WXGRID_MIN_COL_WIDTH
);
3962 if ( resizeExistingCols
)
3964 // TODO: what do we do about events here ?
3965 // Generate an event for each resize ?
3968 for ( col
= 0; col
< m_numCols
; col
++ )
3970 m_colWidths
[col
] = m_defaultColWidth
;
3973 if ( !GetBatchCount() ) Refresh();
3977 void wxGrid::SetColSize( int col
, int width
)
3979 if ( col
>= 0 && col
< m_numCols
)
3981 m_colWidths
[col
] = wxMax( 0, width
);
3983 if ( !GetBatchCount() ) Refresh();
3985 // Note: we are ending the event *after* doing
3986 // default processing in this case
3988 SendEvent( EVT_GRID_COL_SIZE
,
3993 // TODO: log an error here
3997 void wxGrid::SetDefaultCellBackgroundColour( const wxColour
& )
3999 // TODO: everything !!!
4003 void wxGrid::SetCellBackgroundColour( int WXUNUSED(row
), int WXUNUSED(col
), const wxColour
& )
4005 // TODO: everything !!!
4009 void wxGrid::SetDefaultCellTextColour( const wxColour
& )
4011 // TODO: everything !!!
4015 void wxGrid::SetCellTextColour( int WXUNUSED(row
), int WXUNUSED(col
), const wxColour
& )
4017 // TODO: everything !!!
4021 void wxGrid::SetCellHighlightColour( const wxColour
& )
4023 // TODO: everything !!!
4027 void wxGrid::SetDefaultCellFont( const wxFont
& )
4029 // TODO: everything !!!
4033 void wxGrid::SetCellFont( int WXUNUSED(row
), int WXUNUSED(col
), const wxFont
& )
4035 // TODO: everything !!!
4039 void wxGrid::SetDefaultCellAlignment( int WXUNUSED(horiz
), int WXUNUSED(vert
) )
4041 // TODO: everything !!!
4045 void wxGrid::SetCellAlignment( int WXUNUSED(row
), int WXUNUSED(col
), int WXUNUSED(horiz
), int WXUNUSED(vert
) )
4047 // TODO: everything !!!
4053 // ------ cell value accessor functions
4056 void wxGrid::SetCellValue( int row
, int col
, const wxString
& s
)
4060 m_table
->SetValue( row
, col
, s
.c_str() );
4061 DrawCell( row
, col
);
4062 if ( m_currentCellCoords
.GetRow() == row
&&
4063 m_currentCellCoords
.GetCol() == col
)
4065 SetEditControlValue( s
);
4073 // ------ interaction with data model
4075 bool wxGrid::ProcessTableMessage( wxGridTableMessage
& msg
)
4077 switch ( msg
.GetId() )
4079 case wxGRIDTABLE_REQUEST_VIEW_GET_VALUES
:
4080 return GetModelValues();
4082 case wxGRIDTABLE_REQUEST_VIEW_SEND_VALUES
:
4083 return SetModelValues();
4085 case wxGRIDTABLE_NOTIFY_ROWS_INSERTED
:
4086 case wxGRIDTABLE_NOTIFY_ROWS_APPENDED
:
4087 case wxGRIDTABLE_NOTIFY_ROWS_DELETED
:
4088 case wxGRIDTABLE_NOTIFY_COLS_INSERTED
:
4089 case wxGRIDTABLE_NOTIFY_COLS_APPENDED
:
4090 case wxGRIDTABLE_NOTIFY_COLS_DELETED
:
4091 return Redimension( msg
);
4100 // ------ Grid location functions
4102 // (see also inline functions in grid.h)
4105 // check to see if a cell location is wholly visible
4107 bool wxGrid::IsVisible( const wxGridCellCoords
& coords
)
4109 return ( coords
.GetRow() >= m_scrollPosY
&&
4110 coords
.GetRow() < m_scrollPosY
+ m_wholeRowsVisible
&&
4111 coords
.GetCol() >= m_scrollPosX
&&
4112 coords
.GetCol() < m_scrollPosX
+ m_wholeColsVisible
);
4116 // make the specified cell location visible by doing a minimal amount
4119 void wxGrid::MakeCellVisible( int row
, int col
)
4121 int lastX
= m_scrollPosX
;
4122 int lastY
= m_scrollPosY
;
4124 if ( row
>= 0 && row
< m_numRows
&&
4125 col
>= 0 && col
< m_numCols
)
4127 if ( row
< m_scrollPosY
)
4129 SetVerticalScrollPos( row
);
4131 else if ( row
>= m_scrollPosY
+ m_wholeRowsVisible
)
4134 int h
= m_rowBottoms
[row
];
4135 for ( i
= m_scrollPosY
; i
< m_numRows
&& h
> m_bottom
; i
++ )
4137 h
-= m_rowHeights
[i
];
4139 SetVerticalScrollPos( i
);
4142 if ( col
< m_scrollPosX
)
4144 SetHorizontalScrollPos( col
);
4146 else if ( col
>= m_scrollPosX
+ m_wholeColsVisible
)
4149 int w
= m_colRights
[col
];
4150 for ( i
= m_scrollPosX
; i
< m_numCols
&& w
> m_right
; i
++ )
4152 w
-= m_colWidths
[i
];
4154 SetHorizontalScrollPos( i
);
4157 if ( m_scrollPosX
!= lastX
|| m_scrollPosY
!= lastY
)
4159 // The cell was not visible before but not it is
4161 ShowCellEditControl();
4166 // TODO: log an error
4171 void wxGrid::SetVerticalScrollPos( int topMostRow
)
4173 if ( m_vertScrollBar
&& topMostRow
!= m_scrollPosY
)
4175 m_scrollPosY
= topMostRow
;
4183 void wxGrid::SetHorizontalScrollPos( int leftMostCol
)
4185 if ( m_horizScrollBar
&& leftMostCol
!= m_scrollPosX
)
4187 m_scrollPosX
= leftMostCol
;
4196 // ------ block, row and col selection
4199 void wxGrid::SelectRow( int row
, bool addToSelected
)
4201 if ( IsSelection() && addToSelected
)
4203 if ( m_selectedTopLeft
.GetRow() > row
)
4204 m_selectedTopLeft
.SetRow( row
);
4206 m_selectedTopLeft
.SetCol( 0 );
4208 if ( m_selectedBottomRight
.GetRow() < row
)
4209 m_selectedBottomRight
.SetRow( row
);
4211 m_selectedBottomRight
.SetCol( m_numCols
- 1 );
4216 m_selectedTopLeft
.Set( row
, 0 );
4217 m_selectedBottomRight
.Set( row
, m_numCols
-1 );
4220 if ( !GetBatchCount() )
4222 wxRect
rect( SelectionToRect() );
4223 if ( rect
!= wxGridNoCellRect
) Refresh( TRUE
, &rect
);
4226 wxGridRangeSelectEvent
gridEvt( GetId(),
4227 EVT_GRID_RANGE_SELECT
,
4230 m_selectedBottomRight
);
4232 GetEventHandler()->ProcessEvent(gridEvt
);
4236 void wxGrid::SelectCol( int col
, bool addToSelected
)
4238 if ( addToSelected
&& m_selectedTopLeft
!= wxGridNoCellCoords
)
4240 if ( m_selectedTopLeft
.GetCol() > col
)
4241 m_selectedTopLeft
.SetCol( col
);
4243 m_selectedTopLeft
.SetRow( 0 );
4245 if ( m_selectedBottomRight
.GetCol() < col
)
4246 m_selectedBottomRight
.SetCol( col
);
4248 m_selectedBottomRight
.SetRow( m_numRows
- 1 );
4253 m_selectedTopLeft
.Set( 0, col
);
4254 m_selectedBottomRight
.Set( m_numRows
-1, col
);
4257 if ( !GetBatchCount() )
4259 wxRect
rect( SelectionToRect() );
4260 if ( rect
!= wxGridNoCellRect
) Refresh( TRUE
, &rect
);
4263 wxGridRangeSelectEvent
gridEvt( GetId(),
4264 EVT_GRID_RANGE_SELECT
,
4267 m_selectedBottomRight
);
4269 GetEventHandler()->ProcessEvent(gridEvt
);
4273 void wxGrid::SelectBlock( int topRow
, int leftCol
, int bottomRow
, int rightCol
)
4277 if ( topRow
> bottomRow
)
4284 if ( leftCol
> rightCol
)
4291 m_selectedTopLeft
.Set( topRow
, leftCol
);
4292 m_selectedBottomRight
.Set( bottomRow
, rightCol
);
4294 if ( !GetBatchCount() )
4296 wxRect
rect( SelectionToRect() );
4297 if ( rect
!= wxGridNoCellRect
) Refresh( TRUE
, &rect
);
4300 // only generate an event if the block is not being selected by
4301 // dragging the mouse (in which case the event will be generated in
4303 if ( !m_isDragging
)
4305 wxGridRangeSelectEvent
gridEvt( GetId(),
4306 EVT_GRID_RANGE_SELECT
,
4309 m_selectedBottomRight
);
4311 GetEventHandler()->ProcessEvent(gridEvt
);
4315 void wxGrid::SelectAll()
4317 m_selectedTopLeft
.Set( 0, 0 );
4318 m_selectedBottomRight
.Set( m_numRows
-1, m_numCols
-1 );
4320 if ( !GetBatchCount() ) Refresh();
4324 void wxGrid::ClearSelection()
4326 if ( IsSelection() )
4328 wxRect
rect( SelectionToRect() );
4329 if ( rect
!= wxGridNoCellRect
)
4331 Refresh( TRUE
, &rect
);
4334 m_selectedTopLeft
= wxGridNoCellCoords
;
4335 m_selectedBottomRight
= wxGridNoCellCoords
;
4340 wxRect
wxGrid::SelectionToRect()
4345 if ( IsSelection() )
4347 cellRect
= CellToRect( m_selectedTopLeft
);
4348 if ( cellRect
!= wxGridNoCellRect
)
4354 rect
= wxRect( m_left
, m_top
, 0, 0 );
4357 cellRect
= CellToRect( m_selectedBottomRight
);
4358 if ( cellRect
!= wxGridNoCellRect
)
4364 return wxGridNoCellRect
;
4375 // ------ Grid event classes
4378 IMPLEMENT_DYNAMIC_CLASS( wxGridEvent
, wxEvent
)
4380 wxGridEvent::wxGridEvent( int id
, wxEventType type
, wxObject
* obj
,
4381 int row
, int col
, int x
, int y
,
4382 bool control
, bool shift
, bool alt
, bool meta
)
4383 : wxNotifyEvent( type
, id
)
4389 m_control
= control
;
4394 SetEventObject(obj
);
4398 IMPLEMENT_DYNAMIC_CLASS( wxGridSizeEvent
, wxEvent
)
4400 wxGridSizeEvent::wxGridSizeEvent( int id
, wxEventType type
, wxObject
* obj
,
4401 int rowOrCol
, int x
, int y
,
4402 bool control
, bool shift
, bool alt
, bool meta
)
4403 : wxNotifyEvent( type
, id
)
4405 m_rowOrCol
= rowOrCol
;
4408 m_control
= control
;
4413 SetEventObject(obj
);
4417 IMPLEMENT_DYNAMIC_CLASS( wxGridRangeSelectEvent
, wxEvent
)
4419 wxGridRangeSelectEvent::wxGridRangeSelectEvent(int id
, wxEventType type
, wxObject
* obj
,
4420 const wxGridCellCoords
& topLeft
,
4421 const wxGridCellCoords
& bottomRight
,
4422 bool control
, bool shift
, bool alt
, bool meta
)
4423 : wxNotifyEvent( type
, id
)
4425 m_topLeft
= topLeft
;
4426 m_bottomRight
= bottomRight
;
4427 m_control
= control
;
4432 SetEventObject(obj
);
4436 #endif // ifndef wxUSE_NEW_GRID