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() ) if( m_dragging || selection.Empty() )
return 0; 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 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 // 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 ); 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 else
{ {
updateModificationPoint( selection ); std::vector<BOARD_ITEM*> items;
m_cursor = grid.Align( m_cursor );
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 ); 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(); clearAnchors();
computeAnchors( aItem, aMousePos, true );
for( auto item : aItems )
computeAnchors( item, aMousePos, true );
double worldScale = m_frame->GetCanvas()->GetGAL()->GetWorldScale(); double worldScale = m_frame->GetCanvas()->GetGAL()->GetWorldScale();
double lineSnapMinCornerDistance = 50.0 / worldScale; 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, 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::set<BOARD_ITEM*> items;
std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems; 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, 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(); double worldScale = m_frame->GetCanvas()->GetGAL()->GetWorldScale();
int snapRange = (int) ( m_snapSize / worldScale ); int snapRange = (int) ( m_snapSize / worldScale );

View File

@ -58,10 +58,10 @@ public:
VECTOR2I AlignToSegment ( const VECTOR2I& aPoint, const SEG& aSeg ); 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, BOARD_ITEM* aDraggedItem );
VECTOR2I BestSnapAnchor( const VECTOR2I& aOrigin, const LSET& aLayers, VECTOR2I BestSnapAnchor( const VECTOR2I& aOrigin, const LSET& aLayers,
const std::vector<BOARD_ITEM*> aSkip = {} ); const std::vector<BOARD_ITEM*>& aSkip = {} );
void SetSnap( bool aSnap ) void SetSnap( bool aSnap )
{ {
@ -102,7 +102,7 @@ private:
std::vector<ANCHOR> m_anchors; std::vector<ANCHOR> m_anchors;
std::set<BOARD_ITEM*> queryVisible( const BOX2I& aArea, 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 ) 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; 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 #ifndef PCBNEW_SELECTION_H
#define PCBNEW_SELECTION_H #define PCBNEW_SELECTION_H
#include <layers_id_colors_and_visibility.h>
#include <tool/selection.h> #include <tool/selection.h>
@ -33,6 +34,8 @@ public:
EDA_ITEM* GetTopLeftItem( bool onlyModules = false ) const override; EDA_ITEM* GetTopLeftItem( bool onlyModules = false ) const override;
const KIGFX::VIEW_GROUP::ITEMS updateDrawList() const override; const KIGFX::VIEW_GROUP::ITEMS updateDrawList() const override;
const LSET GetSelectionLayers();
}; };
#endif // PCBNEW_SELECTION_H #endif // PCBNEW_SELECTION_H