227 lines
6.4 KiB
C++
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;
|
||
|
}
|