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:
parent
e0b4e5135c
commit
e882753ebf
|
@ -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 );
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
*
|
*
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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 )
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue