gridsel.cpp

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,132 行 · 第 1/3 页

CPP
1,132
字号
                                   bool ControlDown, bool ShiftDown,
                                   bool AltDown, bool MetaDown,
                                   bool sendEvent )
{
    // Fix the coordinates of the block if needed.
    if ( m_selectionMode == wxGrid::wxGridSelectRows )
    {
        leftCol = 0;
        rightCol = m_grid->GetNumberCols() - 1;
    }
    else if ( m_selectionMode == wxGrid::wxGridSelectColumns )
    {
        topRow = 0;
        bottomRow = m_grid->GetNumberRows() - 1;
    }
    if ( topRow > bottomRow )
    {
        int temp = topRow;
        topRow = bottomRow;
        bottomRow = temp;
    }

    if ( leftCol > rightCol )
    {
        int temp = leftCol;
        leftCol = rightCol;
        rightCol = temp;
    }

    // Handle single cell selection in SelectCell.
    // (MB: added check for selection mode here to prevent
    //  crashes if, for example, we are select rows and the
    //  grid only has 1 col)
    if ( m_selectionMode == wxGrid::wxGridSelectCells &&
         topRow == bottomRow && leftCol == rightCol )
        SelectCell( topRow, leftCol, ControlDown,  ShiftDown,
                    AltDown, MetaDown, sendEvent );

    size_t count, n;
    // Remove single cells contained in newly selected block.
    if ( m_selectionMode == wxGrid::wxGridSelectCells )
    {
        count = m_cellSelection.GetCount();
        for ( n = 0; n < count; n++ )
        {
            wxGridCellCoords& coords = m_cellSelection[n];
            if ( BlockContainsCell( topRow, leftCol, bottomRow, rightCol,
                                    coords.GetRow(), coords.GetCol() ) )
            {
                m_cellSelection.RemoveAt(n);
                n--; count--;
            }
        }
    }

    // If a block containing the selection is already selected, return,
    // if a block contained in the selection is found, remove it.

    count = m_blockSelectionTopLeft.GetCount();
    for ( n = 0; n < count; n++ )
    {
        wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
        wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
        switch ( BlockContain( coords1.GetRow(), coords1.GetCol(),
                               coords2.GetRow(), coords2.GetCol(),
                               topRow, leftCol, bottomRow, rightCol ) )
        {
            case 1:
                return;

            case -1:
                m_blockSelectionTopLeft.RemoveAt(n);
                m_blockSelectionBottomRight.RemoveAt(n);
                n--; count--;
                break;

            default:
                break;
        }
    }

    // If a row containing the selection is already selected, return,
    // if a row contained in newly selected block is found, remove it.
    if ( m_selectionMode != wxGrid::wxGridSelectColumns )
    {
        count = m_rowSelection.GetCount();
        for ( n = 0; n < count; n++ )
        {
            switch ( BlockContain( m_rowSelection[n], 0,
                                   m_rowSelection[n], m_grid->GetNumberCols()-1,
                                   topRow, leftCol, bottomRow, rightCol ) )
            {
                case 1:
                    return;

                case -1:
                    m_rowSelection.RemoveAt(n);
                    n--; count--;
                    break;

                default:
                    break;
            }
        }
    }
    if ( m_selectionMode != wxGrid::wxGridSelectRows )
    {
        count = m_colSelection.GetCount();
        for ( n = 0; n < count; n++ )
        {
            switch ( BlockContain( 0, m_colSelection[n],
                                   m_grid->GetNumberRows()-1, m_colSelection[n],
                                   topRow, leftCol, bottomRow, rightCol ) )
            {
                case 1:
                    return;

                case -1:
                    m_colSelection.RemoveAt(n);
                    n--; count--;
                    break;

                default:
                    break;
            }
        }
    }
    m_blockSelectionTopLeft.Add( wxGridCellCoords( topRow, leftCol ) );
    m_blockSelectionBottomRight.Add( wxGridCellCoords( bottomRow, rightCol ) );

    // Update View:
    if ( !m_grid->GetBatchCount() )
    {
        wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( topRow, leftCol ),
                                              wxGridCellCoords( bottomRow, rightCol ) );
        ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r );
    }

    // Send Event, if not disabled.
    if ( sendEvent )
    {
        wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
                                        wxEVT_GRID_RANGE_SELECT,
                                        m_grid,
                                        wxGridCellCoords( topRow, leftCol ),
                                        wxGridCellCoords( bottomRow, rightCol ),
                                        true,
                                        ControlDown, ShiftDown,
                                        AltDown, MetaDown );
        m_grid->GetEventHandler()->ProcessEvent(gridEvt);
    }
}

