GRID_HELPER: Finish drawing closed path

When we draw a path, we usually want to close the path when clicking on
the end of another line.  This uses grid helper to ensure this
progression happens as expected.
This commit is contained in:
Seth Hillbrand 2018-11-24 07:58:33 -08:00
parent 239482ec98
commit 908c2a37e5
3 changed files with 50 additions and 9 deletions

View File

@ -1105,27 +1105,47 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic,
} }
else else
{ {
auto snapItem = dyn_cast<DRAWSEGMENT*>( grid.GetSnapped() );
auto mod = dyn_cast<MODULE*>( m_frame->GetModel() );
if( aGraphic->GetEnd() == aGraphic->GetStart() if( aGraphic->GetEnd() == aGraphic->GetStart()
|| ( evt->IsDblClick( BUT_LEFT ) && aShape == S_SEGMENT ) ) || ( evt->IsDblClick( BUT_LEFT ) && aShape == S_SEGMENT )
|| snapItem )
// User has clicked twice in the same spot // User has clicked twice in the same spot
// or clicked on the end of an existing segment (closing a path)
{ {
BOARD_COMMIT commit( m_frame );
// a clear sign that the current drawing is finished // a clear sign that the current drawing is finished
// Now we have to add the helper line as well, unless it is zero-length // Now we have to add the helper line as well, unless it is zero-length
if( direction45 && line45.GetStart() != aGraphic->GetStart() ) if( direction45 && line45.GetStart() != aGraphic->GetStart() )
{ {
BOARD_ITEM_CONTAINER* parent = m_frame->GetModel(); DRAWSEGMENT* l = m_editModules ? new EDGE_MODULE( mod ) : new DRAWSEGMENT;
DRAWSEGMENT* l = m_editModules ? new EDGE_MODULE( (MODULE*) parent )
: new DRAWSEGMENT;
// Copy coordinates, layer, etc. // Copy coordinates, layer, etc.
*static_cast<DRAWSEGMENT*>( l ) = line45; *l = line45;
l->SetEnd( aGraphic->GetStart() );
BOARD_COMMIT commit( m_frame ); // If snapping, add both paths
if( snapItem && l->GetLength() > 0.0 )
commit.Add( l->Clone() );
l->SetEnd( aGraphic->GetStart() );
commit.Add( l ); commit.Add( l );
commit.Push( _( "Draw a line" ) );
} }
// If the user clicks on an existing snap point from a drawsegment
// we finish the segment as they are likely closing a path
else if( snapItem && aGraphic->GetLength() > 0.0 )
{
DRAWSEGMENT* l = m_editModules ? new EDGE_MODULE( mod ) : new DRAWSEGMENT;
*l = *aGraphic;
commit.Add( l );
}
if( !commit.Empty() )
commit.Push( _( "Draw a line" ) );
delete aGraphic; delete aGraphic;
aGraphic = NULL; aGraphic = NULL;
} }

View File

@ -304,15 +304,26 @@ VECTOR2I GRID_HELPER::BestSnapAnchor( const VECTOR2I& aOrigin, const LSET& aLaye
else else
m_frame->GetGalCanvas()->GetView()->SetVisible( &m_viewSnapPoint, true ); m_frame->GetGalCanvas()->GetView()->SetVisible( &m_viewSnapPoint, true );
m_snapItem = nearest;
return nearest->pos; return nearest->pos;
} }
} }
m_snapItem = nullptr;
m_frame->GetGalCanvas()->GetView()->SetVisible( &m_viewSnapPoint, false ); m_frame->GetGalCanvas()->GetView()->SetVisible( &m_viewSnapPoint, false );
return nearestGrid; return nearestGrid;
} }
BOARD_ITEM* GRID_HELPER::GetSnapped( void ) const
{
if( !m_snapItem )
return nullptr;
return m_snapItem->item;
}
void GRID_HELPER::computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos ) void GRID_HELPER::computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos )
{ {
VECTOR2I origin; VECTOR2I origin;

View File

@ -49,6 +49,15 @@ public:
VECTOR2I GetGrid() const; VECTOR2I GetGrid() const;
VECTOR2I GetOrigin() const; VECTOR2I GetOrigin() const;
/**
* Function GetSnapped
* If the GRID_HELPER has highlighted a snap point (target shown), this function
* will return a pointer to the item to which it snapped.
*
* @return NULL if not snapped. Pointer to snapped item otherwise
*/
BOARD_ITEM* GetSnapped() const;
void SetAuxAxes( bool aEnable, const VECTOR2I& aOrigin = VECTOR2I( 0, 0 ), bool aEnableDiagonal = false ); void SetAuxAxes( bool aEnable, const VECTOR2I& aOrigin = VECTOR2I( 0, 0 ), bool aEnableDiagonal = false );
VECTOR2I Align( const VECTOR2I& aPoint ) const; VECTOR2I Align( const VECTOR2I& aPoint ) const;
@ -119,6 +128,7 @@ private:
bool m_enableSnap; ///< If true, allow snapping to other items on the layers bool m_enableSnap; ///< If true, allow snapping to other items on the layers
bool m_enableGrid; ///< If true, allow snapping to grid bool m_enableGrid; ///< If true, allow snapping to grid
int m_snapSize; ///< Sets the radius in screen units for snapping to items int m_snapSize; ///< Sets the radius in screen units for snapping to items
ANCHOR* m_snapItem; ///< Pointer to the currently snapped item in m_anchors (NULL if not snapped)
KIGFX::ORIGIN_VIEWITEM m_viewSnapPoint; KIGFX::ORIGIN_VIEWITEM m_viewSnapPoint;
KIGFX::ORIGIN_VIEWITEM m_viewAxis; KIGFX::ORIGIN_VIEWITEM m_viewAxis;