Rework footprint selection filtering to improve behavior

Fixes: lp:1751960
* https://bugs.launchpad.net/kicad/+bug/1751960
This commit is contained in:
Jon Evans 2018-03-07 20:40:50 -05:00
parent 9c532dfada
commit 1e66a23dbc
3 changed files with 69 additions and 5 deletions

View File

@ -42,6 +42,7 @@
#include <macros.h>
#include <msgpanel.h>
#include <bitmaps.h>
#include <unordered_set>
#include <pcb_edit_frame.h>
#include <class_board.h>
@ -924,6 +925,36 @@ void MODULE::RunOnChildren( const std::function<void (BOARD_ITEM*)>& aFunction )
}
}
void MODULE::GetAllDrawingLayers( int aLayers[], int& aCount, bool aIncludePads ) const
{
std::unordered_set<int> layers;
for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
{
layers.insert( static_cast<int>( item->GetLayer() ) );
}
if( aIncludePads )
{
for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
{
int pad_layers[KIGFX::VIEW::VIEW_MAX_LAYERS], pad_layers_count;
pad->ViewGetLayers( pad_layers, pad_layers_count );
for( int i = 0; i < pad_layers_count; i++ )
layers.insert( pad_layers[i] );
}
}
aCount = layers.size();
int i = 0;
for( auto layer : layers )
aLayers[i++] = layer;
}
void MODULE::ViewGetLayers( int aLayers[], int& aCount ) const
{
aCount = 2;

View File

@ -610,6 +610,15 @@ public:
*/
void RunOnChildren( const std::function<void (BOARD_ITEM*)>& aFunction );
/**
* Returns a set of all layers that this module has drawings on
* similar to ViewGetLayers()
*
* @param aLayers is an array to store layer ids
* @param aCount is the number of layers stored in the array
* @param aIncludePads controls whether to also include pad layers
*/
void GetAllDrawingLayers( int aLayers[], int& aCount, bool aIncludePads = true ) const;
virtual void ViewGetLayers( int aLayers[], int& aCount ) const override;

View File

@ -1599,13 +1599,37 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
if( viewArea > 0.0 && modArea > viewArea )
return false;
if( aItem->IsOnLayer( F_Cu ) && board()->IsElementVisible( LAYER_MOD_FR ) )
return !m_editModules;
// Allow selection of footprints if at least one draw layer is on and
// the appropriate LAYER_MOD is on
if( aItem->IsOnLayer( B_Cu ) && board()->IsElementVisible( LAYER_MOD_BK ) )
return !m_editModules;
bool layer_mod = ( ( aItem->IsOnLayer( F_Cu ) && board()->IsElementVisible( LAYER_MOD_FR ) ) ||
( aItem->IsOnLayer( B_Cu ) && board()->IsElementVisible( LAYER_MOD_BK ) ) );
return false;
bool draw_layer_visible = false;
int draw_layers[KIGFX::VIEW::VIEW_MAX_LAYERS], draw_layers_count;
static_cast<const MODULE*>( aItem )->GetAllDrawingLayers( draw_layers,
draw_layers_count,
true );
for( int i = 0; i < draw_layers_count; ++i )
{
// NOTE: Pads return LAYER_PADS_PLATEDHOLES but the visibility
// control only directly switches LAYER_PADS_TH, so we overwrite it
// here so that the visibility check is accurate
if( draw_layers[i] == LAYER_PADS_PLATEDHOLES )
draw_layers[i] = LAYER_PADS_TH;
if( ( ( draw_layers[i] < PCB_LAYER_ID_COUNT ) &&
board()->IsLayerVisible( static_cast<PCB_LAYER_ID>( draw_layers[i] ) ) ) ||
( ( draw_layers[i] >= GAL_LAYER_ID_START ) &&
board()->IsElementVisible( static_cast<GAL_LAYER_ID>( draw_layers[i] ) ) ) )
{
draw_layer_visible = true;
}
}
return ( draw_layer_visible && layer_mod );
break;
}