void wxGridSelection::SelectCell( int row, int col,
                                  bool ControlDown, bool ShiftDown,
                                  bool AltDown, bool MetaDown,
                                  bool sendEvent )
{
    if ( m_selectionMode == wxGrid::wxGridSelectRows )
    {
        SelectBlock(row, 0, row, m_grid->GetNumberCols() - 1,
                    ControlDown, ShiftDown, AltDown, MetaDown, sendEvent);
        return;
    }
    else if ( m_selectionMode == wxGrid::wxGridSelectColumns )
    {
        SelectBlock(0, col, m_grid->GetNumberRows() - 1, col,
                    ControlDown, ShiftDown, AltDown, MetaDown, sendEvent);
        return;
    }
    else if ( IsInSelection ( row, col ) )
        return;
    m_cellSelection.Add( wxGridCellCoords( row, col ) );

    // Update View:
    if ( !m_grid->GetBatchCount() )
    {
        wxRect r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, col ),
                                              wxGridCellCoords( row, col ) );
        ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r );
    }

    // Send event
    if (sendEvent)
    {
        wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
                                        wxEVT_GRID_RANGE_SELECT,
                                        m_grid,
                                        wxGridCellCoords( row, col ),
                                        wxGridCellCoords( row, col ),
                                        true,
                                        ControlDown, ShiftDown,
                                        AltDown, MetaDown);
        m_grid->GetEventHandler()->ProcessEvent(gridEvt);
    }
}

