ADDED: 45° snapping for rectangles aka Squares

The snap obeys only the Ctrl key and not the global preference setting
for drawsegments because rectangles are _always_ on H/V lines when drawn

Fixes https://gitlab.com/kicad/code/kicad/issues/5607
This commit is contained in:
Seth Hillbrand 2020-09-15 11:21:10 -07:00
parent c5eba871e3
commit 08bf5f4b4e
2 changed files with 10 additions and 37 deletions

View File

@ -87,17 +87,17 @@ int GetCircleToPolyCorrection( int aMaxError );
* @return the snapped vector
*/
template<typename T>
VECTOR2<T> GetVectorSnapped45( const VECTOR2<T>& aVec )
VECTOR2<T> GetVectorSnapped45( const VECTOR2<T>& aVec, bool only45 = false )
{
auto newVec = aVec;
const VECTOR2<T> absVec { std::abs( aVec.x ), std::abs( aVec.y ) };
if ( absVec.x > absVec.y * 2 )
if ( !only45 && absVec.x > absVec.y * 2 )
{
// snap along x-axis
newVec.y = 0;
}
else if ( absVec.y > absVec.x * 2 )
else if ( !only45 && absVec.y > absVec.x * 2 )
{
// snap onto y-axis
newVec.x = 0;

View File

@ -1092,10 +1092,7 @@ bool DRAWING_TOOL::drawSegment( const std::string& aTool, int aShape, DRAWSEGMEN
// drawing assistant overlay
// TODO: workaround because STROKE_T is not visible from commons.
KIGFX::PREVIEW::GEOM_SHAPE geomShape =
( aShape == S_SEGMENT ) ? KIGFX::PREVIEW::GEOM_SHAPE::SEGMENT :
( aShape == S_CIRCLE ) ? KIGFX::PREVIEW::GEOM_SHAPE::CIRCLE :
KIGFX::PREVIEW::GEOM_SHAPE::RECT;
KIGFX::PREVIEW::GEOM_SHAPE geomShape( static_cast<KIGFX::PREVIEW::GEOM_SHAPE>( aShape ) );
KIGFX::PREVIEW::TWO_POINT_ASSISTANT twoPointAsst(
twoPointManager, m_frame->GetUserUnits(), geomShape );
@ -1106,7 +1103,6 @@ bool DRAWING_TOOL::drawSegment( const std::string& aTool, int aShape, DRAWSEGMEN
m_controls->ShowCursor( true );
bool direction45 = false; // 45 degrees only mode
bool started = false;
bool cancelled = false;
bool isLocalOriginSet = ( m_frame->GetScreen()->m_LocalOrigin != VECTOR2D( 0, 0 ) );
@ -1118,12 +1114,15 @@ bool DRAWING_TOOL::drawSegment( const std::string& aTool, int aShape, DRAWSEGMEN
if( aStartingPoint )
m_toolMgr->RunAction( ACTIONS::cursorClick );
frame()->SetMsgPanel( graphic );
// Main loop: keep receiving events
while( TOOL_EVENT* evt = Wait() )
{
if( !pointEditor->HasPoint() )
m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_PENCIL );
m_frame->SetMsgPanel( graphic );
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
grid.SetUseGrid( m_frame->IsGridVisible() );
cursorPos = grid.BestSnapAnchor( m_controls->GetMousePosition(), m_frame->GetActiveLayer() );
@ -1135,33 +1134,6 @@ bool DRAWING_TOOL::drawSegment( const std::string& aTool, int aShape, DRAWSEGMEN
if( evt->Modifier( MD_CTRL ) )
limit45 = !limit45;
if( direction45 != limit45 && started && aShape == S_SEGMENT )
{
direction45 = limit45;
if( direction45 )
{
const VECTOR2I lineVector( cursorPos - VECTOR2I( twoPointManager.GetOrigin() ) );
// get a restricted 45/H/V line from the last fixed point to the cursor
auto newEnd = GetVectorSnapped45( lineVector );
m_controls->ForceCursorPosition( true, VECTOR2I( twoPointManager.GetEnd() ) );
twoPointManager.SetEnd( twoPointManager.GetOrigin() + (wxPoint) newEnd );
twoPointManager.SetAngleSnap( true );
}
else
{
twoPointManager.SetEnd( (wxPoint) cursorPos );
twoPointManager.SetAngleSnap( false );
}
updateSegmentFromConstructionMgr( twoPointManager, graphic );
m_view->Update( &preview );
m_view->Update( &twoPointAsst );
frame()->SetMsgPanel( graphic );
}
auto cleanup = [&] () {
preview.Clear();
m_view->Update( &preview );
@ -1288,12 +1260,13 @@ bool DRAWING_TOOL::drawSegment( const std::string& aTool, int aShape, DRAWSEGMEN
else if( evt->IsMotion() )
{
// 45 degree lines
if( direction45 && aShape == S_SEGMENT )
if( ( limit45 && aShape == S_SEGMENT )
|| ( evt->Modifier( MD_CTRL ) && aShape == S_RECT ) )
{
const VECTOR2I lineVector( cursorPos - VECTOR2I( twoPointManager.GetOrigin() ) );
// get a restricted 45/H/V line from the last fixed point to the cursor
auto newEnd = GetVectorSnapped45( lineVector );
auto newEnd = GetVectorSnapped45( lineVector, ( aShape == S_RECT ) );
m_controls->ForceCursorPosition( true, VECTOR2I( twoPointManager.GetEnd() ) );
twoPointManager.SetEnd( twoPointManager.GetOrigin() + (wxPoint) newEnd );
twoPointManager.SetAngleSnap( true );