Improve handling of dragging around locked segments
Locked segments now are not modified if they weren't the start item. If a locked segment is the start item, it is automatically unlocked. Fixes https://gitlab.com/kicad/code/kicad/-/issues/9145
This commit is contained in:
parent
b605111542
commit
cf53b053a1
|
@ -1068,19 +1068,23 @@ int NODE::FindLinesBetweenJoints( const JOINT& aA, const JOINT& aB, std::vector<
|
|||
|
||||
void NODE::FixupVirtualVias()
|
||||
{
|
||||
SEGMENT* locked_seg = nullptr;
|
||||
std::vector<VVIA*> vvias;
|
||||
|
||||
for( auto& joint : m_joints )
|
||||
for( auto& jointPair : m_joints )
|
||||
{
|
||||
if( joint.second.Layers().IsMultilayer() )
|
||||
JOINT joint = jointPair.second;
|
||||
|
||||
if( joint.Layers().IsMultilayer() )
|
||||
continue;
|
||||
|
||||
int n_seg = 0, n_solid = 0, n_vias = 0;
|
||||
int prev_w = -1;
|
||||
int max_w = -1;
|
||||
int prev_w = -1;
|
||||
int max_w = -1;
|
||||
bool is_width_change = false;
|
||||
bool is_locked = false;
|
||||
|
||||
for( const auto& lnk : joint.second.LinkList() )
|
||||
for( const auto& lnk : joint.LinkList() )
|
||||
{
|
||||
if( lnk.item->OfKind( ITEM::VIA_T ) )
|
||||
{
|
||||
|
@ -1101,15 +1105,28 @@ void NODE::FixupVirtualVias()
|
|||
|
||||
max_w = std::max( w, max_w );
|
||||
prev_w = w;
|
||||
|
||||
is_locked = t->IsLocked();
|
||||
locked_seg = t;
|
||||
}
|
||||
}
|
||||
|
||||
if( ( is_width_change || n_seg >= 3 ) && n_solid == 0 && n_vias == 0 )
|
||||
if( ( is_width_change || n_seg >= 3 || is_locked ) && n_solid == 0 && n_vias == 0 )
|
||||
{
|
||||
// fixme: the hull margin here is an ugly temporary workaround. The real fix
|
||||
// is to use octagons for via force propagation.
|
||||
vvias.push_back( new VVIA( joint.second.Pos(), joint.second.Layers().Start(),
|
||||
max_w + 2 * PNS_HULL_MARGIN, joint.second.Net() ) );
|
||||
vvias.push_back( new VVIA( joint.Pos(), joint.Layers().Start(),
|
||||
max_w + 2 * PNS_HULL_MARGIN, joint.Net() ) );
|
||||
}
|
||||
|
||||
if( is_locked )
|
||||
{
|
||||
const VECTOR2I& secondPos = ( locked_seg->Seg().A == joint.Pos() ) ?
|
||||
locked_seg->Seg().B :
|
||||
locked_seg->Seg().A;
|
||||
|
||||
vvias.push_back( new VVIA( secondPos, joint.Layers().Start(),
|
||||
max_w + 2 * PNS_HULL_MARGIN, joint.Net() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1564,7 +1564,7 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
|||
if( selection.Size() != 1 )
|
||||
return 0;
|
||||
|
||||
const BOARD_ITEM* item = static_cast<const BOARD_ITEM*>( selection.Front() );
|
||||
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.Front() );
|
||||
|
||||
if( item->Type() != PCB_TRACE_T
|
||||
&& item->Type() != PCB_VIA_T
|
||||
|
@ -1573,6 +1573,19 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
|||
return 0;
|
||||
}
|
||||
|
||||
// If we overrode locks, we want to clear the flag from the source item before SyncWorld is
|
||||
// called so that virtual vias are not generated for the (now unlocked) track segment. Note in
|
||||
// this case the lock can't be reliably re-applied, because there is no guarantee that the end
|
||||
// state of the drag results in the same number of segments so it's not clear which segment to
|
||||
// apply the lock state to.
|
||||
bool wasLocked = false;
|
||||
|
||||
if( item->IsLocked() )
|
||||
{
|
||||
wasLocked = true;
|
||||
item->SetLocked( false );
|
||||
}
|
||||
|
||||
Activate();
|
||||
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
|
@ -1643,7 +1656,12 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
|||
bool dragStarted = m_router->StartDragging( p, itemsToDrag, dragMode );
|
||||
|
||||
if( !dragStarted )
|
||||
{
|
||||
if( wasLocked )
|
||||
item->SetLocked( true );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_gridHelper->SetAuxAxes( true, p );
|
||||
controls()->ShowCursor( true );
|
||||
|
@ -1677,6 +1695,9 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
|||
|
||||
if( evt->IsCancelInteractive() )
|
||||
{
|
||||
if( wasLocked )
|
||||
item->SetLocked( true );
|
||||
|
||||
break;
|
||||
}
|
||||
else if( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) )
|
||||
|
|
Loading…
Reference in New Issue