diff --git a/pcbnew/dialogs/dialog_multichannel_repeat_layout.cpp b/pcbnew/dialogs/dialog_multichannel_repeat_layout.cpp index faedf5e303..40caf12a02 100644 --- a/pcbnew/dialogs/dialog_multichannel_repeat_layout.cpp +++ b/pcbnew/dialogs/dialog_multichannel_repeat_layout.cpp @@ -27,6 +27,8 @@ #include #include #include +#include + DIALOG_MULTICHANNEL_REPEAT_LAYOUT::DIALOG_MULTICHANNEL_REPEAT_LAYOUT ( PCB_BASE_FRAME* aFrame, @@ -34,6 +36,7 @@ DIALOG_MULTICHANNEL_REPEAT_LAYOUT::DIALOG_MULTICHANNEL_REPEAT_LAYOUT ( DIALOG_MULTICHANNEL_REPEAT_LAYOUT_BASE( aFrame ), m_parentTool( aParentTool ) { + m_board = aFrame->GetBoard(); auto data = m_parentTool->GetData(); m_refRAName->SetLabelText( data->m_refRA->m_area->GetZoneName() ); @@ -69,6 +72,7 @@ DIALOG_MULTICHANNEL_REPEAT_LAYOUT::DIALOG_MULTICHANNEL_REPEAT_LAYOUT ( m_raGrid->SetColLabelValue( 0, wxT("Copy") ); m_raGrid->SetColLabelValue( 1, wxT("Target Rule Area") ); m_raGrid->SetColLabelValue( 2, wxT("Status") ); + m_raGrid->SetColLabelValue( 3, wxT( "RefFp" ) ); m_raGrid->AutoSizeColumn( 1 ); m_raGrid->AppendRows( m_targetRAs.size() - 1 ); @@ -82,9 +86,19 @@ DIALOG_MULTICHANNEL_REPEAT_LAYOUT::DIALOG_MULTICHANNEL_REPEAT_LAYOUT ( i++; } - m_raGrid->SetMaxSize( wxSize( -1, 800 ) ); + m_raGrid->SetMaxSize( wxSize( -1, 400 ) ); m_raGrid->Fit(); + wxArrayString refFpNames; + refFpNames.push_back( "" ); + + for( FOOTPRINT* fp : data->m_refRA->m_raFootprints ) + refFpNames.push_back( fp->GetReference() ); + + refFpNames.Sort(); + m_refAnchorFp->Set( refFpNames ); + m_refAnchorFp->SetSelection( 0 ); + m_cbCopyPlacement->SetValue( data->m_options.m_copyPlacement ); m_cbCopyRouting->SetValue( data->m_options.m_copyRouting ); m_cbGroupItems->SetValue( data->m_options.m_groupItems ); @@ -117,6 +131,19 @@ bool DIALOG_MULTICHANNEL_REPEAT_LAYOUT::TransferDataFromWindow() data->m_options.m_includeLockedItems = m_cbIncludeLockedComponents->GetValue(); data->m_options.m_moveOffRAComponents = m_cbIncludeOffRAComponents->GetValue(); + if( m_refAnchorFp->GetString( m_refAnchorFp->GetSelection() ) == "" ) + { + data->m_options.m_anchorFp = nullptr; + } + else + { + for( FOOTPRINT* fp : m_board->Footprints() ) + { + if( fp->GetReference() == m_refAnchorFp->GetString( m_refAnchorFp->GetSelection() ) ) + data->m_options.m_anchorFp = fp; + } + } + return true; } diff --git a/pcbnew/dialogs/dialog_multichannel_repeat_layout.fbp b/pcbnew/dialogs/dialog_multichannel_repeat_layout.fbp index 73980a7c94..4080f52542 100644 --- a/pcbnew/dialogs/dialog_multichannel_repeat_layout.fbp +++ b/pcbnew/dialogs/dialog_multichannel_repeat_layout.fbp @@ -47,7 +47,7 @@ 0 wxID_ANY - 800,-1 + -1,-1 DIALOG_MULTICHANNEL_REPEAT_LAYOUT_BASE -1,-1 @@ -61,30 +61,316 @@ OnInitDlg OnUpdateUI - - 800,300 - m_GeneralBoxSizer - wxVERTICAL - private + + 1 + wxBOTH + 0 + 1 + 0 + 600,-1 + fgSizer3 + wxFLEX_GROWMODE_SPECIFIED + none + 0 + 0 + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Target areas: + 0 + + 0 + + + 0 + + 1 + m_staticText4 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + 1 + 1 + + + + 1 + + + wxALIGN_LEFT + + wxALIGN_TOP + 0 + 1 + wxALIGN_CENTER + wxGRID_AUTOSIZE + + wxALIGN_CENTER + 3 + + + 1 + 0 + Dock + 0 + Left + 0 + 0 + 1 + 0 + 1 + 0 + 1 + + 1 + + + 1 + 0 + 0 + wxID_ANY + + + + 0 + 0 + + 0 + -1,-1 + + 0 + -1,-1 + 1 + m_raGrid + 1 + + + protected + 1 + + Resizable + wxALIGN_CENTER + wxGRID_AUTOSIZE + + wxALIGN_CENTER + + 1 + 1 + + ; ; forward_declare + 0 + + + + wxVSCROLL + + 5 wxEXPAND 1 - - 1 - wxBOTH - 0 - 2 - 0 - 800,300 - fgSizer3 - wxFLEX_GROWMODE_SPECIFIED + + + bSizer4 + wxHORIZONTAL + none + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Reference Rule Area: + 0 + + 0 + + + 0 + + 1 + m_staticText1 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + ,90,92,-1,70,0 + 0 + 0 + wxID_ANY + MyLabel + 0 + + 0 + + + 0 + + 1 + m_refRAName + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + + + 5 + wxEXPAND + 1 + + + bSizer41 + wxHORIZONTAL none - 0 - 0 5 - wxALL + wxALIGN_CENTER_VERTICAL|wxALL 0 1 @@ -115,7 +401,7 @@ 0 0 wxID_ANY - Target areas: + Anchor footprint: 0 0 @@ -124,7 +410,7 @@ 0 1 - m_staticText4 + m_staticText2 1 @@ -144,11 +430,11 @@ -1 - + 5 - wxALL|wxEXPAND - 1 - + wxALL + 0 + 1 1 1 @@ -157,25 +443,13 @@ 0 0 - 1 - 1 1 - - - wxALIGN_LEFT - - wxALIGN_TOP 0 + 1 - wxALIGN_CENTER - - - wxALIGN_CENTER - 3 - 1 0 @@ -183,33 +457,21 @@ 0 Left 0 - 1 - 1 - 0 - 1 - 0 1 1 - - 1 0 0 wxID_ANY - - - - 0 - 0 0 - + -1,400 0 1 - m_raGrid + m_refAnchorFp 1 @@ -217,595 +479,460 @@ 1 Resizable - wxALIGN_CENTER - wxGRID_AUTOSIZE - - wxALIGN_CENTER - - 1 + 0 1 + ; ; forward_declare 0 - + Optional, use for precise and/or rotated placement. Select reference rule area footprint, place corresponding target rule area footprint(s). + + wxFILTER_NONE + wxDefaultValidator + - + + + + 5 + wxEXPAND + 1 + + + bSizer13 + wxVERTICAL + none + 5 - wxEXPAND - 1 - + wxALL + 0 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Copy footprint placement + + 0 + + + 0 - bSizer4 - wxHORIZONTAL - none - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - 1 - 1 - 1 - 1 - 0 - - 0 - 0 - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 0 - 1 - - 1 - - 0 - 0 - wxID_ANY - Reference Rule Area: - 0 - - 0 - - - 0 - - 1 - m_staticText1 - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - - - -1 - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - 1 - 1 - 1 - 1 - 0 - - 0 - 0 - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 0 - 1 - - 1 - ,90,92,-1,70,0 - 0 - 0 - wxID_ANY - MyLabel - 0 - - 0 - - - 0 - - 1 - m_refRAName - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - - - -1 - - - - - - 5 - wxEXPAND - 1 - - - bSizer13 - wxVERTICAL - none - - 5 - wxALL - 0 - - 1 - 1 - 1 - 1 - 0 - - 0 - 0 - - - - 1 - 0 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 0 - 1 - - 1 - - 0 - 0 - wxID_ANY - Copy footprint placement - - 0 - - - 0 - - 1 - m_cbCopyPlacement - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - 5 - wxALL - 0 - - 1 - 1 - 1 - 1 - 0 - - 0 - 0 - - - - 1 - 0 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 0 - 1 - - 1 - - 0 - 0 - wxID_ANY - Copy routing - - 0 - - - 0 - - 1 - m_cbCopyRouting - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - 5 - wxALL - 0 - - 1 - 1 - 1 - 1 - 0 - - 0 - 0 - - - - 1 - 0 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 0 - 1 - - 1 - - 0 - 0 - wxID_ANY - Copy other items - - 0 - - - 0 - - 1 - m_cbCopyOtherItems - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - Copy text, shapes, zones, and other items inside the source rule area - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - 5 - wxALL - 0 - - 1 - 1 - 1 - 1 - 0 - - 0 - 0 - - - - 1 - 0 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 0 - 1 - - 1 - - 0 - 1 - wxID_ANY - Include footprints outside the reference rule area - - 0 - - - 0 - - 1 - m_cbIncludeOffRAComponents - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - 5 - wxALL - 0 - - 1 - 1 - 1 - 1 - 0 - - 0 - 0 - - - - 1 - 0 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 0 - 1 - - 1 - - 0 - 0 - wxID_ANY - Group items with their target rule areas - - 0 - - - 0 - - 1 - m_cbGroupItems - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - 5 - wxALL - 0 - - 1 - 1 - 1 - 1 - 0 - - 0 - 0 - - - - 1 - 0 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 0 - 1 - - 1 - - 0 - 0 - wxID_ANY - Remove locked items from target rule areas - - 0 - - - 0 - - 1 - m_cbIncludeLockedComponents - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - + 1 + m_cbCopyPlacement + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + 5 - wxEXPAND|wxLEFT + wxALL 0 - + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Copy routing + + 0 + + + 0 - bottomButtonsSizer - wxHORIZONTAL - none - - 5 - - 0 - - 0 - protected - 10 - - - - 5 - wxEXPAND|wxALL - 1 - - 0 - 1 - 0 - 0 - 0 - 1 - 0 - 0 - - m_sdbSizerStdButtons - protected - - + 1 + m_cbCopyRouting + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Copy other items + + 0 + + + 0 + + 1 + m_cbCopyOtherItems + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + Copy text, shapes, zones, and other items inside the source rule area + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 1 + wxID_ANY + Include footprints outside the reference rule area + + 0 + + + 0 + + 1 + m_cbIncludeOffRAComponents + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Group items with their target rule areas + + 0 + + + 0 + + 1 + m_cbGroupItems + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Remove locked items from target rule areas + + 0 + + + 0 + + 1 + m_cbIncludeLockedComponents + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + 5 + wxEXPAND|wxLEFT + 0 + + + bottomButtonsSizer + wxHORIZONTAL + none + + 5 + + 0 + + 0 + protected + 10 + + + + 5 + wxEXPAND|wxALL + 1 + + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 0 + + m_sdbSizerStdButtons + protected diff --git a/pcbnew/dialogs/dialog_multichannel_repeat_layout.h b/pcbnew/dialogs/dialog_multichannel_repeat_layout.h index 03bd964b17..293d3f9cf0 100644 --- a/pcbnew/dialogs/dialog_multichannel_repeat_layout.h +++ b/pcbnew/dialogs/dialog_multichannel_repeat_layout.h @@ -25,6 +25,7 @@ #define __DIALOG_MULTICHANNEL_REPEAT_LAYOUT__ #include +#include #include #include @@ -54,6 +55,7 @@ private: std::vector m_targetRAs; MULTICHANNEL_TOOL* m_parentTool; + BOARD* m_board; }; #endif diff --git a/pcbnew/dialogs/dialog_multichannel_repeat_layout_base.cpp b/pcbnew/dialogs/dialog_multichannel_repeat_layout_base.cpp index a82324b3b7..3caf6ecb0b 100644 --- a/pcbnew/dialogs/dialog_multichannel_repeat_layout_base.cpp +++ b/pcbnew/dialogs/dialog_multichannel_repeat_layout_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6) +// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -11,24 +11,21 @@ DIALOG_MULTICHANNEL_REPEAT_LAYOUT_BASE::DIALOG_MULTICHANNEL_REPEAT_LAYOUT_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style ) { - this->SetSizeHints( wxSize( 800,-1 ), wxDefaultSize ); + this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize ); - m_GeneralBoxSizer = new wxBoxSizer( wxVERTICAL ); - - m_GeneralBoxSizer->SetMinSize( wxSize( 800,300 ) ); wxFlexGridSizer* fgSizer3; fgSizer3 = new wxFlexGridSizer( 0, 1, 0, 0 ); fgSizer3->AddGrowableCol( 0 ); - fgSizer3->AddGrowableRow( 2 ); + fgSizer3->AddGrowableRow( 1 ); fgSizer3->SetFlexibleDirection( wxBOTH ); fgSizer3->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); - fgSizer3->SetMinSize( wxSize( 800,300 ) ); + fgSizer3->SetMinSize( wxSize( 600,-1 ) ); m_staticText4 = new wxStaticText( this, wxID_ANY, _("Target areas:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText4->Wrap( -1 ); fgSizer3->Add( m_staticText4, 0, wxALL, 5 ); - m_raGrid = new wxGrid( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + m_raGrid = new wxGrid( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL ); // Grid m_raGrid->CreateGrid( 1, 3 ); @@ -39,8 +36,9 @@ DIALOG_MULTICHANNEL_REPEAT_LAYOUT_BASE::DIALOG_MULTICHANNEL_REPEAT_LAYOUT_BASE( // Columns m_raGrid->AutoSizeColumns(); - m_raGrid->EnableDragColMove( true ); + m_raGrid->EnableDragColMove( false ); m_raGrid->EnableDragColSize( true ); + m_raGrid->SetColLabelSize( wxGRID_AUTOSIZE ); m_raGrid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER ); // Rows @@ -71,6 +69,24 @@ DIALOG_MULTICHANNEL_REPEAT_LAYOUT_BASE::DIALOG_MULTICHANNEL_REPEAT_LAYOUT_BASE( fgSizer3->Add( bSizer4, 1, wxEXPAND, 5 ); + wxBoxSizer* bSizer41; + bSizer41 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText2 = new wxStaticText( this, wxID_ANY, _("Anchor footprint:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText2->Wrap( -1 ); + bSizer41->Add( m_staticText2, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxArrayString m_refAnchorFpChoices; + m_refAnchorFp = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_refAnchorFpChoices, 0 ); + m_refAnchorFp->SetSelection( 0 ); + m_refAnchorFp->SetToolTip( _("Optional, use for precise and/or rotated placement.\nSelect reference rule area footprint, place corresponding\ntarget rule area footprint(s).") ); + m_refAnchorFp->SetMaxSize( wxSize( -1,400 ) ); + + bSizer41->Add( m_refAnchorFp, 0, wxALL, 5 ); + + + fgSizer3->Add( bSizer41, 1, wxEXPAND, 5 ); + wxBoxSizer* bSizer13; bSizer13 = new wxBoxSizer( wxVERTICAL ); @@ -118,12 +134,9 @@ DIALOG_MULTICHANNEL_REPEAT_LAYOUT_BASE::DIALOG_MULTICHANNEL_REPEAT_LAYOUT_BASE( fgSizer3->Add( bottomButtonsSizer, 0, wxEXPAND|wxLEFT, 5 ); - m_GeneralBoxSizer->Add( fgSizer3, 1, wxEXPAND, 5 ); - - - this->SetSizer( m_GeneralBoxSizer ); + this->SetSizer( fgSizer3 ); this->Layout(); - m_GeneralBoxSizer->Fit( this ); + fgSizer3->Fit( this ); // Connect Events this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_MULTICHANNEL_REPEAT_LAYOUT_BASE::OnInitDlg ) ); diff --git a/pcbnew/dialogs/dialog_multichannel_repeat_layout_base.h b/pcbnew/dialogs/dialog_multichannel_repeat_layout_base.h index 4e01168cfd..1e0937748c 100644 --- a/pcbnew/dialogs/dialog_multichannel_repeat_layout_base.h +++ b/pcbnew/dialogs/dialog_multichannel_repeat_layout_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6) +// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -31,13 +32,14 @@ class DIALOG_MULTICHANNEL_REPEAT_LAYOUT_BASE : public DIALOG_SHIM { private: - wxBoxSizer* m_GeneralBoxSizer; protected: wxStaticText* m_staticText4; wxGrid* m_raGrid; wxStaticText* m_staticText1; wxStaticText* m_refRAName; + wxStaticText* m_staticText2; + wxChoice* m_refAnchorFp; wxCheckBox* m_cbCopyPlacement; wxCheckBox* m_cbCopyRouting; wxCheckBox* m_cbCopyOtherItems; diff --git a/pcbnew/tools/multichannel_tool.cpp b/pcbnew/tools/multichannel_tool.cpp index 703e40cb3f..315127185a 100644 --- a/pcbnew/tools/multichannel_tool.cpp +++ b/pcbnew/tools/multichannel_tool.cpp @@ -528,7 +528,6 @@ int MULTICHANNEL_TOOL::RepeatLayout( const TOOL_EVENT& aEvent, ZONE* aRefZone ) int totalCopied = 0; BOARD_COMMIT commit( GetManager(), true ); - for( auto& targetArea : m_areas.m_compatMap ) { if( !targetArea.second.m_doCopy ) @@ -541,9 +540,8 @@ int MULTICHANNEL_TOOL::RepeatLayout( const TOOL_EVENT& aEvent, ZONE* aRefZone ) if( !targetArea.second.m_isOk ) continue; - - if( !copyRuleAreaContents( targetArea.second.m_matchingComponents, &commit, m_areas.m_refRA, - targetArea.first, m_areas.m_options, targetArea.second.m_affectedItems, + if( !copyRuleAreaContents( targetArea.second.m_matchingComponents, &commit, m_areas.m_refRA, targetArea.first, + m_areas.m_options, targetArea.second.m_affectedItems, targetArea.second.m_groupableItems ) ) { auto errMsg = wxString::Format( @@ -561,6 +559,7 @@ int MULTICHANNEL_TOOL::RepeatLayout( const TOOL_EVENT& aEvent, ZONE* aRefZone ) return -1; } totalCopied++; + wxSafeYield(); } if( m_areas.m_options.m_groupItems ) @@ -707,10 +706,8 @@ int MULTICHANNEL_TOOL::findRoutedConnections( std::set& } -bool MULTICHANNEL_TOOL::copyRuleAreaContents( TMATCH::COMPONENT_MATCHES& aMatches, - BOARD_COMMIT* aCommit, - RULE_AREA* aRefArea, RULE_AREA* aTargetArea, - REPEAT_LAYOUT_OPTIONS aOpts, +bool MULTICHANNEL_TOOL::copyRuleAreaContents( TMATCH::COMPONENT_MATCHES& aMatches, BOARD_COMMIT* aCommit, + RULE_AREA* aRefArea, RULE_AREA* aTargetArea, REPEAT_LAYOUT_OPTIONS aOpts, std::unordered_set& aAffectedItems, std::unordered_set& aGroupableItems ) { @@ -718,7 +715,29 @@ bool MULTICHANNEL_TOOL::copyRuleAreaContents( TMATCH::COMPONENT_MATCHES& aMatche SHAPE_LINE_CHAIN refOutline = aRefArea->m_area->Outline()->COutline( 0 ); SHAPE_LINE_CHAIN targetOutline = aTargetArea->m_area->Outline()->COutline( 0 ); + FOOTPRINT* targetAnchorFp = nullptr; VECTOR2I disp = aTargetArea->m_center - aRefArea->m_center; + EDA_ANGLE rot = EDA_ANGLE( 0 ); + + if( aOpts.m_anchorFp ) + { + for( auto& fpPair : aMatches ) + { + if( fpPair.first->GetReference() == aOpts.m_anchorFp->GetReference() ) + targetAnchorFp = fpPair.second; + } + + if( targetAnchorFp ) + { + VECTOR2I oldpos = aOpts.m_anchorFp->GetPosition(); + rot = EDA_ANGLE( targetAnchorFp->GetOrientationDegrees() - aOpts.m_anchorFp->GetOrientationDegrees() ); + aOpts.m_anchorFp->Rotate( VECTOR2( 0, 0 ), EDA_ANGLE( rot ) ); + oldpos = aOpts.m_anchorFp->GetPosition(); + VECTOR2I newpos = targetAnchorFp->GetPosition(); + disp = newpos - oldpos; + aOpts.m_anchorFp->Rotate( VECTOR2( 0, 0 ), EDA_ANGLE( -rot ) ); + } + } SHAPE_POLY_SET refPoly; refPoly.AddOutline( refOutline ); @@ -727,6 +746,7 @@ bool MULTICHANNEL_TOOL::copyRuleAreaContents( TMATCH::COMPONENT_MATCHES& aMatche SHAPE_POLY_SET targetPoly; SHAPE_LINE_CHAIN newTargetOutline( refOutline ); + newTargetOutline.Rotate( rot, VECTOR2( 0, 0 ) ); newTargetOutline.Move( disp ); targetPoly.AddOutline( newTargetOutline ); targetPoly.CacheTriangulation( false ); @@ -786,6 +806,7 @@ bool MULTICHANNEL_TOOL::copyRuleAreaContents( TMATCH::COMPONENT_MATCHES& aMatche fixupNet( static_cast( item ), static_cast( copied ), aMatches ); } + copied->Rotate( VECTOR2( 0, 0 ), rot ); copied->Move( disp ); copied->SetParentGroup( nullptr ); const_cast( copied->m_Uuid ) = KIID(); @@ -900,6 +921,7 @@ bool MULTICHANNEL_TOOL::copyRuleAreaContents( TMATCH::COMPONENT_MATCHES& aMatche copied->ClearFlags(); copied->SetParentGroup( nullptr ); const_cast( copied->m_Uuid ) = KIID(); + copied->Rotate( VECTOR2( 0, 0 ), rot ); copied->Move( disp ); aGroupableItems.insert( copied ); aCommit->Add( copied ); @@ -907,11 +929,6 @@ bool MULTICHANNEL_TOOL::copyRuleAreaContents( TMATCH::COMPONENT_MATCHES& aMatche } } - aTargetArea->m_area->RemoveAllContours(); - aTargetArea->m_area->AddPolygon( newTargetOutline ); - aTargetArea->m_area->UnHatchBorder(); - aTargetArea->m_area->HatchBorder(); - if( aOpts.m_copyPlacement ) { for( auto& fpPair : aMatches ) @@ -943,9 +960,9 @@ bool MULTICHANNEL_TOOL::copyRuleAreaContents( TMATCH::COMPONENT_MATCHES& aMatche targetFP->SetLayerAndFlip( refFP->GetLayer() ); targetFP->SetOrientation( refFP->GetOrientation() ); - VECTOR2I targetPos = refFP->GetPosition() + disp; - targetFP->SetPosition( targetPos ); - + targetFP->SetPosition( refFP->GetPosition() ); + targetFP->Rotate( VECTOR2( 0, 0 ), rot ); + targetFP->Move( disp ); for( PCB_FIELD* refField : refFP->GetFields() ) { if( !refField->IsVisible() ) @@ -955,7 +972,9 @@ bool MULTICHANNEL_TOOL::copyRuleAreaContents( TMATCH::COMPONENT_MATCHES& aMatche wxCHECK2( targetField, continue ); targetField->SetAttributes( refField->GetAttributes() ); - targetField->SetPosition( refField->GetPosition() + disp ); + targetField->SetPosition( refField->GetPosition() ); + targetField->Rotate( VECTOR2( 0, 0 ), rot ); + targetField->Move( disp ); targetField->SetIsKnockout( refField->IsKnockout() ); } @@ -964,6 +983,11 @@ bool MULTICHANNEL_TOOL::copyRuleAreaContents( TMATCH::COMPONENT_MATCHES& aMatche } } + aTargetArea->m_area->RemoveAllContours(); + aTargetArea->m_area->AddPolygon( newTargetOutline ); + aTargetArea->m_area->UnHatchBorder(); + aTargetArea->m_area->HatchBorder(); + return true; } diff --git a/pcbnew/tools/multichannel_tool.h b/pcbnew/tools/multichannel_tool.h index 24f7494321..316ceeefbe 100644 --- a/pcbnew/tools/multichannel_tool.h +++ b/pcbnew/tools/multichannel_tool.h @@ -55,6 +55,7 @@ struct REPEAT_LAYOUT_OPTIONS bool m_includeLockedItems = true; bool m_keepOldRouting = false; bool m_copyOnlyMatchingRAShapes = false; + FOOTPRINT* m_anchorFp = nullptr; REPEAT_LAYOUT_EDGE_MODE m_edgeMode = REPEAT_LAYOUT_EDGE_MODE::INSIDE; };