Eeschema: Fix selection of items inside filled shapes

The selection heuristic broke down when one item was a filled
shape. Because all hit tests would succeed with distance 0 for
these shapes, they would always be considered the closest item
to the exclusion of all else, which made it very hard to
click on a graphic inside a filled shape.

Now, recognise when an item would be "dominating" and
decline to promote it to the "closet" spot. It will still
be selectable if there are no other items nearby, or if
there are multiple shapes.
This commit is contained in:
John Beard 2024-05-23 11:25:28 +08:00
parent cd83666b72
commit fd4c15517f
1 changed files with 21 additions and 7 deletions

View File

@ -1495,6 +1495,11 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const
BOX2I bbox = item->GetBoundingBox();
int dist = INT_MAX / 4;
// A dominating item is one that would unfairly win distance tests
// and mask out other items. For example, a filled rectangle "wins"
// with a zero distance over anything inside it.
bool dominating = false;
if( exactHits.contains( item ) )
{
if( item->Type() == SCH_PIN_T || item->Type() == SCH_JUNCTION_T )
@ -1551,6 +1556,9 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const
delete s;
}
// Filled shapes win hit tests anywhere inside them
dominating = shape->IsFilled();
}
else if( symbol )
{
@ -1574,15 +1582,21 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const
rect.Collide( poss, collector.m_Threshold, &dist );
}
if( dist == closestDist )
// Don't promote dominating items to be the closest item
// (they'll always win) - they'll still be available for selection, but they
// won't boot out worthy competitors.
if ( !dominating )
{
if( item->GetParent() == closest )
if( dist == closestDist )
{
if( item->GetParent() == closest )
closest = item;
}
else if( dist < closestDist )
{
closestDist = dist;
closest = item;
}
else if( dist < closestDist )
{
closestDist = dist;
closest = item;
}
}
}