Further simplify selection logic.
The select-single-wire stuff is no longer needed, and the prefer-wire-ends stuff needs to be distance-based. Also improved wire hit-testing to include bubbles the size of the dangling symbol at each end. Fixes https://gitlab.com/kicad/code/kicad/issues/9187
This commit is contained in:
parent
28bd734313
commit
ec2ac181a2
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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<SCH_LINE*>( 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<SCH_LINE*>( 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;
|
||||
|
|
Loading…
Reference in New Issue