Ejemplo n.º 1
0
bool SCH_SCREEN::BreakSegment( const wxPoint& aPoint )
{
    SCH_LINE* segment;
    SCH_LINE* newSegment;
    bool brokenSegments = false;

    for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
    {
        if( (item->Type() != SCH_LINE_T) || (item->GetLayer() == LAYER_NOTES) )
            continue;

        segment = (SCH_LINE*) item;

        if( !segment->HitTest( aPoint, 0 ) || segment->IsEndPoint( aPoint ) )
            continue;

        // Break the segment at aPoint and create a new segment.
        newSegment = new SCH_LINE( *segment );
        newSegment->SetStartPoint( aPoint );
        segment->SetEndPoint( aPoint );
        m_drawList.Insert( newSegment, segment->Next() );
        item = newSegment;
        brokenSegments = true;
    }

    return brokenSegments;
}
/**
 * Function ComputeBreakPoint
 * computes the middle coordinate for 2 segments from the start point to \a aPosition
 * with the segments kept in the horizontal or vertical axis only.
 *
 * @param aSegment A pointer to a #SCH_LINE object containing the first line break point
 *                 to compute.
 * @param aPosition A reference to a wxPoint object containing the coordinates of the
 *                  position used to calculate the line break point.
 */
static void ComputeBreakPoint( SCH_LINE* aSegment, const wxPoint& aPosition )
{
    wxCHECK_RET( aSegment != NULL, wxT( "Cannot compute break point of NULL line segment." ) );

    SCH_LINE* nextSegment = aSegment->Next();
    wxPoint midPoint = aPosition;

    wxCHECK_RET( nextSegment != NULL,
                 wxT( "Cannot compute break point of NULL second line segment." ) );

#if 0
    if( ABS( midPoint.x - aSegment->GetStartPoint().x ) <
        ABS( midPoint.y - aSegment->GetStartPoint().y ) )
        midPoint.x = aSegment->GetStartPoint().x;
    else
        midPoint.y = aSegment->GetStartPoint().y;
#else
    int iDx = aSegment->GetEndPoint().x - aSegment->GetStartPoint().x;
    int iDy = aSegment->GetEndPoint().y - aSegment->GetStartPoint().y;

    if( iDy != 0 )         // keep the first segment orientation (currently horizontal)
    {
        midPoint.x = aSegment->GetStartPoint().x;
    }
    else if( iDx != 0 )    // keep the first segment orientation (currently vertical)
    {
        midPoint.y = aSegment->GetStartPoint().y;
    }
    else
    {
        if( std::abs( midPoint.x - aSegment->GetStartPoint().x ) <
            std::abs( midPoint.y - aSegment->GetStartPoint().y ) )
            midPoint.x = aSegment->GetStartPoint().x;
        else
            midPoint.y = aSegment->GetStartPoint().y;
    }
#endif

    aSegment->SetEndPoint( midPoint );
    nextSegment->SetStartPoint( midPoint );
    nextSegment->SetEndPoint( aPosition );
}
void SCH_EDIT_FRAME::BeginSegment( wxDC* DC, int type )
{
    SCH_LINE* segment;
    SCH_LINE* nextSegment;
    wxPoint   cursorpos = GetCrossHairPosition();

    // We should know if a segment is currently in progress
    segment = (SCH_LINE*) GetScreen()->GetCurItem();
    if( segment )   // a current item exists, but not necessary a currently edited item
    {
        if( !segment->GetFlags() || ( segment->Type() != SCH_LINE_T ) )
        {
            if( segment->GetFlags() )
            {
                wxLogDebug( wxT( "BeginSegment: item->GetFlags()== %X" ),
                    segment->GetFlags() );
            }
            // no wire, bus or graphic line in progress
            segment = NULL;
        }
    }

    if( !segment )      // first point : Create the first wire or bus segment
    {
        switch( type )
        {
        default:
            segment = new SCH_LINE( cursorpos, LAYER_NOTES );
            break;

        case LAYER_WIRE:
            segment = new SCH_LINE( cursorpos, LAYER_WIRE );

            /* A junction will be created later, when we'll know the
             * segment end position, and if the junction is really needed */
            break;

        case LAYER_BUS:
            segment = new SCH_LINE( cursorpos, LAYER_BUS );
            break;
        }

        segment->SetFlags( IS_NEW );
        s_wires.PushBack( segment );
        GetScreen()->SetCurItem( segment );

        // We need 2 segments to go from a given start pin to an end point when the horizontal
        // and vertical lines only switch is on.
        if( GetForceHVLines() )
        {
            nextSegment = new SCH_LINE( *segment );
            nextSegment->SetFlags( IS_NEW );
            s_wires.PushBack( nextSegment );
            GetScreen()->SetCurItem( nextSegment );
        }

        m_canvas->SetMouseCapture( DrawSegment, AbortCreateNewLine );
        SetRepeatItem( NULL );
    }
    else    // A segment is in progress: terminates the current segment and add a new segment.
    {
        SCH_LINE* prevSegment = segment->Back();

        // Be aware prevSegment can be null when the horizontal and vertical lines only switch is off
        // when we create the first segment.

        if( !GetForceHVLines() )
        {
            // If only one segment is needed and it has a zero length, do not create a new one.
            if( segment->IsNull() )
                return;
        }
        else
        {
            wxCHECK_RET( prevSegment != NULL, wxT( "Failed to create second line segment." ) );

            // If two segments are required and they both have zero length, do not
            // create a new one.
            if( prevSegment && prevSegment->IsNull() && segment->IsNull() )
                return;
        }

        m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );

        // Terminate the command if the end point is on a pin, junction, or another wire or bus.
        if( GetScreen()->IsTerminalPoint( cursorpos, segment->GetLayer() ) )
        {
            EndSegment( DC );
            return;
        }

        // Create a new segment, and chain it after the current new segment.
        nextSegment = new SCH_LINE( *segment );
        nextSegment->SetStartPoint( cursorpos );
        s_wires.PushBack( nextSegment );

        segment->SetEndPoint( cursorpos );
        segment->ClearFlags( IS_NEW );
        segment->SetFlags( SELECTED );
        nextSegment->SetFlags( IS_NEW );
        GetScreen()->SetCurItem( nextSegment );
        m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
    }
}