void wxGridSelection::ToggleCellSelection( int row, int col,
                                           bool ControlDown, bool ShiftDown,
                                           bool AltDown, bool MetaDown )
{
    // if the cell is not selected, select it
    if ( !IsInSelection ( row, col ) )
    {
        SelectCell( row, col, ControlDown, ShiftDown,
                    AltDown, MetaDown );
        return;
    }

    // otherwise deselect it. This can be simple or more or
    // less difficult, depending on how the cell is selected.
    size_t count, n;

    // The simplest case: The cell is contained in m_cellSelection
    // Then it can't be contained in rows/cols/block (since those
    // would remove the cell from m_cellSelection on creation), so
    // we just have to remove it from m_cellSelection.

    if ( m_selectionMode == wxGrid::wxGridSelectCells )
    {
        count = m_cellSelection.GetCount();
        for ( n = 0; n < count; n++ )
        {
            wxGridCellCoords& coords = m_cellSelection[n];
            if ( row == coords.GetRow() && col == coords.GetCol() )
            {
                wxGridCellCoords coords = m_cellSelection[n];
                m_cellSelection.RemoveAt(n);
                if ( !m_grid->GetBatchCount() )
                {
                    wxRect r = m_grid->BlockToDeviceRect( coords, coords );
                    ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r );
                }

                // Send event
                wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
                                                wxEVT_GRID_RANGE_SELECT,
                                                m_grid,
                                                wxGridCellCoords( row, col ),
                                                wxGridCellCoords( row, col ),
                                                false,
                                                ControlDown, ShiftDown,
                                                AltDown, MetaDown );
                m_grid->GetEventHandler()->ProcessEvent(gridEvt);
                return;
            }
        }
    }

    // The most difficult case: The cell is member of one or even several
    // blocks. Split each such block in up to 4 new parts, that don't
    // contain the cell to be selected, like this:
    // |---------------------------|
    // |                           |
    // |           part 1          |
    // |                           |
    // |---------------------------|
    // |   part 3   |x|   part 4   |
    // |---------------------------|
    // |                           |
    // |           part 2          |
    // |                           |
    // |---------------------------|
    //   (The x marks the newly deselected cell).
    // Note: in row selection mode, we only need part1 and part2;
    //       in column selection mode, we only need part 3 and part4,
    //          which are expanded to whole columns automatically!

    count = m_blockSelectionTopLeft.GetCount();
    for ( n = 0; n < count; n++ )
      {
        wxGridCellCoords& coords1 = m_blockSelectionTopLeft[n];
        wxGridCellCoords& coords2 = m_blockSelectionBottomRight[n];
        int topRow = coords1.GetRow();
        int leftCol = coords1.GetCol();
        int bottomRow = coords2.GetRow();
        int rightCol = coords2.GetCol();
        if ( BlockContainsCell( topRow, leftCol, bottomRow, rightCol,
                                row, col ) )
        {
            // remove the block
            m_blockSelectionTopLeft.RemoveAt(n);
            m_blockSelectionBottomRight.RemoveAt(n);
            n--; count--;
            // add up to 4 smaller blocks and set update region
            if ( m_selectionMode != wxGrid::wxGridSelectColumns )
            {
                if ( topRow < row )
                    SelectBlock( topRow, leftCol, row - 1, rightCol,
                                 false, false, false, false, false );
                if ( bottomRow > row )
                    SelectBlock( row + 1, leftCol, bottomRow, rightCol,
                                 false, false, false, false, false );
            }
            if ( m_selectionMode != wxGrid::wxGridSelectRows )
            {
                if ( leftCol < col )
                    SelectBlock( row, leftCol, row, col - 1,
                                 false, false, false, false, false );
                if ( rightCol > col )
                    SelectBlock( row, col + 1, row, rightCol,
                                 false, false, false, false, false );
            }
        }
    }

    // remove a cell from a row, adding up to two new blocks
    if ( m_selectionMode != wxGrid::wxGridSelectColumns )
    {
        count = m_rowSelection.GetCount();
        for ( n = 0; n < count; n++ )
        {
            if ( m_rowSelection[n] == row )
            {
                m_rowSelection.RemoveAt(n);
                n--; count--;
                if (m_selectionMode == wxGrid::wxGridSelectCells)
                {
                    if ( col > 0 )
                        SelectBlock( row, 0, row, col - 1,
                                     false, false, false, false, false );
                    if ( col < m_grid->GetNumberCols() - 1 )
                        SelectBlock( row, col + 1,
                                     row, m_grid->GetNumberCols() - 1,
                                     false, false, false, false, false );
                }
            }
        }
    }

    // remove a cell from a column, adding up to two new blocks
    if ( m_selectionMode != wxGrid::wxGridSelectRows )
    {
        count = m_colSelection.GetCount();
        for ( n = 0; n < count; n++ )
        {
            if ( m_colSelection[n] == col )
            {
                m_colSelection.RemoveAt(n);
                n--; count--;
                if (m_selectionMode == wxGrid::wxGridSelectCells)
                {
                    if ( row > 0 )
                        SelectBlock( 0, col, row - 1, col,
                                     false, false, false, false, false );
                    if ( row < m_grid->GetNumberRows() - 1 )
                        SelectBlock( row + 1, col,
                                     m_grid->GetNumberRows() - 1, col,
                                     false, false, false, false, false );
                }
            }
        }
    }

    // Refresh the screen and send the event; according to m_selectionMode,
    // we need to either update only the cell, or the whole row/column.
    wxRect r;
    switch (m_selectionMode)
    {
      case wxGrid::wxGridSelectCells:
      {
          if ( !m_grid->GetBatchCount() )
          {
              r = m_grid->BlockToDeviceRect( wxGridCellCoords( row, col ),
                                             wxGridCellCoords( row, col ) );
              ((wxWindow *)m_grid->m_gridWin)->Refresh( false, &r );
          }

          wxGridRangeSelectEvent gridEvt( m_grid->GetId(),
                                          wxEVT_GRID_RANGE_SELECT,
                                          m_grid,
                                          wxGridCellCoords( row, col ),
                                          wxGridCellCoords( row, col ),
                                          false,
                                          ControlDown, ShiftDown,
                                          AltDown, MetaDown );
          m_grid->GetEventHandler()->ProcessEvent(gridEvt);
          break;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?