diff --git a/eeschema/sch_line.cpp b/eeschema/sch_line.cpp index 37eb99039d..fcdd76ea26 100644 --- a/eeschema/sch_line.cpp +++ b/eeschema/sch_line.cpp @@ -788,7 +788,13 @@ bool SCH_LINE::HitTest( const wxPoint& aPosition, int aAccuracy ) const else aAccuracy = abs( aAccuracy ); - return TestSegmentHit( aPosition, m_start, m_end, aAccuracy ); + if( TestSegmentHit( aPosition, m_start, m_end, aAccuracy ) ) + return true; + + aAccuracy += Mils2iu( DANGLING_SYMBOL_SIZE ); + + return ( EuclideanNorm( aPosition - m_start ) < aAccuracy + || EuclideanNorm( aPosition - m_end ) < aAccuracy ); } diff --git a/eeschema/sch_painter.cpp b/eeschema/sch_painter.cpp index ec4979a525..812d7d0637 100644 --- a/eeschema/sch_painter.cpp +++ b/eeschema/sch_painter.cpp @@ -1246,7 +1246,7 @@ void SCH_PAINTER::draw( const LIB_BEZIER *aCurve, int aLayer ) void SCH_PAINTER::drawDanglingSymbol( const wxPoint& aPos, int aWidth, bool aDrawingShadows ) { wxPoint radius( aWidth + Mils2iu( DANGLING_SYMBOL_SIZE / 2 ), - aWidth + Mils2iu( DANGLING_SYMBOL_SIZE /2 ) ); + aWidth + Mils2iu( DANGLING_SYMBOL_SIZE / 2 ) ); m_gal->SetIsStroke( true ); m_gal->SetIsFill( false ); diff --git a/eeschema/tools/ee_selection_tool.cpp b/eeschema/tools/ee_selection_tool.cpp index 162f2b9c73..41b5b67930 100644 --- a/eeschema/tools/ee_selection_tool.cpp +++ b/eeschema/tools/ee_selection_tool.cpp @@ -981,9 +981,20 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const for( int i = collector.GetCount() - 1; i >= 0; --i ) { EDA_ITEM* item = collector[ i ]; + SCH_LINE* line = dynamic_cast( item ); - if( item->HitTest( (wxPoint) aPos, 0 ) ) - exactHits.insert( item ); + // Lines are hard to hit. Give them a bit more slop to still be considered "exact". + + if( line ) + { + if( line->HitTest( (wxPoint) aPos, Mils2iu( DANGLING_SYMBOL_SIZE ) ) ) + exactHits.insert( line ); + } + else + { + if( item->HitTest( (wxPoint) aPos, 0 ) ) + exactHits.insert( item ); + } } if( exactHits.size() > 0 && exactHits.size() < (unsigned) collector.GetCount() ) @@ -992,35 +1003,11 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const { EDA_ITEM* item = collector[ i ]; - if( !item->HitTest( (wxPoint) aPos, 0 ) ) + if( !exactHits.count( item ) ) collector.Transfer( item ); } } - // No need for multiple wires at a single point; if there's a junction select that; - // otherwise any of the wires will do - bool junction = false; - bool wiresOnly = true; - - for( EDA_ITEM* item : collector ) - { - if( item->Type() == SCH_JUNCTION_T ) - junction = true; - else if( item->Type() != SCH_LINE_T ) - wiresOnly = false; - } - - if( wiresOnly ) - { - for( int j = collector.GetCount() - 1; j >= 0; --j ) - { - if( junction && collector[ j ]->Type() != SCH_JUNCTION_T ) - collector.Transfer( j ); - else if( !junction && j > 0 ) - collector.Transfer( j ); - } - } - // Find the closest item. (Note that at this point all hits are either exact or non-exact.) EDA_ITEM* closest = nullptr; int closestDist = INT_MAX; @@ -1032,7 +1019,13 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const if( exactHits.count( item ) ) { - dist = EuclideanNorm( bbox.GetCenter() - (wxPoint) aPos ); + wxPoint pos( aPos ); + SCH_LINE* line = dynamic_cast( item ); + + if( line ) + dist = DistanceLinePoint( line->GetStartPoint(), line->GetEndPoint(), pos ); + else + dist = EuclideanNorm( bbox.GetCenter() - pos ) * 2; } else { @@ -1043,10 +1036,6 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const if( item->IsType( EE_COLLECTOR::FieldOwners ) ) dist += INT_MAX / 4; - // For wires, if we hit one of the endpoints, consider that perfect - if( item->Type() == SCH_LINE_T && ( item->GetFlags() & ( STARTPOINT | ENDPOINT ) ) ) - dist = 0; - if( dist < closestDist ) { closestDist = dist;