Clean up selection logic.

Don't try to do too many things at once.  Separate
out fooptrint-children handling, visibility-handling,
and footprintEditor vs boardEditor differences.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17562

(cherry picked from commit 3958d1bf14)
This commit is contained in:
Jeff Young 2024-04-16 18:12:23 +01:00
parent fa490644dd
commit 4f776050e6
1 changed files with 33 additions and 64 deletions

View File

@ -2602,6 +2602,15 @@ bool PCB_SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibili
}
};
auto layerVisible =
[&]( PCB_LAYER_ID aLayer )
{
if( m_isFootprintEditor )
return view()->IsLayerVisible( aLayer );
else
return board()->IsLayerVisible( aLayer );
};
if( settings->GetHighContrast() )
{
const std::set<int> activeLayers = settings->GetHighContrastLayers();
@ -2691,6 +2700,13 @@ bool PCB_SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibili
const PCB_TEXT* text = nullptr;
const PCB_FIELD* field = nullptr;
// Most footprint children can only be selected in the footprint editor.
if( aItem->GetParentFootprint() && !m_isFootprintEditor && !checkVisibilityOnly )
{
if( aItem->Type() != PCB_FIELD_T && aItem->Type() != PCB_PAD_T )
return false;
}
switch( aItem->Type() )
{
case PCB_ZONE_T:
@ -2704,15 +2720,6 @@ bool PCB_SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibili
if( zone->IsTeardropArea() && !board()->LegacyTeardrops() )
return false;
// A footprint zone is only selectable within the footprint editor
if( zone->GetParent()
&& zone->GetParent()->Type() == PCB_FOOTPRINT_T
&& !m_isFootprintEditor
&& !checkVisibilityOnly )
{
return false;
}
// zones can exist on multiple layers!
if( !( zone->GetLayerSet() & visibleLayers() ).any() )
return false;
@ -2724,16 +2731,8 @@ bool PCB_SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibili
if( !board()->IsElementVisible( LAYER_TRACKS ) || ( options.m_TrackOpacity == 0.00 ) )
return false;
if( m_isFootprintEditor )
{
if( !view()->IsLayerVisible( aItem->GetLayer() ) )
if( !layerVisible( aItem->GetLayer() ) )
return false;
}
else
{
if( !board()->IsLayerVisible( aItem->GetLayer() ) )
return false;
}
break;
@ -2763,27 +2762,21 @@ bool PCB_SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibili
case PCB_TEXT_T:
text = static_cast<const PCB_TEXT*>( aItem );
if( m_isFootprintEditor )
if( !text->IsVisible() )
{
if( !text->IsVisible() && !view()->IsLayerVisible( LAYER_HIDDEN_TEXT ) )
return false;
if( !view()->IsLayerVisible( text->GetLayer() ) )
if( !m_isFootprintEditor || !view()->IsLayerVisible( LAYER_HIDDEN_TEXT ) )
return false;
}
else if( aItem->GetParentFootprint() )
{
// Footprint text selections are only allowed in footprint editor mode.
// Careful, though: we also get here through the PCB_FIELD_T case.
if( aItem->Type() == PCB_TEXT_T && !checkVisibilityOnly )
if( !layerVisible( text->GetLayer() ) )
return false;
// Apply the LOD visibility test as well
if( !view()->IsVisible( text ) )
return false;
if( !board()->IsLayerVisible( text->GetLayer() ) )
return false;
if( aItem->GetParentFootprint() )
{
int controlLayer = LAYER_FP_TEXT;
if( text->GetText() == wxT( "${REFERENCE}" ) )
@ -2809,20 +2802,8 @@ bool PCB_SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibili
case PCB_SHAPE_T:
case PCB_TEXTBOX_T:
if( m_isFootprintEditor )
{
if( !view()->IsLayerVisible( aItem->GetLayer() ) )
if( !layerVisible( aItem->GetLayer() ) )
return false;
}
else if( aItem->GetParentFootprint() )
{
// Footprint shape selections are only allowed in footprint editor mode.
if( !checkVisibilityOnly )
return false;
if( !board()->IsLayerVisible( aItem->GetLayer() ) )
return false;
}
break;
@ -2831,20 +2812,8 @@ bool PCB_SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibili
case PCB_DIM_CENTER_T:
case PCB_DIM_RADIAL_T:
case PCB_DIM_ORTHOGONAL_T:
if( m_isFootprintEditor )
{
if( !view()->IsLayerVisible( aItem->GetLayer() ) )
if( !layerVisible( aItem->GetLayer() ) )
return false;
}
else if( aItem->GetParentFootprint() )
{
// Footprint dimension selections are only allowed in footprint editor mode.
if( !checkVisibilityOnly )
return false;
if( !board()->IsLayerVisible( aItem->GetLayer() ) )
return false;
}
break;