X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/304969053696308d0d68a063c999309c618dad19..a246ab8b5e30b09705b485b6021c0149c80becda:/src/generic/grid.cpp diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index 86612f914d..6e276fe316 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -155,6 +155,7 @@ wxDEFINE_EVENT( wxEVT_GRID_SELECT_CELL, wxGridEvent ); wxDEFINE_EVENT( wxEVT_GRID_EDITOR_SHOWN, wxGridEvent ); wxDEFINE_EVENT( wxEVT_GRID_EDITOR_HIDDEN, wxGridEvent ); wxDEFINE_EVENT( wxEVT_GRID_EDITOR_CREATED, wxGridEditorCreatedEvent ); +wxDEFINE_EVENT( wxEVT_GRID_TABBING, wxGridEvent ); // ---------------------------------------------------------------------------- // private helpers @@ -2413,6 +2414,8 @@ wxGrid::SetTable(wxGridTableBase *table, m_created = true; } + InvalidateBestSize(); + return m_created; } @@ -2514,6 +2517,8 @@ void wxGrid::Init() // now anyhow, so just set the parameters directly m_xScrollPixelsPerLine = GRID_SCROLL_LINE_X; m_yScrollPixelsPerLine = GRID_SCROLL_LINE_Y; + + m_tabBehaviour = Tab_Stop; } // ---------------------------------------------------------------------------- @@ -2877,7 +2882,6 @@ bool wxGrid::Redimension( wxGridTableMessage& msg ) if ( !m_colAt.IsEmpty() ) { //Shift the column IDs - int i; for ( i = 0; i < m_numCols - numCols; i++ ) { if ( m_colAt[i] >= (int)pos ) @@ -2947,7 +2951,6 @@ bool wxGrid::Redimension( wxGridTableMessage& msg ) m_colAt.Add( 0, numCols ); //Set the new columns' positions - int i; for ( i = oldNumCols; i < m_numCols; i++ ) { m_colAt[i] = i; @@ -3067,6 +3070,8 @@ bool wxGrid::Redimension( wxGridTableMessage& msg ) break; } + InvalidateBestSize(); + if (result && !GetBatchCount() ) m_gridWin->Refresh(); @@ -3531,9 +3536,8 @@ void wxGrid::DoUpdateResizeColWidth(int w) void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event ) { - int x, y; - wxPoint pos( event.GetPosition() ); - CalcUnscrolledPosition( pos.x, pos.y, &x, &y ); + int x; + CalcUnscrolledPosition( event.GetPosition().x, 0, &x, NULL ); int col = XToCol(x); if ( event.Dragging() ) @@ -3649,14 +3653,13 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event ) // else if ( event.LeftDown() ) { - int col = XToEdgeOfCol(x); - if ( col != wxNOT_FOUND && CanDragColSize(col) ) + int colEdge = XToEdgeOfCol(x); + if ( colEdge != wxNOT_FOUND && CanDragColSize(colEdge) ) { ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL, GetColLabelWindow()); } else // not a request to start resizing { - col = XToCol(x); if ( col >= 0 && !SendEvent( wxEVT_GRID_LABEL_LEFT_CLICK, -1, col, event ) ) { @@ -4415,14 +4418,14 @@ bool wxGrid::DoEndDragResizeLine(const wxGridOperations& oper) oper.SelectSize(rect) = oper.Select(size); int subtractLines = 0; - const int lineStart = doper.PosToLine(this, posLineStart); - if ( lineStart >= 0 ) + int line = doper.PosToLine(this, posLineStart); + if ( line >= 0 ) { // ensure that if we have a multi-cell block we redraw all of // it by increasing the refresh area to cover it entirely if a // part of it is affected const int lineEnd = doper.PosToLine(this, posLineEnd, true); - for ( int line = lineStart; line < lineEnd; line++ ) + for ( ; line < lineEnd; line++ ) { int cellLines = oper.Select( GetCellSize(oper.MakeCoords(m_dragRowOrCol, line))); @@ -4937,30 +4940,18 @@ void wxGrid::OnKeyDown( wxKeyEvent& event ) break; case WXK_TAB: - if (event.ShiftDown()) - { - if ( GetGridCursorCol() > 0 ) - { - MoveCursorLeft( false ); - } - else - { - // at left of grid - DisableCellEditControl(); - } - } - else { - if ( GetGridCursorCol() < GetNumberCols() - 1 ) - { - MoveCursorRight( false ); - } - else + // send an event to the grid's parents for custom handling + wxGridEvent gridEvt(GetId(), wxEVT_GRID_TABBING, this, + GetGridCursorRow(), GetGridCursorCol(), + -1, -1, false, event); + if ( ProcessWindowEvent(gridEvt) ) { - // at right of grid - DisableCellEditControl(); + // the event has been handled so no need for more processing + break; } } + DoGridProcessTab( event ); break; case WXK_HOME: @@ -5092,6 +5083,69 @@ void wxGrid::OnEraseBackground(wxEraseEvent&) { } +void wxGrid::DoGridProcessTab(wxKeyboardState& kbdState) +{ + const bool isForwardTab = !kbdState.ShiftDown(); + + // TAB processing only changes when we are at the borders of the grid, so + // let's first handle the common behaviour when we are not at the border. + if ( isForwardTab ) + { + if ( GetGridCursorCol() < GetNumberCols() - 1 ) + { + MoveCursorRight( false ); + return; + } + } + else // going back + { + if ( GetGridCursorCol() ) + { + MoveCursorLeft( false ); + return; + } + } + + + // We only get here if the cursor is at the border of the grid, apply the + // configured behaviour. + switch ( m_tabBehaviour ) + { + case Tab_Stop: + // Nothing special to do, we remain at the current cell. + break; + + case Tab_Wrap: + // Go to the beginning of the next or the end of the previous row. + if ( isForwardTab ) + { + if ( GetGridCursorRow() < GetNumberRows() - 1 ) + { + GoToCell( GetGridCursorRow() + 1, 0 ); + return; + } + } + else + { + if ( GetGridCursorRow() > 0 ) + { + GoToCell( GetGridCursorRow() - 1, GetNumberCols() - 1 ); + return; + } + } + break; + + case Tab_Leave: + if ( Navigate( isForwardTab ? wxNavigationKeyEvent::IsForward + : wxNavigationKeyEvent::IsBackward ) ) + return; + break; + } + + // If we remain in this cell, stop editing it if we were doing so. + DisableCellEditControl(); +} + bool wxGrid::SetCurrentCell( const wxGridCellCoords& coords ) { if ( SendEvent(wxEVT_GRID_SELECT_CELL, coords) == -1 ) @@ -5508,7 +5562,7 @@ void wxGrid::DrawCell( wxDC& dc, const wxGridCellCoords& coords ) // implicitly, causing this out-of order render. #if !defined(__WXMAC__) wxGridCellEditor *editor = attr->GetEditor(this, row, col); - editor->PaintBackground(rect, attr); + editor->PaintBackground(dc, rect, *attr); editor->DecRef(); #endif } @@ -7067,6 +7121,7 @@ void wxGrid::SetRowLabelSize( int width ) } m_rowLabelWidth = width; + InvalidateBestSize(); CalcWindowSizes(); wxScrolledWindow::Refresh( true ); } @@ -7096,6 +7151,7 @@ void wxGrid::SetColLabelSize( int height ) } m_colLabelHeight = height; + InvalidateBestSize(); CalcWindowSizes(); wxScrolledWindow::Refresh( true ); } @@ -8089,6 +8145,10 @@ void wxGrid::SetRowSize( int row, int height ) // The value of -1 is special and means to fit the height to the row label. if ( height == -1 ) { + // As with the columns, ignore attempts to auto-size the hidden rows. + if ( GetRowHeight(row) == 0 ) + return; + long w, h; wxArrayString lines; wxClientDC dc(m_rowLabelWin); @@ -8121,6 +8181,8 @@ void wxGrid::DoSetRowSize( int row, int height ) m_rowBottoms[i] += diff; } + InvalidateBestSize(); + if ( !GetBatchCount() ) { CalcDimensions(); @@ -8159,6 +8221,12 @@ void wxGrid::SetColSize( int col, int width ) // The value of -1 is special and means to fit the width to the column label. if ( width == -1 ) { + // We currently don't support auto-sizing hidden columns. We could, but + // it's not clear whether this is really needed and it would make the + // code more complex. + if ( GetColWidth(col) == 0 ) + return; + long w, h; wxArrayString lines; wxClientDC dc(m_colWindow); @@ -8199,6 +8267,8 @@ void wxGrid::DoSetColSize( int col, int width ) m_colRights[GetColAt(colPos)] += diff; } + InvalidateBestSize(); + if ( !GetBatchCount() ) { CalcDimensions(); @@ -8275,6 +8345,19 @@ wxGrid::AutoSizeColOrRow(int colOrRow, bool setAsMin, wxGridDirection direction) { const bool column = direction == wxGRID_COLUMN; + // We don't support auto-sizing hidden rows or columns, this doesn't seem + // to make much sense. + if ( column ) + { + if ( GetColWidth(colOrRow) == 0 ) + return; + } + else + { + if ( GetRowHeight(colOrRow) == 0 ) + return; + } + wxClientDC dc(m_gridWin); // cancel editing of cell @@ -8305,7 +8388,7 @@ wxGrid::AutoSizeColOrRow(int colOrRow, bool setAsMin, wxGridDirection direction) row = rowOrCol; col = colOrRow; } - else + else { row = colOrRow; col = rowOrCol; @@ -8595,11 +8678,6 @@ wxSize wxGrid::DoGetBestSize() const wxSize size(self->SetOrCalcColumnSizes(true) - m_rowLabelWidth + m_extraWidth, self->SetOrCalcRowSizes(true) - m_colLabelHeight + m_extraHeight); - // 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 wxSize(size.x + m_rowLabelWidth, size.y + m_colLabelHeight) + GetWindowBorderSize(); }