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_initialDraggedItems = aPrimitives;
m_p0 = aP; 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() ) for( auto item : aPrimitives.Items() )
{ {
if( item.item->Kind() != ITEM::SOLID_T ) 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() ) for( auto link : jt->LinkList() )
{ {
if( link.item->OfKind( ITEM::SEGMENT_T | ITEM::ARC_T ) ) 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 ); if( extraJoint->Net() == jt->Net() && extraJoint->LinkCount() == 1 )
int segIndex; {
LINKED_ITEM* li = static_cast<LINKED_ITEM*>( extraJoint->LinkList()[0].item );
auto l0 = m_world->AssembleLine( li, &segIndex ); if( li->Collide( solid, 0, false, nullptr, nullptr, false ) )
addLinked( solid, li, extraJoint->Pos() - solid->Pos() );
DRAGGED_CONNECTION cn; }
cn.origLine = l0;
cn.attachedPad = solid;
m_conns.push_back( cn );
} }
} }
} }
@ -108,8 +134,8 @@ bool COMPONENT_DRAGGER::Drag( const VECTOR2I& aP )
{ {
if( l.attachedPad == s ) if( l.attachedPad == s )
{ {
l.p_orig = s->Pos(); l.p_orig = s->Pos() + l.offset;
l.p_next = p_next; l.p_next = p_next + l.offset;
} }
} }
} }

View File

@ -114,6 +114,7 @@ private:
LINE origLine; LINE origLine;
SOLID* attachedPad; SOLID* attachedPad;
VECTOR2I p_orig, p_next; VECTOR2I p_orig, p_next;
VECTOR2I offset;
}; };
std::set<SOLID*> m_solids; 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(); 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++; n++;
} }
} }
@ -1436,13 +1439,13 @@ int NODE::QueryJoints( const BOX2I& aBox, std::vector<JOINT*>& aJoints, int aLay
if( isRoot() ) if( isRoot() )
return n; 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++; n++;
} }
} }