kicad/qa/qa_utils/pcb_test_selection_tool.cpp

227 lines
6.4 KiB
C++

#include "pcb_test_frame.h"
#include "pcb_test_selection_tool.h"
#include <pcbnew/tools/pcb_actions.h>
#include <tool/actions.h>
#include <tool/tool_manager.h>
PCB_TEST_SELECTION_TOOL::PCB_TEST_SELECTION_TOOL()
: SELECTION_TOOL( "pcbnew.InteractiveSelection" )
{
}
PCB_TEST_SELECTION_TOOL::~PCB_TEST_SELECTION_TOOL()
{
view()->Remove( &m_selection );
}
bool PCB_TEST_SELECTION_TOOL::Init()
{
view()->Remove( &m_selection );
view()->Add( &m_selection );
return true;
}
void PCB_TEST_SELECTION_TOOL::Reset( RESET_REASON aReason )
{
}
void PCB_TEST_SELECTION_TOOL::ClearSelection()
{
if( m_selection.Empty() )
return;
while( m_selection.GetSize() )
unhighlight( m_selection.Front(), SELECTED, &m_selection );
view()->Update( &m_selection );
m_selection.SetIsHover( false );
m_selection.ClearReferencePoint();
}
#include <collectors.h>
const GENERAL_COLLECTORS_GUIDE PCB_TEST_SELECTION_TOOL::getCollectorsGuide() const
{
GENERAL_COLLECTORS_GUIDE guide( board()->GetVisibleLayers(),
(PCB_LAYER_ID) view()->GetTopLayer(), view() );
bool padsDisabled = !board()->IsElementVisible( LAYER_PADS );
// account for the globals
guide.SetIgnoreMTextsMarkedNoShow( !board()->IsElementVisible( LAYER_HIDDEN_TEXT ) );
guide.SetIgnoreMTextsOnBack( !board()->IsElementVisible( LAYER_FP_TEXT ) );
guide.SetIgnoreMTextsOnFront( !board()->IsElementVisible( LAYER_FP_TEXT ) );
guide.SetIgnoreModulesOnBack( !board()->IsElementVisible( LAYER_FOOTPRINTS_BK ) );
guide.SetIgnoreModulesOnFront( !board()->IsElementVisible( LAYER_FOOTPRINTS_FR ) );
guide.SetIgnorePadsOnBack( padsDisabled || !board()->IsElementVisible( LAYER_PADS_SMD_BK ) );
guide.SetIgnorePadsOnFront( padsDisabled || !board()->IsElementVisible( LAYER_PADS_SMD_FR ) );
guide.SetIgnoreThroughHolePads( padsDisabled || !board()->IsElementVisible( LAYER_PADS_TH ) );
guide.SetIgnoreModulesVals( !board()->IsElementVisible( LAYER_FP_VALUES ) );
guide.SetIgnoreModulesRefs( !board()->IsElementVisible( LAYER_FP_REFERENCES ) );
guide.SetIgnoreThroughVias( !board()->IsElementVisible( LAYER_VIAS ) );
guide.SetIgnoreBlindBuriedVias( !board()->IsElementVisible( LAYER_VIAS ) );
guide.SetIgnoreMicroVias( !board()->IsElementVisible( LAYER_VIAS ) );
guide.SetIgnoreTracks( !board()->IsElementVisible( LAYER_TRACKS ) );
return guide;
}
bool PCB_TEST_SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere )
{
GENERAL_COLLECTORS_GUIDE guide = getCollectorsGuide();
GENERAL_COLLECTOR collector;
for( auto item : m_selection.Items() )
{
unhighlight( item, SELECTED, &m_selection );
}
m_selection.Clear();
m_selection.ClearReferencePoint();
if( m_selectableTypes.empty() )
collector.Collect( board(), GENERAL_COLLECTOR::AllBoardItems, aWhere, guide );
else
collector.Collect( board(), m_selectableTypes, aWhere, guide );
if( collector.GetCount() > 0 )
{
for( int i = 0; i < collector.GetCount(); ++i )
{
{
select( collector[i] );
}
}
}
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
if( m_selectionHook )
m_selectionHook( frame(), &m_selection );
return false;
}
void PCB_TEST_SELECTION_TOOL::setTransitions()
{
Go( &PCB_TEST_SELECTION_TOOL::Main, PCB_ACTIONS::selectionActivate.MakeEvent() );
}
void PCB_TEST_SELECTION_TOOL::highlightInternal( EDA_ITEM* aItem, int aMode, bool aUsingOverlay )
{
if( aMode == SELECTED )
aItem->SetSelected();
else if( aMode == BRIGHTENED )
aItem->SetBrightened();
if( aUsingOverlay && aMode != BRIGHTENED )
view()->Hide( aItem, true ); // Hide the original item, so it is shown only on overlay
if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( aItem ) )
{
boardItem->RunOnDescendants( std::bind( &PCB_TEST_SELECTION_TOOL::highlightInternal, this,
std::placeholders::_1, aMode, aUsingOverlay ) );
}
}
void PCB_TEST_SELECTION_TOOL::unhighlight( EDA_ITEM* aItem, int aMode, SELECTION* aGroup )
{
if( aGroup )
aGroup->Remove( aItem );
unhighlightInternal( aItem, aMode, aGroup != nullptr );
view()->Update( aItem, KIGFX::REPAINT );
// Many selections are very temporal and updating the display each time just creates noise.
if( aMode == BRIGHTENED )
getView()->MarkTargetDirty( KIGFX::TARGET_OVERLAY );
}
void PCB_TEST_SELECTION_TOOL::unhighlightInternal( EDA_ITEM* aItem, int aMode, bool aUsingOverlay )
{
if( aMode == SELECTED )
aItem->ClearSelected();
else if( aMode == BRIGHTENED )
aItem->ClearBrightened();
if( aUsingOverlay && aMode != BRIGHTENED )
{
view()->Hide( aItem, false ); // Restore original item visibility...
view()->Update( aItem ); // ... and make sure it's redrawn un-selected
}
if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( aItem ) )
{
boardItem->RunOnDescendants( std::bind( &PCB_TEST_SELECTION_TOOL::unhighlightInternal, this,
std::placeholders::_1, aMode, aUsingOverlay ) );
}
}
void PCB_TEST_SELECTION_TOOL::highlight( EDA_ITEM* aItem, int aMode, SELECTION* aGroup )
{
if( aGroup )
aGroup->Add( aItem );
highlightInternal( aItem, aMode, aGroup != nullptr );
view()->Update( aItem, KIGFX::REPAINT );
}
void PCB_TEST_SELECTION_TOOL::select( EDA_ITEM* aItem )
{
if( aItem->IsSelected() )
return;
highlight( aItem, SELECTED, &m_selection );
}
void PCB_TEST_SELECTION_TOOL::unselect( EDA_ITEM* aItem )
{
unhighlight( aItem, SELECTED, &m_selection );
}
int PCB_TEST_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
{
// Main loop: keep receiving events
while( TOOL_EVENT* evt = Wait() )
{
if( evt->IsClick( BUT_LEFT ) )
{
selectPoint( evt->Position() );
}
else if( evt->IsCancel() )
{
if( !GetSelection().Empty() )
{
ClearSelection();
}
}
else
{
evt->SetPassEvent();
}
}
// Shutting down; clear the selection
m_selection.Clear();
m_disambiguateTimer.Stop();
return 0;
}
void PCB_TEST_SELECTION_TOOL::SetSelectableItemTypes( const std::vector<KICAD_T> aTypes )
{
m_selectableTypes = aTypes;
}