Pcbnew: fix footprint selection bug.
Do not remove footprint objects from list of selected objects when there are no drawable objects other than the reference and value text. Increase the minimum size rectangle for footprints from 0.025mm to 1mm when the footprint has no drawing objects so that it is easier to select the footprint in this case. Add debugging code to show the footprint bounding box and polygon outline so that it's possible to tell the difference between selection areas. Fixes https://gitlab.com/kicad/code/kicad/-/issues/8379
This commit is contained in:
parent
c9cc824761
commit
5c1c24cdab
|
@ -4,7 +4,7 @@
|
||||||
* Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
* Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||||
* Copyright (C) 2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
* Copyright (C) 2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||||
* Copyright (C) 2015 Wayne Stambaugh <stambaughw@gmail.com>
|
* Copyright (C) 2015 Wayne Stambaugh <stambaughw@gmail.com>
|
||||||
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -460,7 +460,9 @@ EDA_RECT MODULE::GetFootprintRect() const
|
||||||
|
|
||||||
area.SetOrigin( m_Pos );
|
area.SetOrigin( m_Pos );
|
||||||
area.SetEnd( m_Pos );
|
area.SetEnd( m_Pos );
|
||||||
area.Inflate( Millimeter2iu( 0.25 ) ); // Give a min size to the area
|
|
||||||
|
// Give a minimum size to the area in case footprint has no drawing or pad objects.
|
||||||
|
area.Inflate( Millimeter2iu( 0.5 ) );
|
||||||
|
|
||||||
for( const BOARD_ITEM* item = m_Drawings.GetFirst(); item; item = item->Next() )
|
for( const BOARD_ITEM* item = m_Drawings.GetFirst(); item; item = item->Next() )
|
||||||
{
|
{
|
||||||
|
@ -479,13 +481,6 @@ const EDA_RECT MODULE::GetBoundingBox() const
|
||||||
{
|
{
|
||||||
EDA_RECT area = GetFootprintRect();
|
EDA_RECT area = GetFootprintRect();
|
||||||
|
|
||||||
// Add in items not collected by GetFootprintRect():
|
|
||||||
for( const BOARD_ITEM* item = m_Drawings.GetFirst(); item; item = item->Next() )
|
|
||||||
{
|
|
||||||
if( item->Type() != PCB_MODULE_EDGE_T )
|
|
||||||
area.Merge( item->GetBoundingBox() );
|
|
||||||
}
|
|
||||||
|
|
||||||
area.Merge( m_Value->GetBoundingBox() );
|
area.Merge( m_Value->GetBoundingBox() );
|
||||||
area.Merge( m_Reference->GetBoundingBox() );
|
area.Merge( m_Reference->GetBoundingBox() );
|
||||||
|
|
||||||
|
@ -529,6 +524,7 @@ SHAPE_POLY_SET MODULE::GetBoundingPoly() const
|
||||||
poly.Append( p );
|
poly.Append( p );
|
||||||
|
|
||||||
BOARD* board = GetBoard();
|
BOARD* board = GetBoard();
|
||||||
|
|
||||||
if( board )
|
if( board )
|
||||||
{
|
{
|
||||||
int biggest_clearance = board->GetDesignSettings().GetBiggestClearanceValue();
|
int biggest_clearance = board->GetDesignSettings().GetBiggestClearanceValue();
|
||||||
|
@ -650,13 +646,20 @@ bool MODULE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) co
|
||||||
arect.Inflate( aAccuracy );
|
arect.Inflate( aAccuracy );
|
||||||
|
|
||||||
if( aContained )
|
if( aContained )
|
||||||
|
{
|
||||||
return arect.Contains( m_BoundaryBox );
|
return arect.Contains( m_BoundaryBox );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If the rect does not intersect the bounding box, skip any tests
|
// If the rect does not intersect the bounding box, skip any tests
|
||||||
if( !aRect.Intersects( GetBoundingBox() ) )
|
if( !aRect.Intersects( GetBoundingBox() ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// If there are no drawing objects, there was still an intersection with the reference
|
||||||
|
// and/or value text.
|
||||||
|
if( m_Pads.GetCount() == 0 && m_Drawings.GetCount() == 0 )
|
||||||
|
return true;
|
||||||
|
|
||||||
// Determine if any elements in the MODULE intersect the rect
|
// Determine if any elements in the MODULE intersect the rect
|
||||||
for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
|
for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013-2019 CERN
|
* Copyright (C) 2013-2019 CERN
|
||||||
|
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
*
|
*
|
||||||
|
@ -383,7 +385,40 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
// Draw bounding boxes after drawing objects so they can be seen.
|
||||||
|
#if 0
|
||||||
|
// Show bounding boxes of painted objects for debugging.
|
||||||
|
EDA_RECT box = item->GetBoundingBox();
|
||||||
|
m_gal->SetIsFill( false );
|
||||||
|
m_gal->SetIsStroke( true );
|
||||||
|
|
||||||
|
if( item->Type() == PCB_MODULE_T )
|
||||||
|
m_gal->SetStrokeColor( item->IsSelected() ? COLOR4D( 1.0, 0.2, 0.2, 1 ) :
|
||||||
|
COLOR4D( MAGENTA ) );
|
||||||
|
else
|
||||||
|
m_gal->SetStrokeColor( item->IsSelected() ? COLOR4D( 1.0, 0.2, 0.2, 1 ) :
|
||||||
|
COLOR4D( 0.2, 0.2, 0.2, 1 ) );
|
||||||
|
|
||||||
|
m_gal->SetLineWidth( 1.5 / m_gal->GetWorldScale() );
|
||||||
|
m_gal->DrawRectangle( box.GetOrigin(), box.GetEnd() );
|
||||||
|
|
||||||
|
if( item->Type() == PCB_MODULE_T )
|
||||||
|
{
|
||||||
|
m_gal->SetStrokeColor( item->IsSelected() ? COLOR4D( 1.0, 0.2, 0.2, 1 ) :
|
||||||
|
COLOR4D( CYAN ) );
|
||||||
|
|
||||||
|
const MODULE* fp = static_cast<const MODULE*>( item );
|
||||||
|
|
||||||
|
if( fp )
|
||||||
|
{
|
||||||
|
SHAPE_POLY_SET convex = fp->GetBoundingPoly();
|
||||||
|
|
||||||
|
m_gal->DrawPolyline( convex.COutline( 0 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013-2017 CERN
|
* Copyright (C) 2013-2017 CERN
|
||||||
|
* Copyright (C) 2018-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
* Copyright (C) 2018 KiCad Developers, see AUTHORS.txt for contributors.
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -1701,9 +1702,14 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem, bool checkVisibilityOn
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Allow selection of footprints if some part of the footprint is visible.
|
// Allow selection of footprints if some part of the footprint is visible.
|
||||||
|
|
||||||
MODULE* module = const_cast<MODULE*>( static_cast<const MODULE*>( aItem ) );
|
MODULE* module = const_cast<MODULE*>( static_cast<const MODULE*>( aItem ) );
|
||||||
|
|
||||||
|
// If the footprint has no drawable items other than the reference and value test,
|
||||||
|
// then it can be selected.
|
||||||
|
if( ( module->GraphicalItemsList().GetCount() == 0 ) &&
|
||||||
|
( module->PadsList().GetCount() == 0 ) )
|
||||||
|
return true;
|
||||||
|
|
||||||
for( auto item : module->GraphicalItems() )
|
for( auto item : module->GraphicalItems() )
|
||||||
{
|
{
|
||||||
if( selectable( item, true ) )
|
if( selectable( item, true ) )
|
||||||
|
|
Loading…
Reference in New Issue