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

View File

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