X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b3a7510d21b9d4f9646b32edf9fe6f453f2c6dc9..dfc6cd933d3558c81623c272dcd805f6dc7433f1:/src/generic/grid.cpp diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index faeb6fcc13..623d484c3b 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// Name: grid.cpp +// Name: generic/grid.cpp // Purpose: wxGrid and related classes // Author: Michael Bedward (based on code by Julian Smart, Robin Dunn) // Modified by: @@ -48,7 +48,6 @@ #include "wx/grid.h" - // ---------------------------------------------------------------------------- // array classes // ---------------------------------------------------------------------------- @@ -267,6 +266,10 @@ public: static size_t gs_nAttrCacheMisses = 0; #endif // DEBUG_ATTR_CACHE +// ---------------------------------------------------------------------------- +// constants +// ---------------------------------------------------------------------------- + wxGridCellCoords wxGridNoCellCoords( -1, -1 ); wxRect wxGridNoCellRect( -1, -1, -1, -1 ); @@ -274,6 +277,10 @@ wxRect wxGridNoCellRect( -1, -1, -1, -1 ); // TODO: fixed so far - make configurable later (and also different for x/y) static const size_t GRID_SCROLL_LINE = 10; +// the size of hash tables used a bit everywhere (the max number of elements +// in these hash tables is the number of rows/columns) +static const int GRID_HASH_SIZE = 100; + // ============================================================================ // implementation // ============================================================================ @@ -1965,10 +1972,41 @@ void wxGridWindow::OnKeyDown( wxKeyEvent& event ) if ( !m_owner->ProcessEvent( event ) ) event.Skip(); } -void wxGridWindow::OnEraseBackground(wxEraseEvent&) -{ } - - +// We are trapping erase background events to reduce flicker under MSW +// and GTK but this can leave junk in the space beyond the last row and +// col. So here we paint these spaces if they are visible. +// +void wxGridWindow::OnEraseBackground(wxEraseEvent& event) +{ + int cw, ch; + GetClientSize( &cw, &ch ); + + int right, bottom; + m_owner->CalcUnscrolledPosition( cw, ch, &right, &bottom ); + + wxRect rightRect; + rightRect = m_owner->CellToRect( 0, m_owner->GetNumberCols()-1 ); + + wxRect bottomRect; + bottomRect = m_owner->CellToRect( m_owner->GetNumberRows()-1, 0 ); + + if ( right > rightRect.GetRight() || bottom > bottomRect.GetBottom() ) + { + int left, top; + m_owner->CalcUnscrolledPosition( 0, 0, &left, &top ); + + wxClientDC dc( this ); + m_owner->PrepareDC( dc ); + dc.SetBrush( wxBrush(m_owner->GetDefaultCellBackgroundColour(), wxSOLID) ); + dc.SetPen( *wxTRANSPARENT_PEN ); + + if ( right > rightRect.GetRight() ) + dc.DrawRectangle( rightRect.GetRight()+1, top, right - rightRect.GetRight(), ch ); + + if ( bottom > bottomRect.GetBottom() ) + dc.DrawRectangle( left, bottomRect.GetBottom()+1, cw, bottom - bottomRect.GetBottom() ); + } +} ////////////////////////////////////////////////////////////////////// @@ -1989,7 +2027,8 @@ wxGrid::wxGrid( wxWindow *parent, const wxSize& size, long style, const wxString& name ) - : wxScrolledWindow( parent, id, pos, size, style, name ) + : wxScrolledWindow( parent, id, pos, size, style, name ), + m_colMinWidths(wxKEY_INTEGER, GRID_HASH_SIZE) { Create(); } @@ -2118,8 +2157,6 @@ bool wxGrid::SetTable( wxGridTableBase *table, bool takeOwnership ) void wxGrid::Init() { - int i; - if ( m_numRows <= 0 ) m_numRows = WXGRID_DEFAULT_NUMBER_ROWS; @@ -2163,26 +2200,6 @@ void wxGrid::Init() m_defaultRowHeight += 4; #endif - m_rowHeights.Alloc( m_numRows ); - m_rowBottoms.Alloc( m_numRows ); - int rowBottom = 0; - for ( i = 0; i < m_numRows; i++ ) - { - m_rowHeights.Add( m_defaultRowHeight ); - rowBottom += m_defaultRowHeight; - m_rowBottoms.Add( rowBottom ); - } - - m_colWidths.Alloc( m_numCols ); - m_colRights.Alloc( m_numCols ); - int colRight = 0; - for ( i = 0; i < m_numCols; i++ ) - { - m_colWidths.Add( m_defaultColWidth ); - colRight += m_defaultColWidth; - m_colRights.Add( colRight ); - } - // Set default cell attributes m_defaultCellAttr->SetFont(GetFont()); m_defaultCellAttr->SetAlignment(wxLEFT, wxTOP); @@ -2220,9 +2237,84 @@ void wxGrid::Init() m_inOnKeyDown = FALSE; m_batchCount = 0; +} +// ---------------------------------------------------------------------------- +// the idea is to call these functions only when necessary because they create +// quite big arrays which eat memory mostly unnecessary - in particular, if +// default widths/heights are used for all rows/columns, we may not use these +// arrays at all +// +// with some extra code, it should be possible to only store the +// widths/heights different from default ones but this will be done later... +// ---------------------------------------------------------------------------- + +void wxGrid::InitRowHeights() +{ + m_rowHeights.Empty(); + m_rowBottoms.Empty(); + + m_rowHeights.Alloc( m_numRows ); + m_rowBottoms.Alloc( m_numRows ); + + int rowBottom = 0; + for ( int i = 0; i < m_numRows; i++ ) + { + m_rowHeights.Add( m_defaultRowHeight ); + rowBottom += m_defaultRowHeight; + m_rowBottoms.Add( rowBottom ); + } } +void wxGrid::InitColWidths() +{ + m_colWidths.Empty(); + m_colRights.Empty(); + + m_colWidths.Alloc( m_numCols ); + m_colRights.Alloc( m_numCols ); + int colRight = 0; + for ( int i = 0; i < m_numCols; i++ ) + { + m_colWidths.Add( m_defaultColWidth ); + colRight += m_defaultColWidth; + m_colRights.Add( colRight ); + } +} + +int wxGrid::GetColWidth(int col) const +{ + return m_colWidths.IsEmpty() ? m_defaultColWidth : m_colWidths[col]; +} + +int wxGrid::GetColLeft(int col) const +{ + return m_colRights.IsEmpty() ? col * m_defaultColWidth + : m_colRights[col] - m_colWidths[col]; +} + +int wxGrid::GetColRight(int col) const +{ + return m_colRights.IsEmpty() ? (col + 1) * m_defaultColWidth + : m_colRights[col]; +} + +int wxGrid::GetRowHeight(int row) const +{ + return m_rowHeights.IsEmpty() ? m_defaultRowHeight : m_rowHeights[row]; +} + +int wxGrid::GetRowTop(int row) const +{ + return m_rowBottoms.IsEmpty() ? row * m_defaultRowHeight + : m_rowBottoms[row] - m_rowHeights[row]; +} + +int wxGrid::GetRowBottom(int row) const +{ + return m_rowBottoms.IsEmpty() ? (row + 1) * m_defaultRowHeight + : m_rowBottoms[row]; +} void wxGrid::CalcDimensions() { @@ -2231,8 +2323,8 @@ void wxGrid::CalcDimensions() if ( m_numRows > 0 && m_numCols > 0 ) { - int right = m_colRights[ m_numCols-1 ] + 50; - int bottom = m_rowBottoms[ m_numRows-1 ] + 50; + int right = GetColRight( m_numCols-1 ) + 50; + int bottom = GetRowBottom( m_numRows-1 ) + 50; // TODO: restore the scroll position that we had before sizing // @@ -2271,6 +2363,18 @@ bool wxGrid::Redimension( wxGridTableMessage& msg ) { int i; + // if we were using the default widths/heights so far, we must change them + // now + if ( m_colWidths.IsEmpty() ) + { + InitColWidths(); + } + + if ( m_rowHeights.IsEmpty() ) + { + InitRowHeights(); + } + switch ( msg.GetId() ) { case wxGRIDTABLE_NOTIFY_ROWS_INSERTED: @@ -2476,13 +2580,13 @@ void wxGrid::CalcRowLabelsExposed( wxRegion& reg ) // find the row labels within these bounds // int row; - int rowTop; for ( row = 0; row < m_numRows; row++ ) { - if ( m_rowBottoms[row] < top ) continue; + if ( GetRowBottom(row) < top ) + continue; - rowTop = m_rowBottoms[row] - m_rowHeights[row]; - if ( rowTop > bottom ) break; + if ( GetRowTop(row) > bottom ) + break; m_rowLabelsExposed.Add( row ); } @@ -2525,13 +2629,13 @@ void wxGrid::CalcColLabelsExposed( wxRegion& reg ) // find the cells within these bounds // int col; - int colLeft; for ( col = 0; col < m_numCols; col++ ) { - if ( m_colRights[col] < left ) continue; + if ( GetColRight(col) < left ) + continue; - colLeft = m_colRights[col] - m_colWidths[col]; - if ( colLeft > right ) break; + if ( GetColLeft(col) > right ) + break; m_colLabelsExposed.Add( col ); } @@ -2577,29 +2681,31 @@ void wxGrid::CalcCellsExposed( wxRegion& reg ) // find the cells within these bounds // int row, col; - int colLeft, rowTop; for ( row = 0; row < m_numRows; row++ ) { - if ( m_rowBottoms[row] <= top ) continue; + if ( GetRowBottom(row) <= top ) + continue; - rowTop = m_rowBottoms[row] - m_rowHeights[row]; - if ( rowTop > bottom ) break; + if ( GetRowTop(row) > bottom ) + break; m_rowsExposed.Add( row ); for ( col = 0; col < m_numCols; col++ ) { - if ( m_colRights[col] <= left ) continue; + if ( GetColRight(col) <= left ) + continue; - colLeft = m_colRights[col] - m_colWidths[col]; - if ( colLeft > right ) break; + if ( GetColLeft(col) > right ) + break; - if ( m_colsExposed.Index( col ) == wxNOT_FOUND ) m_colsExposed.Add( col ); + if ( m_colsExposed.Index( col ) == wxNOT_FOUND ) + m_colsExposed.Add( col ); m_cellsExposed.Add( wxGridCellCoords( row, col ) ); } } - iter++ ; + iter++; } } @@ -2626,10 +2732,7 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event ) wxClientDC dc( m_gridWin ); PrepareDC( dc ); - y = wxMax( y, - m_rowBottoms[m_dragRowOrCol] - - m_rowHeights[m_dragRowOrCol] + - WXGRID_MIN_ROW_HEIGHT ); + y = wxMax( y, GetRowTop(m_dragRowOrCol) + WXGRID_MIN_ROW_HEIGHT ); dc.SetLogicalFunction(wxINVERT); if ( m_dragLastPos >= 0 ) { @@ -2792,10 +2895,9 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event ) wxClientDC dc( m_gridWin ); PrepareDC( dc ); - x = wxMax( x, - m_colRights[m_dragRowOrCol] - - m_colWidths[m_dragRowOrCol] + - WXGRID_MIN_COL_WIDTH ); + + x = wxMax( x, GetColLeft(m_dragRowOrCol) + + GetColMinimalWidth(m_dragRowOrCol)); dc.SetLogicalFunction(wxINVERT); if ( m_dragLastPos >= 0 ) { @@ -3103,10 +3205,7 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event ) wxClientDC dc( m_gridWin ); PrepareDC( dc ); - y = wxMax( y, - m_rowBottoms[m_dragRowOrCol] - - m_rowHeights[m_dragRowOrCol] + - WXGRID_MIN_ROW_HEIGHT ); + y = wxMax( y, GetRowTop(m_dragRowOrCol) + WXGRID_MIN_ROW_HEIGHT ); dc.SetLogicalFunction(wxINVERT); if ( m_dragLastPos >= 0 ) { @@ -3123,9 +3222,8 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event ) wxClientDC dc( m_gridWin ); PrepareDC( dc ); - x = wxMax( x, - m_colRights[m_dragRowOrCol] - - m_colWidths[m_dragRowOrCol] + WXGRID_MIN_COL_WIDTH ); + x = wxMax( x, GetColLeft(m_dragRowOrCol) + + GetColMinimalWidth(m_dragRowOrCol) ); dc.SetLogicalFunction(wxINVERT); if ( m_dragLastPos >= 0 ) { @@ -3355,7 +3453,7 @@ void wxGrid::DoEndDragResizeRow() dc.DrawLine( left, m_dragLastPos, left+cw, m_dragLastPos ); HideCellEditControl(); - int rowTop = m_rowBottoms[m_dragRowOrCol] - m_rowHeights[m_dragRowOrCol]; + int rowTop = GetRowTop(m_dragRowOrCol); SetRowSize( m_dragRowOrCol, wxMax( m_dragLastPos - rowTop, WXGRID_MIN_ROW_HEIGHT ) ); @@ -3393,9 +3491,10 @@ void wxGrid::DoEndDragResizeCol() dc.DrawLine( m_dragLastPos, top, m_dragLastPos, top+ch ); HideCellEditControl(); - int colLeft = m_colRights[m_dragRowOrCol] - m_colWidths[m_dragRowOrCol]; + int colLeft = GetColLeft(m_dragRowOrCol); SetColSize( m_dragRowOrCol, - wxMax( m_dragLastPos - colLeft, WXGRID_MIN_COL_WIDTH ) ); + wxMax( m_dragLastPos - colLeft, + GetColMinimalWidth(m_dragRowOrCol) ) ); if ( !GetBatchCount() ) { @@ -4075,7 +4174,7 @@ void wxGrid::DrawCell( wxDC& dc, const wxGridCellCoords& coords ) int row = coords.GetRow(); int col = coords.GetCol(); - if ( m_colWidths[col] <= 0 || m_rowHeights[row] <= 0 ) + if ( GetColWidth(col) <= 0 || GetRowHeight(row) <= 0 ) return; // we draw the cell border ourselves @@ -4089,10 +4188,10 @@ void wxGrid::DrawCell( wxDC& dc, const wxGridCellCoords& coords ) bool isCurrent = coords == m_currentCellCoords; wxRect rect; - rect.x = m_colRights[col] - m_colWidths[col]; - rect.y = m_rowBottoms[row] - m_rowHeights[row]; - rect.width = m_colWidths[col] - 1; - rect.height = m_rowHeights[row] - 1; + rect.x = GetColLeft(col); + rect.y = GetRowTop(row); + rect.width = GetColWidth(col) - 1; + rect.height = GetRowHeight(row) - 1; // if the editor is shown, we should use it and not the renderer if ( isCurrent && IsCellEditControlEnabled() ) @@ -4114,14 +4213,14 @@ void wxGrid::DrawCellHighlight( wxDC& dc, const wxGridCellAttr *attr ) int row = m_currentCellCoords.GetRow(); int col = m_currentCellCoords.GetCol(); - if ( m_colWidths[col] <= 0 || m_rowHeights[row] <= 0 ) + if ( GetColWidth(col) <= 0 || GetRowHeight(row) <= 0 ) return; wxRect rect; - rect.x = m_colRights[col] - m_colWidths[col]; - rect.y = m_rowBottoms[row] - m_rowHeights[row]; - rect.width = m_colWidths[col] - 1; - rect.height = m_rowHeights[row] - 1; + rect.x = GetColLeft(col); + rect.y = GetRowTop(row); + rect.width = GetColWidth(col) - 1; + rect.height = GetRowHeight(row) - 1; // hmmm... what could we do here to show that the cell is disabled? // for now, I just draw a thinner border than for the other ones, but @@ -4155,22 +4254,22 @@ void wxGrid::DrawCellHighlight( wxDC& dc, const wxGridCellAttr *attr ) void wxGrid::DrawCellBorder( wxDC& dc, const wxGridCellCoords& coords ) { - if ( m_colWidths[coords.GetCol()] <=0 || - m_rowHeights[coords.GetRow()] <= 0 ) return; - - dc.SetPen( wxPen(GetGridLineColour(), 1, wxSOLID) ); int row = coords.GetRow(); int col = coords.GetCol(); + if ( GetColWidth(col) <= 0 || GetRowHeight(row) <= 0 ) + return; + + dc.SetPen( wxPen(GetGridLineColour(), 1, wxSOLID) ); // right hand border // - dc.DrawLine( m_colRights[col], m_rowBottoms[row] - m_rowHeights[row], - m_colRights[col], m_rowBottoms[row] ); + dc.DrawLine( GetColRight(col), GetRowTop(row), + GetColRight(col), GetRowBottom(row) ); // bottom border // - dc.DrawLine( m_colRights[col] - m_colWidths[col], m_rowBottoms[row], - m_colRights[col], m_rowBottoms[row] ); + dc.DrawLine( GetColLeft(col), GetRowBottom(row), + GetColRight(col), GetRowBottom(row) ); } void wxGrid::DrawHighlight(wxDC& dc) @@ -4223,8 +4322,8 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & reg ) // avoid drawing grid lines past the last row and col // - right = wxMin( right, m_colRights[m_numCols-1] ); - bottom = wxMin( bottom, m_rowBottoms[m_numRows-1] ); + right = wxMin( right, GetColRight(m_numCols - 1) ); + bottom = wxMin( bottom, GetRowBottom(m_numRows - 1) ); dc.SetPen( wxPen(GetGridLineColour(), 1, wxSOLID) ); @@ -4233,13 +4332,16 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & reg ) int i; for ( i = 0; i < m_numRows; i++ ) { - if ( m_rowBottoms[i]-1 > bottom ) + int bot = GetRowBottom(i) - 1; + + if ( bot > bottom ) { break; } - else if ( m_rowBottoms[i]-1 >= top ) + + if ( bot >= top ) { - dc.DrawLine( left, m_rowBottoms[i]-1, right, m_rowBottoms[i]-1 ); + dc.DrawLine( left, bot, right, bot ); } } @@ -4248,13 +4350,15 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & reg ) // for ( i = 0; i < m_numCols; i++ ) { - if ( m_colRights[i]-1 > right ) + int colRight = GetColRight(i) - 1; + if ( colRight > right ) { break; } - else if ( m_colRights[i]-1 >= left ) + + if ( colRight >= left ) { - dc.DrawLine( m_colRights[i]-1, top, m_colRights[i]-1, bottom ); + dc.DrawLine( colRight, top, colRight, bottom ); } } } @@ -4276,19 +4380,20 @@ void wxGrid::DrawRowLabels( wxDC& dc ) void wxGrid::DrawRowLabel( wxDC& dc, int row ) { - if ( m_rowHeights[row] <= 0 ) return; + if ( GetRowHeight(row) <= 0 ) + return; - int rowTop = m_rowBottoms[row] - m_rowHeights[row]; + int rowTop = GetRowTop(row), + rowBottom = GetRowBottom(row) - 1; dc.SetPen( *wxBLACK_PEN ); dc.DrawLine( m_rowLabelWidth-1, rowTop, - m_rowLabelWidth-1, m_rowBottoms[row]-1 ); + m_rowLabelWidth-1, rowBottom ); - dc.DrawLine( 0, m_rowBottoms[row]-1, - m_rowLabelWidth-1, m_rowBottoms[row]-1 ); + dc.DrawLine( 0, rowBottom, m_rowLabelWidth-1, rowBottom ); dc.SetPen( *wxWHITE_PEN ); - dc.DrawLine( 0, rowTop, 0, m_rowBottoms[row]-1 ); + dc.DrawLine( 0, rowTop, 0, rowBottom ); dc.DrawLine( 0, rowTop, m_rowLabelWidth-1, rowTop ); dc.SetBackgroundMode( wxTRANSPARENT ); @@ -4300,9 +4405,9 @@ void wxGrid::DrawRowLabel( wxDC& dc, int row ) wxRect rect; rect.SetX( 2 ); - rect.SetY( m_rowBottoms[row] - m_rowHeights[row] + 2 ); + rect.SetY( GetRowTop(row) + 2 ); rect.SetWidth( m_rowLabelWidth - 4 ); - rect.SetHeight( m_rowHeights[row] - 4 ); + rect.SetHeight( GetRowHeight(row) - 4 ); DrawTextRectangle( dc, GetRowLabelValue( row ), rect, hAlign, vAlign ); } @@ -4323,20 +4428,22 @@ void wxGrid::DrawColLabels( wxDC& dc ) void wxGrid::DrawColLabel( wxDC& dc, int col ) { - if ( m_colWidths[col] <= 0 ) return; + if ( GetColWidth(col) <= 0 ) + return; - int colLeft = m_colRights[col] - m_colWidths[col]; + int colLeft = GetColLeft(col), + colRight = GetColRight(col) - 1; dc.SetPen( *wxBLACK_PEN ); - dc.DrawLine( m_colRights[col]-1, 0, - m_colRights[col]-1, m_colLabelHeight-1 ); + dc.DrawLine( colRight, 0, + colRight, m_colLabelHeight-1 ); dc.DrawLine( colLeft, m_colLabelHeight-1, - m_colRights[col]-1, m_colLabelHeight-1 ); + colRight, m_colLabelHeight-1 ); dc.SetPen( *wxWHITE_PEN ); dc.DrawLine( colLeft, 0, colLeft, m_colLabelHeight-1 ); - dc.DrawLine( colLeft, 0, m_colRights[col]-1, 0 ); + dc.DrawLine( colLeft, 0, colRight, 0 ); dc.SetBackgroundMode( wxTRANSPARENT ); dc.SetTextForeground( GetLabelTextColour() ); @@ -4350,9 +4457,9 @@ void wxGrid::DrawColLabel( wxDC& dc, int col ) GetColLabelAlignment( &hAlign, &vAlign ); wxRect rect; - rect.SetX( m_colRights[col] - m_colWidths[col] + 2 ); + rect.SetX( colLeft + 2 ); rect.SetY( 2 ); - rect.SetWidth( m_colWidths[col] - 4 ); + rect.SetWidth( GetColWidth(col) - 4 ); rect.SetHeight( m_colLabelHeight - 4 ); DrawTextRectangle( dc, GetColLabelValue( col ), rect, hAlign, vAlign ); } @@ -4717,7 +4824,8 @@ int wxGrid::YToRow( int y ) for ( i = 0; i < m_numRows; i++ ) { - if ( y < m_rowBottoms[i] ) return i; + if ( y < GetRowBottom(i) ) + return i; } return m_numRows; //-1; @@ -4730,7 +4838,8 @@ int wxGrid::XToCol( int x ) for ( i = 0; i < m_numCols; i++ ) { - if ( x < m_colRights[i] ) return i; + if ( x < GetColRight(i) ) + return i; } return m_numCols; //-1; @@ -4746,12 +4855,11 @@ int wxGrid::YToEdgeOfRow( int y ) for ( i = 0; i < m_numRows; i++ ) { - if ( m_rowHeights[i] > WXGRID_LABEL_EDGE_ZONE ) + if ( GetRowHeight(i) > WXGRID_LABEL_EDGE_ZONE ) { - d = abs( y - m_rowBottoms[i] ); - { - if ( d < WXGRID_LABEL_EDGE_ZONE ) return i; - } + d = abs( y - GetRowBottom(i) ); + if ( d < WXGRID_LABEL_EDGE_ZONE ) + return i; } } @@ -4768,12 +4876,11 @@ int wxGrid::XToEdgeOfCol( int x ) for ( i = 0; i < m_numCols; i++ ) { - if ( m_colWidths[i] > WXGRID_LABEL_EDGE_ZONE ) + if ( GetColWidth(i) > WXGRID_LABEL_EDGE_ZONE ) { - d = abs( x - m_colRights[i] ); - { - if ( d < WXGRID_LABEL_EDGE_ZONE ) return i; - } + d = abs( x - GetColRight(i) ); + if ( d < WXGRID_LABEL_EDGE_ZONE ) + return i; } } @@ -4788,10 +4895,10 @@ wxRect wxGrid::CellToRect( int row, int col ) if ( row >= 0 && row < m_numRows && col >= 0 && col < m_numCols ) { - rect.x = m_colRights[col] - m_colWidths[col]; - rect.y = m_rowBottoms[row] - m_rowHeights[row]; - rect.width = m_colWidths[col]; - rect.height = m_rowHeights[ row ]; + rect.x = GetColLeft(col); + rect.y = GetRowTop(row); + rect.width = GetColWidth(col); + rect.height = GetRowHeight(row); } return rect; @@ -4866,10 +4973,12 @@ void wxGrid::MakeCellVisible( int row, int col ) ypos = r.GetTop(); for ( i = row-1; i >= 0; i-- ) { - if ( h + m_rowHeights[i] > ch ) break; + int rowHeight = GetRowHeight(i); + if ( h + rowHeight > ch ) + break; - h += m_rowHeights[i]; - ypos -= m_rowHeights[i]; + h += rowHeight; + ypos -= rowHeight; } // we divide it later by GRID_SCROLL_LINE, make sure that we don't @@ -4888,10 +4997,12 @@ void wxGrid::MakeCellVisible( int row, int col ) xpos = r.GetLeft(); for ( i = col-1; i >= 0; i-- ) { - if ( w + m_colWidths[i] > cw ) break; + int colWidth = GetColWidth(i); + if ( w + colWidth > cw ) + break; - w += m_colWidths[i]; - xpos -= m_colWidths[i]; + w += colWidth; + xpos -= colWidth; } // see comment for ypos above @@ -4997,7 +5108,7 @@ bool wxGrid::MovePageUp() int cw, ch; m_gridWin->GetClientSize( &cw, &ch ); - int y = m_rowBottoms[ row ] - m_rowHeights[ row ]; + int y = GetRowTop(row); int newRow = YToRow( y - ch + 1 ); if ( newRow == -1 ) { @@ -5027,7 +5138,7 @@ bool wxGrid::MovePageDown() int cw, ch; m_gridWin->GetClientSize( &cw, &ch ); - int y = m_rowBottoms[ row ] - m_rowHeights[ row ]; + int y = GetRowTop(row); int newRow = YToRow( y + ch ); if ( newRow == -1 ) { @@ -5519,7 +5630,7 @@ int wxGrid::GetRowSize( int row ) { wxCHECK_MSG( row >= 0 && row < m_numRows, 0, _T("invalid row index") ); - return m_rowHeights[row]; + return GetRowHeight(row); } int wxGrid::GetDefaultColSize() @@ -5531,7 +5642,7 @@ int wxGrid::GetColSize( int col ) { wxCHECK_MSG( col >= 0 && col < m_numCols, 0, _T("invalid column index") ); - return m_colWidths[col]; + return GetColWidth(col); } // ============================================================================ @@ -5892,14 +6003,8 @@ void wxGrid::SetDefaultRowSize( int height, bool resizeExistingRows ) if ( resizeExistingRows ) { - int row; - int bottom = 0; - for ( row = 0; row < m_numRows; row++ ) - { - m_rowHeights[row] = m_defaultRowHeight; - bottom += m_defaultRowHeight; - m_rowBottoms[row] = bottom; - } + InitRowHeights(); + CalcDimensions(); } } @@ -5908,12 +6013,17 @@ void wxGrid::SetRowSize( int row, int height ) { wxCHECK_RET( row >= 0 && row < m_numRows, _T("invalid row index") ); - int i; + if ( m_rowHeights.IsEmpty() ) + { + // need to really create the array + InitRowHeights(); + } int h = wxMax( 0, height ); int diff = h - m_rowHeights[row]; m_rowHeights[row] = h; + int i; for ( i = row; i < m_numRows; i++ ) { m_rowBottoms[i] += diff; @@ -5927,14 +6037,8 @@ void wxGrid::SetDefaultColSize( int width, bool resizeExistingCols ) if ( resizeExistingCols ) { - int col; - int right = 0; - for ( col = 0; col < m_numCols; col++ ) - { - m_colWidths[col] = m_defaultColWidth; - right += m_defaultColWidth; - m_colRights[col] = right; - } + InitColWidths(); + CalcDimensions(); } } @@ -5943,12 +6047,19 @@ void wxGrid::SetColSize( int col, int width ) { wxCHECK_RET( col >= 0 && col < m_numCols, _T("invalid column index") ); - int i; + // should we check that it's bigger than GetColMinimalWidth(col) here? + + if ( m_colWidths.IsEmpty() ) + { + // need to really create the array + InitColWidths(); + } int w = wxMax( 0, width ); int diff = w - m_colWidths[col]; m_colWidths[col] = w; + int i; for ( i = col; i < m_numCols; i++ ) { m_colRights[i] += diff; @@ -5957,6 +6068,17 @@ void wxGrid::SetColSize( int col, int width ) } +void wxGrid::SetColMinimalWidth( int col, int width ) +{ + m_colMinWidths.Put(col, (wxObject *)width); +} + +int wxGrid::GetColMinimalWidth(int col) const +{ + wxObject *obj = m_colMinWidths.Get(m_dragRowOrCol); + return obj ? (int)obj : WXGRID_MIN_COL_WIDTH; +} + // // ------ cell value accessor functions //