pcbnew: Snap items to grouped layers

When moving a group of items, the allowed snapping layers should be each
layer in the group, not just the first item's LSET.

Fixes: lp:1830164
* https://bugs.launchpad.net/kicad/+bug/1830164
This commit is contained in:
Seth Hillbrand 2019-08-20 21:31:11 -07:00
parent 22fdc7f51f
commit 8576668eba
5 changed files with 40 additions and 19 deletions

View File

@ -268,7 +268,7 @@ int EDIT_TOOL::Move( const TOOL_EVENT& aEvent )
if( m_dragging || selection.Empty() )
return 0;
LSET item_layers = static_cast<BOARD_ITEM*>( selection.Front() )->GetLayerSet();
LSET item_layers = selection.GetSelectionLayers();
bool unselect = selection.IsHover(); //N.B. This must be saved before the re-selection below
// Now filter out locked pads. We cannot do this in the first RequestSelection() as we need
@ -408,18 +408,18 @@ int EDIT_TOOL::Move( const TOOL_EVENT& aEvent )
selection.SetReferencePoint( m_cursor );
}
else if( selection.Size() == 1 )
{
// Set the current cursor position to the first dragged item origin, so the
// movement vector could be computed later
updateModificationPoint( selection );
m_cursor = grid.BestDragOrigin( originalCursorPos, curr_item );
grid.SetAuxAxes( true, m_cursor );
}
else
{
updateModificationPoint( selection );
m_cursor = grid.Align( m_cursor );
std::vector<BOARD_ITEM*> items;
for( auto item : selection.Items() )
items.push_back( static_cast<BOARD_ITEM*>( item ) );
// Set the current cursor position to the first dragged item origin, so the
// movement vector could be computed later
m_cursor = grid.BestDragOrigin( originalCursorPos, items );
selection.SetReferencePoint( m_cursor );
grid.SetAuxAxes( true, m_cursor );
}
controls->SetCursorPosition( m_cursor, false );

View File

@ -167,10 +167,12 @@ VECTOR2I GRID_HELPER::AlignToSegment( const VECTOR2I& aPoint, const SEG& aSeg )
}
VECTOR2I GRID_HELPER::BestDragOrigin( const VECTOR2I &aMousePos, BOARD_ITEM* aItem )
VECTOR2I GRID_HELPER::BestDragOrigin( const VECTOR2I &aMousePos, std::vector<BOARD_ITEM*>& aItems )
{
clearAnchors();
computeAnchors( aItem, aMousePos, true );
for( auto item : aItems )
computeAnchors( item, aMousePos, true );
double worldScale = m_frame->GetCanvas()->GetGAL()->GetWorldScale();
double lineSnapMinCornerDistance = 50.0 / worldScale;
@ -211,7 +213,7 @@ VECTOR2I GRID_HELPER::BestDragOrigin( const VECTOR2I &aMousePos, BOARD_ITEM* aIt
std::set<BOARD_ITEM*> GRID_HELPER::queryVisible( const BOX2I& aArea,
const std::vector<BOARD_ITEM*> aSkip ) const
const std::vector<BOARD_ITEM*>& aSkip ) const
{
std::set<BOARD_ITEM*> items;
std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems;
@ -256,7 +258,7 @@ VECTOR2I GRID_HELPER::BestSnapAnchor( const VECTOR2I& aOrigin, BOARD_ITEM* aDrag
VECTOR2I GRID_HELPER::BestSnapAnchor( const VECTOR2I& aOrigin, const LSET& aLayers,
const std::vector<BOARD_ITEM*> aSkip )
const std::vector<BOARD_ITEM*>& aSkip )
{
double worldScale = m_frame->GetCanvas()->GetGAL()->GetWorldScale();
int snapRange = (int) ( m_snapSize / worldScale );

View File

@ -58,10 +58,10 @@ public:
VECTOR2I AlignToSegment ( const VECTOR2I& aPoint, const SEG& aSeg );
VECTOR2I BestDragOrigin( const VECTOR2I& aMousePos, BOARD_ITEM* aItem );
VECTOR2I BestDragOrigin( const VECTOR2I& aMousePos, std::vector<BOARD_ITEM*>& aItem );
VECTOR2I BestSnapAnchor( const VECTOR2I& aOrigin, BOARD_ITEM* aDraggedItem );
VECTOR2I BestSnapAnchor( const VECTOR2I& aOrigin, const LSET& aLayers,
const std::vector<BOARD_ITEM*> aSkip = {} );
const std::vector<BOARD_ITEM*>& aSkip = {} );
void SetSnap( bool aSnap )
{
@ -102,7 +102,7 @@ private:
std::vector<ANCHOR> m_anchors;
std::set<BOARD_ITEM*> queryVisible( const BOX2I& aArea,
const std::vector<BOARD_ITEM*> aSkip ) const;
const std::vector<BOARD_ITEM*>& aSkip ) const;
void addAnchor( const VECTOR2I& aPos, int aFlags, BOARD_ITEM* aItem )
{

View File

@ -108,3 +108,19 @@ const KIGFX::VIEW_GROUP::ITEMS PCBNEW_SELECTION::updateDrawList() const
return items;
}
const LSET PCBNEW_SELECTION::GetSelectionLayers()
{
LSET retval;
for( auto item : m_items )
{
auto board_item = dynamic_cast<BOARD_ITEM*>( item );
if( board_item )
retval |= board_item->GetLayerSet();
}
return retval;
}

View File

@ -24,6 +24,7 @@
#ifndef PCBNEW_SELECTION_H
#define PCBNEW_SELECTION_H
#include <layers_id_colors_and_visibility.h>
#include <tool/selection.h>
@ -33,6 +34,8 @@ public:
EDA_ITEM* GetTopLeftItem( bool onlyModules = false ) const override;
const KIGFX::VIEW_GROUP::ITEMS updateDrawList() const override;
const LSET GetSelectionLayers();
};
#endif // PCBNEW_SELECTION_H