Regularize RunOnChildren() at the BOARD_ITEM level.

BOARD_ITEM sub-classes which don't have children simply don't
overrid it.
This commit is contained in:
Jeff Young 2023-10-14 15:04:13 +01:00
parent 8028ea893f
commit 504652b972
12 changed files with 88 additions and 201 deletions

View File

@ -179,6 +179,15 @@ public:
virtual std::shared_ptr<SHAPE_SEGMENT> GetEffectiveHoleShape() const;
/**
* Invoke a function on all children.
*
* @note This function should not add or remove items to the parent.
*
* @param aFunction is the function to be invoked.
*/
virtual void RunOnChildren( const std::function<void ( BOARD_ITEM* )>& aFunction ) const { }
BOARD_ITEM_CONTAINER* GetParent() const { return (BOARD_ITEM_CONTAINER*) m_parent; }
FOOTPRINT* GetParentFootprint() const;

View File

@ -211,14 +211,8 @@ public:
/// @copydoc EDA_ITEM::GetMsgPanelInfo
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
/**
* Invoke a function on all members of the group.
*
* @note This function should not add or remove items to the group.
*
* @param aFunction is the function to be invoked.
*/
void RunOnChildren( const std::function<void ( BOARD_ITEM* )>& aFunction ) const;
///< @copydoc BOARD_ITEM::RunOnChildren
void RunOnChildren( const std::function<void ( BOARD_ITEM* )>& aFunction ) const override;
/**
* Invoke a function on all descendants of the group.

View File

@ -114,37 +114,28 @@ void BOARD_COMMIT::dirtyIntersectingZones( BOARD_ITEM* item, int aChangeType )
if( item->Type() == PCB_ZONE_T )
zoneFillerTool->DirtyZone( static_cast<ZONE*>( item ) );
if( item->Type() == PCB_GROUP_T )
{
static_cast<PCB_GROUP*>( item )->RunOnChildren(
[&]( BOARD_ITEM* child )
{
dirtyIntersectingZones( child, aChangeType );
} );
}
item->RunOnChildren( std::bind( &BOARD_COMMIT::dirtyIntersectingZones, this, _1, aChangeType ) );
BOARD* board = static_cast<BOARD*>( m_toolMgr->GetModel() );
BOX2I bbox = item->GetBoundingBox();
LSET layers = item->GetLayerSet();
if( layers.test( Edge_Cuts ) || layers.test( Margin ) )
layers = LSET::PhysicalLayersMask();
else
layers &= LSET::AllCuMask();
if( layers.any() )
{
BOARD* board = static_cast<BOARD*>( m_toolMgr->GetModel() );
BOX2I bbox = item->GetBoundingBox();
LSET layers = item->GetLayerSet();
if( layers.test( Edge_Cuts ) || layers.test( Margin ) )
layers = LSET::PhysicalLayersMask();
else
layers &= LSET::AllCuMask();
if( layers.any() )
for( ZONE* zone : board->Zones() )
{
for( ZONE* zone : board->Zones() )
{
if( zone->GetIsRuleArea() )
continue;
if( zone->GetIsRuleArea() )
continue;
if( ( zone->GetLayerSet() & layers ).any()
&& zone->GetBoundingBox().Intersects( bbox ) )
{
zoneFillerTool->DirtyZone( zone );
}
if( ( zone->GetLayerSet() & layers ).any()
&& zone->GetBoundingBox().Intersects( bbox ) )
{
zoneFillerTool->DirtyZone( zone );
}
}
}
@ -628,14 +619,13 @@ void BOARD_COMMIT::Revert()
wxASSERT( boardItemCopy );
boardItem->SwapItemData( boardItemCopy );
if( boardItem->Type() == PCB_GROUP_T || boardItem->Type() == PCB_GENERATOR_T)
if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( boardItem ) )
{
PCB_GROUP* group = static_cast<PCB_GROUP*>( boardItem );
group->RunOnChildren( [&]( BOARD_ITEM* child )
{
child->SetParentGroup( group );
} );
group->RunOnChildren(
[&]( BOARD_ITEM* child )
{
child->SetParentGroup( group );
} );
}
view->Add( boardItem );

View File

@ -834,7 +834,7 @@ public:
*
* @param aFunction is the function to be invoked.
*/
void RunOnChildren( const std::function<void (BOARD_ITEM*)>& aFunction ) const;
void RunOnChildren( const std::function<void (BOARD_ITEM*)>& aFunction ) const override;
virtual void ViewGetLayers( int aLayers[], int& aCount ) const override;

