X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/238c4e17980d862fa9cc872c0f5c7a473f475b46..9b1801c19c82340be79810c8b7617b05caa0cd59:/src/generic/grid.cpp diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index a9232d42ed..e856345409 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -36,6 +36,10 @@ #include "wx/generic/grid.h" +#ifndef DRAW_LINES +#define DRAW_LINES 1 +#endif + ////////////////////////////////////////////////////////////////////// wxGridCellCoords wxGridNoCellCoords( -1, -1 ); @@ -608,6 +612,7 @@ void wxGridTextCtrl::OnKeyDown( wxKeyEvent& event ) case WXK_RIGHT: case WXK_PRIOR: case WXK_NEXT: + case WXK_SPACE: if ( m_isCellControl ) { // send the event to the parent grid, skipping the @@ -629,7 +634,7 @@ void wxGridTextCtrl::OnKeyDown( wxKeyEvent& event ) { if ( !m_grid->ProcessEvent( event ) ) { -#ifdef __WXMOTIF__ +#if defined(__WXMOTIF__) || defined(__WXGTK__) // wxMotif needs a little extra help... // int pos = GetInsertionPoint(); @@ -705,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 ); @@ -758,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 ); @@ -868,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 DRAW_LINES + m_owner->DrawAllGridLines( dc, reg ); +#endif } @@ -1584,9 +1592,14 @@ 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; + rect.width = m_rowLabelWidth; + rect.height = ch - rect.y; + m_rowLabelWin->Refresh( TRUE, &rect ); + rect.width = cw; + m_gridWin->Refresh( TRUE, &rect ); } ShowCellEditControl(); @@ -1766,9 +1779,14 @@ 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; + rect.width = cw - rect.x; + rect.height = m_colLabelHeight; + m_colLabelWin->Refresh( TRUE, &rect ); + rect.height = ch; + m_gridWin->Refresh( TRUE, &rect ); } ShowCellEditControl(); @@ -2436,6 +2454,17 @@ void wxGrid::OnKeyDown( wxKeyEvent& event ) MoveCursorRight(); } break; + + case WXK_SPACE: + if ( !IsEditable() ) + { + MoveCursorRight(); + } + else + { + event.Skip(); + } + break; case WXK_RETURN: if ( event.ControlDown() ) @@ -2590,8 +2619,10 @@ void wxGrid::DrawCell( wxDC& dc, const wxGridCellCoords& coords ) if ( m_colWidths[coords.GetCol()] <=0 || m_rowHeights[coords.GetRow()] <= 0 ) return; +#if !DRAW_LINES if ( m_gridLinesEnabled ) DrawCellBorder( dc, coords ); +#endif DrawCellBackground( dc, coords ); @@ -2695,20 +2726,29 @@ 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); - - // virtual coords of visible area - // int top, bottom, left, right; - CalcUnscrolledPosition( 0, 0, &left, &top ); - CalcUnscrolledPosition( cw, ch, &right, &bottom ); + + 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 ); + } dc.SetPen( wxPen(GetGridLineColour(), 1, wxSOLID) ); @@ -3892,7 +3932,6 @@ void wxGrid::SetRowLabelAlignment( int horiz, int vert ) if ( !GetBatchCount() ) { m_rowLabelWin->Refresh(); - m_colLabelWin->Refresh(); } } @@ -3910,7 +3949,6 @@ void wxGrid::SetColLabelAlignment( int horiz, int vert ) if ( !GetBatchCount() ) { - m_rowLabelWin->Refresh(); m_colLabelWin->Refresh(); } } @@ -3922,9 +3960,13 @@ 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 ) + { + rect.x = m_left; + rect.width = m_rowLabelWidth; + m_rowLabelWin->Refresh( TRUE, &rect ); + } } } } @@ -3936,9 +3978,13 @@ 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 ) + { + rect.y = m_top; + rect.height = m_colLabelHeight; + m_colLabelWin->Refresh( TRUE, &rect ); + } } } } @@ -4242,21 +4288,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 ) ); - if ( m_selectedBottomRight.GetRow() < row ) + m_selectedTopLeft.SetCol( 0 ); + } + + 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 { @@ -4282,28 +4363,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 ); @@ -4327,7 +4442,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 ) @@ -4344,46 +4458,100 @@ void wxGrid::SelectBlock( int topRow, int leftCol, int bottomRow, int rightCol ) rightCol = temp; } - updateTopLeft = m_selectedTopLeft; - if (m_selectedTopLeft != wxGridCellCoords( topRow, leftCol ) ) - { - m_selectedTopLeft = wxGridCellCoords( topRow, leftCol ); - if (updateTopLeft == wxGridNoCellCoords) - { - updateTopLeft = m_selectedTopLeft; - } - else - { - if(updateTopLeft.GetRow() > topRow) - updateTopLeft.SetRow(topRow); - if (updateTopLeft.GetCol() > leftCol) - updateTopLeft.SetCol(leftCol); - } - changed = true; - } + updateTopLeft = wxGridCellCoords( topRow, leftCol ); + updateBottomRight = wxGridCellCoords( bottomRow, rightCol ); - updateBottomRight = m_selectedBottomRight; - if (m_selectedBottomRight != wxGridCellCoords( bottomRow, rightCol ) ) + if ( m_selectedTopLeft != updateTopLeft || + m_selectedBottomRight != updateBottomRight ) { - m_selectedBottomRight = wxGridCellCoords( bottomRow, rightCol ); - if (updateBottomRight == 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) { - updateBottomRight = m_selectedBottomRight; - } - else + temp = oldLeft; + oldLeft = leftCol; + leftCol = temp; + } + if (oldTop > topRow ) { - if (updateBottomRight.GetRow() < bottomRow) - updateBottomRight.SetRow(bottomRow); - if (updateBottomRight.GetCol() < rightCol) - updateBottomRight.SetCol(rightCol); - } - changed = true; - } - - if (changed) - { - wxRect r( BlockToDeviceRect( updateTopLeft, updateBottomRight ) ); - m_gridWin->Refresh( TRUE, &r ); + temp = oldTop; + oldTop = topRow; + topRow = temp; + } + if (oldRight < rightCol ) + { + temp = oldRight; + oldRight = rightCol; + rightCol = temp; + } + if (oldBottom < bottomRow) + { + temp = oldBottom; + oldBottom = bottomRow; + bottomRow = temp; + } + + // 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 ) + { + need_refresh[0] = TRUE; + rect[0] = BlockToDeviceRect( wxGridCellCoords ( oldTop, + oldLeft ), + wxGridCellCoords ( oldBottom, + leftCol - 1 ) ); + } + + if ( oldTop < topRow ) + { + need_refresh[1] = TRUE; + rect[1] = BlockToDeviceRect( wxGridCellCoords ( oldTop, + leftCol ), + wxGridCellCoords ( topRow - 1, + rightCol ) ); + } + + 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