You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

229 lines
6.3 KiB

1 year ago
  1. #include "pcb_test_frame.h"
  2. #include "pcb_test_selection_tool.h"
  3. #include <pcbnew/tools/pcb_actions.h>
  4. #include <tool/actions.h>
  5. #include <tool/tool_manager.h>
  6. PCB_TEST_SELECTION_TOOL::PCB_TEST_SELECTION_TOOL()
  7. : SELECTION_TOOL( "pcbnew.InteractiveSelection" )
  8. {
  9. }
  10. PCB_TEST_SELECTION_TOOL::~PCB_TEST_SELECTION_TOOL()
  11. {
  12. view()->Remove( &m_selection );
  13. }
  14. bool PCB_TEST_SELECTION_TOOL::Init()
  15. {
  16. view()->Remove( &m_selection );
  17. view()->Add( &m_selection );
  18. return true;
  19. }
  20. void PCB_TEST_SELECTION_TOOL::Reset( RESET_REASON aReason )
  21. {
  22. }
  23. void PCB_TEST_SELECTION_TOOL::ClearSelection()
  24. {
  25. if( m_selection.Empty() )
  26. return;
  27. while( m_selection.GetSize() )
  28. unhighlight( m_selection.Front(), SELECTED, &m_selection );
  29. view()->Update( &m_selection );
  30. m_selection.SetIsHover( false );
  31. m_selection.ClearReferencePoint();
  32. }
  33. #include <collectors.h>
  34. const GENERAL_COLLECTORS_GUIDE PCB_TEST_SELECTION_TOOL::getCollectorsGuide() const
  35. {
  36. GENERAL_COLLECTORS_GUIDE guide( board()->GetVisibleLayers(),
  37. (PCB_LAYER_ID) view()->GetTopLayer(), view() );
  38. bool padsDisabled = !board()->IsElementVisible( LAYER_PADS );
  39. // account for the globals
  40. guide.SetIgnoreFPTextOnBack( !board()->IsElementVisible( LAYER_FP_TEXT ) );
  41. guide.SetIgnoreFPTextOnFront( !board()->IsElementVisible( LAYER_FP_TEXT ) );
  42. guide.SetIgnoreFootprintsOnBack( !board()->IsElementVisible( LAYER_FOOTPRINTS_BK ) );
  43. guide.SetIgnoreFootprintsOnFront( !board()->IsElementVisible( LAYER_FOOTPRINTS_FR ) );
  44. guide.SetIgnorePadsOnBack( padsDisabled );
  45. guide.SetIgnorePadsOnFront( padsDisabled );
  46. guide.SetIgnoreThroughHolePads( padsDisabled );
  47. guide.SetIgnoreFPValues( !board()->IsElementVisible( LAYER_FP_VALUES ) );
  48. guide.SetIgnoreFPReferences( !board()->IsElementVisible( LAYER_FP_REFERENCES ) );
  49. guide.SetIgnoreThroughVias( !board()->IsElementVisible( LAYER_VIAS ) );
  50. guide.SetIgnoreBlindBuriedVias( !board()->IsElementVisible( LAYER_VIAS ) );
  51. guide.SetIgnoreMicroVias( !board()->IsElementVisible( LAYER_VIAS ) );
  52. guide.SetIgnoreTracks( !board()->IsElementVisible( LAYER_TRACKS ) );
  53. return guide;
  54. }
  55. bool PCB_TEST_SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere )
  56. {
  57. GENERAL_COLLECTORS_GUIDE guide = getCollectorsGuide();
  58. GENERAL_COLLECTOR collector;
  59. for( auto item : m_selection.Items() )
  60. {
  61. unhighlight( item, SELECTED, &m_selection );
  62. }
  63. m_selection.Clear();
  64. m_selection.ClearReferencePoint();
  65. if( m_selectableTypes.empty() )
  66. collector.Collect( board(), GENERAL_COLLECTOR::AllBoardItems, aWhere, guide );
  67. else
  68. collector.Collect( board(), m_selectableTypes, aWhere, guide );
  69. if( collector.GetCount() > 0 )
  70. {
  71. for( int i = 0; i < collector.GetCount(); ++i )
  72. {
  73. {
  74. select( collector[i] );
  75. }
  76. }
  77. }
  78. m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
  79. if( m_selectionHook )
  80. m_selectionHook( frame(), &m_selection );
  81. return false;
  82. }
  83. void PCB_TEST_SELECTION_TOOL::setTransitions()
  84. {
  85. Go( &PCB_TEST_SELECTION_TOOL::Main, PCB_ACTIONS::selectionActivate.MakeEvent() );
  86. }
  87. void PCB_TEST_SELECTION_TOOL::highlightInternal( EDA_ITEM* aItem, int aMode, bool aUsingOverlay )
  88. {
  89. if( aMode == SELECTED )
  90. aItem->SetSelected();
  91. else if( aMode == BRIGHTENED )
  92. aItem->SetBrightened();
  93. if( aUsingOverlay && aMode != BRIGHTENED )
  94. view()->Hide( aItem, true ); // Hide the original item, so it is shown only on overlay
  95. if( aItem->IsBOARD_ITEM() )
  96. {
  97. BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( aItem );
  98. boardItem->RunOnChildren( std::bind( &PCB_TEST_SELECTION_TOOL::highlightInternal, this, std::placeholders::_1,
  99. aMode, aUsingOverlay ),
  100. RECURSE_MODE::RECURSE );
  101. }
  102. }
  103. void PCB_TEST_SELECTION_TOOL::unhighlight( EDA_ITEM* aItem, int aMode, SELECTION* aGroup )
  104. {
  105. if( aGroup )
  106. aGroup->Remove( aItem );
  107. unhighlightInternal( aItem, aMode, aGroup != nullptr );
  108. view()->Update( aItem, KIGFX::REPAINT );
  109. // Many selections are very temporal and updating the display each time just creates noise.
  110. if( aMode == BRIGHTENED )
  111. getView()->MarkTargetDirty( KIGFX::TARGET_OVERLAY );
  112. }
  113. void PCB_TEST_SELECTION_TOOL::unhighlightInternal( EDA_ITEM* aItem, int aMode, bool aUsingOverlay )
  114. {
  115. if( aMode == SELECTED )
  116. aItem->ClearSelected();
  117. else if( aMode == BRIGHTENED )
  118. aItem->ClearBrightened();
  119. if( aUsingOverlay && aMode != BRIGHTENED )
  120. {
  121. view()->Hide( aItem, false ); // Restore original item visibility...
  122. view()->Update( aItem ); // ... and make sure it's redrawn un-selected
  123. }
  124. if( aItem->IsBOARD_ITEM() )
  125. {
  126. BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( aItem );
  127. boardItem->RunOnChildren( std::bind( &PCB_TEST_SELECTION_TOOL::unhighlightInternal, this, std::placeholders::_1,
  128. aMode, aUsingOverlay ),
  129. RECURSE_MODE::RECURSE );
  130. }
  131. }
  132. void PCB_TEST_SELECTION_TOOL::highlight( EDA_ITEM* aItem, int aMode, SELECTION* aGroup )
  133. {
  134. if( aGroup )
  135. aGroup->Add( aItem );
  136. highlightInternal( aItem, aMode, aGroup != nullptr );
  137. view()->Update( aItem, KIGFX::REPAINT );
  138. }
  139. void PCB_TEST_SELECTION_TOOL::select( EDA_ITEM* aItem )
  140. {
  141. if( aItem->IsSelected() )
  142. return;
  143. highlight( aItem, SELECTED, &m_selection );
  144. }
  145. void PCB_TEST_SELECTION_TOOL::unselect( EDA_ITEM* aItem )
  146. {
  147. unhighlight( aItem, SELECTED, &m_selection );
  148. }
  149. int PCB_TEST_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
  150. {
  151. // Main loop: keep receiving events
  152. while( TOOL_EVENT* evt = Wait() )
  153. {
  154. if( evt->IsClick( BUT_LEFT ) )
  155. {
  156. selectPoint( evt->Position() );
  157. }
  158. else if( evt->IsCancel() )
  159. {
  160. if( !GetSelection().Empty() )
  161. {
  162. ClearSelection();
  163. }
  164. }
  165. else
  166. {
  167. evt->SetPassEvent();
  168. }
  169. }
  170. // Shutting down; clear the selection
  171. m_selection.Clear();
  172. m_disambiguateTimer.Stop();
  173. return 0;
  174. }
  175. void PCB_TEST_SELECTION_TOOL::SetSelectableItemTypes( const std::vector<KICAD_T> aTypes )
  176. {
  177. m_selectableTypes = aTypes;
  178. }