From 4f776050e69bfd176db473e33134e877cdc33457 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Tue, 16 Apr 2024 18:12:23 +0100 Subject: [PATCH] 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 3958d1bf1440244da2434df5ace86d8dd2664435) --- pcbnew/tools/pcb_selection_tool.cpp | 97 ++++++++++------------------- 1 file changed, 33 insertions(+), 64 deletions(-) diff --git a/pcbnew/tools/pcb_selection_tool.cpp b/pcbnew/tools/pcb_selection_tool.cpp index d001152b6f..05ba1d1d7d 100644 --- a/pcbnew/tools/pcb_selection_tool.cpp +++ b/pcbnew/tools/pcb_selection_tool.cpp @@ -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 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() ) ) - return false; - } - else - { - if( !board()->IsLayerVisible( aItem->GetLayer() ) ) - return false; - } + if( !layerVisible( 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( 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() ) + + if( !layerVisible( text->GetLayer() ) ) + return false; + + // Apply the LOD visibility test as well + if( !view()->IsVisible( text ) ) + return false; + + 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 ) - return false; - - if( !view()->IsVisible( text ) ) - return false; - - if( !board()->IsLayerVisible( text->GetLayer() ) ) - return false; - 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() ) ) - 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; - } + if( !layerVisible( 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() ) ) - 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; - } + if( !layerVisible( aItem->GetLayer() ) ) + return false; break;