Component dragger: be more generous about picking up tracks

We now pick up tracks that end anywhere in the pad, not just
at the pad anchor.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/5945
This commit is contained in:
Jon Evans 2020-12-22 22:28:13 -05:00
parent 6641168cbc
commit 70c6314c67
3 changed files with 48 additions and 18 deletions

View File

@ -50,6 +50,26 @@ bool COMPONENT_DRAGGER::Start( const VECTOR2I& aP, ITEM_SET& aPrimitives )
m_initialDraggedItems = aPrimitives;
m_p0 = aP;
std::unordered_set<LINKED_ITEM*> seenItems;
auto addLinked =
[&]( SOLID* aSolid, LINKED_ITEM* aItem, VECTOR2I aOffset = {} )
{
if( seenItems.count( aItem ) )
return;
seenItems.insert( aItem );
int segIndex;
DRAGGED_CONNECTION cn;
cn.origLine = m_world->AssembleLine( aItem, &segIndex );
cn.attachedPad = aSolid;
cn.offset = aOffset;
m_conns.push_back( cn );
};
for( auto item : aPrimitives.Items() )
{
if( item.item->Kind() != ITEM::SOLID_T )
@ -66,17 +86,23 @@ bool COMPONENT_DRAGGER::Start( const VECTOR2I& aP, ITEM_SET& aPrimitives )
for( auto link : jt->LinkList() )
{
if( link.item->OfKind( ITEM::SEGMENT_T | ITEM::ARC_T ) )
addLinked( solid, static_cast<LINKED_ITEM*>( link.item ) );
}
std::vector<JOINT*> extraJoints;
if( m_world->QueryJoints( solid->Hull().BBox(), extraJoints, solid->Layer(),
ITEM::SEGMENT_T | ITEM::ARC_T ) )
{
for( JOINT* extraJoint : extraJoints )
{
LINKED_ITEM* li = static_cast<LINKED_ITEM*>( link.item );
int segIndex;
if( extraJoint->Net() == jt->Net() && extraJoint->LinkCount() == 1 )
{
LINKED_ITEM* li = static_cast<LINKED_ITEM*>( extraJoint->LinkList()[0].item );
auto l0 = m_world->AssembleLine( li, &segIndex );
DRAGGED_CONNECTION cn;
cn.origLine = l0;
cn.attachedPad = solid;
m_conns.push_back( cn );
if( li->Collide( solid, 0, false, nullptr, nullptr, false ) )
addLinked( solid, li, extraJoint->Pos() - solid->Pos() );
}
}
}
}
@ -108,8 +134,8 @@ bool COMPONENT_DRAGGER::Drag( const VECTOR2I& aP )
{
if( l.attachedPad == s )
{
l.p_orig = s->Pos();
l.p_next = p_next;
l.p_orig = s->Pos() + l.offset;
l.p_next = p_next + l.offset;
}
}
}

View File

@ -114,6 +114,7 @@ private:
LINE origLine;
SOLID* attachedPad;
VECTOR2I p_orig, p_next;
VECTOR2I offset;
};
std::set<SOLID*> m_solids;

View File

@ -1424,11 +1424,14 @@ int NODE::QueryJoints( const BOX2I& aBox, std::vector<JOINT*>& aJoints, int aLay
aJoints.clear();
for( auto j = m_joints.begin(); j != m_joints.end(); ++j )
for( JOINT_MAP::value_type& j : m_joints )
{
if( aBox.Contains( j->second.Pos() ) && j->second.LinkCount( aKindMask ) )
if( j.second.Layer() != aLayerMask )
continue;
if( aBox.Contains( j.second.Pos() ) && j.second.LinkCount( aKindMask ) )
{
aJoints.push_back( &j->second );
aJoints.push_back( &j.second );
n++;
}
}
@ -1436,13 +1439,13 @@ int NODE::QueryJoints( const BOX2I& aBox, std::vector<JOINT*>& aJoints, int aLay
if( isRoot() )
return n;
for( auto j = m_root->m_joints.begin(); j != m_root->m_joints.end(); ++j )
for( JOINT_MAP::value_type& j : m_root->m_joints )
{
if( !Overrides( &j->second) )
if( !Overrides( &j.second ) && j.second.Layer() == aLayerMask )
{
if( aBox.Contains( j->second.Pos() ) && j->second.LinkCount( aKindMask ) )
if( aBox.Contains( j.second.Pos() ) && j.second.LinkCount( aKindMask ) )
{
aJoints.push_back( &j->second );
aJoints.push_back( &j.second );
n++;
}
}