Fix pad snapping in renumber pads

Snap shouldn't be looking for other items in this routine or using the
grid

Fixes https://gitlab.com/kicad/code/kicad/issues/10238
This commit is contained in:
Seth Hillbrand 2022-01-03 17:16:51 -08:00
parent 58b07efd99
commit ed9a3deb57
3 changed files with 51 additions and 1 deletions

View File

@ -32,9 +32,11 @@
#include <footprint.h> #include <footprint.h>
#include <fp_shape.h> #include <fp_shape.h>
#include <pad.h> #include <pad.h>
#include <pcbnew_settings.h>
#include <board_commit.h> #include <board_commit.h>
#include <dialogs/dialog_push_pad_properties.h> #include <dialogs/dialog_push_pad_properties.h>
#include <tools/pcb_actions.h> #include <tools/pcb_actions.h>
#include <tools/pcb_grid_helper.h>
#include <tools/pcb_selection_tool.h> #include <tools/pcb_selection_tool.h>
#include <tools/pcb_selection_conditions.h> #include <tools/pcb_selection_conditions.h>
#include <tools/edit_tool.h> #include <tools/edit_tool.h>
@ -295,6 +297,16 @@ int PAD_TOOL::EnumeratePads( const TOOL_EVENT& aEvent )
std::list<PAD*> selectedPads; std::list<PAD*> selectedPads;
BOARD_COMMIT commit( frame() ); BOARD_COMMIT commit( frame() );
bool isFirstPoint = true; // make sure oldCursorPos is initialized at least once bool isFirstPoint = true; // make sure oldCursorPos is initialized at least once
PADS pads = board()->GetFirstFootprint()->Pads();
MAGNETIC_SETTINGS mag_settings;
mag_settings.graphics = false;
mag_settings.tracks = MAGNETIC_OPTIONS::NO_EFFECT;
mag_settings.pads = MAGNETIC_OPTIONS::CAPTURE_ALWAYS;
PCB_GRID_HELPER grid( m_toolMgr, &mag_settings );
grid.SetSnap( true );
grid.SetUseGrid( false );
auto setCursor = auto setCursor =
[&]() [&]()
@ -318,6 +330,9 @@ int PAD_TOOL::EnumeratePads( const TOOL_EVENT& aEvent )
{ {
setCursor(); setCursor();
VECTOR2I cursorPos = grid.AlignToNearestPad( getViewControls()->GetMousePosition(), pads );
getViewControls()->ForceCursorPosition( true, cursorPos );
if( evt->IsCancelInteractive() ) if( evt->IsCancelInteractive() )
{ {
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
@ -336,7 +351,6 @@ int PAD_TOOL::EnumeratePads( const TOOL_EVENT& aEvent )
else if( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) else if( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
{ {
selectedPads.clear(); selectedPads.clear();
VECTOR2I cursorPos = getViewControls()->GetCursorPosition();
// Be sure the old cursor mouse position was initialized: // Be sure the old cursor mouse position was initialized:
if( isFirstPoint ) if( isFirstPoint )

View File

@ -151,6 +151,39 @@ VECTOR2I PCB_GRID_HELPER::AlignToArc( const VECTOR2I& aPoint, const SHAPE_ARC& a
} }
VECTOR2I PCB_GRID_HELPER::AlignToNearestPad( const VECTOR2I& aMousePos, PADS& aPads )
{
clearAnchors();
for( BOARD_ITEM* item : aPads )
computeAnchors( item, aMousePos, true );
double minDist = std::numeric_limits<double>::max();
ANCHOR* nearestOrigin = nullptr;
for( ANCHOR& a : m_anchors )
{
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( a.item );
if( ( ORIGIN & a.flags ) != ORIGIN )
continue;
if( !item->HitTest( wxPoint( aMousePos.x, aMousePos.y ) ) )
continue;
double dist = a.Distance( aMousePos );
if( dist < minDist )
{
minDist = dist;
nearestOrigin = &a;
}
}
return nearestOrigin ? nearestOrigin->pos : aMousePos;
}
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 )
{ {

View File

@ -27,6 +27,7 @@
#define PCB_GRID_HELPER_H #define PCB_GRID_HELPER_H
#include <vector> #include <vector>
#include <pcb_item_containers.h>
#include <tool/grid_helper.h> #include <tool/grid_helper.h>
class TOOL_MANAGER; class TOOL_MANAGER;
@ -52,6 +53,8 @@ public:
VECTOR2I AlignToArc ( const VECTOR2I& aPoint, const SHAPE_ARC& aSeg ); VECTOR2I AlignToArc ( const VECTOR2I& aPoint, const SHAPE_ARC& aSeg );
VECTOR2I AlignToNearestPad( const VECTOR2I& aMousePos, PADS& aPads );
/** /**
* Chooses the "best" snap anchor around the given point, optionally taking layers from * Chooses the "best" snap anchor around the given point, optionally taking layers from
* the reference item. The reference item will not be snapped to (it is being dragged or * the reference item. The reference item will not be snapped to (it is being dragged or