/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2017 Kicad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, you may find one here: * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * or you may search the http://www.gnu.org website for the version 2 license, * or you may write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include #include #include #include // For frame ToolID values #include // For action icons #include #include #include #include #include #include #include #include "ar_autoplacer.h" #include "autoplacer_tool.h" TOOL_ACTION PCB_ACTIONS::autoplaceSelectedComponents( "pcbnew.Autoplacer.autoplaceSelected", AS_GLOBAL, 0, "", _( "Place Selected Footprints" ), _( "Performs automatic placement of selected components" ), module_check_xpm ); TOOL_ACTION PCB_ACTIONS::autoplaceOffboardComponents( "pcbnew.Autoplacer.autoplaceOffboard", AS_GLOBAL, 0, "", _( "Place Off-Board Footprints" ), _( "Performs automatic placement of components outside board area" ), module_xpm ); AUTOPLACE_TOOL::AUTOPLACE_TOOL() : PCB_TOOL_BASE( "pcbnew.Autoplacer" ) { } AUTOPLACE_TOOL::~AUTOPLACE_TOOL() { } // A helper call back function used by autoplace. // It is called by the autoplacer to update the view, when something must be displayed // especially each time a footprint is autoplaced, static PCB_BASE_EDIT_FRAME* fparent; static int refreshCallback( MODULE* aModule ) { if( aModule ) { fparent->GetGalCanvas()->GetView()->Update( aModule ); } fparent->GetGalCanvas()->GetView()->MarkDirty(); fparent->GetGalCanvas()->Refresh(); wxSafeYield(); // Give a slice of time to refresh the display return 0; } int AUTOPLACE_TOOL::autoplace( std::vector& aModules, bool aPlaceOffboard ) { auto overlay = view()->MakeOverlay(); Activate(); AR_AUTOPLACER autoplacer( board() ); BOARD_COMMIT commit( frame() ); autoplacer.SetOverlay( overlay ); fparent = frame(); std::function callback = refreshCallback; autoplacer.SetRefreshCallback( callback ); std::unique_ptr progressReporter( new WX_PROGRESS_REPORTER( frame(), _( "Autoplace Components" ), 1 ) ); autoplacer.SetProgressReporter( progressReporter.get() ); auto result = autoplacer.AutoplaceModules( aModules, &commit, aPlaceOffboard ); if( result == AR_COMPLETED ) commit.Push( _( "Autoplace components" ) ); else commit.Revert(); return 0; } int AUTOPLACE_TOOL::autoplaceSelected( const TOOL_EVENT& aEvent ) { std::vector mods; for( auto item : selection() ) { if( item->Type() == PCB_MODULE_T ) mods.push_back( static_cast( item ) ); } return autoplace( mods, false ); } int AUTOPLACE_TOOL::autoplaceOffboard( const TOOL_EVENT& aEvent ) { std::vector mods; return autoplace( mods, true ); } void AUTOPLACE_TOOL::setTransitions() { Go( &AUTOPLACE_TOOL::autoplaceSelected, PCB_ACTIONS::autoplaceSelectedComponents.MakeEvent() ); Go( &AUTOPLACE_TOOL::autoplaceOffboard, PCB_ACTIONS::autoplaceOffboardComponents.MakeEvent() ); }