Make snapping more predictable.
In particular, allow grid positions to override line snapping if they're a better match (and do this independently on x and y axes). We already allow a nearer anchor to override, but that should be based on a cartesian distance rather than independent axes. Fixes https://gitlab.com/kicad/code/kicad/issues/6626
This commit is contained in:
parent
4e100b8d03
commit
a3406e7514
|
@ -267,8 +267,14 @@ VECTOR2I EE_GRID_HELPER::BestSnapAnchor( const VECTOR2I& aOrigin, int aLayer, SC
|
|||
VECTOR2I EE_GRID_HELPER::BestSnapAnchor( const VECTOR2I& aOrigin, int aLayer,
|
||||
const EE_SELECTION& aSkip )
|
||||
{
|
||||
int snapDist = GetGrid().x;
|
||||
int snapRange = SNAP_RANGE * IU_PER_MILS;
|
||||
constexpr int snapRange = SNAP_RANGE * IU_PER_MILS;
|
||||
|
||||
VECTOR2I pt = aOrigin;
|
||||
VECTOR2I snapDist( snapRange, snapRange );
|
||||
bool snapLineX = false;
|
||||
bool snapLineY = false;
|
||||
bool snapPoint = false;
|
||||
bool gridChecked = false;
|
||||
|
||||
BOX2I bb( VECTOR2I( aOrigin.x - snapRange / 2, aOrigin.y - snapRange / 2 ),
|
||||
VECTOR2I( snapRange, snapRange ) );
|
||||
|
@ -281,63 +287,92 @@ VECTOR2I EE_GRID_HELPER::BestSnapAnchor( const VECTOR2I& aOrigin, int aLayer,
|
|||
ANCHOR* nearest = nearestAnchor( aOrigin, SNAPPABLE, aLayer );
|
||||
VECTOR2I nearestGrid = m_enableGrid ? Align( aOrigin ) : aOrigin;
|
||||
|
||||
if( nearest )
|
||||
snapDist = nearest->Distance( aOrigin );
|
||||
|
||||
if( m_snapItem && m_enableSnapLine && m_enableSnap )
|
||||
if( m_enableSnapLine && m_snapItem && m_skipPoint != VECTOR2I( m_viewSnapLine.GetPosition() ) )
|
||||
{
|
||||
bool snapLine = false;
|
||||
int x_dist = std::abs( m_viewSnapLine.GetPosition().x - aOrigin.x );
|
||||
int y_dist = std::abs( m_viewSnapLine.GetPosition().y - aOrigin.y );
|
||||
|
||||
/// Allows de-snapping from the line if you are closer to another snap point
|
||||
if( x_dist < snapRange && x_dist < snapDist )
|
||||
if( std::abs( m_viewSnapLine.GetPosition().x - aOrigin.x ) < snapDist.x )
|
||||
{
|
||||
nearestGrid.x = m_viewSnapLine.GetPosition().x;
|
||||
snapLine = true;
|
||||
pt.x = m_viewSnapLine.GetPosition().x;
|
||||
snapDist.x = std::abs( m_viewSnapLine.GetPosition().x - aOrigin.x );
|
||||
snapLineX = true;
|
||||
}
|
||||
|
||||
if( y_dist < snapRange && y_dist < snapDist )
|
||||
if( std::abs( m_viewSnapLine.GetPosition().y - aOrigin.y ) < snapDist.y )
|
||||
{
|
||||
nearestGrid.y = m_viewSnapLine.GetPosition().y;
|
||||
snapLine = true;
|
||||
pt.y = m_viewSnapLine.GetPosition().y;
|
||||
snapDist.y = std::abs( m_viewSnapLine.GetPosition().y - aOrigin.y );
|
||||
snapLineY = true;
|
||||
}
|
||||
|
||||
if( snapLine && m_skipPoint != VECTOR2I( m_viewSnapLine.GetPosition() ) )
|
||||
if( m_enableGrid && std::abs( nearestGrid.x - aOrigin.x ) < snapDist.x )
|
||||
{
|
||||
m_viewSnapLine.SetEndPosition( nearestGrid );
|
||||
pt.x = nearestGrid.x;
|
||||
snapDist.x = std::abs( nearestGrid.x - aOrigin.x );
|
||||
snapLineX = false;
|
||||
}
|
||||
|
||||
if( m_enableGrid && std::abs( nearestGrid.y - aOrigin.y ) < snapDist.y )
|
||||
{
|
||||
pt.y = nearestGrid.y;
|
||||
snapDist.x = std::abs( nearestGrid.y - aOrigin.y );
|
||||
snapLineY = false;
|
||||
}
|
||||
|
||||
gridChecked = true;
|
||||
}
|
||||
|
||||
if( m_enableSnap && nearest && nearest->Distance( aOrigin ) < snapDist.EuclideanNorm() )
|
||||
{
|
||||
pt = nearest->pos;
|
||||
snapDist.x = std::abs( nearest->pos.x - aOrigin.x );
|
||||
snapDist.y = std::abs( nearest->pos.y - aOrigin.y );
|
||||
snapLineX = snapLineY = false;
|
||||
snapPoint = true;
|
||||
|
||||
if( m_enableGrid && ( nearestGrid - aOrigin ).EuclideanNorm() < snapDist.EuclideanNorm() )
|
||||
{
|
||||
pt = nearestGrid;
|
||||
snapDist.x = std::abs( nearestGrid.x - aOrigin.x );
|
||||
snapDist.y = std::abs( nearestGrid.y - aOrigin.y );
|
||||
snapPoint = false;
|
||||
}
|
||||
|
||||
gridChecked = true;
|
||||
}
|
||||
|
||||
if( m_enableGrid && !gridChecked )
|
||||
pt = nearestGrid;
|
||||
|
||||
if( snapLineX || snapLineY )
|
||||
{
|
||||
m_viewSnapLine.SetEndPosition( pt );
|
||||
|
||||
if( m_toolMgr->GetView()->IsVisible( &m_viewSnapLine ) )
|
||||
m_toolMgr->GetView()->Update( &m_viewSnapLine, KIGFX::GEOMETRY );
|
||||
else
|
||||
m_toolMgr->GetView()->SetVisible( &m_viewSnapLine, true );
|
||||
|
||||
return nearestGrid;
|
||||
}
|
||||
}
|
||||
else if( snapPoint )
|
||||
{
|
||||
m_snapItem = nearest;
|
||||
m_viewSnapPoint.SetPosition( (wxPoint) pt );
|
||||
m_viewSnapLine.SetPosition( (wxPoint) pt );
|
||||
|
||||
if( nearest && m_enableSnap )
|
||||
{
|
||||
if( snapDist <= snapRange )
|
||||
{
|
||||
m_viewSnapPoint.SetPosition( wxPoint( nearest->pos ) );
|
||||
m_viewSnapLine.SetPosition( wxPoint( nearest->pos ) );
|
||||
m_toolMgr->GetView()->SetVisible( &m_viewSnapLine, false );
|
||||
|
||||
if( m_toolMgr->GetView()->IsVisible( &m_viewSnapPoint ) )
|
||||
m_toolMgr->GetView()->Update( &m_viewSnapPoint, KIGFX::GEOMETRY);
|
||||
else
|
||||
m_toolMgr->GetView()->SetVisible( &m_viewSnapPoint, true );
|
||||
|
||||
m_snapItem = nearest;
|
||||
return nearest->pos;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
m_snapItem = nullptr;
|
||||
|
||||
m_toolMgr->GetView()->SetVisible( &m_viewSnapPoint, false );
|
||||
m_toolMgr->GetView()->SetVisible( &m_viewSnapLine, false );
|
||||
return nearestGrid;
|
||||
}
|
||||
|
||||
return pt;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue