PNS: Allow dragging more than one footprint
Fixes https://gitlab.com/kicad/code/kicad/-/issues/11312
This commit is contained in:
parent
5dc62368b0
commit
5a9c028e85
|
@ -2107,8 +2107,6 @@ bool ROUTER_TOOL::CanInlineDrag( int aDragMode )
|
||||||
NeighboringSegmentFilter );
|
NeighboringSegmentFilter );
|
||||||
const PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
|
const PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
|
||||||
|
|
||||||
if( selection.Size() == 1 )
|
|
||||||
{
|
|
||||||
const BOARD_ITEM* item = static_cast<const BOARD_ITEM*>( selection.Front() );
|
const BOARD_ITEM* item = static_cast<const BOARD_ITEM*>( selection.Front() );
|
||||||
|
|
||||||
// Note: EDIT_TOOL::Drag temporarily handles items of type PCB_ARC_T on its own using
|
// Note: EDIT_TOOL::Drag temporarily handles items of type PCB_ARC_T on its own using
|
||||||
|
@ -2121,7 +2119,6 @@ bool ROUTER_TOOL::CanInlineDrag( int aDragMode )
|
||||||
else
|
else
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2137,7 +2134,7 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
||||||
NeighboringSegmentFilter );
|
NeighboringSegmentFilter );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( selection.Size() != 1 )
|
if( selection.Empty() )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.Front() );
|
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.Front() );
|
||||||
|
@ -2149,6 +2146,25 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::set<FOOTPRINT*> footprints;
|
||||||
|
|
||||||
|
// We can drag multiple footprints, but not a grab-bag of items
|
||||||
|
if( selection.Size() > 1 )
|
||||||
|
{
|
||||||
|
if( item->Type() != PCB_FOOTPRINT_T )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
footprints.insert( static_cast<FOOTPRINT*>( item ) );
|
||||||
|
|
||||||
|
for( int idx = 1; idx < selection.Size(); ++idx )
|
||||||
|
{
|
||||||
|
if( static_cast<BOARD_ITEM*>( selection.GetItem( idx ) )->Type() != PCB_FOOTPRINT_T )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
footprints.insert( static_cast<FOOTPRINT*>( selection.GetItem( idx ) ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If we overrode locks, we want to clear the flag from the source item before SyncWorld is
|
// 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
|
// 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
|
// this case the lock can't be reliably re-applied, because there is no guarantee that the end
|
||||||
|
@ -2171,7 +2187,6 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
PNS::ITEM* startItem = nullptr;
|
PNS::ITEM* startItem = nullptr;
|
||||||
PNS::ITEM_SET itemsToDrag;
|
PNS::ITEM_SET itemsToDrag;
|
||||||
FOOTPRINT* footprint = nullptr;
|
|
||||||
|
|
||||||
bool showCourtyardConflicts = frame()->GetPcbNewSettings()->m_ShowCourtyardCollisions;
|
bool showCourtyardConflicts = frame()->GetPcbNewSettings()->m_ShowCourtyardCollisions;
|
||||||
|
|
||||||
|
@ -2183,10 +2198,13 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
||||||
std::unique_ptr<CONNECTIVITY_DATA> dynamicData = nullptr;
|
std::unique_ptr<CONNECTIVITY_DATA> dynamicData = nullptr;
|
||||||
VECTOR2I lastOffset;
|
VECTOR2I lastOffset;
|
||||||
|
|
||||||
if( item->Type() == PCB_FOOTPRINT_T )
|
if( !footprints.empty() )
|
||||||
{
|
{
|
||||||
footprint = static_cast<FOOTPRINT*>( item );
|
if( showCourtyardConflicts )
|
||||||
|
courtyardClearanceDRC.Init( board() );
|
||||||
|
|
||||||
|
for( FOOTPRINT* footprint : footprints )
|
||||||
|
{
|
||||||
for( PAD* pad : footprint->Pads() )
|
for( PAD* pad : footprint->Pads() )
|
||||||
{
|
{
|
||||||
PNS::ITEM* solid = m_router->GetWorld()->FindItemByParent( pad );
|
PNS::ITEM* solid = m_router->GetWorld()->FindItemByParent( pad );
|
||||||
|
@ -2210,8 +2228,6 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
if( showCourtyardConflicts )
|
if( showCourtyardConflicts )
|
||||||
{
|
|
||||||
courtyardClearanceDRC.Init( board() );
|
|
||||||
courtyardClearanceDRC.m_FpInMove.push_back( footprint );
|
courtyardClearanceDRC.m_FpInMove.push_back( footprint );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2241,8 +2257,10 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
||||||
if( m_startItem->Net() )
|
if( m_startItem->Net() )
|
||||||
highlightNets( true, { m_startItem->Net() } );
|
highlightNets( true, { m_startItem->Net() } );
|
||||||
}
|
}
|
||||||
else if( footprint )
|
else if( !footprints.empty() )
|
||||||
{
|
{
|
||||||
|
FOOTPRINT* footprint = static_cast<FOOTPRINT*>( item );
|
||||||
|
|
||||||
// The mouse is going to be moved on grid before dragging begins.
|
// The mouse is going to be moved on grid before dragging begins.
|
||||||
VECTOR2I tweakedMousePos;
|
VECTOR2I tweakedMousePos;
|
||||||
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
|
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
|
||||||
|
@ -2319,13 +2337,15 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
||||||
updateEndItem( *evt );
|
updateEndItem( *evt );
|
||||||
m_router->Move( m_endSnapPoint, m_endItem );
|
m_router->Move( m_endSnapPoint, m_endItem );
|
||||||
|
|
||||||
if( footprint )
|
if( !footprints.empty() )
|
||||||
{
|
{
|
||||||
VECTOR2I offset = m_endSnapPoint - p;
|
VECTOR2I offset = m_endSnapPoint - p;
|
||||||
BOARD_ITEM* previewItem;
|
BOARD_ITEM* previewItem;
|
||||||
|
|
||||||
view()->ClearPreview();
|
view()->ClearPreview();
|
||||||
|
|
||||||
|
for( FOOTPRINT* footprint : footprints )
|
||||||
|
{
|
||||||
for( BOARD_ITEM* drawing : footprint->GraphicalItems() )
|
for( BOARD_ITEM* drawing : footprint->GraphicalItems() )
|
||||||
{
|
{
|
||||||
previewItem = static_cast<BOARD_ITEM*>( drawing->Clone() );
|
previewItem = static_cast<BOARD_ITEM*>( drawing->Clone() );
|
||||||
|
@ -2364,10 +2384,15 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
||||||
view()->Hide( &footprint->Value() );
|
view()->Hide( &footprint->Value() );
|
||||||
|
|
||||||
if( showCourtyardConflicts )
|
if( showCourtyardConflicts )
|
||||||
{
|
|
||||||
footprint->Move( offset );
|
footprint->Move( offset );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( showCourtyardConflicts )
|
||||||
|
{
|
||||||
courtyardClearanceDRC.Run();
|
courtyardClearanceDRC.Run();
|
||||||
courtyardClearanceDRC.UpdateConflicts( getView(), false );
|
courtyardClearanceDRC.UpdateConflicts( getView(), false );
|
||||||
|
|
||||||
|
for( FOOTPRINT* footprint : footprints )
|
||||||
footprint->Move( -offset );
|
footprint->Move( -offset );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2422,7 +2447,9 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
||||||
handleCommonEvents( *evt );
|
handleCommonEvents( *evt );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( footprint )
|
if( !footprints.empty() )
|
||||||
|
{
|
||||||
|
for( FOOTPRINT* footprint : footprints )
|
||||||
{
|
{
|
||||||
for( BOARD_ITEM* drawing : footprint->GraphicalItems() )
|
for( BOARD_ITEM* drawing : footprint->GraphicalItems() )
|
||||||
view()->Hide( drawing, false );
|
view()->Hide( drawing, false );
|
||||||
|
@ -2432,6 +2459,7 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
for( PAD* pad : footprint->Pads() )
|
for( PAD* pad : footprint->Pads() )
|
||||||
view()->Hide( pad, false );
|
view()->Hide( pad, false );
|
||||||
|
}
|
||||||
|
|
||||||
view()->ClearPreview();
|
view()->ClearPreview();
|
||||||
view()->ShowPreview( false );
|
view()->ShowPreview( false );
|
||||||
|
|
Loading…
Reference in New Issue