Apply SPECIAL_CASE_LABEL_INFO architecture to one-ended-drag.

We've been doing this for some time to wires that are attached to
the moving block (and therefore have the other end anchored).  However
we also need to apply it when dragging a single end of a wire.

Fixes https://gitlab.com/kicad/code/kicad/issues/7807
This commit is contained in:
Jeff Young 2021-04-07 14:37:58 +01:00
parent 30a073c2bb
commit 21d4197eab
1 changed files with 65 additions and 29 deletions

View File

@ -527,21 +527,21 @@ void SCH_MOVE_TOOL::getConnectedDragItems( SCH_ITEM* aOriginalItem, wxPoint aPoi
if( ptHasUnselectedJunction ) if( ptHasUnselectedJunction )
break; break;
SCH_LINE* testLine = static_cast<SCH_LINE*>( test ); SCH_LINE* line = static_cast<SCH_LINE*>( test );
if( testLine->GetStartPoint() == aPoint ) if( line->GetStartPoint() == aPoint )
{ {
if( !testLine->HasFlag( TEMP_SELECTED ) ) if( !line->HasFlag(TEMP_SELECTED ) )
aList.push_back( testLine ); aList.push_back( line );
testLine->SetFlags( STARTPOINT | TEMP_SELECTED ); line->SetFlags(STARTPOINT | TEMP_SELECTED );
} }
else if( testLine->GetEndPoint() == aPoint ) else if( line->GetEndPoint() == aPoint )
{ {
if( !testLine->HasFlag( TEMP_SELECTED ) ) if( !line->HasFlag(TEMP_SELECTED ) )
aList.push_back( testLine ); aList.push_back( line );
testLine->SetFlags( ENDPOINT | TEMP_SELECTED ); line->SetFlags(ENDPOINT | TEMP_SELECTED );
} }
else else
{ {
@ -560,14 +560,16 @@ void SCH_MOVE_TOOL::getConnectedDragItems( SCH_ITEM* aOriginalItem, wxPoint aPoi
if( label->IsSelected() ) if( label->IsSelected() )
continue; // These will be moved on their own because they're selected continue; // These will be moved on their own because they're selected
if( label->CanConnect( testLine ) if( label->HasFlag( TEMP_SELECTED ) )
&& testLine->HitTest( label->GetPosition(), 1 ) ) continue;
if( label->CanConnect( line ) && line->HitTest( label->GetPosition(), 1 ) )
{ {
if( !label->HasFlag( TEMP_SELECTED ) ) label->SetFlags( TEMP_SELECTED );
aList.push_back( label ); aList.push_back( label );
SPECIAL_CASE_LABEL_INFO info; SPECIAL_CASE_LABEL_INFO info;
info.attachedLine = testLine; info.attachedLine = line;
info.originalLabelPos = label->GetPosition(); info.originalLabelPos = label->GetPosition();
m_specialCaseLabels[label] = info; m_specialCaseLabels[label] = info;
} }
@ -616,37 +618,71 @@ void SCH_MOVE_TOOL::getConnectedDragItems( SCH_ITEM* aOriginalItem, wxPoint aPoi
case SCH_LABEL_T: case SCH_LABEL_T:
case SCH_GLOBAL_LABEL_T: case SCH_GLOBAL_LABEL_T:
case SCH_HIER_LABEL_T: case SCH_HIER_LABEL_T:
// Performance optimization:
if( test->HasFlag( TEMP_SELECTED ) )
break;
// Select labels that are connected to a wire (or bus) being moved.
if( aOriginalItem->Type() == SCH_LINE_T && test->CanConnect( aOriginalItem ) )
{
SCH_TEXT* label = static_cast<SCH_TEXT*>( test );
SCH_LINE* line = static_cast<SCH_LINE*>( aOriginalItem );
bool oneEndFixed = !line->HasFlag( STARTPOINT ) || !line->HasFlag( ENDPOINT );
if( line->HitTest( label->GetTextPos(), 1 ) )
{
label->SetFlags( TEMP_SELECTED );
aList.push_back( label );
if( oneEndFixed )
{
SPECIAL_CASE_LABEL_INFO info;
info.attachedLine = line;
info.originalLabelPos = label->GetPosition();
m_specialCaseLabels[ label ] = info;
}
}
}
break;
case SCH_BUS_WIRE_ENTRY_T: case SCH_BUS_WIRE_ENTRY_T:
case SCH_BUS_BUS_ENTRY_T: case SCH_BUS_BUS_ENTRY_T:
// Performance optimization: // Performance optimization:
if( test->HasFlag( TEMP_SELECTED ) ) if( test->HasFlag( TEMP_SELECTED ) )
break; break;
// Select labels and bus entries that are connected to a wire being moved. // Select bus entries that are connected to a bus being moved.
if( aOriginalItem->Type() == SCH_LINE_T ) if( aOriginalItem->Type() == SCH_LINE_T && test->CanConnect( aOriginalItem ) )
{ {
std::vector<wxPoint> connections = test->GetConnectionPoints(); SCH_LINE* line = static_cast<SCH_LINE*>( aOriginalItem );
bool oneEndFixed = !line->HasFlag( STARTPOINT ) || !line->HasFlag( ENDPOINT );
for( wxPoint& point : connections ) if( oneEndFixed )
{ {
if( aOriginalItem->HitTest( point, 1 ) ) // This is only going to end in tears, so don't go there
continue;
}
for( wxPoint& point : test->GetConnectionPoints() )
{
if( line->HitTest( point, 1 ) )
{ {
test->SetFlags( TEMP_SELECTED ); test->SetFlags( TEMP_SELECTED );
aList.push_back( test ); aList.push_back( test );
// A bus entry needs its wire & label as well // A bus entry needs its wire & label as well
if( testType == SCH_BUS_WIRE_ENTRY_T || testType == SCH_BUS_BUS_ENTRY_T ) std::vector<wxPoint> ends = test->GetConnectionPoints();
{ wxPoint otherEnd;
std::vector<wxPoint> ends = test->GetConnectionPoints();
wxPoint otherEnd;
if( ends[0] == point ) if( ends[0] == point )
otherEnd = ends[1]; otherEnd = ends[1];
else else
otherEnd = ends[0]; otherEnd = ends[0];
getConnectedDragItems( test, otherEnd, aList ); getConnectedDragItems( test, otherEnd, aList );
}
// No need to test the other end of the bus entry
break; break;
} }
} }