View File

@ -290,22 +290,11 @@ void PCB_BASE_FRAME::FocusOnItems( std::vector<BOARD_ITEM*> aItems, PCB_LAYER_ID
{
lastItem->ClearBrightened();
if( lastItem->Type() == PCB_FOOTPRINT_T )
{
static_cast<FOOTPRINT*>( lastItem )->RunOnChildren(
[&]( BOARD_ITEM* child )
{
child->ClearBrightened();
} );
}
else if( lastItem->Type() == PCB_GROUP_T || lastItem->Type() == PCB_GENERATOR_T )
{
static_cast<PCB_GROUP*>( lastItem )->RunOnChildren(
[&]( BOARD_ITEM* child )
{
child->ClearBrightened();
} );
}
lastItem->RunOnChildren(
[&]( BOARD_ITEM* child )
{
child->ClearBrightened();
} );
GetCanvas()->GetView()->Update( lastItem );
lastBrightenedItemID = niluuid;
@ -348,22 +337,11 @@ void PCB_BASE_FRAME::FocusOnItems( std::vector<BOARD_ITEM*> aItems, PCB_LAYER_ID
{
item->SetBrightened();
if( item->Type() == PCB_FOOTPRINT_T )
{
static_cast<FOOTPRINT*>( item )->RunOnChildren(
[&]( BOARD_ITEM* child )
{
child->SetBrightened();
});
}
else if( item->Type() == PCB_GROUP_T || item->Type() == PCB_GENERATOR_T )
{
static_cast<PCB_GROUP*>( item )->RunOnChildren(
[&]( BOARD_ITEM* child )
{
child->SetBrightened();
});
}
item->RunOnChildren(
[&]( BOARD_ITEM* child )
{
child->SetBrightened();
});
GetCanvas()->GetView()->Update( item );
lastBrightenedItemIDs.push_back( item->m_Uuid );

View File

@ -58,16 +58,8 @@ PCB_VIEW::~PCB_VIEW()
void PCB_VIEW::Add( KIGFX::VIEW_ITEM* aItem, int aDrawPriority )
{
BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( aItem );
if( boardItem && boardItem->Type() == PCB_FOOTPRINT_T )
{
FOOTPRINT* footprint = static_cast<FOOTPRINT*>( boardItem );
footprint->RunOnChildren( [this]( BOARD_ITEM* aChild )
{
VIEW::Add( aChild );
} );
}
if( FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( aItem ) )
footprint->RunOnChildren( std::bind( &PCB_VIEW::Add, this, _1, aDrawPriority ) );
VIEW::Add( aItem, aDrawPriority );
}
@ -75,16 +67,8 @@ void PCB_VIEW::Add( KIGFX::VIEW_ITEM* aItem, int aDrawPriority )
void PCB_VIEW::Remove( KIGFX::VIEW_ITEM* aItem )
{
BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( aItem );
if( boardItem && boardItem->Type() == PCB_FOOTPRINT_T )
{
FOOTPRINT* footprint = static_cast<FOOTPRINT*>( boardItem );
footprint->RunOnChildren( [this]( BOARD_ITEM* aChild )
{
VIEW::Remove( aChild );
} );
}
if( FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( aItem ) )
footprint->RunOnChildren( std::bind( &PCB_VIEW::Remove, this, _1 ) );
VIEW::Remove( aItem );
}
@ -92,27 +76,14 @@ void PCB_VIEW::Remove( KIGFX::VIEW_ITEM* aItem )
void PCB_VIEW::Update( const KIGFX::VIEW_ITEM* aItem, int aUpdateFlags ) const
{
const BOARD_ITEM* boardItem = dynamic_cast<const BOARD_ITEM*>( aItem );
if( boardItem && boardItem->Type() == PCB_FOOTPRINT_T )
if( const BOARD_ITEM* boardItem = dynamic_cast<const BOARD_ITEM*>( aItem ) )
{
const FOOTPRINT* footprint = static_cast<const FOOTPRINT*>( boardItem );
footprint->RunOnChildren(
boardItem->RunOnChildren(
[this, aUpdateFlags]( BOARD_ITEM* child )
{
VIEW::Update( child, aUpdateFlags );
} );
}
else if( boardItem
&& ( boardItem->Type() == PCB_GROUP_T || boardItem->Type() == PCB_GENERATOR_T ) )
{
const PCB_GROUP* group = static_cast<const PCB_GROUP*>( boardItem );
group->RunOnChildren(
[this, aUpdateFlags]( BOARD_ITEM* child )
{
Update( child, aUpdateFlags );
} );
}
VIEW::Update( aItem, aUpdateFlags );
}

View File

@ -1093,13 +1093,13 @@ void PCB_PARSER::resolveGroups( BOARD_ITEM* aParent )
{
BOARD_ITEM* aItem = nullptr;
if( dynamic_cast<BOARD*>( aParent ) )
if( BOARD* board = dynamic_cast<BOARD*>( aParent ) )
{
aItem = static_cast<BOARD*>( aParent )->GetItem( aId );
aItem = board->GetItem( aId );
}
else if( aParent->Type() == PCB_FOOTPRINT_T )
else if( FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( aParent ) )
{
static_cast<FOOTPRINT*>( aParent )->RunOnChildren(
footprint->RunOnChildren(
[&]( BOARD_ITEM* child )
{
if( child->m_Uuid == aId )

View File

@ -516,23 +516,11 @@ std::set<BOARD_ITEM*> PCB_GRID_HELPER::queryVisible( const BOX2I& aArea,
{
items.erase( aItem );
if( FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( aItem ) )
{
footprint->RunOnChildren(
[&]( BOARD_ITEM* aChild )
{
skipItem( aChild );
} );
}
if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( aItem ) )
{
group->RunOnChildren(
[&]( BOARD_ITEM* aChild )
{
skipItem( aChild );
} );
}
aItem->RunOnChildren(
[&]( BOARD_ITEM* aChild )
{
skipItem( aChild );
} );
};
for( BOARD_ITEM* item : aSkip )

View File

@ -86,27 +86,18 @@ const std::vector<KIGFX::VIEW_ITEM*> PCB_SELECTION::updateDrawList() const
{
std::vector<VIEW_ITEM*> items;
std::function<void ( EDA_ITEM* )> addItem;
addItem = [&]( EDA_ITEM* item )
std::function<void ( EDA_ITEM* )> addItem =
[&]( EDA_ITEM* item )
{
items.push_back( item );
if( item->Type() == PCB_FOOTPRINT_T )
if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item ) )
{
FOOTPRINT* footprint = static_cast<FOOTPRINT*>( item );
footprint->RunOnChildren( [&]( BOARD_ITEM* bitem )
boardItem->RunOnChildren( [&]( BOARD_ITEM* bitem )
{
addItem( bitem );
} );
}
else if( item->Type() == PCB_GROUP_T || item->Type() == PCB_GENERATOR_T )
{
PCB_GROUP* group = static_cast<PCB_GROUP*>( item );
group->RunOnChildren( [&]( BOARD_ITEM* bitem )
{
addItem( bitem );
} );
}
};
for( EDA_ITEM* item : m_items )

View File

@ -2855,21 +2855,10 @@ void PCB_SELECTION_TOOL::highlightInternal( EDA_ITEM* aItem, int aMode, bool aUs
if( aUsingOverlay && aMode != BRIGHTENED )
view()->Hide( aItem, true ); // Hide the original item, so it is shown only on overlay
if( aItem->Type() == PCB_FOOTPRINT_T )
if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( aItem ) )
{
static_cast<FOOTPRINT*>( aItem )->RunOnChildren(
[&]( BOARD_ITEM* aChild )
{
highlightInternal( aChild, aMode, aUsingOverlay );
} );
}
else if( aItem->Type() == PCB_GROUP_T || aItem->Type() == PCB_GENERATOR_T )
{
static_cast<PCB_GROUP*>( aItem )->RunOnChildren(
[&]( BOARD_ITEM* aChild )
{
highlightInternal( aChild, aMode, aUsingOverlay );
} );
boardItem->RunOnChildren( std::bind( &PCB_SELECTION_TOOL::highlightInternal, this, _1,
aMode, aUsingOverlay ) );
}
}
@ -2898,21 +2887,10 @@ void PCB_SELECTION_TOOL::unhighlightInternal( EDA_ITEM* aItem, int aMode, bool a
if( aUsingOverlay && aMode != BRIGHTENED )
view()->Hide( aItem, false ); // // Restore original item visibility
if( aItem->Type() == PCB_FOOTPRINT_T )
if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( aItem ) )
{
static_cast<FOOTPRINT*>( aItem )->RunOnChildren(
[&]( BOARD_ITEM* aChild )
{
unhighlightInternal( aChild, aMode, aUsingOverlay );
} );
}
else if( aItem->Type() == PCB_GROUP_T || aItem->Type() == PCB_GENERATOR_T )
{
static_cast<PCB_GROUP*>( aItem )->RunOnChildren(
[&]( BOARD_ITEM* aChild )
{
unhighlightInternal( aChild, aMode, aUsingOverlay );
} );
boardItem->RunOnChildren( std::bind( &PCB_SELECTION_TOOL::unhighlightInternal, this, _1,
aMode, aUsingOverlay ) );
}
}
@ -2935,21 +2913,15 @@ bool PCB_SELECTION_TOOL::selectionContains( const VECTOR2I& aPoint ) const
bool found = false;
std::function<void( PCB_GROUP* )> checkGroup =
[&]( PCB_GROUP* aGroup )
{
aGroup->RunOnChildren(
[&]( BOARD_ITEM* aItem )
{
if( aItem->Type() == PCB_GROUP_T || aItem->Type() == PCB_GENERATOR_T )
checkGroup( static_cast<PCB_GROUP*>( aItem ) );
else if( aItem->HitTest( aPoint, margin ) )
found = true;
} );
};
if( item->Type() == PCB_GROUP_T || item->Type() == PCB_GENERATOR_T )
checkGroup( static_cast<PCB_GROUP*>( item ) );
if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( item ) )
{
group->RunOnDescendants(
[&]( BOARD_ITEM* aItem )
{
if( aItem->HitTest( aPoint, margin ) )
found = true;
} );
}
if( found )
return true;

View File

@ -79,13 +79,9 @@ void PCB_TOOL_BASE::doInteractiveItemPlacement( const TOOL_EVENT& aTool,
newItem->SetPosition( aPosition );
preview.Add( newItem.get() );
if( newItem->Type() == PCB_FOOTPRINT_T )
{
FOOTPRINT* fp = static_cast<FOOTPRINT*>( newItem.get() );
// footprints have more drawable parts
// footprints have more drawable parts
if( FOOTPRINT* fp = dynamic_cast<FOOTPRINT*>( newItem.get() ) )
fp->RunOnChildren( std::bind( &KIGFX::VIEW_GROUP::Add, &preview, _1 ) );
}
}
};

View File

@ -273,7 +273,7 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
auto view = GetCanvas()->GetView();
auto connectivity = GetBoard()->GetConnectivity();
PCB_GROUP* group = nullptr;
PCB_GROUP* addedGroup = nullptr;
GetBoard()->IncrementTimeStamp(); // clear caches
@ -383,10 +383,8 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
item->SwapItemData( image );
if( item->Type() == PCB_GROUP_T || item->Type() == PCB_GENERATOR_T )
if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( item ) )
{
group = static_cast<PCB_GROUP*>( item );
group->RunOnChildren( [&]( BOARD_ITEM* child )
{
child->SetParentGroup( group );
@ -416,8 +414,8 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
if( eda_item->Type() != PCB_NETINFO_T )
view->Add( eda_item );
if( eda_item->Type() == PCB_GROUP_T || eda_item->Type() == PCB_GENERATOR_T )
group = static_cast<PCB_GROUP*>( eda_item );
if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( eda_item ) )
addedGroup = group;
break;
@ -434,8 +432,8 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( eda_item ) )
{
if( group )
group->AddItem( boardItem );
if( addedGroup )
addedGroup->AddItem( boardItem );
}
break;