From 21d4197eabcec08c1d4e48382c63d4523e34d250 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Wed, 7 Apr 2021 14:37:58 +0100 Subject: [PATCH] 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 --- eeschema/tools/sch_move_tool.cpp | 94 ++++++++++++++++++++++---------- 1 file changed, 65 insertions(+), 29 deletions(-) diff --git a/eeschema/tools/sch_move_tool.cpp b/eeschema/tools/sch_move_tool.cpp index 3d59d71d58..86dcc98443 100644 --- a/eeschema/tools/sch_move_tool.cpp +++ b/eeschema/tools/sch_move_tool.cpp @@ -527,21 +527,21 @@ void SCH_MOVE_TOOL::getConnectedDragItems( SCH_ITEM* aOriginalItem, wxPoint aPoi if( ptHasUnselectedJunction ) break; - SCH_LINE* testLine = static_cast( test ); + SCH_LINE* line = static_cast( test ); - if( testLine->GetStartPoint() == aPoint ) + if( line->GetStartPoint() == aPoint ) { - if( !testLine->HasFlag( TEMP_SELECTED ) ) - aList.push_back( testLine ); + if( !line->HasFlag(TEMP_SELECTED ) ) + 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 ) ) - aList.push_back( testLine ); + if( !line->HasFlag(TEMP_SELECTED ) ) + aList.push_back( line ); - testLine->SetFlags( ENDPOINT | TEMP_SELECTED ); + line->SetFlags(ENDPOINT | TEMP_SELECTED ); } else { @@ -560,14 +560,16 @@ void SCH_MOVE_TOOL::getConnectedDragItems( SCH_ITEM* aOriginalItem, wxPoint aPoi if( label->IsSelected() ) continue; // These will be moved on their own because they're selected - if( label->CanConnect( testLine ) - && testLine->HitTest( label->GetPosition(), 1 ) ) + if( label->HasFlag( TEMP_SELECTED ) ) + continue; + + if( label->CanConnect( line ) && line->HitTest( label->GetPosition(), 1 ) ) { - if( !label->HasFlag( TEMP_SELECTED ) ) - aList.push_back( label ); + label->SetFlags( TEMP_SELECTED ); + aList.push_back( label ); SPECIAL_CASE_LABEL_INFO info; - info.attachedLine = testLine; + info.attachedLine = line; info.originalLabelPos = label->GetPosition(); m_specialCaseLabels[label] = info; } @@ -616,37 +618,71 @@ void SCH_MOVE_TOOL::getConnectedDragItems( SCH_ITEM* aOriginalItem, wxPoint aPoi case SCH_LABEL_T: case SCH_GLOBAL_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( test ); + SCH_LINE* line = static_cast( 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_BUS_ENTRY_T: // Performance optimization: if( test->HasFlag( TEMP_SELECTED ) ) break; - // Select labels and bus entries that are connected to a wire being moved. - if( aOriginalItem->Type() == SCH_LINE_T ) + // Select bus entries that are connected to a bus being moved. + if( aOriginalItem->Type() == SCH_LINE_T && test->CanConnect( aOriginalItem ) ) { - std::vector connections = test->GetConnectionPoints(); + SCH_LINE* line = static_cast( 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 ); aList.push_back( test ); // A bus entry needs its wire & label as well - if( testType == SCH_BUS_WIRE_ENTRY_T || testType == SCH_BUS_BUS_ENTRY_T ) - { - std::vector ends = test->GetConnectionPoints(); - wxPoint otherEnd; + std::vector ends = test->GetConnectionPoints(); + wxPoint otherEnd; - if( ends[0] == point ) - otherEnd = ends[1]; - else - otherEnd = ends[0]; + if( ends[0] == point ) + otherEnd = ends[1]; + else + otherEnd = ends[0]; - getConnectedDragItems( test, otherEnd, aList ); - } + getConnectedDragItems( test, otherEnd, aList ); + + // No need to test the other end of the bus entry break; } }