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(); setCursor();
grid.SetSnap( !evt->Modifier( MD_SHIFT ) ); 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, VECTOR2I cursorPos = grid.BestSnapAnchor( controls->GetCursorPosition( false ), snapLayer,
item ); item );

View File

@ -504,7 +504,7 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType,
{ {
setCursor(); setCursor();
grid.SetSnap( !evt->Modifier( MD_SHIFT ) ); 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 cursorPos = evt->IsPrime() ? (wxPoint) evt->Position()
: (wxPoint) controls->GetMousePosition(); : (wxPoint) controls->GetMousePosition();

View File

@ -32,6 +32,15 @@ class EDIT_POINT;
class EDIT_LINE; class EDIT_LINE;
class EDIT_POINTS; 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 * EDIT_CONSTRAINT
* *

View File

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

View File

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

View File

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

View File

@ -233,7 +233,7 @@ int PCB_VIEWER_TOOLS::MeasureTool( const TOOL_EVENT& aEvent )
{ {
setCursor(); setCursor();
grid.SetSnap( !evt->Modifier( MD_SHIFT ) ); 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 ); const VECTOR2I cursorPos = grid.BestSnapAnchor( controls.GetMousePosition(), nullptr );
controls.ForceCursorPosition(true, cursorPos ); controls.ForceCursorPosition(true, cursorPos );

View File

@ -67,7 +67,7 @@ int PCBNEW_PICKER_TOOL::Main( const TOOL_EVENT& aEvent )
setCursor(); setCursor();
grid.SetSnap( !evt->Modifier( MD_SHIFT ) ); 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 ); VECTOR2I cursorPos = grid.BestSnapAnchor( controls->GetMousePosition(), nullptr );
controls->ForceCursorPosition(true, cursorPos ); 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_MID ).SetConstraint( new EC_LINE( points->Point( ARC_MID ),
points->Point( ARC_CENTER ) ) ); points->Point( ARC_CENTER ) ) );
points->Point( ARC_MID ).SetGridFree(); points->Point( ARC_MID ).SetGridConstraint( IGNORE_GRID );
break; break;
case S_CIRCLE: case S_CIRCLE:
@ -437,11 +437,13 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
while( TOOL_EVENT* evt = Wait() ) while( TOOL_EVENT* evt = Wait() )
{ {
grid.SetSnap( !evt->Modifier( MD_SHIFT ) ); grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
grid.SetUseGrid( editFrame->IsGridVisible() ); grid.SetUseGrid( view->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) );
if( !m_editPoints || evt->IsSelectionEvent() || if( !m_editPoints || evt->IsSelectionEvent() ||
evt->Matches( EVENTS::InhibitSelectionEditing ) ) evt->Matches( EVENTS::InhibitSelectionEditing ) )
{
break; break;
}
EDIT_POINT* prevHover = m_hoveredPoint; 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 //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() ); m_editedPoint->SetPosition( evt->Position() );
} break;
else
{ case SNAP_TO_GRID:
m_editedPoint->SetPosition( grid.BestSnapAnchor( evt->Position(), snapLayers, m_editedPoint->SetPosition( grid.BestSnapAnchor( evt->Position(), snapLayers,
{ item } ) ); { 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° // The alternative constraint limits to 45°
@ -487,12 +521,13 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
else else
m_editedPoint->ApplyConstraint(); m_editedPoint->ApplyConstraint();
if( !m_editedPoint->IsGridFree() ) if( m_editedPoint->GetGridConstraint() == SNAP_TO_GRID )
{ {
m_editedPoint->SetPosition( grid.BestSnapAnchor( m_editedPoint->GetPosition(), m_editedPoint->SetPosition( grid.BestSnapAnchor( m_editedPoint->GetPosition(),
snapLayers, { item } ) ); snapLayers, { item } ) );
} }
controls->ForceCursorPosition( true, m_editedPoint->GetPosition() );
updateItem(); updateItem();
updatePoints(); updatePoints();
} }