KiCad PCB EDA Suite
pad_tool.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2017-2019 KiCad Developers, see AUTHORS.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 
24 
25 #include "pad_tool.h"
26 #include <class_draw_panel_gal.h>
27 #include <view/view_controls.h>
28 #include <view/view.h>
29 #include <tool/tool_manager.h>
30 #include <bitmaps.h>
31 #include <board_item.h>
32 #include <footprint.h>
33 #include <fp_shape.h>
34 #include <board_commit.h>
36 #include <tools/pcb_actions.h>
39 #include <tools/edit_tool.h>
41 #include <pad_naming.h>
42 #include <widgets/infobar.h>
43 
45  PCB_TOOL_BASE( "pcbnew.PadTool" ),
46  m_padCopied( false ),
47  m_wasHighContrast( false ),
48  m_editPad( niluuid )
49 {}
50 
51 
53 {}
54 
55 
57 {
58  if( aReason == MODEL_RELOAD )
59  m_lastPadName = wxT( "1" );
60 
61  m_padCopied = false;
63 }
64 
65 
67 {
69 
70  if( selTool )
71  {
72  // Add context menu entries that are displayed when selection tool is active
73  CONDITIONAL_MENU& menu = selTool->GetToolMenu().GetMenu();
74 
78 
79  auto explodeCondition = [&]( const SELECTION& aSel )
80  {
81  return m_editPad == niluuid
82  && aSel.Size() == 1 && aSel[0]->Type() == PCB_PAD_T;
83  };
84 
85  auto recombineCondition = [&]( const SELECTION& aSel )
86  {
87  return m_editPad != niluuid;
88  };
89 
90  menu.AddSeparator( 400 );
91 
93  {
95  menu.AddItem( PCB_ACTIONS::recombinePad, recombineCondition, 400 );
96  menu.AddItem( PCB_ACTIONS::explodePad, explodeCondition, 400 );
97  }
98 
99  menu.AddItem( PCB_ACTIONS::copyPadSettings, singlePadSel, 400 );
100  menu.AddItem( PCB_ACTIONS::applyPadSettings, padSel, 400 );
101  menu.AddItem( PCB_ACTIONS::pushPadSettings, singlePadSel, 400 );
102  }
103 
104  auto& ctxMenu = m_menu.GetMenu();
105 
106  // cancel current tool goes in main context menu at the top if present
108  ctxMenu.AddSeparator( 1 );
109 
115 
116  // Finally, add the standard zoom/grid items
117  getEditFrame<PCB_BASE_FRAME>()->AddStandardSubMenus( m_menu );
118 
119  return true;
120 
121 }
122 
123 
125 {
127  const PCB_SELECTION& selection = selTool->GetSelection();
128  const PAD& masterPad = frame()->GetDesignSettings().m_Pad_Master;
129 
130  BOARD_COMMIT commit( frame() );
131 
132  // for every selected pad, paste global settings
133  for( EDA_ITEM* item : selection )
134  {
135  if( item->Type() == PCB_PAD_T )
136  {
137  commit.Modify( item );
138  static_cast<PAD&>( *item ).ImportSettingsFrom( masterPad );
139  }
140  }
141 
142  commit.Push( _( "Paste Pad Properties" ) );
143 
145  frame()->Refresh();
146 
147  return 0;
148 }
149 
150 
152 {
154  const PCB_SELECTION& selection = selTool->GetSelection();
155  PAD& masterPad = frame()->GetDesignSettings().m_Pad_Master;
156 
157  // can only copy from a single pad
158  if( selection.Size() == 1 )
159  {
160  EDA_ITEM* item = selection[0];
161 
162  if( item->Type() == PCB_PAD_T )
163  {
164  const PAD& selPad = static_cast<const PAD&>( *item );
165  masterPad.ImportSettingsFrom( selPad );
166  m_padCopied = true;
167  }
168  }
169 
170  return 0;
171 }
172 
173 
174 static void doPushPadProperties( BOARD& board, const PAD& aSrcPad, BOARD_COMMIT& commit,
175  bool aSameFootprints,
176  bool aPadShapeFilter,
177  bool aPadOrientFilter,
178  bool aPadLayerFilter,
179  bool aPadTypeFilter )
180 {
181  const FOOTPRINT* refFootprint = aSrcPad.GetParent();
182 
183  double pad_orient = aSrcPad.GetOrientation() - refFootprint->GetOrientation();
184 
185  for( FOOTPRINT* footprint : board.Footprints() )
186  {
187  if( !aSameFootprints && ( footprint != refFootprint ) )
188  continue;
189 
190  if( footprint->GetFPID() != refFootprint->GetFPID() )
191  continue;
192 
193  for( auto pad : footprint->Pads() )
194  {
195  if( aPadShapeFilter && ( pad->GetShape() != aSrcPad.GetShape() ) )
196  continue;
197 
198  double currpad_orient = pad->GetOrientation() - footprint->GetOrientation();
199 
200  if( aPadOrientFilter && ( currpad_orient != pad_orient ) )
201  continue;
202 
203  if( aPadLayerFilter && ( pad->GetLayerSet() != aSrcPad.GetLayerSet() ) )
204  continue;
205 
206  if( aPadTypeFilter && ( pad->GetAttribute() != aSrcPad.GetAttribute() ) )
207  continue;
208 
209  // Special-case for aperture pads
210  if( aPadTypeFilter && pad->GetAttribute() == PAD_ATTRIB_CONN )
211  {
212  if( pad->IsAperturePad() != aSrcPad.IsAperturePad() )
213  continue;
214  }
215 
216  commit.Modify( pad );
217 
218  // Apply source pad settings to this pad
219  pad->ImportSettingsFrom( aSrcPad );
220  }
221  }
222 }
223 
224 
226 {
228  const PCB_SELECTION& selection = selTool->GetSelection();
229  PAD* srcPad;
230 
231  if( selection.Size() == 1 && selection[0]->Type() == PCB_PAD_T )
232  srcPad = static_cast<PAD*>( selection[0] );
233  else
234  return 0;
235 
236  FOOTPRINT* footprint = srcPad->GetParent();
237 
238  if( !footprint )
239  return 0;
240 
242 
244  int dialogRet = dlg.ShowModal();
245 
246  if( dialogRet == wxID_CANCEL )
247  return 0;
248 
249  const bool edit_Same_Modules = (dialogRet == 1);
250 
251  BOARD_COMMIT commit( frame() );
252 
253  doPushPadProperties( *getModel<BOARD>(), *srcPad, commit, edit_Same_Modules,
258 
259  commit.Push( _( "Push Pad Settings" ) );
260 
262  frame()->Refresh();
263 
264  return 0;
265 }
266 
267 
269 {
270  if( !board()->GetFirstFootprint() || board()->GetFirstFootprint()->Pads().empty() )
271  return 0;
272 
273  DIALOG_ENUM_PADS settingsDlg( frame() );
274 
275  if( settingsDlg.ShowModal() != wxID_OK )
276  return 0;
277 
278  std::string tool = aEvent.GetCommandStr().get();
279  frame()->PushTool( tool );
280  Activate();
281 
282  GENERAL_COLLECTOR collector;
283  const KICAD_T types[] = { PCB_PAD_T, EOT };
284 
286  guide.SetIgnoreMTextsMarkedNoShow( true );
287  guide.SetIgnoreMTextsOnBack( true );
288  guide.SetIgnoreMTextsOnFront( true );
289  guide.SetIgnoreModulesVals( true );
290  guide.SetIgnoreModulesRefs( true );
291 
292  int seqPadNum = settingsDlg.GetStartNumber();
293  wxString padPrefix = settingsDlg.GetPrefix();
294  std::deque<int> storedPadNumbers;
295 
297  getViewControls()->ShowCursor( true );
298 
300  VECTOR2I oldCursorPos; // store the previous mouse cursor position, during mouse drag
301  std::list<PAD*> selectedPads;
302  BOARD_COMMIT commit( frame() );
303  std::map<wxString, std::pair<int, wxString>> oldNames;
304  bool isFirstPoint = true; // used to be sure oldCursorPos will be initialized at least once.
305 
306  STATUS_TEXT_POPUP statusPopup( frame() );
307  wxString msg = _( "Click on pad %s%d\nPress <esc> to cancel or double-click to commit" );
308  statusPopup.SetText( wxString::Format( msg, padPrefix, seqPadNum ) );
309  statusPopup.Popup();
310  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
311 
312  auto setCursor =
313  [&]()
314  {
316  };
317 
318  // Set initial cursor
319  setCursor();
320 
321  while( TOOL_EVENT* evt = Wait() )
322  {
323  setCursor();
324 
325  if( evt->IsCancelInteractive() )
326  {
328  commit.Revert();
329 
330  frame()->PopTool( tool );
331  break;
332  }
333  else if( evt->IsActivate() )
334  {
335  commit.Push( _( "Renumber pads" ) );
336 
337  frame()->PopTool( tool );
338  break;
339  }
340  else if( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
341  {
342  selectedPads.clear();
343  VECTOR2I cursorPos = getViewControls()->GetCursorPosition();
344 
345  // Be sure the old cursor mouse position was initialized:
346  if( isFirstPoint )
347  {
348  oldCursorPos = cursorPos;
349  isFirstPoint = false;
350  }
351 
352  // wxWidgets deliver mouse move events not frequently enough, resulting in skipping
353  // pads if the user moves cursor too fast. To solve it, create a line that approximates
354  // the mouse move and search pads that are on the line.
355  int distance = ( cursorPos - oldCursorPos ).EuclideanNorm();
356  // Search will be made every 0.1 mm:
357  int segments = distance / int( 0.1*IU_PER_MM ) + 1;
358  const wxPoint line_step( ( cursorPos - oldCursorPos ) / segments );
359 
360  collector.Empty();
361 
362  for( int j = 0; j < segments; ++j )
363  {
364  wxPoint testpoint( cursorPos.x - j * line_step.x, cursorPos.y - j * line_step.y );
365  collector.Collect( board(), types, testpoint, guide );
366 
367  for( int i = 0; i < collector.GetCount(); ++i )
368  selectedPads.push_back( static_cast<PAD*>( collector[i] ) );
369  }
370 
371  selectedPads.unique();
372 
373  for( PAD* pad : selectedPads )
374  {
375  // If pad was not selected, then enumerate it
376  if( !pad->IsSelected() )
377  {
378  commit.Modify( pad );
379 
380  // Rename pad and store the old name
381  int newval;
382 
383  if( storedPadNumbers.size() > 0 )
384  {
385  newval = storedPadNumbers.front();
386  storedPadNumbers.pop_front();
387  }
388  else
389  newval = seqPadNum++;
390 
391  wxString newName = wxString::Format( wxT( "%s%d" ), padPrefix, newval );
392  oldNames[newName] = { newval, pad->GetName() };
393  pad->SetName( newName );
394  SetLastPadName( newName );
395  pad->SetSelected();
396  getView()->Update( pad );
397 
398  // Ensure the popup text shows the correct next value
399  if( storedPadNumbers.size() > 0 )
400  newval = storedPadNumbers.front();
401  else
402  newval = seqPadNum;
403 
404  statusPopup.SetText( wxString::Format( msg, padPrefix, newval ) );
405  }
406 
407  // ... or restore the old name if it was enumerated and clicked again
408  else if( pad->IsSelected() && evt->IsClick( BUT_LEFT ) )
409  {
410  auto it = oldNames.find( pad->GetName() );
411  wxASSERT( it != oldNames.end() );
412 
413  if( it != oldNames.end() )
414  {
415  storedPadNumbers.push_back( it->second.first );
416  pad->SetName( it->second.second );
417  SetLastPadName( it->second.second );
418  oldNames.erase( it );
419 
420  int newval = storedPadNumbers.front();
421 
422  statusPopup.SetText( wxString::Format( msg, padPrefix, newval ) );
423  }
424 
425  pad->ClearSelected();
426  getView()->Update( pad );
427  }
428  }
429  }
430  else if( ( evt->IsKeyPressed() && evt->KeyCode() == WXK_RETURN ) ||
431  evt->IsDblClick( BUT_LEFT ) )
432  {
433  commit.Push( _( "Renumber pads" ) );
434  frame()->PopTool( tool );
435  break;
436  }
437  else if( evt->IsClick( BUT_RIGHT ) )
438  {
440  }
441  else
442  {
443  evt->SetPassEvent();
444  }
445 
446  // Prepare the next loop by updating the old cursor mouse position
447  // to this last mouse cursor position
448  oldCursorPos = getViewControls()->GetCursorPosition();
449  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
450  }
451 
452  for( PAD* p : board()->GetFirstFootprint()->Pads() )
453  {
454  p->ClearSelected();
455  view->Update( p );
456  }
457 
458  statusPopup.Hide();
460  return 0;
461 }
462 
463 
464 int PAD_TOOL::PlacePad( const TOOL_EVENT& aEvent )
465 {
466  if( !board()->GetFirstFootprint() )
467  return 0;
468 
469  struct PAD_PLACER : public INTERACTIVE_PLACER_BASE
470  {
471  PAD_PLACER( PAD_TOOL* aPadTool )
472  {
473  m_padTool = aPadTool;
474  }
475 
476  virtual ~PAD_PLACER()
477  {
478  }
479 
480  std::unique_ptr<BOARD_ITEM> CreateItem() override
481  {
482  PAD* pad = new PAD( m_board->GetFirstFootprint() );
483 
484  pad->ImportSettingsFrom( m_frame->GetDesignSettings().m_Pad_Master );
485 
486  if( PAD_NAMING::PadCanHaveName( *pad ) )
487  {
488  wxString padName = m_padTool->GetLastPadName();
489  padName = m_board->GetFirstFootprint()->GetNextPadName( padName );
490  pad->SetName( padName );
491  m_padTool->SetLastPadName( padName );
492  }
493 
494  return std::unique_ptr<BOARD_ITEM>( pad );
495  }
496 
497  bool PlaceItem( BOARD_ITEM *aItem, BOARD_COMMIT& aCommit ) override
498  {
499  PAD* pad = dynamic_cast<PAD*>( aItem );
500 
501  if( pad )
502  {
503  m_frame->GetDesignSettings().m_Pad_Master.ImportSettingsFrom( *pad );
504  pad->SetLocalCoord();
505  aCommit.Add( aItem );
506  return true;
507  }
508 
509  return false;
510  }
511 
512  PAD_TOOL* m_padTool;
513  };
514 
515  PAD_PLACER placer( this );
516 
517  doInteractiveItemPlacement( aEvent.GetCommandStr().get(), &placer, _( "Place pad" ),
519 
520  return 0;
521 }
522 
523 
524 int PAD_TOOL::EditPad( const TOOL_EVENT& aEvent )
525 {
527  WX_INFOBAR* infoBar = frame()->GetInfoBar();
529  wxString msg;
530 
531  if( m_editPad != niluuid )
532  {
533  PAD* pad = dynamic_cast<PAD*>( frame()->GetItem( m_editPad ) );
534 
535  if( pad )
536  recombinePad( pad );
537 
538  m_editPad = niluuid;
539  }
540  else if( selection.Size() == 1 && selection[0]->Type() == PCB_PAD_T )
541  {
542  PAD* pad = static_cast<PAD*>( selection[0] );
543  PCB_LAYER_ID layer = explodePad( pad );
544 
546  frame()->SetActiveLayer( layer );
547 
548  if( !m_wasHighContrast )
550 
551  if( PCB_ACTIONS::explodePad.GetHotKey() == PCB_ACTIONS::recombinePad.GetHotKey() )
552  {
553  msg.Printf( _( "Pad Edit Mode. Press %s again to exit." ),
555 
556  else
557  {
558  msg.Printf( _( "Pad Edit Mode. Press %s to exit." ),
560  }
561 
562  infoBar->RemoveAllButtons();
563  infoBar->ShowMessage( msg, wxICON_INFORMATION );
564 
565  m_editPad = pad->m_Uuid;
566  }
567 
568  if( m_editPad == niluuid )
569  {
570  bool highContrast = ( opts.m_ContrastModeDisplay != HIGH_CONTRAST_MODE::NORMAL );
571 
572  if( m_wasHighContrast != highContrast )
574 
575  infoBar->Dismiss();
576  }
577 
578  return 0;
579 }
580 
581 
583 {
584  PCB_LAYER_ID layer;
585  BOARD_COMMIT commit( frame() );
586 
587  if( aPad->IsOnLayer( F_Cu ) )
588  layer = F_Cu;
589  else if( aPad->IsOnLayer( B_Cu ) )
590  layer = B_Cu;
591  else
592  layer = *aPad->GetLayerSet().UIOrder();
593 
594  if( aPad->GetShape() == PAD_SHAPE_CUSTOM )
595  {
596  commit.Modify( aPad );
597 
598  for( const std::shared_ptr<PCB_SHAPE>& primitive : aPad->GetPrimitives() )
599  {
600  FP_SHAPE* shape = new FP_SHAPE( board()->GetFirstFootprint() );
601 
602  shape->SetShape( primitive->GetShape() );
603  shape->SetFilled( primitive->IsFilled() );
604  shape->SetWidth( primitive->GetWidth() );
605  shape->SetStart( primitive->GetStart() );
606  shape->SetEnd( primitive->GetEnd() );
607  shape->SetBezControl1( primitive->GetBezControl1() );
608  shape->SetBezControl2( primitive->GetBezControl2() );
609  shape->SetAngle( primitive->GetAngle() );
610  shape->SetPolyShape( primitive->GetPolyShape() );
611  shape->SetLocalCoord();
612  shape->Move( aPad->GetPosition() );
613  shape->Rotate( aPad->GetPosition(), aPad->GetOrientation() );
614  shape->SetLayer( layer );
615 
616  commit.Add( shape );
617  }
618 
619  aPad->SetShape( aPad->GetAnchorPadShape() );
620  aPad->DeletePrimitivesList();
621  m_editPad = aPad->m_Uuid;
622  }
623 
624  commit.Push( _("Edit pad shapes") );
626  return layer;
627 }
628 
629 
631 {
632  int maxError = board()->GetDesignSettings().m_MaxError;
633 
634  auto findNext =
635  [&]( PCB_LAYER_ID aLayer ) -> FP_SHAPE*
636  {
637  SHAPE_POLY_SET padPoly;
638  aPad->TransformShapeWithClearanceToPolygon( padPoly, aLayer, 0, maxError,
639  ERROR_INSIDE );
640 
641  for( BOARD_ITEM* item : board()->GetFirstFootprint()->GraphicalItems() )
642  {
643  PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( item );
644 
645  if( !shape || ( shape->GetEditFlags() & STRUCT_DELETED ) )
646  continue;
647 
648  if( shape->GetLayer() != aLayer )
649  continue;
650 
651  SHAPE_POLY_SET drawPoly;
652  shape->TransformShapeWithClearanceToPolygon( drawPoly, aLayer, 0, maxError,
653  ERROR_INSIDE );
654  drawPoly.BooleanIntersection( padPoly, SHAPE_POLY_SET::PM_FAST );
655 
656  if( !drawPoly.IsEmpty() )
657  return (FP_SHAPE*) item;
658  }
659 
660  return nullptr;
661  };
662 
663  BOARD_COMMIT commit( frame() );
664  PCB_LAYER_ID layer;
665 
666  if( aPad->IsOnLayer( F_Cu ) )
667  layer = F_Cu;
668  else if( aPad->IsOnLayer( B_Cu ) )
669  layer = B_Cu;
670  else
671  layer = *aPad->GetLayerSet().UIOrder();
672 
673  while( FP_SHAPE* fpShape = findNext( layer ) )
674  {
675  commit.Modify( aPad );
676 
677  // We've found an intersecting item. First convert the pad to a custom-shape
678  // pad (if it isn't already)
679  //
680  if( aPad->GetShape() == PAD_SHAPE_RECT || aPad->GetShape() == PAD_SHAPE_CIRCLE )
681  {
682  aPad->SetAnchorPadShape( aPad->GetShape() );
683  }
684  else if( aPad->GetShape() != PAD_SHAPE_CUSTOM )
685  {
686  // Create a new minimally-sized circular anchor and convert existing pad
687  // to a polygon primitive
688  SHAPE_POLY_SET existingOutline;
689  aPad->TransformShapeWithClearanceToPolygon( existingOutline, layer, 0, maxError,
690  ERROR_INSIDE );
691 
693  wxSize minAnnulus( Millimeter2iu( 0.2 ), Millimeter2iu( 0.2 ) );
694  aPad->SetSize( aPad->GetDrillSize() + minAnnulus );
695  aPad->SetOffset( wxPoint( 0, 0 ) );
696 
697  PCB_SHAPE* shape = new PCB_SHAPE;
698  shape->SetShape( S_POLYGON );
699  shape->SetFilled( true );
700  shape->SetPolyShape( existingOutline );
701  shape->Move( - aPad->GetPosition() );
702  shape->Rotate( wxPoint( 0, 0 ), - aPad->GetOrientation() );
703 
704  aPad->AddPrimitive( shape );
705  }
706 
707  aPad->SetShape( PAD_SHAPE_CUSTOM );
708 
709  // Now add the new shape to the primitives list
710  //
711  PCB_SHAPE* pcbShape = new PCB_SHAPE;
712 
713  pcbShape->SetShape( fpShape->GetShape() );
714  pcbShape->SetFilled( fpShape->IsFilled() );
715  pcbShape->SetWidth( fpShape->GetWidth() );
716  pcbShape->SetStart( fpShape->GetStart() );
717  pcbShape->SetEnd( fpShape->GetEnd() );
718  pcbShape->SetBezControl1( fpShape->GetBezControl1() );
719  pcbShape->SetBezControl2( fpShape->GetBezControl2() );
720  pcbShape->SetAngle( fpShape->GetAngle() );
721  pcbShape->SetPolyShape( fpShape->GetPolyShape() );
722 
723  pcbShape->Move( - aPad->GetPosition() );
724  pcbShape->Rotate( wxPoint( 0, 0 ), - aPad->GetOrientation() );
725  aPad->AddPrimitive( pcbShape );
726 
727  fpShape->SetFlags( STRUCT_DELETED );
728  commit.Remove( fpShape );
729  }
730 
731  commit.Push(_("Recombine pads") );
732 }
733 
734 
736 {
740 
743 
746 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:148
void Empty()
Clear the list.
Definition: collector.h:95
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:63
virtual void ShowCursor(bool aEnabled)
Enable or disables display of cursor.
static bool ShowAlways(const SELECTION &aSelection)
The default condition function (always returns true).
void ShowMessage(const wxString &aMessage, int aFlags=wxICON_INFORMATION) override
Show the info bar with the provided message and icon.
Definition: infobar.cpp:124
KIGFX::VIEW * GetView() const
Definition: tool_manager.h:289
void SetOffset(const wxPoint &aOffset)
Definition: pad.h:248
COMMIT & Modify(EDA_ITEM *aItem)
Create an undo entry for an item that has been already modified.
Definition: commit.h:103
TOOL_MENU m_menu
The functions below are not yet implemented - their interface may change.
static TOOL_ACTION explodePad
Definition: pcb_actions.h:380
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Returns the BOARD_DESIGN_SETTINGS for the open project.
KIID niluuid(0)
TOOL_EVENT * Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Suspend execution of the tool until an event specified in aEventList arrives.
Handle flip action in the loop by calling the item's flip method.
BOARD * board() const
KIID m_editPad
Definition: pad_tool.h:85
Model changes (required full reload)
Definition: tool_base.h:81
void DeletePrimitivesList()
Clear the basic shapes list.
void SetBezControl2(const wxPoint &aPoint)
Definition: pcb_shape.h:135
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:194
static void doPushPadProperties(BOARD &board, const PAD &aSrcPad, BOARD_COMMIT &commit, bool aSameFootprints, bool aPadShapeFilter, bool aPadOrientFilter, bool aPadLayerFilter, bool aPadTypeFilter)
Definition: pad_tool.cpp:174
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
COMMIT & Add(EDA_ITEM *aItem)
Notify observers that aItem has been added.
Definition: commit.h:78
static constexpr double IU_PER_MM
Mock up a conversion function.
void Collect(BOARD_ITEM *aItem, const KICAD_T aScanList[], const wxPoint &aRefPos, const COLLECTORS_GUIDE &aGuide)
Scan a BOARD_ITEM using this class's Inspector method, which does the collection.
Definition: collectors.cpp:567
void SetIgnoreModulesVals(bool ignore)
Definition: collectors.h:585
void SetFilled(bool aFlag)
Definition: pcb_shape.h:94
Extension of STATUS_POPUP for displaying a single line text.
Definition: status_popup.h:79
virtual void Revert() override
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
CONDITIONAL_MENU & GetMenu()
Definition: tool_menu.cpp:46
PAD_TOOL()
Definition: pad_tool.cpp:44
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
bool IsEmpty() const
static TOOL_ACTION enumeratePads
Tool for quick pad enumeration.
Definition: pcb_actions.h:384
void SetAnchorPadShape(PAD_SHAPE_T aShape)
Set the shape of the anchor pad for custom shaped pads.
Definition: pad.h:208
static TOOL_ACTION cancelInteractive
Definition: actions.h:65
virtual void PushTool(const std::string &actionName)
NB: the definition of "tool" is different at the user level.
static TOOL_ACTION properties
Activation of the edit tool.
Definition: pcb_actions.h:121
polygon (not yet used for tracks, but could be in microwave apps)
Definition: board_item.h:54
void SetName(const wxString &aName)
Set the pad name (sometimes called pad number, although it can be an array reference like AA12).
Definition: pad.h:132
Tool relating to pads and pad settings.
Definition: pad_tool.h:35
double GetOrientation() const
Definition: footprint.h:186
TOOL_MENU & GetToolMenu()
void SetIgnoreModulesRefs(bool ignore)
Definition: collectors.h:591
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:141
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Test to see if this object is on the given layer.
Definition: pad.h:559
static SELECTION_CONDITION HasType(KICAD_T aType)
Create a functor that tests if among the selected items there is at least one of a given type.
bool m_padCopied
Definition: pad_tool.h:82
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.h:591
static TOOL_ACTION placePad
Activation of the drawing tool (placing a PAD)
Definition: pcb_actions.h:378
static TOOL_ACTION mirror
Mirroring of selected items.
Definition: pcb_actions.h:112
class PAD, a pad in a footprint
Definition: typeinfo.h:89
PAD_SHAPE_T GetShape() const
Definition: pad.h:169
void SetSize(const wxSize &aSize)
Definition: pad.h:231
static SELECTION_CONDITION Count(int aNumber)
Create a functor that tests if the number of selected items is equal to the value given as parameter.
virtual void Rotate(const wxPoint &aRotCentre, double aAngle) override
Rotate this object.
Definition: pcb_shape.cpp:197
bool IsAperturePad() const
Definition: pad.h:370
const PCB_DISPLAY_OPTIONS & GetDisplayOptions() const
Display options control the way tracks, vias, outlines and other things are shown (for instance solid...
void Reset(RESET_REASON aReason) override
Basic initialization.
Definition: pad_tool.cpp:56
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Define which state (aStateFunc) to go when a certain event arrives (aConditions).
void SetCurrentCursor(KICURSOR cursor)
Set the current cursor shape for this panel.
search types array terminator (End Of Types)
Definition: typeinfo.h:81
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:77
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:214
PAD_ATTR_T GetAttribute() const
Definition: pad.h:363
void ImportSettingsFrom(const PAD &aMasterPad)
Import the pad settings from aMasterPad.
PCB_BASE_EDIT_FRAME * frame() const
static TOOL_ACTION pushPadSettings
Copy the current pad's settings to other pads in the footprint or on the board.
Definition: pcb_actions.h:404
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:87
PCB_SELECTION & GetSelection()
Return the set of currently selected items.
virtual void Move(const wxPoint &aMoveVector) override
Move this object.
Definition: pcb_shape.cpp:112
const wxSize & GetDrillSize() const
Definition: pad.h:242
Container for display options like enable/disable some optional drawings.
PCB_LAYER_ID
A quick note on layer IDs:
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
Definition: infobar.cpp:166
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const override
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition: pcb_view.cpp:92
GENERAL_COLLECTORS_GUIDE GetCollectorsGuide()
static TOOL_ACTION rotateCw
Rotation of selected objects.
Definition: pcb_actions.h:105
bool m_wasHighContrast
Definition: pad_tool.h:84
const PCB_SELECTION & selection() const
void SetLastPadName(const wxString &aPadName)
Definition: pad_tool.h:63
double GetOrientation() const
Return the rotation angle of the pad in a variety of units (the basic call returns tenths of degrees)...
Definition: pad.h:341
void SetShape(PCB_SHAPE_TYPE_T aShape)
Definition: pcb_shape.h:129
int pushPadSettings(const TOOL_EVENT &aEvent)
Definition: pad_tool.cpp:225
void SetIgnoreMTextsOnBack(bool ignore)
Definition: collectors.h:543
static TOOL_ACTION copyPadSettings
Copy the selected pad's settings to the board design settings.
Definition: pcb_actions.h:398
void SetLocalCoord()
< Set relative coordinates.
Definition: pcbnew/pad.cpp:545
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
STATUS_FLAGS GetEditFlags() const
Definition: eda_item.h:207
Allow repeat placement of the item.
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagate an event to tools that requested events of matching type(s).
Represent a set of closed polygons.
virtual void PopTool(const std::string &actionName)
void SetIgnoreMTextsOnFront(bool ignore)
Definition: collectors.h:549
void Rotate(const wxPoint &aRotCentre, double aAngle) override
Rotate an edge of the footprint.
Definition: fp_shape.cpp:276
bool PadCanHaveName(const PAD &aPad)
Check if a pad should be named.
Definition: pad_naming.cpp:26
FOOTPRINTS & Footprints()
Definition: board.h:303
void SetAngle(double aAngle, bool aUpdateEnd=true) override
Sets the angle for arcs, and normalizes it within the range 0 - 360 degrees.
Definition: fp_shape.cpp:141
Generic, UI-independent tool event.
Definition: tool_event.h:173
Non-active layers are shown normally (no high-contrast mode)
wxString GetPrefix() const
static TOOL_ACTION applyPadSettings
Copy the default pad settings to the selected pad.
Definition: pcb_actions.h:401
int pastePadProperties(const TOOL_EVENT &aEvent)
Copy pad settings from a pad to the board design settings.
Definition: pad_tool.cpp:124
FOOTPRINT * footprint() const
static TOOL_ACTION recombinePad
Definition: pcb_actions.h:381
KIGFX::PCB_VIEW * view() const
virtual void Popup(wxWindow *aFocus=nullptr)
HIGH_CONTRAST_MODE m_ContrastModeDisplay
How inactive layers are displayed.
const LIB_ID & GetFPID() const
Definition: footprint.h:190
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: pad.h:360
COMMIT & Remove(EDA_ITEM *aItem)
Notify observers that aItem has been removed.
Definition: commit.h:90
std::function< bool(const SELECTION &)> SELECTION_CONDITION
< Functor type that checks a specific condition for selected items.
#define STRUCT_DELETED
flag indication structures to be erased
Definition: eda_item.h:115
Create an item immediately on placement starting, otherwise show the pencil cursor until the item is ...
virtual void SetActiveLayer(PCB_LAYER_ID aLayer)
virtual void Move(const wxPoint &aWhere)
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
PAD_SHAPE_T GetAnchorPadShape() const
Definition: pad.h:182
void SetIgnoreMTextsMarkedNoShow(bool ignore)
Definition: collectors.h:537
void SetBezControl1(const wxPoint &aPoint)
Definition: pcb_shape.h:132
void SetShape(PAD_SHAPE_T aShape)
Set the new shape of this pad.
Definition: pad.h:160
int EnumeratePads(const TOOL_EVENT &aEvent)
Tool for quick pad enumeration.
Definition: pad_tool.cpp:268
void BooleanIntersection(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Perform boolean polyset union between a and b, store the result in it self For aFastMode meaning,...
Like smd, does not appear on the solder paste layer (default) note also has a special attribute in Ge...
Definition: pad_shapes.h:82
bool m_isFootprintEditor
void RemoveAllButtons()
Remove all the buttons that have been added by the user.
Definition: infobar.cpp:277
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
PCB_LAYER_ID explodePad(PAD *aPad)
Definition: pad_tool.cpp:582
void AddSeparator(int aOrder=ANY_ORDER)
Add a separator to the menu.
const KIID m_Uuid
Definition: eda_item.h:524
static TOOL_ACTION rotateCcw
Definition: pcb_actions.h:106
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
FOOTPRINT * GetParent() const
OPT< std::string > GetCommandStr() const
Definition: tool_event.h:471
static TOOL_ACTION flip
Flipping of selected objects.
Definition: pcb_actions.h:109
A modified version of the wxInfoBar class that allows us to:
Definition: infobar.h:71
Handle the rotate action in the loop by calling the item's rotate method.
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, int aMaxError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the pad shape to a closed polygon.
wxPoint GetPosition() const override
Definition: pad.h:177
void SetStart(const wxPoint &aStart)
Definition: pcb_shape.h:148
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
#define _(s)
Definition: 3d_actions.cpp:33
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:241
~PAD_TOOL()
React to model/view changes.
Definition: pad_tool.cpp:52
wxString m_lastPadName
Definition: pad_tool.h:81
static SELECTION_CONDITION OnlyType(KICAD_T aType)
Create a functor that tests if the selected items are only of given type.
int Size() const
Returns the number of selected parts.
Definition: selection.h:128
void AddPrimitive(PCB_SHAPE *aPrimitive)
Add item to the custom shape primitives list.
void SetWidth(int aWidth)
Definition: pcb_shape.h:117
The selection tool: currently supports:
static bool empty(const wxTextEntryBase *aCtrl)
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:149
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true, bool aSetDirtyBit=true) override
Revert the commit by restoring the modified items state.
RESET_REASON
Determine the reason of reset for a tool.
Definition: tool_base.h:78
void Activate()
Run the tool.
WX_INFOBAR * GetInfoBar()
wxString KeyNameFromKeyCode(int aKeycode, bool *aIsFound)
Return the key name from the key code.
void SetLocalCoord()
Set relative coordinates from draw coordinates.
Definition: fp_shape.cpp:53
void SetPolyShape(const SHAPE_POLY_SET &aShape)
Definition: pcb_shape.h:276
int GetStartNumber() const
Return common prefix for all enumerated pads.
void Move(const wxPoint &aMoveVector) override
Move an edge of the footprint.
Definition: fp_shape.cpp:288
void doInteractiveItemPlacement(const std::string &aTool, INTERACTIVE_PLACER_BASE *aPlacer, const wxString &aCommitMessage, int aOptions=IPO_ROTATE|IPO_FLIP|IPO_REPEAT)
Helper function for performing a common interactive idiom: wait for a left click, place an item there...
static PCB_SHAPE * findNext(PCB_SHAPE *aShape, const wxPoint &aPoint, const std::vector< PCB_SHAPE * > &aList, unsigned aLimit)
Searches for a PCB_SHAPE matching a given end point or start point in a list.
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:42
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:67
void recombinePad(PAD *aPad)
Definition: pad_tool.cpp:630
int EditPad(const TOOL_EVENT &aEvent)
Enter/exit WYSIWYG pad shape editing.
Definition: pad_tool.cpp:524
A general implementation of a COLLECTORS_GUIDE.
Definition: collectors.h:381
Definition: pad.h:60
bool Init() override
Init() is called once upon a registration of the tool.
Definition: pad_tool.cpp:66
int PlacePad(const TOOL_EVENT &aEvent)
Place a pad in footprint editor.
Definition: pad_tool.cpp:464
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Function TransformShapeWithClearanceToPolygon Convert the draw segment to a closed polygon Used in fi...
LSEQ UIOrder() const
Definition: lset.cpp:895
virtual void SetAngle(double aAngle, bool aUpdateEnd=true)
Sets the angle for arcs, and normalizes it within the range 0 - 360 degrees.
Definition: pcb_shape.cpp:465
static constexpr int Millimeter2iu(double mm)
static TOOL_ACTION highContrastMode
Definition: actions.h:106
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Add a menu entry to run a TOOL_ACTION on selected items.
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:173
void setTransitions() override
< Bind handlers to corresponding TOOL_ACTIONs.
Definition: pad_tool.cpp:735
void ShowContextMenu(SELECTION &aSelection)
Helper function to set and immediately show a CONDITIONAL_MENU in concert with the given SELECTION.
Definition: tool_menu.cpp:59
const std::vector< std::shared_ptr< PCB_SHAPE > > & GetPrimitives() const
Accessor to the basic shape list for custom-shaped pads.
Definition: pad.h:293
void SetText(const wxString &aText)
Display a text.
void SetEnd(const wxPoint &aEnd)
Definition: pcb_shape.h:159
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition: view.cpp:1508
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:162
int copyPadSettings(const TOOL_EVENT &aEvent)
Push pad settings from a pad to other pads on board or footprint.
Definition: pad_tool.cpp:151