Honour selection filter when picking move anchors.
Fixes https://gitlab.com/kicad/code/kicad/issues/12773
This commit is contained in:
parent
1d7c5dce70
commit
2cfe78170c
|
@ -634,7 +634,8 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
|
||||||
drc_on_move->m_FpInMove.push_back( static_cast<FOOTPRINT*>( item ) );
|
drc_on_move->m_FpInMove.push_back( static_cast<FOOTPRINT*>( item ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
m_cursor = grid.BestDragOrigin( originalCursorPos, items );
|
m_cursor = grid.BestDragOrigin( originalCursorPos, items,
|
||||||
|
&m_selectionTool->GetFilter() );
|
||||||
|
|
||||||
// Set the current cursor position to the first dragged item origin, so the
|
// Set the current cursor position to the first dragged item origin, so the
|
||||||
// movement vector could be computed later
|
// movement vector could be computed later
|
||||||
|
|
|
@ -184,12 +184,13 @@ VECTOR2I PCB_GRID_HELPER::AlignToNearestPad( const VECTOR2I& aMousePos, PADS& aP
|
||||||
|
|
||||||
|
|
||||||
VECTOR2I PCB_GRID_HELPER::BestDragOrigin( const VECTOR2I &aMousePos,
|
VECTOR2I PCB_GRID_HELPER::BestDragOrigin( const VECTOR2I &aMousePos,
|
||||||
std::vector<BOARD_ITEM*>& aItems )
|
std::vector<BOARD_ITEM*>& aItems,
|
||||||
|
const SELECTION_FILTER_OPTIONS* aSelectionFilter )
|
||||||
{
|
{
|
||||||
clearAnchors();
|
clearAnchors();
|
||||||
|
|
||||||
for( BOARD_ITEM* item : aItems )
|
for( BOARD_ITEM* item : aItems )
|
||||||
computeAnchors( item, aMousePos, true );
|
computeAnchors( item, aMousePos, true, aSelectionFilter );
|
||||||
|
|
||||||
double worldScale = m_toolMgr->GetView()->GetGAL()->GetWorldScale();
|
double worldScale = m_toolMgr->GetView()->GetGAL()->GetWorldScale();
|
||||||
double lineSnapMinCornerDistance = 50.0 / worldScale;
|
double lineSnapMinCornerDistance = 50.0 / worldScale;
|
||||||
|
@ -385,7 +386,8 @@ std::set<BOARD_ITEM*> PCB_GRID_HELPER::queryVisible( const BOX2I& aArea,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PCB_GRID_HELPER::computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos, bool aFrom )
|
void PCB_GRID_HELPER::computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos, bool aFrom,
|
||||||
|
const SELECTION_FILTER_OPTIONS* aSelectionFilter )
|
||||||
{
|
{
|
||||||
KIGFX::VIEW* view = m_toolMgr->GetView();
|
KIGFX::VIEW* view = m_toolMgr->GetView();
|
||||||
RENDER_SETTINGS* settings = view->GetPainter()->GetSettings();
|
RENDER_SETTINGS* settings = view->GetPainter()->GetSettings();
|
||||||
|
@ -494,74 +496,9 @@ void PCB_GRID_HELPER::computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
switch( aItem->Type() )
|
auto handleShape =
|
||||||
|
[&]( PCB_SHAPE* shape )
|
||||||
{
|
{
|
||||||
case PCB_FOOTPRINT_T:
|
|
||||||
{
|
|
||||||
FOOTPRINT* footprint = static_cast<FOOTPRINT*>( aItem );
|
|
||||||
|
|
||||||
for( PAD* pad : footprint->Pads() )
|
|
||||||
{
|
|
||||||
if( !aFrom && m_magneticSettings->pads != MAGNETIC_OPTIONS::CAPTURE_ALWAYS )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if( !view->IsVisible( pad ) || !pad->GetBoundingBox().Contains( aRefPos ) )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Getting pads from a footprint requires re-checking that the pads are shown
|
|
||||||
bool onActiveLayer = !isHighContrast;
|
|
||||||
bool isLODVisible = false;
|
|
||||||
|
|
||||||
for( PCB_LAYER_ID layer : pad->GetLayerSet().Seq() )
|
|
||||||
{
|
|
||||||
if( !onActiveLayer && activeLayers.count( layer ) )
|
|
||||||
onActiveLayer = true;
|
|
||||||
|
|
||||||
if( !isLODVisible && pad->ViewGetLOD( layer, view ) < view->GetScale() )
|
|
||||||
isLODVisible = true;
|
|
||||||
|
|
||||||
if( onActiveLayer && isLODVisible )
|
|
||||||
{
|
|
||||||
handlePadShape( pad );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the cursor is not over a pad, then drag the footprint by its origin
|
|
||||||
VECTOR2I position = footprint->GetPosition();
|
|
||||||
addAnchor( position, ORIGIN | SNAPPABLE, footprint );
|
|
||||||
|
|
||||||
// Add the footprint center point if it is markedly different from the origin
|
|
||||||
VECTOR2I center = footprint->GetBoundingBox( false, false ).Centre();
|
|
||||||
VECTOR2I grid( GetGrid() );
|
|
||||||
|
|
||||||
if( ( center - position ).SquaredEuclideanNorm() > grid.SquaredEuclideanNorm() )
|
|
||||||
addAnchor( center, ORIGIN | SNAPPABLE, footprint );
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case PCB_PAD_T:
|
|
||||||
{
|
|
||||||
if( aFrom || m_magneticSettings->pads == MAGNETIC_OPTIONS::CAPTURE_ALWAYS )
|
|
||||||
{
|
|
||||||
PAD* pad = static_cast<PAD*>( aItem );
|
|
||||||
handlePadShape( pad );
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case PCB_FP_SHAPE_T:
|
|
||||||
case PCB_SHAPE_T:
|
|
||||||
case PCB_FP_TEXTBOX_T:
|
|
||||||
case PCB_TEXTBOX_T:
|
|
||||||
{
|
|
||||||
if( !m_magneticSettings->graphics )
|
|
||||||
break;
|
|
||||||
|
|
||||||
PCB_SHAPE* shape = static_cast<PCB_SHAPE*>( aItem );
|
|
||||||
VECTOR2I start = shape->GetStart();
|
VECTOR2I start = shape->GetStart();
|
||||||
VECTOR2I end = shape->GetEnd();
|
VECTOR2I end = shape->GetEnd();
|
||||||
|
|
||||||
|
@ -638,20 +575,134 @@ void PCB_GRID_HELPER::computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos
|
||||||
addAnchor( shape->GetPosition(), ORIGIN | SNAPPABLE, shape );
|
addAnchor( shape->GetPosition(), ORIGIN | SNAPPABLE, shape );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
switch( aItem->Type() )
|
||||||
|
{
|
||||||
|
case PCB_FOOTPRINT_T:
|
||||||
|
{
|
||||||
|
FOOTPRINT* footprint = static_cast<FOOTPRINT*>( aItem );
|
||||||
|
|
||||||
|
for( PAD* pad : footprint->Pads() )
|
||||||
|
{
|
||||||
|
if( aFrom )
|
||||||
|
{
|
||||||
|
if( aSelectionFilter && !aSelectionFilter->pads )
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( m_magneticSettings->pads != MAGNETIC_OPTIONS::CAPTURE_ALWAYS )
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !view->IsVisible( pad ) || !pad->GetBoundingBox().Contains( aRefPos ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Getting pads from a footprint requires re-checking that the pads are shown
|
||||||
|
bool onActiveLayer = !isHighContrast;
|
||||||
|
bool isLODVisible = false;
|
||||||
|
|
||||||
|
for( PCB_LAYER_ID layer : pad->GetLayerSet().Seq() )
|
||||||
|
{
|
||||||
|
if( !onActiveLayer && activeLayers.count( layer ) )
|
||||||
|
onActiveLayer = true;
|
||||||
|
|
||||||
|
if( !isLODVisible && pad->ViewGetLOD( layer, view ) < view->GetScale() )
|
||||||
|
isLODVisible = true;
|
||||||
|
|
||||||
|
if( onActiveLayer && isLODVisible )
|
||||||
|
{
|
||||||
|
handlePadShape( pad );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( aFrom && aSelectionFilter && !aSelectionFilter->footprints )
|
||||||
|
break;
|
||||||
|
|
||||||
|
// if the cursor is not over a pad, then drag the footprint by its origin
|
||||||
|
VECTOR2I position = footprint->GetPosition();
|
||||||
|
addAnchor( position, ORIGIN | SNAPPABLE, footprint );
|
||||||
|
|
||||||
|
// Add the footprint center point if it is markedly different from the origin
|
||||||
|
VECTOR2I center = footprint->GetBoundingBox( false, false ).Centre();
|
||||||
|
VECTOR2I grid( GetGrid() );
|
||||||
|
|
||||||
|
if( ( center - position ).SquaredEuclideanNorm() > grid.SquaredEuclideanNorm() )
|
||||||
|
addAnchor( center, ORIGIN | SNAPPABLE, footprint );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PCB_PAD_T:
|
||||||
|
if( aFrom )
|
||||||
|
{
|
||||||
|
if( aSelectionFilter && !aSelectionFilter->pads )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( m_magneticSettings->pads != MAGNETIC_OPTIONS::CAPTURE_ALWAYS )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePadShape( static_cast<PAD*>( aItem ) );
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PCB_FP_TEXTBOX_T:
|
||||||
|
case PCB_TEXTBOX_T:
|
||||||
|
if( aFrom )
|
||||||
|
{
|
||||||
|
if( aSelectionFilter && !aSelectionFilter->text )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( !m_magneticSettings->graphics )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleShape( static_cast<PCB_SHAPE*>( aItem ) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PCB_FP_SHAPE_T:
|
||||||
|
case PCB_SHAPE_T:
|
||||||
|
if( aFrom )
|
||||||
|
{
|
||||||
|
if( aSelectionFilter && !aSelectionFilter->graphics )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( !m_magneticSettings->graphics )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleShape( static_cast<PCB_SHAPE*>( aItem ) );
|
||||||
|
break;
|
||||||
|
|
||||||
case PCB_TRACE_T:
|
case PCB_TRACE_T:
|
||||||
case PCB_ARC_T:
|
case PCB_ARC_T:
|
||||||
{
|
{
|
||||||
if( aFrom || m_magneticSettings->tracks == MAGNETIC_OPTIONS::CAPTURE_ALWAYS )
|
if( aFrom )
|
||||||
{
|
{
|
||||||
|
if( aSelectionFilter && !aSelectionFilter->tracks )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( m_magneticSettings->tracks != MAGNETIC_OPTIONS::CAPTURE_ALWAYS )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
PCB_TRACK* track = static_cast<PCB_TRACK*>( aItem );
|
PCB_TRACK* track = static_cast<PCB_TRACK*>( aItem );
|
||||||
|
|
||||||
addAnchor( track->GetStart(), CORNER | SNAPPABLE, track );
|
addAnchor( track->GetStart(), CORNER | SNAPPABLE, track );
|
||||||
addAnchor( track->GetEnd(), CORNER | SNAPPABLE, track );
|
addAnchor( track->GetEnd(), CORNER | SNAPPABLE, track );
|
||||||
addAnchor( track->GetCenter(), ORIGIN, track);
|
addAnchor( track->GetCenter(), ORIGIN, track);
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -662,15 +713,26 @@ void PCB_GRID_HELPER::computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCB_VIA_T:
|
case PCB_VIA_T:
|
||||||
|
if( aFrom )
|
||||||
{
|
{
|
||||||
if( aFrom || m_magneticSettings->tracks == MAGNETIC_OPTIONS::CAPTURE_ALWAYS )
|
if( aSelectionFilter && !aSelectionFilter->vias )
|
||||||
addAnchor( aItem->GetPosition(), ORIGIN | CORNER | SNAPPABLE, aItem );
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( m_magneticSettings->tracks != MAGNETIC_OPTIONS::CAPTURE_ALWAYS )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addAnchor( aItem->GetPosition(), ORIGIN | CORNER | SNAPPABLE, aItem );
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case PCB_ZONE_T:
|
case PCB_ZONE_T:
|
||||||
{
|
{
|
||||||
|
if( aFrom && aSelectionFilter && !aSelectionFilter->zones )
|
||||||
|
break;
|
||||||
|
|
||||||
const SHAPE_POLY_SET* outline = static_cast<const ZONE*>( aItem )->Outline();
|
const SHAPE_POLY_SET* outline = static_cast<const ZONE*>( aItem )->Outline();
|
||||||
|
|
||||||
SHAPE_LINE_CHAIN lc;
|
SHAPE_LINE_CHAIN lc;
|
||||||
|
@ -689,6 +751,9 @@ void PCB_GRID_HELPER::computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos
|
||||||
|
|
||||||
case PCB_FP_ZONE_T:
|
case PCB_FP_ZONE_T:
|
||||||
{
|
{
|
||||||
|
if( aFrom && aSelectionFilter && !aSelectionFilter->zones )
|
||||||
|
break;
|
||||||
|
|
||||||
const SHAPE_POLY_SET* outline = static_cast<const FP_ZONE*>( aItem )->Outline();
|
const SHAPE_POLY_SET* outline = static_cast<const FP_ZONE*>( aItem )->Outline();
|
||||||
|
|
||||||
SHAPE_LINE_CHAIN lc;
|
SHAPE_LINE_CHAIN lc;
|
||||||
|
@ -710,6 +775,9 @@ void PCB_GRID_HELPER::computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos
|
||||||
case PCB_FP_DIM_ALIGNED_T:
|
case PCB_FP_DIM_ALIGNED_T:
|
||||||
case PCB_FP_DIM_ORTHOGONAL_T:
|
case PCB_FP_DIM_ORTHOGONAL_T:
|
||||||
{
|
{
|
||||||
|
if( aFrom && aSelectionFilter && !aSelectionFilter->dimensions )
|
||||||
|
break;
|
||||||
|
|
||||||
const PCB_DIM_ALIGNED* dim = static_cast<const PCB_DIM_ALIGNED*>( aItem );
|
const PCB_DIM_ALIGNED* dim = static_cast<const PCB_DIM_ALIGNED*>( aItem );
|
||||||
addAnchor( dim->GetCrossbarStart(), CORNER | SNAPPABLE, aItem );
|
addAnchor( dim->GetCrossbarStart(), CORNER | SNAPPABLE, aItem );
|
||||||
addAnchor( dim->GetCrossbarEnd(), CORNER | SNAPPABLE, aItem );
|
addAnchor( dim->GetCrossbarEnd(), CORNER | SNAPPABLE, aItem );
|
||||||
|
@ -721,6 +789,9 @@ void PCB_GRID_HELPER::computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos
|
||||||
case PCB_DIM_CENTER_T:
|
case PCB_DIM_CENTER_T:
|
||||||
case PCB_FP_DIM_CENTER_T:
|
case PCB_FP_DIM_CENTER_T:
|
||||||
{
|
{
|
||||||
|
if( aFrom && aSelectionFilter && !aSelectionFilter->dimensions )
|
||||||
|
break;
|
||||||
|
|
||||||
const PCB_DIM_CENTER* dim = static_cast<const PCB_DIM_CENTER*>( aItem );
|
const PCB_DIM_CENTER* dim = static_cast<const PCB_DIM_CENTER*>( aItem );
|
||||||
addAnchor( dim->GetStart(), CORNER | SNAPPABLE, aItem );
|
addAnchor( dim->GetStart(), CORNER | SNAPPABLE, aItem );
|
||||||
addAnchor( dim->GetEnd(), CORNER | SNAPPABLE, aItem );
|
addAnchor( dim->GetEnd(), CORNER | SNAPPABLE, aItem );
|
||||||
|
@ -740,6 +811,9 @@ void PCB_GRID_HELPER::computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos
|
||||||
case PCB_DIM_RADIAL_T:
|
case PCB_DIM_RADIAL_T:
|
||||||
case PCB_FP_DIM_RADIAL_T:
|
case PCB_FP_DIM_RADIAL_T:
|
||||||
{
|
{
|
||||||
|
if( aFrom && aSelectionFilter && !aSelectionFilter->dimensions )
|
||||||
|
break;
|
||||||
|
|
||||||
const PCB_DIM_RADIAL* radialDim = static_cast<const PCB_DIM_RADIAL*>( aItem );
|
const PCB_DIM_RADIAL* radialDim = static_cast<const PCB_DIM_RADIAL*>( aItem );
|
||||||
addAnchor( radialDim->GetStart(), CORNER | SNAPPABLE, aItem );
|
addAnchor( radialDim->GetStart(), CORNER | SNAPPABLE, aItem );
|
||||||
addAnchor( radialDim->GetEnd(), CORNER | SNAPPABLE, aItem );
|
addAnchor( radialDim->GetEnd(), CORNER | SNAPPABLE, aItem );
|
||||||
|
@ -751,6 +825,9 @@ void PCB_GRID_HELPER::computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos
|
||||||
case PCB_DIM_LEADER_T:
|
case PCB_DIM_LEADER_T:
|
||||||
case PCB_FP_DIM_LEADER_T:
|
case PCB_FP_DIM_LEADER_T:
|
||||||
{
|
{
|
||||||
|
if( aFrom && aSelectionFilter && !aSelectionFilter->dimensions )
|
||||||
|
break;
|
||||||
|
|
||||||
const PCB_DIM_LEADER* leader = static_cast<const PCB_DIM_LEADER*>( aItem );
|
const PCB_DIM_LEADER* leader = static_cast<const PCB_DIM_LEADER*>( aItem );
|
||||||
addAnchor( leader->GetStart(), CORNER | SNAPPABLE, aItem );
|
addAnchor( leader->GetStart(), CORNER | SNAPPABLE, aItem );
|
||||||
addAnchor( leader->GetEnd(), CORNER | SNAPPABLE, aItem );
|
addAnchor( leader->GetEnd(), CORNER | SNAPPABLE, aItem );
|
||||||
|
@ -760,6 +837,9 @@ void PCB_GRID_HELPER::computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos
|
||||||
|
|
||||||
case PCB_FP_TEXT_T:
|
case PCB_FP_TEXT_T:
|
||||||
case PCB_TEXT_T:
|
case PCB_TEXT_T:
|
||||||
|
if( aFrom && aSelectionFilter && !aSelectionFilter->text )
|
||||||
|
break;
|
||||||
|
|
||||||
addAnchor( aItem->GetPosition(), ORIGIN, aItem );
|
addAnchor( aItem->GetPosition(), ORIGIN, aItem );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,8 @@ public:
|
||||||
|
|
||||||
VECTOR2I AlignToSegment ( const VECTOR2I& aPoint, const SEG& aSeg );
|
VECTOR2I AlignToSegment ( const VECTOR2I& aPoint, const SEG& aSeg );
|
||||||
|
|
||||||
VECTOR2I BestDragOrigin( const VECTOR2I& aMousePos, std::vector<BOARD_ITEM*>& aItem );
|
VECTOR2I BestDragOrigin( const VECTOR2I& aMousePos, std::vector<BOARD_ITEM*>& aItem,
|
||||||
|
const SELECTION_FILTER_OPTIONS* aSelectionFilter = nullptr );
|
||||||
|
|
||||||
VECTOR2I AlignToArc ( const VECTOR2I& aPoint, const SHAPE_ARC& aSeg );
|
VECTOR2I AlignToArc ( const VECTOR2I& aPoint, const SHAPE_ARC& aSeg );
|
||||||
|
|
||||||
|
@ -81,7 +82,8 @@ private:
|
||||||
* @param aRefPos The point for which to compute the anchors (if used by the component)
|
* @param aRefPos The point for which to compute the anchors (if used by the component)
|
||||||
* @param aFrom Is this for an anchor that is designating a source point (aFrom=true) or not
|
* @param aFrom Is this for an anchor that is designating a source point (aFrom=true) or not
|
||||||
*/
|
*/
|
||||||
void computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos, bool aFrom = false );
|
void computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos, bool aFrom = false,
|
||||||
|
const SELECTION_FILTER_OPTIONS* aSelectionFilter = nullptr );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MAGNETIC_SETTINGS* m_magneticSettings;
|
MAGNETIC_SETTINGS* m_magneticSettings;
|
||||||
|
|
Loading…
Reference in New Issue