X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7c3f33a9430a50a95ed943bad38175b1d02a777c..6cfe484434ddd9e130a0e6e2d5868fd67f189b92:/src/generic/grid.cpp diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index a921b3817c..22939d4afc 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -1234,7 +1234,7 @@ bool wxGridCellFloatEditor::IsAcceptedKey(wxKeyEvent& event) // ---------------------------------------------------------------------------- // the default values for GetValue() -wxString wxGridCellBoolEditor::ms_stringValues[2] = { _T("1"), _T("") }; +wxString wxGridCellBoolEditor::ms_stringValues[2] = { _T(""), _T("1") }; void wxGridCellBoolEditor::Create(wxWindow* parent, wxWindowID id, @@ -4198,8 +4198,12 @@ wxGrid::~wxGrid() total ? (gs_nAttrCacheHits*100) / total : 0); #endif - if (m_ownTable) + // if we own the table, just delete it, otherwise at least don't leave it + // with dangling view pointer + if ( m_ownTable ) delete m_table; + else if ( m_table && m_table->GetView() == this ) + m_table->SetView(NULL); delete m_typeRegistry; delete m_selection; @@ -4481,8 +4485,9 @@ void wxGrid::Init() // 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... +// with some extra code, it should be possible to only store the widths/heights +// different from default ones (resulting in space savings for huge grids) but +// this is not done currently // ---------------------------------------------------------------------------- void wxGrid::InitRowHeights() @@ -4493,10 +4498,9 @@ void wxGrid::InitRowHeights() m_rowHeights.Alloc( m_numRows ); m_rowBottoms.Alloc( m_numRows ); - int rowBottom = 0; - m_rowHeights.Add( m_defaultRowHeight, m_numRows ); + int rowBottom = 0; for ( int i = 0; i < m_numRows; i++ ) { rowBottom += m_defaultRowHeight; @@ -4511,10 +4515,10 @@ void wxGrid::InitColWidths() m_colWidths.Alloc( m_numCols ); m_colRights.Alloc( m_numCols ); - int colRight = 0; m_colWidths.Add( m_defaultColWidth, m_numCols ); + int colRight = 0; for ( int i = 0; i < m_numCols; i++ ) { colRight = ( GetColPos( i ) + 1 ) * m_defaultColWidth; @@ -4558,17 +4562,12 @@ int wxGrid::GetRowBottom(int row) const void wxGrid::CalcDimensions() { - int cw, ch; - GetClientSize( &cw, &ch ); - - if ( m_rowLabelWin->IsShown() ) - cw -= m_rowLabelWidth; - if ( m_colLabelWin->IsShown() ) - ch -= m_colLabelHeight; + // compute the size of the scrollable area + int w = m_numCols > 0 ? GetColRight(GetColAt(m_numCols - 1)) : 0; + int h = m_numRows > 0 ? GetRowBottom(m_numRows - 1) : 0; - // grid total size - int w = m_numCols > 0 ? GetColRight(GetColAt( m_numCols - 1 )) + m_extraWidth + 1 : 0; - int h = m_numRows > 0 ? GetRowBottom(m_numRows - 1) + m_extraHeight + 1 : 0; + w += m_extraWidth; + h += m_extraHeight; // take into account editor if shown if ( IsCellEditControlShown() ) @@ -4605,7 +4604,8 @@ void wxGrid::CalcDimensions() // do set scrollbar parameters SetScrollbars( m_scrollLineX, m_scrollLineY, - GetScrollX(w), GetScrollY(h), x, y, + GetScrollX(w), GetScrollY(h), + x, y, GetBatchCount() != 0); // if our OnSize() hadn't been called (it would if we have scrollbars), we @@ -4623,6 +4623,33 @@ void wxGrid::CalcWindowSizes() int cw, ch; GetClientSize( &cw, &ch ); + // this block of code tries to work around the following problem: the grid + // could have been just resized to have enough space to show the full grid + // window contents without the scrollbars, but its client size could be + // not big enough because the grid has the scrollbars right now and so the + // scrollbars would remain even though we don't need them any more + // + // to prevent this from happening, check if we have enough space for + // everything without the scrollbars and explicitly disable them then + wxSize size = GetSize() - GetWindowBorderSize(); + if ( size != wxSize(cw, ch) ) + { + // check if we have enough space for grid window after accounting for + // the fixed size elements + size.x -= m_rowLabelWidth; + size.y -= m_colLabelHeight; + + const wxSize vsize = m_gridWin->GetVirtualSize(); + + if ( size.x >= vsize.x && size.y >= vsize.y ) + { + // yes, we do, so remove the scrollbars and use the new client size + // (which should be the same as full window size - borders now) + SetScrollbars(0, 0, 0, 0); + GetClientSize(&cw, &ch); + } + } + if ( m_cornerLabelWin && m_cornerLabelWin->IsShown() ) m_cornerLabelWin->SetSize( 0, 0, m_rowLabelWidth, m_colLabelHeight ); @@ -7098,8 +7125,10 @@ void wxGrid::SetCurrentCell( const wxGridCellCoords& coords ) return; } +#if !(defined(__WXMAC__) && wxMAC_USE_CORE_GRAPHICS) wxClientDC dc( m_gridWin ); PrepareDC( dc ); +#endif if ( m_currentCellCoords != wxGridNoCellCoords ) { @@ -7122,15 +7151,21 @@ void wxGrid::SetCurrentCell( const wxGridCellCoords& coords ) // Otherwise refresh redraws the highlight! m_currentCellCoords = coords; +#if defined(__WXMAC__) && wxMAC_USE_CORE_GRAPHICS + m_gridWin->Refresh(true /*, & r */); +#else DrawGridCellArea( dc, cells ); DrawAllGridLines( dc, r ); +#endif } } m_currentCellCoords = coords; wxGridCellAttr *attr = GetCellAttr( coords ); +#if !(defined(__WXMAC__) && wxMAC_USE_CORE_GRAPHICS) DrawCellHighlight( dc, attr ); +#endif attr->DecRef(); } @@ -7506,7 +7541,7 @@ void wxGrid::DrawCell( wxDC& dc, const wxGridCellCoords& coords ) // edit control is erased by this code after being rendered. // On wxMac (QD build only), the cell editor is a wxTextCntl and is rendered // implicitly, causing this out-of order render. -#if !defined(__WXMAC__) || wxMAC_USE_CORE_GRAPHICS +#if !defined(__WXMAC__) wxGridCellEditor *editor = attr->GetEditor(this, row, col); editor->PaintBackground(rect, attr); editor->DecRef(); @@ -7701,8 +7736,7 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & WXUNUSED(reg) ) int rightCol = GetColPos( internalXToCol(right) ); int bottomRow = internalYToRow(bottom); -#ifndef __WXMAC__ - // CS: I don't know why suddenly unscrolled coordinates are used for clipping +#if !defined(__WXMAC__) || wxMAC_USE_CORE_GRAPHICS wxRegion clippedcells(0, 0, cw, ch); int i, j, cell_rows, cell_cols; @@ -10232,8 +10266,7 @@ void wxGrid::SetRowSize( int row, int height ) int diff = h - m_rowHeights[row]; m_rowHeights[row] = h; - int i; - for ( i = row; i < m_numRows; i++ ) + for ( int i = row; i < m_numRows; i++ ) { m_rowBottoms[i] += diff; } @@ -10296,12 +10329,9 @@ void wxGrid::SetColSize( int col, int width ) int diff = w - m_colWidths[col]; m_colWidths[col] = w; - int i; - int colPos; - for ( colPos = GetColPos( col ); colPos < m_numCols; colPos++ ) + for ( int colPos = GetColPos(col); colPos < m_numCols; colPos++ ) { - i = GetColAt( colPos ); - m_colRights[i] += diff; + m_colRights[GetColAt(colPos)] += diff; } if ( !GetBatchCount() ) @@ -10530,21 +10560,17 @@ void wxGrid::AutoSize() { BeginBatch(); - wxSize size(SetOrCalcColumnSizes(false), SetOrCalcRowSizes(false)); - - // round up the size to a multiple of scroll step - this ensures that we - // won't get the scrollbars if we're sized exactly to this width - // CalcDimension adds m_extraWidth + 1 etc. to calculate the necessary - // scrollbar steps - wxSize sizeFit( - GetScrollX(size.x + m_extraWidth + 1) * m_scrollLineX, - GetScrollY(size.y + m_extraHeight + 1) * m_scrollLineY ); + // we need to round up the size of the scrollable area to a multiple of + // scroll step to ensure that we don't get the scrollbars when we're sized + // exactly to fit our contents + wxSize size(SetOrCalcColumnSizes(false) - m_rowLabelWidth + m_extraWidth, + SetOrCalcRowSizes(false) - m_colLabelHeight + m_extraHeight); + wxSize sizeFit(GetScrollX(size.x) * GetScrollLineX(), + GetScrollY(size.y) * GetScrollLineY()); // distribute the extra space between the columns/rows to avoid having // extra white space - - // Remove the extra m_extraWidth + 1 added above - wxCoord diff = sizeFit.x - size.x + (m_extraWidth + 1); + wxCoord diff = sizeFit.x - size.x; if ( diff && m_numCols ) { // try to resize the columns uniformly @@ -10569,7 +10595,7 @@ void wxGrid::AutoSize() } // same for rows - diff = sizeFit.y - size.y - (m_extraHeight + 1); + diff = sizeFit.y - size.y; if ( diff && m_numRows ) { // try to resize the columns uniformly @@ -10593,9 +10619,13 @@ void wxGrid::AutoSize() } } - EndBatch(); + // we know that we're not going to have scrollbars so disable them now to + // avoid trouble in SetClientSize() which can otherwise set the correct + // client size but also leave space for (not needed any more) scrollbars + SetScrollbars(0, 0, 0, 0, 0, 0, true); + SetClientSize(sizeFit.x + m_rowLabelWidth, sizeFit.y + m_colLabelHeight); - SetClientSize(sizeFit); + EndBatch(); } void wxGrid::AutoSizeRowLabelSize( int row ) @@ -10649,46 +10679,22 @@ void wxGrid::AutoSizeColLabelSize( int col ) wxSize wxGrid::DoGetBestSize() const { - // don't set sizes, only calculate them wxGrid *self = (wxGrid *)this; // const_cast - int width, height; - width = self->SetOrCalcColumnSizes(true); - height = self->SetOrCalcRowSizes(true); - - if (!width) - width = 100; - if (!height) - height = 80; - - // Round up to a multiple the scroll rate - // NOTE: this still doesn't get rid of the scrollbars; - // is there any magic incantation for that? - int xpu, ypu; - GetScrollPixelsPerUnit(&xpu, &ypu); - if (xpu) - width += 1 + xpu - (width % xpu); - if (ypu) - height += 1 + ypu - (height % ypu); - - // limit to 1/4 of the screen size - int maxwidth, maxheight; - wxDisplaySize( &maxwidth, &maxheight ); - maxwidth /= 2; - maxheight /= 2; - if ( width > maxwidth ) - width = maxwidth; - if ( height > maxheight ) - height = maxheight; - - wxSize best(width, height); + // we do the same as in AutoSize() here with the exception that we don't + // change the column/row sizes, only calculate them + wxSize size(self->SetOrCalcColumnSizes(true) - m_rowLabelWidth + m_extraWidth, + self->SetOrCalcRowSizes(true) - m_colLabelHeight + m_extraHeight); + wxSize sizeFit(GetScrollX(size.x) * GetScrollLineX(), + GetScrollY(size.y) * GetScrollLineY()); // NOTE: This size should be cached, but first we need to add calls to // InvalidateBestSize everywhere that could change the results of this // calculation. // CacheBestSize(size); - return best; + return wxSize(sizeFit.x + m_rowLabelWidth, sizeFit.y + m_colLabelHeight) + + GetWindowBorderSize(); } void wxGrid::Fit()