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.

129 lines
3.9 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2017-2020 Kicad Developers, see change_log.txt for contributors.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, you may find one here:
  18. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  19. * or you may search the http://www.gnu.org website for the version 2 license,
  20. * or you may write to the Free Software Foundation, Inc.,
  21. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  22. */
  23. #include <board_commit.h>
  24. #include <tools/pcb_actions.h>
  25. #include <widgets/infobar.h>
  26. #include <widgets/progress_reporter.h>
  27. #include "ar_autoplacer.h"
  28. #include "autoplace_tool.h"
  29. AUTOPLACE_TOOL::AUTOPLACE_TOOL() : PCB_TOOL_BASE( "pcbnew.Autoplacer" )
  30. {
  31. }
  32. AUTOPLACE_TOOL::~AUTOPLACE_TOOL()
  33. {
  34. }
  35. // A helper call back function used by autoplace.
  36. // It is called by the autoplacer to update the view, when something must be displayed
  37. // especially each time a footprint is autoplaced,
  38. static PCB_BASE_EDIT_FRAME* fparent;
  39. static int refreshCallback( FOOTPRINT* aFootprint )
  40. {
  41. if( aFootprint )
  42. fparent->GetCanvas()->GetView()->Update( aFootprint );
  43. fparent->GetCanvas()->GetView()->MarkDirty();
  44. fparent->GetCanvas()->Refresh();
  45. wxSafeYield(); // Give a slice of time to refresh the display
  46. return 0;
  47. }
  48. int AUTOPLACE_TOOL::autoplace( std::vector<FOOTPRINT*>& aFootprints, bool aPlaceOffboard )
  49. {
  50. EDA_RECT bbox = board()->GetBoardEdgesBoundingBox();
  51. if( bbox.GetWidth() == 0 || bbox.GetHeight() == 0 )
  52. {
  53. wxString msg = wxString::Format( _( "Board edges must be defined on the %s layer." ),
  54. LayerName( Edge_Cuts ) );
  55. frame()->GetInfoBar()->RemoveAllButtons();
  56. frame()->GetInfoBar()->ShowMessageFor( msg, 5000, wxICON_ERROR );
  57. return 0;
  58. }
  59. Activate();
  60. AR_AUTOPLACER autoplacer( board() );
  61. BOARD_COMMIT commit( frame() );
  62. std::shared_ptr<KIGFX::VIEW_OVERLAY> overlay = view()->MakeOverlay();
  63. autoplacer.SetOverlay( overlay );
  64. fparent = frame();
  65. std::function<int( FOOTPRINT* aFootprint )> callback = refreshCallback;
  66. autoplacer.SetRefreshCallback( callback );
  67. std::unique_ptr<WX_PROGRESS_REPORTER> progressReporter(
  68. new WX_PROGRESS_REPORTER( frame(), _( "Autoplace Components" ), 1 ) );
  69. autoplacer.SetProgressReporter( progressReporter.get() );
  70. auto result = autoplacer.AutoplaceFootprints( aFootprints, &commit, aPlaceOffboard );
  71. if( result == AR_COMPLETED )
  72. commit.Push( _( "Autoplace components" ) );
  73. else
  74. commit.Revert();
  75. return 0;
  76. }
  77. int AUTOPLACE_TOOL::autoplaceSelected( const TOOL_EVENT& aEvent )
  78. {
  79. std::vector<FOOTPRINT*> footprints;
  80. for( EDA_ITEM* item : selection() )
  81. {
  82. if( item->Type() == PCB_FOOTPRINT_T )
  83. footprints.push_back( static_cast<FOOTPRINT*>( item ) );
  84. }
  85. return autoplace( footprints, false );
  86. }
  87. int AUTOPLACE_TOOL::autoplaceOffboard( const TOOL_EVENT& aEvent )
  88. {
  89. std::vector<FOOTPRINT*> footprints;
  90. return autoplace( footprints, true );
  91. }
  92. void AUTOPLACE_TOOL::setTransitions()
  93. {
  94. Go( &AUTOPLACE_TOOL::autoplaceSelected, PCB_ACTIONS::autoplaceSelectedComponents.MakeEvent() );
  95. Go( &AUTOPLACE_TOOL::autoplaceOffboard, PCB_ACTIONS::autoplaceOffboardComponents.MakeEvent() );
  96. }