Grid snapping fixes.

1) Uniformly honour the GAL grid snap settings
2) Make more uniform use of GRID_HELPERs
3) Smarten EDIT_LINE for mid-point snapping

Fixes https://gitlab.com/kicad/code/kicad/issues/6558
This commit is contained in:
Jeff Young 2020-12-03 19:53:39 +00:00
parent e0b4e5135c
commit e882753ebf
9 changed files with 71 additions and 29 deletions

View File

@ -855,7 +855,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
{
setCursor();
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
grid.SetUseGrid( !evt->Modifier( MD_ALT ) );
grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) );
VECTOR2I cursorPos = grid.BestSnapAnchor( controls->GetCursorPosition( false ), snapLayer,
item );

View File

@ -504,7 +504,7 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType,
{
setCursor();
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
grid.SetUseGrid( !evt->Modifier( MD_ALT ) );
grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) );
wxPoint cursorPos = evt->IsPrime() ? (wxPoint) evt->Position()
: (wxPoint) controls->GetMousePosition();

View File

@ -32,6 +32,15 @@ class EDIT_POINT;
class EDIT_LINE;
class EDIT_POINTS;
enum GRID_CONSTRAINT_TYPE
{
IGNORE_GRID,
SNAP_TO_GRID,
SNAP_BY_GRID // Keep it on grid if it started on grid (treat x and y independently)
};
/**
* EDIT_CONSTRAINT
*

View File

@ -30,13 +30,12 @@
#include <list>
#include <deque>
#include "edit_constraints.h"
#include <memory>
#include "edit_constraints.h"
#include <view/view.h>
/**
* EDIT_POINT
*
@ -55,7 +54,7 @@ public:
m_position( aPoint ),
m_isActive( false ),
m_isHover( false ),
m_gridFree( false ),
m_gridConstraint( SNAP_TO_GRID ),
m_connected( aConnected )
{
}
@ -188,8 +187,8 @@ public:
bool IsHover() const { return m_isHover; }
void SetHover( bool aHover = true ) { m_isHover = aHover; }
bool IsGridFree() const { return m_gridFree; }
void SetGridFree( bool aGridFree = true ) { m_gridFree = aGridFree; }
GRID_CONSTRAINT_TYPE GetGridConstraint() const { return m_gridConstraint; }
void SetGridConstraint( GRID_CONSTRAINT_TYPE aConstraint ) { m_gridConstraint = aConstraint; }
bool operator==( const EDIT_POINT& aOther ) const
{
@ -206,10 +205,10 @@ public:
static const int HOVER_SIZE = 5;
private:
VECTOR2I m_position; // Position of EDIT_POINT
bool m_isActive; // True if this point is being manipulated
bool m_isHover; // True if this point is being hovered over
bool m_gridFree; // True if this point should not be snapped to the grid.
VECTOR2I m_position; // Position of EDIT_POINT
bool m_isActive; // True if this point is being manipulated
bool m_isHover; // True if this point is being hovered over
GRID_CONSTRAINT_TYPE m_gridConstraint; // Describes the grid snapping behavior.
///> An optional connected item record used to mimic polyLine behaviour with individual
/// line segments.
@ -241,8 +240,7 @@ public:
m_origin( aOrigin ),
m_end( aEnd )
{
// Don't snap the line center to the grid
SetGridFree();
SetGridConstraint( SNAP_BY_GRID );
}
///> @copydoc EDIT_POINT::GetPosition()

View File

@ -694,7 +694,7 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
setCursor();
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
grid.SetUseGrid( m_frame->IsGridVisible() );
grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) );
VECTOR2I cursorPos = evt->IsPrime() ? evt->Position() : m_controls->GetMousePosition();
cursorPos = grid.BestSnapAnchor( cursorPos, nullptr );
m_controls->ForceCursorPosition( true, cursorPos );
@ -1184,7 +1184,7 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent )
setCursor();
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
grid.SetUseGrid( m_frame->IsGridVisible() );
grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) );
VECTOR2I cursorPos = grid.BestSnapAnchor( m_controls->GetMousePosition(),
LSET::AllLayersMask() );
m_controls->ForceCursorPosition( true, cursorPos );
@ -1297,7 +1297,7 @@ bool DRAWING_TOOL::drawSegment( const std::string& aTool, PCB_SHAPE** aGraphic,
m_frame->SetMsgPanel( graphic );
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
grid.SetUseGrid( m_frame->IsGridVisible() );
grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) );
cursorPos = grid.BestSnapAnchor( m_controls->GetMousePosition(), m_frame->GetActiveLayer() );
m_controls->ForceCursorPosition( true, cursorPos );
@ -1593,7 +1593,7 @@ bool DRAWING_TOOL::drawArc( const std::string& aTool, PCB_SHAPE** aGraphic, bool
graphic->SetLayer( layer );
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
grid.SetUseGrid( m_frame->IsGridVisible() );
grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) );
VECTOR2I cursorPos = grid.BestSnapAnchor( m_controls->GetMousePosition(), graphic );
m_controls->ForceCursorPosition( true, cursorPos );
@ -1878,7 +1878,7 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
LSET layers( m_frame->GetActiveLayer() );
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
grid.SetUseGrid( m_frame->IsGridVisible() );
grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) );
VECTOR2I cursorPos = grid.BestSnapAnchor( evt->IsPrime() ? evt->Position()
: m_controls->GetMousePosition(),
layers );

View File

@ -416,7 +416,7 @@ int EDIT_TOOL::doMoveSelection( TOOL_EVENT aEvent, bool aPickReference )
VECTOR2I movement;
editFrame->GetCanvas()->SetCurrentCursor( KICURSOR::MOVING );
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
grid.SetUseGrid( !evt->Modifier( MD_ALT ) );
grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) );
if( evt->IsAction( &PCB_ACTIONS::move ) || evt->IsMotion() || evt->IsDrag( BUT_LEFT )
|| evt->IsAction( &ACTIONS::refreshPreview )

View File

@ -233,7 +233,7 @@ int PCB_VIEWER_TOOLS::MeasureTool( const TOOL_EVENT& aEvent )
{
setCursor();
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
grid.SetUseGrid( !evt->Modifier( MD_ALT ) );
grid.SetUseGrid( view.GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) );
const VECTOR2I cursorPos = grid.BestSnapAnchor( controls.GetMousePosition(), nullptr );
controls.ForceCursorPosition(true, cursorPos );

View File

@ -67,7 +67,7 @@ int PCBNEW_PICKER_TOOL::Main( const TOOL_EVENT& aEvent )
setCursor();
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
grid.SetUseGrid( !evt->Modifier( MD_ALT ) );
grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) );
VECTOR2I cursorPos = grid.BestSnapAnchor( controls->GetMousePosition(), nullptr );
controls->ForceCursorPosition(true, cursorPos );

View File

@ -171,7 +171,7 @@ public:
points->Point( ARC_MID ).SetConstraint( new EC_LINE( points->Point( ARC_MID ),
points->Point( ARC_CENTER ) ) );
points->Point( ARC_MID ).SetGridFree();
points->Point( ARC_MID ).SetGridConstraint( IGNORE_GRID );
break;
case S_CIRCLE:
@ -437,11 +437,13 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
while( TOOL_EVENT* evt = Wait() )
{
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
grid.SetUseGrid( editFrame->IsGridVisible() );
grid.SetUseGrid( view->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) );
if( !m_editPoints || evt->IsSelectionEvent() ||
evt->Matches( EVENTS::InhibitSelectionEditing ) )
{
break;
}
EDIT_POINT* prevHover = m_hoveredPoint;
@ -469,14 +471,46 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
}
//TODO: unify the constraints to solve simultaneously instead of sequentially
if( m_editedPoint->IsGridFree() )
switch( m_editedPoint->GetGridConstraint() )
{
case IGNORE_GRID:
m_editedPoint->SetPosition( evt->Position() );
}
else
{
break;
case SNAP_TO_GRID:
m_editedPoint->SetPosition( grid.BestSnapAnchor( evt->Position(), snapLayers,
{ item } ) );
break;
case SNAP_BY_GRID:
{
VECTOR2I start = m_editedPoint->GetPosition();
VECTOR2I startGrid = grid.BestSnapAnchor( start, snapLayers, { item } );
VECTOR2I end = evt->Position();
VECTOR2I endGrid = grid.BestSnapAnchor( end, snapLayers, { item } );
if( start == startGrid )
{
end = endGrid;
}
else if( start.x == startGrid.x )
{
end.x = endGrid.x;
if( abs( end.y - start.y ) < grid.GetGrid().y )
end.y = start.y;
}
else if( start.y == startGrid.y )
{
end.y = endGrid.y;
if( abs( end.x - start.x ) < grid.GetGrid().x )
end.x = start.x;
}
m_editedPoint->SetPosition( end );
}
break;
}
// The alternative constraint limits to 45°
@ -487,12 +521,13 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
else
m_editedPoint->ApplyConstraint();
if( !m_editedPoint->IsGridFree() )
if( m_editedPoint->GetGridConstraint() == SNAP_TO_GRID )
{
m_editedPoint->SetPosition( grid.BestSnapAnchor( m_editedPoint->GetPosition(),
snapLayers, { item } ) );
}
controls->ForceCursorPosition( true, m_editedPoint->GetPosition() );
updateItem();
updatePoints();
}