X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/658fb8e6c5952b13e22da0c720573be7a01724f1..11f26ea0e21667bb9ffe53964651e5133c8ded6e:/src/generic/grid.cpp diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index 7b119c6572..1af51feba4 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -36,6 +36,10 @@ #include "wx/generic/grid.h" +#ifndef WXGRID_DRAW_LINES +#define WXGRID_DRAW_LINES 1 +#endif + ////////////////////////////////////////////////////////////////////// wxGridCellCoords wxGridNoCellCoords( -1, -1 ); @@ -706,7 +710,7 @@ void wxGridRowLabelWindow::OnPaint( wxPaintEvent &event ) // // m_owner->PrepareDC( dc ); - wxCoord x, y; + int x, y; m_owner->CalcUnscrolledPosition( 0, 0, &x, &y ); dc.SetDeviceOrigin( 0, -y ); @@ -759,7 +763,7 @@ void wxGridColLabelWindow::OnPaint( wxPaintEvent &event ) // // m_owner->PrepareDC( dc ); - wxCoord x, y; + int x, y; m_owner->CalcUnscrolledPosition( 0, 0, &x, &y ); dc.SetDeviceOrigin( -x, 0 ); @@ -869,9 +873,12 @@ void wxGridWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) { wxPaintDC dc( this ); m_owner->PrepareDC( dc ); - - m_owner->CalcCellsExposed( GetUpdateRegion() ); + wxRegion reg = GetUpdateRegion(); + m_owner->CalcCellsExposed( reg ); m_owner->DrawGridCellArea( dc ); +#if WXGRID_DRAW_LINES + m_owner->DrawAllGridLines( dc, reg ); +#endif } @@ -1585,9 +1592,15 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event ) SetRowSize( m_dragRowOrCol, wxMax( y - rowTop, WXGRID_MIN_ROW_HEIGHT ) ); if ( !GetBatchCount() ) { - // TODO: optimize this - m_rowLabelWin->Refresh(); - m_gridWin->Refresh(); + // Only needed to get the correct rect.y: + wxRect rect ( CellToRect( m_dragRowOrCol, 0 ) ); + rect.x = 0; + CalcScrolledPosition(0, rect.y, &dummy, &rect.y); + rect.width = m_rowLabelWidth; + rect.height = ch - rect.y; + m_rowLabelWin->Refresh( TRUE, &rect ); + rect.width = cw; + m_gridWin->Refresh( TRUE, &rect ); } ShowCellEditControl(); @@ -1599,6 +1612,7 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event ) } } + m_cursorMode = WXGRID_CURSOR_SELECT_CELL; m_dragLastPos = -1; } @@ -1767,9 +1781,15 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event ) if ( !GetBatchCount() ) { - // TODO: optimize this - m_colLabelWin->Refresh(); - m_gridWin->Refresh(); + // Only needed to get the correct rect.x: + wxRect rect ( CellToRect( 0, m_dragRowOrCol ) ); + rect.y = 0; + CalcScrolledPosition(rect.x, 0, &rect.x, &dummy); + rect.width = cw - rect.x; + rect.height = m_colLabelHeight; + m_colLabelWin->Refresh( TRUE, &rect ); + rect.height = ch; + m_gridWin->Refresh( TRUE, &rect ); } ShowCellEditControl(); @@ -1781,6 +1801,7 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event ) } } + m_cursorMode = WXGRID_CURSOR_SELECT_CELL; m_dragLastPos = -1; } @@ -1986,6 +2007,13 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event ) // no default action at the moment } } + + // ------------ Moving and no button action + // + else if ( event.Moving() && !event.IsButton() ) + { + m_cursorMode = WXGRID_CURSOR_SELECT_CELL; + } } } @@ -2447,6 +2475,7 @@ void wxGrid::OnKeyDown( wxKeyEvent& event ) { event.Skip(); } + break; case WXK_RETURN: if ( event.ControlDown() ) @@ -2601,8 +2630,10 @@ void wxGrid::DrawCell( wxDC& dc, const wxGridCellCoords& coords ) if ( m_colWidths[coords.GetCol()] <=0 || m_rowHeights[coords.GetRow()] <= 0 ) return; +#if !WXGRID_DRAW_LINES if ( m_gridLinesEnabled ) DrawCellBorder( dc, coords ); +#endif DrawCellBackground( dc, coords ); @@ -2706,27 +2737,41 @@ void wxGrid::DrawCellValue( wxDC& dc, const wxGridCellCoords& coords ) // This is used to redraw all grid lines e.g. when the grid line colour // has been changed // -void wxGrid::DrawAllGridLines( wxDC& dc ) +void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & reg ) { if ( !m_gridLinesEnabled || !m_numRows || !m_numCols ) return; - int cw, ch; - m_gridWin->GetClientSize(&cw, &ch); + int top, bottom, left, right; + + if (reg.IsEmpty()){ + int cw, ch; + m_gridWin->GetClientSize(&cw, &ch); + + // virtual coords of visible area + // + CalcUnscrolledPosition( 0, 0, &left, &top ); + CalcUnscrolledPosition( cw, ch, &right, &bottom ); + } + else{ + wxCoord x, y, w, h; + reg.GetBox(x, y, w, h); + CalcUnscrolledPosition( x, y, &left, &top ); + CalcUnscrolledPosition( x + w, y + h, &right, &bottom ); + } - // virtual coords of visible area + // avoid drawing grid lines past the last row and col // - int top, bottom, left, right; - CalcUnscrolledPosition( 0, 0, &left, &top ); - CalcUnscrolledPosition( cw, ch, &right, &bottom ); + right = wxMin( right, m_colRights[m_numCols-1] ); + bottom = wxMin( bottom, m_rowBottoms[m_numRows-1] ); dc.SetPen( wxPen(GetGridLineColour(), 1, wxSOLID) ); // horizontal grid lines // int i; - for ( i = 0; i <= m_numRows; i++ ) + for ( i = 0; i < m_numRows; i++ ) { if ( m_rowBottoms[i] > bottom ) { @@ -2741,7 +2786,7 @@ void wxGrid::DrawAllGridLines( wxDC& dc ) // vertical grid lines // - for ( i = 0; i <= m_numCols; i++ ) + for ( i = 0; i < m_numCols; i++ ) { if ( m_colRights[i] > right ) { @@ -3903,7 +3948,6 @@ void wxGrid::SetRowLabelAlignment( int horiz, int vert ) if ( !GetBatchCount() ) { m_rowLabelWin->Refresh(); - m_colLabelWin->Refresh(); } } @@ -3921,7 +3965,6 @@ void wxGrid::SetColLabelAlignment( int horiz, int vert ) if ( !GetBatchCount() ) { - m_rowLabelWin->Refresh(); m_colLabelWin->Refresh(); } } @@ -3933,9 +3976,14 @@ void wxGrid::SetRowLabelValue( int row, const wxString& s ) m_table->SetRowLabelValue( row, s ); if ( !GetBatchCount() ) { - // TODO: Optimize this - // - m_rowLabelWin->Refresh(); + wxRect rect = CellToRect( row, 0); + if ( rect.height > 0 ) + { + CalcScrolledPosition(0, rect.y, &rect.x, &rect.y); + rect.x = m_left; + rect.width = m_rowLabelWidth; + m_rowLabelWin->Refresh( TRUE, &rect ); + } } } } @@ -3947,9 +3995,14 @@ void wxGrid::SetColLabelValue( int col, const wxString& s ) m_table->SetColLabelValue( col, s ); if ( !GetBatchCount() ) { - // TODO: optimize this - // - m_colLabelWin->Refresh(); + wxRect rect = CellToRect( 0, col ); + if ( rect.width > 0 ) + { + CalcScrolledPosition(rect.x, 0, &rect.x, &rect.y); + rect.y = m_top; + rect.height = m_colLabelHeight; + m_colLabelWin->Refresh( TRUE, &rect ); + } } } } @@ -4253,21 +4306,56 @@ void wxGrid::SelectRow( int row, bool addToSelected ) if ( IsSelection() && addToSelected ) { - if ( m_selectedTopLeft.GetRow() > row ) + wxRect rect[4]; + bool need_refresh[4] = { FALSE, FALSE, FALSE, FALSE }; + int i; + + wxCoord oldLeft = m_selectedTopLeft.GetCol(); + wxCoord oldTop = m_selectedTopLeft.GetRow(); + wxCoord oldRight = m_selectedBottomRight.GetCol(); + wxCoord oldBottom = m_selectedBottomRight.GetRow(); + + if ( oldTop > row ) + { + need_refresh[0] = TRUE; + rect[0] = BlockToDeviceRect( wxGridCellCoords ( row, 0 ), + wxGridCellCoords ( oldTop - 1, + m_numCols - 1 ) ); m_selectedTopLeft.SetRow( row ); + } - m_selectedTopLeft.SetCol( 0 ); + if ( oldLeft > 0 ) + { + need_refresh[1] = TRUE; + rect[1] = BlockToDeviceRect( wxGridCellCoords ( oldTop, 0 ), + wxGridCellCoords ( oldBottom, + oldLeft - 1 ) ); + + m_selectedTopLeft.SetCol( 0 ); + } - if ( m_selectedBottomRight.GetRow() < row ) + if ( oldBottom < row ) + { + need_refresh[2] = TRUE; + rect[2] = BlockToDeviceRect( wxGridCellCoords ( oldBottom + 1, 0 ), + wxGridCellCoords ( row, + m_numCols - 1 ) ); m_selectedBottomRight.SetRow( row ); + } - m_selectedBottomRight.SetCol( m_numCols - 1 ); + if ( oldRight < m_numCols - 1 ) + { + need_refresh[3] = TRUE; + rect[3] = BlockToDeviceRect( wxGridCellCoords ( oldTop , + oldRight + 1 ), + wxGridCellCoords ( oldBottom, + m_numCols - 1 ) ); + m_selectedBottomRight.SetCol( m_numCols - 1 ); + } - // TODO: optimize this so that we only refresh the newly - // selected cells - // - r = SelectionToDeviceRect(); - if ( r != wxGridNoCellRect ) m_gridWin->Refresh( TRUE, &r ); + for (i = 0; i < 4; i++ ) + if ( need_refresh[i] && rect[i] != wxGridNoCellRect ) + m_gridWin->Refresh( TRUE, &(rect[i]) ); } else { @@ -4293,28 +4381,62 @@ void wxGrid::SelectRow( int row, bool addToSelected ) void wxGrid::SelectCol( int col, bool addToSelected ) { - wxRect r; - if ( IsSelection() && addToSelected ) { - if ( m_selectedTopLeft.GetCol() > col ) + wxRect rect[4]; + bool need_refresh[4] = { FALSE, FALSE, FALSE, FALSE }; + int i; + + wxCoord oldLeft = m_selectedTopLeft.GetCol(); + wxCoord oldTop = m_selectedTopLeft.GetRow(); + wxCoord oldRight = m_selectedBottomRight.GetCol(); + wxCoord oldBottom = m_selectedBottomRight.GetRow(); + + if ( oldLeft > col ) + { + need_refresh[0] = TRUE; + rect[0] = BlockToDeviceRect( wxGridCellCoords ( 0, col ), + wxGridCellCoords ( m_numRows - 1, + oldLeft - 1 ) ); m_selectedTopLeft.SetCol( col ); + } - m_selectedTopLeft.SetRow( 0 ); + if ( oldTop > 0 ) + { + need_refresh[1] = TRUE; + rect[1] = BlockToDeviceRect( wxGridCellCoords ( 0, oldLeft ), + wxGridCellCoords ( oldTop - 1, + oldRight ) ); + m_selectedTopLeft.SetRow( 0 ); + } - if ( m_selectedBottomRight.GetCol() < col ) + if ( oldRight < col ) + { + need_refresh[2] = TRUE; + rect[2] = BlockToDeviceRect( wxGridCellCoords ( 0, oldRight + 1 ), + wxGridCellCoords ( m_numRows - 1, + col ) ); m_selectedBottomRight.SetCol( col ); + } - m_selectedBottomRight.SetRow( m_numRows - 1 ); + if ( oldBottom < m_numRows - 1 ) + { + need_refresh[3] = TRUE; + rect[3] = BlockToDeviceRect( wxGridCellCoords ( oldBottom + 1, + oldLeft ), + wxGridCellCoords ( m_numRows - 1, + oldRight ) ); + m_selectedBottomRight.SetRow( m_numRows - 1 ); + } - // TODO: optimize this so that we only refresh the newly - // selected cells - // - r = SelectionToDeviceRect(); - if ( r != wxGridNoCellRect ) m_gridWin->Refresh( TRUE, &r ); + for (i = 0; i < 4; i++ ) + if ( need_refresh[i] && rect[i] != wxGridNoCellRect ) + m_gridWin->Refresh( TRUE, &(rect[i]) ); } else { + wxRect r; + r = SelectionToDeviceRect(); ClearSelection(); if ( r != wxGridNoCellRect ) m_gridWin->Refresh( TRUE, &r ); @@ -4338,7 +4460,6 @@ void wxGrid::SelectCol( int col, bool addToSelected ) void wxGrid::SelectBlock( int topRow, int leftCol, int bottomRow, int rightCol ) { int temp; - bool changed = FALSE; wxGridCellCoords updateTopLeft, updateBottomRight; if ( topRow > bottomRow ) @@ -4355,46 +4476,100 @@ void wxGrid::SelectBlock( int topRow, int leftCol, int bottomRow, int rightCol ) rightCol = temp; } - updateTopLeft = m_selectedTopLeft; - if (m_selectedTopLeft != wxGridCellCoords( topRow, leftCol ) ) + updateTopLeft = wxGridCellCoords( topRow, leftCol ); + updateBottomRight = wxGridCellCoords( bottomRow, rightCol ); + + if ( m_selectedTopLeft != updateTopLeft || + m_selectedBottomRight != updateBottomRight ) { - m_selectedTopLeft = wxGridCellCoords( topRow, leftCol ); - if (updateTopLeft == wxGridNoCellCoords) + // Compute two optimal update rectangles: + // Either one rectangle is a real subset of the + // other, or they are (almost) disjoint! + wxRect rect[4]; + bool need_refresh[4] = { FALSE, FALSE, FALSE, FALSE }; + int i; + + // Store intermediate values + wxCoord oldLeft = m_selectedTopLeft.GetCol(); + wxCoord oldTop = m_selectedTopLeft.GetRow(); + wxCoord oldRight = m_selectedBottomRight.GetCol(); + wxCoord oldBottom = m_selectedBottomRight.GetRow(); + + // Determine the outer/inner coordinates. + if (oldLeft > leftCol) { - updateTopLeft = m_selectedTopLeft; + temp = oldLeft; + oldLeft = leftCol; + leftCol = temp; } - else + if (oldTop > topRow ) { - if(updateTopLeft.GetRow() > topRow) - updateTopLeft.SetRow(topRow); - if (updateTopLeft.GetCol() > leftCol) - updateTopLeft.SetCol(leftCol); + temp = oldTop; + oldTop = topRow; + topRow = temp; + } + if (oldRight < rightCol ) + { + temp = oldRight; + oldRight = rightCol; + rightCol = temp; + } + if (oldBottom < bottomRow) + { + temp = oldBottom; + oldBottom = bottomRow; + bottomRow = temp; } - changed = TRUE; - } - updateBottomRight = m_selectedBottomRight; - if (m_selectedBottomRight != wxGridCellCoords( bottomRow, rightCol ) ) - { - m_selectedBottomRight = wxGridCellCoords( bottomRow, rightCol ); - if (updateBottomRight == wxGridNoCellCoords) + // Now, either the stuff marked old is the outer + // rectangle or we don't have a situation where one + // is contained in the other. + + if ( oldLeft < leftCol ) { - updateBottomRight = m_selectedBottomRight; + need_refresh[0] = TRUE; + rect[0] = BlockToDeviceRect( wxGridCellCoords ( oldTop, + oldLeft ), + wxGridCellCoords ( oldBottom, + leftCol - 1 ) ); } - else + + if ( oldTop < topRow ) { - if (updateBottomRight.GetRow() < bottomRow) - updateBottomRight.SetRow(bottomRow); - if (updateBottomRight.GetCol() < rightCol) - updateBottomRight.SetCol(rightCol); + need_refresh[1] = TRUE; + rect[1] = BlockToDeviceRect( wxGridCellCoords ( oldTop, + leftCol ), + wxGridCellCoords ( topRow - 1, + rightCol ) ); } - changed = TRUE; - } - if (changed) - { - wxRect r( BlockToDeviceRect( updateTopLeft, updateBottomRight ) ); - m_gridWin->Refresh( TRUE, &r ); + if ( oldRight > rightCol ) + { + need_refresh[2] = TRUE; + rect[2] = BlockToDeviceRect( wxGridCellCoords ( oldTop, + rightCol + 1 ), + wxGridCellCoords ( oldBottom, + oldRight ) ); + } + + if ( oldBottom > bottomRow ) + { + need_refresh[3] = TRUE; + rect[3] = BlockToDeviceRect( wxGridCellCoords ( bottomRow + 1, + leftCol ), + wxGridCellCoords ( oldBottom, + rightCol ) ); + } + + + // Change Selection + m_selectedTopLeft = updateTopLeft; + m_selectedBottomRight = updateBottomRight; + + // various Refresh() calls + for (i = 0; i < 4; i++ ) + if ( need_refresh[i] && rect[i] != wxGridNoCellRect ) + m_gridWin->Refresh( TRUE, &(rect[i]) ); } // only generate an event if the block is not being selected by