Allow selection of nested items (ie: pads) inside an entered group.

Also moves some group-related functionality from BOARD to PCB_GROUP.
This commit is contained in:
Jeff Young 2020-09-26 17:06:32 +01:00
parent b6e4b7bf7d
commit 7f33c229d8
7 changed files with 46 additions and 33 deletions

View File

@ -87,6 +87,15 @@ public:
void RemoveAll();
/*
* Searches for highest level group containing item.
* @param scope restricts the search to groups within the group scope.
* @return group containing item, if it exists, otherwise, NULL
*/
static PCB_GROUP* TopLevelGroup( BOARD_ITEM* item, PCB_GROUP* scope );
static bool WithinScope( BOARD_ITEM* item, PCB_GROUP* scope );
#if defined( DEBUG )
void Show( int nestLevel, std::ostream& os ) const override
{

View File

@ -1967,17 +1967,6 @@ void BOARD::HighLightON( bool aValue )
}
PCB_GROUP* BOARD::TopLevelGroup( BOARD_ITEM* item, PCB_GROUP* scope )
{
PCB_GROUP* candidate = item->GetParentGroup();
while( candidate && candidate->GetParentGroup() && candidate->GetParentGroup() != scope )
candidate = candidate->GetParentGroup();
return candidate == scope ? nullptr : candidate;
}
wxString BOARD::GroupsSanityCheck( bool repair )
{
if( repair )

View File

@ -1099,13 +1099,6 @@ public:
*/
wxString GroupsSanityCheckInternal( bool repair );
/*
* Searches for highest level group containing item.
* @param scope restricts the search to groups within the group scope.
* @return group containing item, if it exists, otherwise, NULL
*/
PCB_GROUP* TopLevelGroup( BOARD_ITEM* item, PCB_GROUP* scope );
struct GroupLegalOpsField
{
bool create : 1;

View File

@ -69,6 +69,35 @@ void PCB_GROUP::RemoveAll()
}
PCB_GROUP* PCB_GROUP::TopLevelGroup( BOARD_ITEM* item, PCB_GROUP* scope )
{
if( item->GetParent() && item->GetParent()->Type() == PCB_MODULE_T )
item = item->GetParent();
PCB_GROUP* candidate = item->GetParentGroup();
while( candidate && candidate->GetParentGroup() && candidate->GetParentGroup() != scope )
candidate = candidate->GetParentGroup();
return candidate == scope ? nullptr : candidate;
}
bool PCB_GROUP::WithinScope( BOARD_ITEM* item, PCB_GROUP* scope )
{
if( item->GetParent() && item->GetParent()->Type() == PCB_MODULE_T )
item = item->GetParent();
for( PCB_GROUP* parent = item->GetParentGroup(); parent; parent = parent->GetParentGroup() )
{
if( parent == scope )
return true;
}
return false;
}
wxPoint PCB_GROUP::GetPosition() const
{
return GetBoundingBox().Centre();

View File

@ -155,20 +155,10 @@ void PCB_BASE_EDIT_FRAME::SetBoard( BOARD* aBoard )
if( new_board )
{
m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD );
BOARD_DESIGN_SETTINGS& bds = aBoard->GetDesignSettings();
bds.m_DRCEngine = std::make_shared<DRC_ENGINE>( aBoard, &bds );
try
{
bds.m_DRCEngine->InitEngine( GetDesignRulesPath() );
}
catch( PARSE_ERROR& pe )
{
// TODO: We could redirect to Board Setup here and report the error. Or we could
// wait till they run DRC or do an Inspect Clearance. Not sure which is better....
}
m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD );
}
}
}

View File

@ -1031,6 +1031,9 @@ void PCB_EDIT_FRAME::SetActiveLayer( PCB_LAYER_ID aLayer )
void PCB_EDIT_FRAME::onBoardLoaded()
{
DRC_TOOL* drcTool = m_toolManager->GetTool<DRC_TOOL>();
drcTool->Reset( TOOL_BASE::MODEL_RELOAD );
UpdateTitle();
wxFileName fn = GetBoard()->GetFileName();

View File

@ -1552,7 +1552,7 @@ bool SELECTION_TOOL::itemPassesFilter( BOARD_ITEM* aItem )
return false;
}
if( m_enteredGroup && aItem->GetParentGroup() != m_enteredGroup )
if( m_enteredGroup && !PCB_GROUP::WithinScope( aItem, m_enteredGroup ) )
return false;
return true;
@ -2566,7 +2566,7 @@ void SELECTION_TOOL::FilterCollectorForGroups( GENERAL_COLLECTOR& aCollector ) c
// If any element is a member of a group, replace those elements with the top containing group.
for( int j = 0; j < aCollector.GetCount(); ++j )
{
PCB_GROUP* aTop = board()->TopLevelGroup( aCollector[j], m_enteredGroup );
PCB_GROUP* aTop = PCB_GROUP::TopLevelGroup( aCollector[j], m_enteredGroup );
if( aTop != NULL )
{
@ -2576,9 +2576,9 @@ void SELECTION_TOOL::FilterCollectorForGroups( GENERAL_COLLECTOR& aCollector ) c
aCollector.Remove( aCollector[j] );
}
}
else if( m_enteredGroup && aCollector[j]->GetParentGroup() != m_enteredGroup )
else if( m_enteredGroup && !PCB_GROUP::WithinScope( aCollector[j], m_enteredGroup ) )
{
// If a group is entered, no selections of objects not in the group.
// If a group is entered, disallow selections of objects outside the group.
aCollector.Remove( aCollector[j] );
}
}