Keep labels on dragged wires.

Fixes https://gitlab.com/kicad/code/kicad/issues/2107
This commit is contained in:
Jeff Young 2020-04-19 17:04:14 +01:00
parent 71fd560735
commit a286cb5a8f
4 changed files with 58 additions and 9 deletions

View File

@ -790,6 +790,9 @@ bool SCH_SCREEN::TestDanglingEnds( const SCH_SHEET_PATH* aPath )
SCH_LINE* SCH_SCREEN::GetLine( const wxPoint& aPosition, int aAccuracy, int aLayer, SCH_LINE* SCH_SCREEN::GetLine( const wxPoint& aPosition, int aAccuracy, int aLayer,
SCH_LINE_TEST_T aSearchType ) SCH_LINE_TEST_T aSearchType )
{ {
// an accuracy of 0 had problems with rounding errors; use at least 1
aAccuracy = std::max( aAccuracy, 1 );
for( SCH_ITEM* item : Items() ) for( SCH_ITEM* item : Items() )
{ {
if( item->Type() != SCH_LINE_T ) if( item->Type() != SCH_LINE_T )

View File

@ -368,8 +368,11 @@ bool SCH_TEXT::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList,
wxCHECK_MSG( ii < aItemList.size(), previousState != m_isDangling, wxCHECK_MSG( ii < aItemList.size(), previousState != m_isDangling,
wxT( "Dangling end type list overflow. Bad programmer!" ) ); wxT( "Dangling end type list overflow. Bad programmer!" ) );
int accuracy = 1; // We have rounding issues with an accuracy of 0
DANGLING_END_ITEM & nextItem = aItemList[ii]; DANGLING_END_ITEM & nextItem = aItemList[ii];
m_isDangling = !IsPointOnSegment( item.GetPosition(), nextItem.GetPosition(), GetTextPos() ); m_isDangling = !TestSegmentHit( GetTextPos(), item.GetPosition(),
nextItem.GetPosition(), accuracy );
if( !m_isDangling ) if( !m_isDangling )
{ {

View File

@ -289,7 +289,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
if( item->GetParent() && item->GetParent()->IsSelected() ) if( item->GetParent() && item->GetParent()->IsSelected() )
continue; continue;
moveItem( item, delta, m_isDragOperation ); moveItem( item, delta );
updateView( item ); updateView( item );
} }
@ -339,7 +339,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
if( item->GetParent() && item->GetParent()->IsSelected() ) if( item->GetParent() && item->GetParent()->IsSelected() )
continue; continue;
moveItem( item, delta, m_isDragOperation ); moveItem( item, delta );
updateView( item ); updateView( item );
} }
@ -496,7 +496,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
void SCH_MOVE_TOOL::getConnectedDragItems( SCH_ITEM* aOriginalItem, wxPoint aPoint, void SCH_MOVE_TOOL::getConnectedDragItems( SCH_ITEM* aOriginalItem, wxPoint aPoint,
EDA_ITEMS& aList ) EDA_ITEMS& aList )
{ {
for( auto test : m_frame->GetScreen()->Items() ) for( SCH_ITEM* test : m_frame->GetScreen()->Items() )
{ {
if( test->IsSelected() || !test->IsConnectable() || !test->CanConnect( aOriginalItem ) ) if( test->IsSelected() || !test->IsConnectable() || !test->CanConnect( aOriginalItem ) )
continue; continue;
@ -574,7 +574,7 @@ void SCH_MOVE_TOOL::getConnectedDragItems( SCH_ITEM* aOriginalItem, wxPoint aPoi
for( wxPoint& point : connections ) for( wxPoint& point : connections )
{ {
if( aOriginalItem->HitTest( point ) ) if( aOriginalItem->HitTest( point, 1 ) )
{ {
test->SetFlags( TEMP_SELECTED ); test->SetFlags( TEMP_SELECTED );
aList.push_back( test ); aList.push_back( test );
@ -608,17 +608,60 @@ void SCH_MOVE_TOOL::getConnectedDragItems( SCH_ITEM* aOriginalItem, wxPoint aPoi
} }
void SCH_MOVE_TOOL::moveItem( EDA_ITEM* aItem, VECTOR2I aDelta, bool isDrag ) void SCH_MOVE_TOOL::moveItem( EDA_ITEM* aItem, const VECTOR2I& aDelta )
{ {
std::vector< std::pair<double, SCH_TEXT*> > labels;
auto collectLabels =
[&] ( SCH_LINE* aLine )
{
for( SCH_ITEM* test : m_frame->GetScreen()->Items().OfType( SCH_LABEL_T ) )
{
if( test->IsSelected() )
continue; // These will be moved on their own because they're selected
if( !test->CanConnect( aLine ) || !aLine->HitTest( test->GetPosition(), 1 ) )
continue;
SCH_TEXT* label = static_cast<SCH_TEXT*>( test );
double pct = GetLineLength( label->GetPosition(), aLine->GetStartPoint() ) /
GetLineLength( aLine->GetEndPoint(), aLine->GetStartPoint() );
labels.emplace_back( pct, label );
}
};
auto adjustLabels =
[&] ( SCH_LINE* aLine )
{
for( std::pair<double, SCH_TEXT*> pair : labels )
{
double pct = pair.first;
SCH_TEXT* label = pair.second;
wxPoint lineVector( aLine->GetEndPoint() - aLine->GetStartPoint() );
label->SetPosition( aLine->GetStartPoint() + ( lineVector * pct ) );
m_frame->RefreshItem( label );
}
};
switch( aItem->Type() ) switch( aItem->Type() )
{ {
case SCH_LINE_T: case SCH_LINE_T:
{
SCH_LINE* line = static_cast<SCH_LINE*>( aItem );
if( aItem->HasFlag( STARTPOINT ) || aItem->HasFlag( ENDPOINT ) )
collectLabels( line );
if( aItem->HasFlag( STARTPOINT ) ) if( aItem->HasFlag( STARTPOINT ) )
static_cast<SCH_LINE*>( aItem )->MoveStart( (wxPoint) aDelta ); line->MoveStart( (wxPoint) aDelta );
if( aItem->HasFlag( ENDPOINT ) ) if( aItem->HasFlag( ENDPOINT ) )
static_cast<SCH_LINE*>( aItem )->MoveEnd( (wxPoint) aDelta ); line->MoveEnd( (wxPoint) aDelta );
adjustLabels( line );
}
break; break;
case SCH_PIN_T: case SCH_PIN_T:

View File

@ -50,7 +50,7 @@ public:
int Main( const TOOL_EVENT& aEvent ); int Main( const TOOL_EVENT& aEvent );
private: private:
void moveItem( EDA_ITEM* aItem, VECTOR2I aDelta, bool isDrag ); void moveItem( EDA_ITEM* aItem, const VECTOR2I& aDelta );
///> Finds additional items for a drag operation. ///> Finds additional items for a drag operation.
///> Connected items with no wire are included (as there is no wire to adjust for the drag). ///> Connected items with no wire are included (as there is no wire to adjust for the drag).