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 ); } }