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_design_settings.h>
32 #include <board_item.h>
33 #include <footprint.h>
34 #include <fp_shape.h>
35 #include <pad.h>
36 #include <board_commit.h>
38 #include <tools/pcb_actions.h>
41 #include <tools/edit_tool.h>
43 #include <pad_naming.h>
44 #include <widgets/infobar.h>
45 
47  PCB_TOOL_BASE( "pcbnew.PadTool" ),
48  m_padCopied( false ),
49  m_wasHighContrast( false ),
50  m_editPad( niluuid )
51 {}
52 
53 
55 {}
56 
57 
59 {
60  if( aReason == MODEL_RELOAD )
61  m_lastPadName = wxT( "1" );
62 
63  m_padCopied = false;
65 }
66 
67 
69 {
71 
72  if( selTool )
73  {
74  // Add context menu entries that are displayed when selection tool is active
75  CONDITIONAL_MENU& menu = selTool->GetToolMenu().GetMenu();
76 
80 
81  auto explodeCondition = [&]( const SELECTION& aSel )
82  {
83  return m_editPad == niluuid
84  && aSel.Size() == 1 && aSel[0]->Type() == PCB_PAD_T;
85  };
86 
87  auto recombineCondition = [&]( const SELECTION& aSel )
88  {
89  return m_editPad != niluuid;
90  };
91 
92  menu.AddSeparator( 400 );
93 
95  {
97  menu.AddItem( PCB_ACTIONS::recombinePad, recombineCondition, 400 );
98  menu.AddItem( PCB_ACTIONS::explodePad, explodeCondition, 400 );
99  }
100 
101  menu.AddItem( PCB_ACTIONS::copyPadSettings, singlePadSel, 400 );
102  menu.AddItem( PCB_ACTIONS::applyPadSettings, padSel, 400 );
103  menu.AddItem( PCB_ACTIONS::pushPadSettings, singlePadSel, 400 );
104  }
105 
106  auto& ctxMenu = m_menu.GetMenu();
107 
108  // cancel current tool goes in main context menu at the top if present
110  ctxMenu.AddSeparator( 1 );
111 
117 
118  // Finally, add the standard zoom/grid items
119  getEditFrame<PCB_BASE_FRAME>()->AddStandardSubMenus( m_menu );
120 
121  return true;
122 
123 }
124 
125 
127 {
129  const PCB_SELECTION& selection = selTool->GetSelection();
130  const PAD* masterPad = frame()->GetDesignSettings().m_Pad_Master.get();
131 
132  BOARD_COMMIT commit( frame() );
133 
134  // for every selected pad, paste global settings
135  for( EDA_ITEM* item : selection )
136  {
137  if( item->Type() == PCB_PAD_T )
138  {
139  commit.Modify( item );
140  static_cast<PAD&>( *item ).ImportSettingsFrom( *masterPad );
141  }
142  }
143 
144  commit.Push( _( "Paste Pad Properties" ) );
145 
147  frame()->Refresh();
148 
149  return 0;
150 }
151 
152 
154 {
156  const PCB_SELECTION& selection = selTool->GetSelection();
157 
158  // can only copy from a single pad
159  if( selection.Size() == 1 )
160  {
161  EDA_ITEM* item = selection[0];
162 
163  if( item->Type() == PCB_PAD_T )
164  {
165  const PAD& selPad = static_cast<const PAD&>( *item );
166  frame()->GetDesignSettings().m_Pad_Master->ImportSettingsFrom( selPad );
167  m_padCopied = true;
168  }
169  }
170 
171  return 0;
172 }
173 
174 
175 static void doPushPadProperties( BOARD& board, const PAD& aSrcPad, BOARD_COMMIT& commit,
176  bool aSameFootprints,
177  bool aPadShapeFilter,
178  bool aPadOrientFilter,
179  bool aPadLayerFilter,
180  bool aPadTypeFilter )
181 {
182  const FOOTPRINT* refFootprint = aSrcPad.GetParent();
183 
184  double pad_orient = aSrcPad.GetOrientation() - refFootprint->GetOrientation();
185 
186  for( FOOTPRINT* footprint : board.Footprints() )
187  {
188  if( !aSameFootprints && ( footprint != refFootprint ) )
189  continue;
190 
191  if( footprint->GetFPID() != refFootprint->GetFPID() )
192  continue;
193 
194  for( auto pad : footprint->Pads() )
195  {
196  if( aPadShapeFilter && ( pad->GetShape() != aSrcPad.GetShape() ) )
197  continue;
198 
199  double currpad_orient = pad->GetOrientation() - footprint->GetOrientation();
200 
201  if( aPadOrientFilter && ( currpad_orient != pad_orient ) )
202  continue;
203 
204  if( aPadLayerFilter && ( pad->GetLayerSet() != aSrcPad.GetLayerSet() ) )
205  continue;
206 
207  if( aPadTypeFilter && ( pad->GetAttribute() != aSrcPad.GetAttribute() ) )
208  continue;
209 
210  // Special-case for aperture pads
211  if( aPadTypeFilter && pad->GetAttribute() == PAD_ATTRIB::CONN )
212  {
213  if( pad->IsAperturePad() != aSrcPad.IsAperturePad() )
214  continue;
215  }
216 
217  commit.Modify( pad );
218 
219  // Apply source pad settings to this pad
220  pad->ImportSettingsFrom( aSrcPad );
221  }
222  }
223 }
224 
225 
227 {
229  const PCB_SELECTION& selection = selTool->GetSelection();
230  PAD* srcPad;
231 
232  if( selection.Size() == 1 && selection[0]->Type() == PCB_PAD_T )
233  srcPad = static_cast<PAD*>( selection[0] );
234  else
235  return 0;
236 
237  FOOTPRINT* footprint = srcPad->GetParent();
238 
239  if( !footprint )
240  return 0;
241 
243 
245  int dialogRet = dlg.ShowModal();
246 
247  if( dialogRet == wxID_CANCEL )
248  return 0;
249 
250  const bool edit_Same_Modules = (dialogRet == 1);
251 
252  BOARD_COMMIT commit( frame() );
253 
254  doPushPadProperties( *getModel<BOARD>(), *srcPad, commit, edit_Same_Modules,
259 
260  commit.Push( _( "Push Pad Settings" ) );
261 
263  frame()->Refresh();
264 
265  return 0;
266 }
267 
268 
270 {
271  if( !board()->GetFirstFootprint() || board()->GetFirstFootprint()->Pads().empty() )
272  return 0;
273 
274  DIALOG_ENUM_PADS settingsDlg( frame() );
275 
276  if( settingsDlg.ShowModal() != wxID_OK )
277  return 0;
278 
279  std::string tool = aEvent.GetCommandStr().get();
280  frame()->PushTool( tool );
281  Activate();
282 
283  GENERAL_COLLECTOR collector;
284  const KICAD_T types[] = { PCB_PAD_T, EOT };
285 
287  guide.SetIgnoreMTextsMarkedNoShow( true );
288  guide.SetIgnoreMTextsOnBack( true );
289  guide.SetIgnoreMTextsOnFront( true );
290  guide.SetIgnoreModulesVals( true );
291  guide.SetIgnoreModulesRefs( true );
292 
293  int seqPadNum = settingsDlg.GetStartNumber();
294  wxString padPrefix = settingsDlg.GetPrefix();
295  std::deque<int> storedPadNumbers;
296 
298  getViewControls()->ShowCursor( true );
299 
301  VECTOR2I oldCursorPos; // store the previous mouse cursor position, during mouse drag
302  std::list<PAD*> selectedPads;
303  BOARD_COMMIT commit( frame() );
304  std::map<wxString, std::pair<int, wxString>> oldNames;
305  bool isFirstPoint = true; // used to be sure oldCursorPos will be initialized at least once.
306 
307  STATUS_TEXT_POPUP statusPopup( frame() );
308  wxString msg = _( "Click on pad %s%d\nPress <esc> to cancel or double-click to commit" );
309  statusPopup.SetText( wxString::Format( msg, padPrefix, seqPadNum ) );
310  statusPopup.Popup();
311  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
312 
313  auto setCursor =
314  [&]()
315  {
317  };
318 
319  // Set initial cursor
320  setCursor();
321 
322  while( TOOL_EVENT* evt = Wait() )
323  {
324  setCursor();
325 
326  if( evt->IsCancelInteractive() )
327  {
329  commit.Revert();
330 
331  frame()->PopTool( tool );
332  break;
333  }
334  else if( evt->IsActivate() )
335  {
336  commit.Push( _( "Renumber pads" ) );
337 
338  frame()->PopTool( tool );
339  break;
340  }
341  else if( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
342  {
343  selectedPads.clear();
344  VECTOR2I cursorPos = getViewControls()->GetCursorPosition();
345 
346  // Be sure the old cursor mouse position was initialized:
347  if( isFirstPoint )
348  {
349  oldCursorPos = cursorPos;
350  isFirstPoint = false;
351  }
352 
353  // wxWidgets deliver mouse move events not frequently enough, resulting in skipping
354  // pads if the user moves cursor too fast. To solve it, create a line that approximates
355  // the mouse move and search pads that are on the line.
356  int distance = ( cursorPos - oldCursorPos ).EuclideanNorm();
357  // Search will be made every 0.1 mm:
358  int segments = distance / int( 0.1*IU_PER_MM ) + 1;
359  const wxPoint line_step( ( cursorPos - oldCursorPos ) / segments );
360 
361  collector.Empty();
362 
363  for( int j = 0; j < segments; ++j )
364  {
365  wxPoint testpoint( cursorPos.x - j * line_step.x, cursorPos.y - j * line_step.y );
366  collector.Collect( board(), types, testpoint, guide );
367 
368  for( int i = 0; i < collector.GetCount(); ++i )
369  selectedPads.push_back( static_cast<PAD*>( collector[i] ) );
370  }
371 
372  selectedPads.unique();
373 
374  for( PAD* pad : selectedPads )
375  {
376  // If pad was not selected, then enumerate it
377  if( !pad->IsSelected() )
378  {
379  commit.Modify( pad );
380 
381  // Rename pad and store the old name
382  int newval;
383 
384  if( storedPadNumbers.size() > 0 )
385  {
386  newval = storedPadNumbers.front();
387  storedPadNumbers.pop_front();
388  }
389  else
390  newval = seqPadNum++;
391 
392  wxString newName = wxString::Format( wxT( "%s%d" ), padPrefix, newval );
393  oldNames[newName] = { newval, pad->GetName() };
394  pad->SetName( newName );
395  SetLastPadName( newName );
396  pad->SetSelected();
397  getView()->Update( pad );
398 
399  // Ensure the popup text shows the correct next value
400  if( storedPadNumbers.size() > 0 )
401  newval = storedPadNumbers.front();
402  else
403  newval = seqPadNum;
404 
405  statusPopup.SetText( wxString::Format( msg, padPrefix, newval ) );
406  }
407 
408  // ... or restore the old name if it was enumerated and clicked again
409  else if( pad->IsSelected() && evt->IsClick( BUT_LEFT ) )
410  {
411  auto it = oldNames.find( pad->GetName() );
412  wxASSERT( it != oldNames.end() );
413 
414  if( it != oldNames.end() )
415  {
416  storedPadNumbers.push_back( it->second.first );
417  pad->SetName( it->second.second );
418  SetLastPadName( it->second.second );
419  oldNames.erase( it );
420 
421  int newval = storedPadNumbers.front();
422 
423  statusPopup.SetText( wxString::Format( msg, padPrefix, newval ) );
424  }
425 
426  pad->ClearSelected();
427  getView()->Update( pad );
428  }
429  }
430  }
431  else if( ( evt->IsKeyPressed() && evt->KeyCode() == WXK_RETURN ) ||
432  evt->IsDblClick( BUT_LEFT ) )
433  {
434  commit.Push( _( "Renumber pads" ) );
435  frame()->PopTool( tool );
436  break;
437  }
438  else if( evt->IsClick( BUT_RIGHT ) )
439  {
441  }
442  else
443  {
444  evt->SetPassEvent();
445  }
446 
447  // Prepare the next loop by updating the old cursor mouse position
448  // to this last mouse cursor position
449  oldCursorPos = getViewControls()->GetCursorPosition();
450  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
451  }
452 
453  for( PAD* p : board()->GetFirstFootprint()->Pads() )
454  {
455  p->ClearSelected();
456  view->Update( p );
457  }
458 
459  statusPopup.Hide();
461  return 0;
462 }
463 
464 
465 int PAD_TOOL::PlacePad( const TOOL_EVENT& aEvent )
466 {
467  if( !board()->GetFirstFootprint() )
468  return 0;
469 
470  struct PAD_PLACER : public INTERACTIVE_PLACER_BASE
471  {
472  PAD_PLACER( PAD_TOOL* aPadTool )
473  {
474  m_padTool = aPadTool;
475  }
476 
477  virtual ~PAD_PLACER()
478  {
479  }
480 
481  std::unique_ptr<BOARD_ITEM> CreateItem() override
482  {
483  PAD* pad = new PAD( m_board->GetFirstFootprint() );
484 
485  pad->ImportSettingsFrom( *(m_frame->GetDesignSettings().m_Pad_Master.get()) );
486 
488  {
489  wxString padName = m_padTool->GetLastPadName();
490  padName = m_board->GetFirstFootprint()->GetNextPadName( padName );
491  pad->SetName( padName );
492  m_padTool->SetLastPadName( padName );
493  }
494 
495  return std::unique_ptr<BOARD_ITEM>( pad );
496  }
497 
498  bool PlaceItem( BOARD_ITEM *aItem, BOARD_COMMIT& aCommit ) override
499  {
500  PAD* pad = dynamic_cast<PAD*>( aItem );
501 
502  if( pad )
503  {
504  m_frame->GetDesignSettings().m_Pad_Master->ImportSettingsFrom( *pad );
505  pad->SetLocalCoord();
506  aCommit.Add( aItem );
507  return true;
508  }
509 
510  return false;
511  }
512 
513  PAD_TOOL* m_padTool;
514  };
515 
516  PAD_PLACER placer( this );
517 
518  doInteractiveItemPlacement( aEvent.GetCommandStr().get(), &placer, _( "Place pad" ),
520 
521  return 0;
522 }
523 
524 
525 int PAD_TOOL::EditPad( const TOOL_EVENT& aEvent )
526 {
528  WX_INFOBAR* infoBar = frame()->GetInfoBar();
530  wxString msg;
531 
532  if( m_editPad != niluuid )
533  {
534  PAD* pad = dynamic_cast<PAD*>( frame()->GetItem( m_editPad ) );
535 
536  if( pad )
537  recombinePad( pad );
538 
539  m_editPad = niluuid;
540  }
541  else if( selection.Size() == 1 && selection[0]->Type() == PCB_PAD_T )
542  {
543  PAD* pad = static_cast<PAD*>( selection[0] );
544  PCB_LAYER_ID layer = explodePad( pad );
545 
547  frame()->SetActiveLayer( layer );
548 
549  if( !m_wasHighContrast )
551 
552  if( PCB_ACTIONS::explodePad.GetHotKey() == PCB_ACTIONS::recombinePad.GetHotKey() )
553  {
554  msg.Printf( _( "Pad Edit Mode. Press %s again to exit." ),
556 
557  else
558  {
559  msg.Printf( _( "Pad Edit Mode. Press %s to exit." ),
561  }
562 
563  infoBar->RemoveAllButtons();
564  infoBar->ShowMessage( msg, wxICON_INFORMATION );
565 
566  m_editPad = pad->m_Uuid;
567  }
568 
569  if( m_editPad == niluuid )
570  {
571  bool highContrast = ( opts.m_ContrastModeDisplay != HIGH_CONTRAST_MODE::NORMAL );
572 
573  if( m_wasHighContrast != highContrast )
575 
576  infoBar->Dismiss();
577  }
578 
579  return 0;
580 }
581 
582 
584 {
585  PCB_LAYER_ID layer;
586  BOARD_COMMIT commit( frame() );
587 
588  if( aPad->IsOnLayer( F_Cu ) )
589  layer = F_Cu;
590  else if( aPad->IsOnLayer( B_Cu ) )
591  layer = B_Cu;
592  else
593  layer = *aPad->GetLayerSet().UIOrder();
594 
595  if( aPad->GetShape() == PAD_SHAPE::CUSTOM )
596  {
597  commit.Modify( aPad );
598 
599  for( const std::shared_ptr<PCB_SHAPE>& primitive : aPad->GetPrimitives() )
600  {
601  FP_SHAPE* shape = new FP_SHAPE( board()->GetFirstFootprint() );
602 
603  shape->SetShape( primitive->GetShape() );
604  shape->SetFilled( primitive->IsFilled() );
605  shape->SetWidth( primitive->GetWidth() );
606  shape->SetStart( primitive->GetStart() );
607  shape->SetEnd( primitive->GetEnd() );
608  shape->SetBezControl1( primitive->GetBezControl1() );
609  shape->SetBezControl2( primitive->GetBezControl2() );
610  shape->SetAngle( primitive->GetAngle() );
611  shape->SetPolyShape( primitive->GetPolyShape() );
612  shape->SetLocalCoord();
613  shape->Move( aPad->GetPosition() );
614  shape->Rotate( aPad->GetPosition(), aPad->GetOrientation() );
615  shape->SetLayer( layer );
616 
617  commit.Add( shape );
618  }
619 
620  aPad->SetShape( aPad->GetAnchorPadShape() );
621  aPad->DeletePrimitivesList();
622  m_editPad = aPad->m_Uuid;
623  }
624 
625  commit.Push( _("Edit pad shapes") );
627  return layer;
628 }
629 
630 
632 {
633  int maxError = board()->GetDesignSettings().m_MaxError;
634 
635  auto findNext =
636  [&]( PCB_LAYER_ID aLayer ) -> FP_SHAPE*
637  {
638  SHAPE_POLY_SET padPoly;
639  aPad->TransformShapeWithClearanceToPolygon( padPoly, aLayer, 0, maxError,
640  ERROR_INSIDE );
641 
642  for( BOARD_ITEM* item : board()->GetFirstFootprint()->GraphicalItems() )
643  {
644  PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( item );
645 
646  if( !shape || ( shape->GetEditFlags() & STRUCT_DELETED ) )
647  continue;
648 
649  if( shape->GetLayer() != aLayer )
650  continue;
651 
652  SHAPE_POLY_SET drawPoly;
653  shape->TransformShapeWithClearanceToPolygon( drawPoly, aLayer, 0, maxError,
654  ERROR_INSIDE );
655  drawPoly.BooleanIntersection( padPoly, SHAPE_POLY_SET::PM_FAST );
656 
657  if( !drawPoly.IsEmpty() )
658  return (FP_SHAPE*) item;
659  }
660 
661  return nullptr;
662  };
663 
664  BOARD_COMMIT commit( frame() );
665  PCB_LAYER_ID layer;
666 
667  if( aPad->IsOnLayer( F_Cu ) )
668  layer = F_Cu;
669  else if( aPad->IsOnLayer( B_Cu ) )
670  layer = B_Cu;
671  else
672  layer = *aPad->GetLayerSet().UIOrder();
673 
674  while( FP_SHAPE* fpShape = findNext( layer ) )
675  {
676  commit.Modify( aPad );
677 
678  // We've found an intersecting item. First convert the pad to a custom-shape
679  // pad (if it isn't already)
680  //
681  if( aPad->GetShape() == PAD_SHAPE::RECT || aPad->GetShape() == PAD_SHAPE::CIRCLE )
682  {
683  aPad->SetAnchorPadShape( aPad->GetShape() );
684  }
685  else if( aPad->GetShape() != PAD_SHAPE::CUSTOM )
686  {
687  // Create a new minimally-sized circular anchor and convert existing pad
688  // to a polygon primitive
689  SHAPE_POLY_SET existingOutline;
690  aPad->TransformShapeWithClearanceToPolygon( existingOutline, layer, 0, maxError,
691  ERROR_INSIDE );
692 
694  wxSize minAnnulus( Millimeter2iu( 0.2 ), Millimeter2iu( 0.2 ) );
695  aPad->SetSize( aPad->GetDrillSize() + minAnnulus );
696  aPad->SetOffset( wxPoint( 0, 0 ) );
697 
698  PCB_SHAPE* shape = new PCB_SHAPE;
700  shape->SetFilled( true );
701  shape->SetPolyShape( existingOutline );
702  shape->Move( - aPad->GetPosition() );
703  shape->Rotate( wxPoint( 0, 0 ), - aPad->GetOrientation() );
704 
705  aPad->AddPrimitive( shape );
706  }
707 
708  aPad->SetShape( PAD_SHAPE::CUSTOM );
709 
710  // Now add the new shape to the primitives list
711  //
712  PCB_SHAPE* pcbShape = new PCB_SHAPE;
713 
714  pcbShape->SetShape( fpShape->GetShape() );
715  pcbShape->SetFilled( fpShape->IsFilled() );
716  pcbShape->SetWidth( fpShape->GetWidth() );
717  pcbShape->SetStart( fpShape->GetStart() );
718  pcbShape->SetEnd( fpShape->GetEnd() );
719  pcbShape->SetBezControl1( fpShape->GetBezControl1() );
720  pcbShape->SetBezControl2( fpShape->GetBezControl2() );
721  pcbShape->SetAngle( fpShape->GetAngle() );
722  pcbShape->SetPolyShape( fpShape->GetPolyShape() );
723 
724  pcbShape->Move( - aPad->GetPosition() );
725  pcbShape->Rotate( wxPoint( 0, 0 ), - aPad->GetOrientation() );
726  aPad->AddPrimitive( pcbShape );
727 
728  fpShape->SetFlags( STRUCT_DELETED );
729  commit.Remove( fpShape );
730  }
731 
732  commit.Push(_("Recombine pads") );
733 }
734 
735 
737 {
741 
744 
747 }
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:59
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:134
KIGFX::VIEW * GetView() const
Definition: tool_manager.h:283
void SetOffset(const wxPoint &aOffset)
Definition: pad.h:245
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:384
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Returns the BOARD_DESIGN_SETTINGS for the open project.
KIID niluuid(0)
void SetCurrentCursor(KICURSOR aCursor)
Set the current cursor shape for this panel.
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:80
void DeletePrimitivesList()
Clear the basic shapes list.
void SetBezControl2(const wxPoint &aPoint)
Definition: pcb_shape.h:115
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:192
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:175
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:80
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:547
void SetFilled(bool aFlag)
Definition: pcb_shape.h:73
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:46
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:214
bool IsEmpty() const
static TOOL_ACTION enumeratePads
Tool for quick pad enumeration.
Definition: pcb_actions.h:388
Like smd, does not appear on the solder paste layer (default)
static TOOL_ACTION cancelInteractive
Definition: actions.h:62
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:117
Tool relating to pads and pad settings.
Definition: pad_tool.h:35
double GetOrientation() const
Definition: footprint.h:181
TOOL_MENU & GetToolMenu()
void SetIgnoreModulesRefs(bool ignore)
Definition: collectors.h:553
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:143
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Test to see if this object is on the given layer.
Definition: pad.h:564
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
static TOOL_ACTION placePad
Activation of the drawing tool (placing a PAD)
Definition: pcb_actions.h:382
static TOOL_ACTION mirror
Mirroring of selected items.
Definition: pcb_actions.h:108
class PAD, a pad in a footprint
Definition: typeinfo.h:89
void SetSize(const wxSize &aSize)
Definition: pad.h:228
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:200
bool IsAperturePad() const
Definition: pad.h:375
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:58
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:588
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).
std::unique_ptr< PAD > m_Pad_Master
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:204
polygon (not yet used for tracks, but could be in microwave apps)
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:408
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:115
const wxSize & GetDrillSize() const
Definition: pad.h:239
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:176
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:101
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:346
int pushPadSettings(const TOOL_EVENT &aEvent)
Definition: pad_tool.cpp:226
void SetIgnoreMTextsOnBack(bool ignore)
Definition: collectors.h:505
static TOOL_ACTION copyPadSettings
Copy the selected pad's settings to the board design settings.
Definition: pcb_actions.h:402
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
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:511
void Rotate(const wxPoint &aRotCentre, double aAngle) override
Rotate an edge of the footprint.
Definition: fp_shape.cpp:277
bool PadCanHaveName(const PAD &aPad)
Check if a pad should be named.
Definition: pad_naming.cpp:26
FOOTPRINTS & Footprints()
Definition: board.h:233
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:142
Generic, UI-independent tool event.
Definition: tool_event.h:152
Inactive 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:405
int pastePadProperties(const TOOL_EVENT &aEvent)
Copy pad settings from a pad to the board design settings.
Definition: pad_tool.cpp:126
FOOTPRINT * footprint() const
static TOOL_ACTION recombinePad
Definition: pcb_actions.h:385
KIGFX::PCB_VIEW * view() const
PAD_SHAPE GetShape() const
Definition: pad.h:166
#define STRUCT_DELETED
flag indication structures to be erased
#define _(s)
virtual void Popup(wxWindow *aFocus=nullptr)
HIGH_CONTRAST_MODE m_ContrastModeDisplay
How inactive layers are displayed.
const LIB_ID & GetFPID() const
Definition: footprint.h:185
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: pad.h:365
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.
Create an item immediately on placement starting, otherwise show the pencil cursor until the item is ...
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:158
virtual void SetActiveLayer(PCB_LAYER_ID aLayer)
virtual void Move(const wxPoint &aWhere)
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
void SetIgnoreMTextsMarkedNoShow(bool ignore)
Definition: collectors.h:499
void SetBezControl1(const wxPoint &aPoint)
Definition: pcb_shape.h:112
int EnumeratePads(const TOOL_EVENT &aEvent)
Tool for quick pad enumeration.
Definition: pad_tool.cpp:269
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,...
bool m_isFootprintEditor
void RemoveAllButtons()
Remove all the buttons that have been added by the user.
Definition: infobar.cpp:287
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:583
void AddSeparator(int aOrder=ANY_ORDER)
Add a separator to the menu.
const KIID m_Uuid
Definition: eda_item.h:475
static TOOL_ACTION rotateCcw
Definition: pcb_actions.h:102
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
Definition: pad.cpp:1338
OPT< std::string > GetCommandStr() const
Definition: tool_event.h:455
static TOOL_ACTION flip
Flipping of selected objects.
Definition: pcb_actions.h:105
A modified version of the wxInfoBar class that allows us to:
Definition: infobar.h:73
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:174
void SetStart(const wxPoint &aStart)
Definition: pcb_shape.h:127
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
PAD_ATTRIB GetAttribute() const
Definition: pad.h:368
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:240
~PAD_TOOL()
React to model/view changes.
Definition: pad_tool.cpp:54
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:103
void AddPrimitive(PCB_SHAPE *aPrimitive)
Add item to the custom shape primitives list.
void SetWidth(int aWidth)
Definition: pcb_shape.h:96
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:100
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:77
void Activate()
Run the tool.
void SetShape(PAD_SHAPE aShape)
Set the new shape of this pad.
Definition: pad.h:157
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:54
void SetPolyShape(const SHAPE_POLY_SET &aShape)
Definition: pcb_shape.h:247
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:289
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:631
int EditPad(const TOOL_EVENT &aEvent)
Enter/exit WYSIWYG pad shape editing.
Definition: pad_tool.cpp:525
A general implementation of a COLLECTORS_GUIDE.
Definition: collectors.h:377
Definition: pad.h:57
bool Init() override
Init() is called once upon a registration of the tool.
Definition: pad_tool.cpp:68
int PlacePad(const TOOL_EVENT &aEvent)
Place a pad in footprint editor.
Definition: pad_tool.cpp:465
void SetShape(PCB_SHAPE_TYPE aShape)
Definition: pcb_shape.h:109
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the draw segment to a closed polygon.
LSEQ UIOrder() const
Definition: lset.cpp:895
virtual void SetAngle(double aAngle, bool aUpdateEnd=true)
Set the angle for arcs, and normalizes it within the range 0 - 360 degrees.
Definition: pcb_shape.cpp:477
static constexpr int Millimeter2iu(double mm)
static TOOL_ACTION highContrastMode
Definition: actions.h:103
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:171
void setTransitions() override
< Bind handlers to corresponding TOOL_ACTIONs.
Definition: pad_tool.cpp:736
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:298
PAD_SHAPE GetAnchorPadShape() const
Definition: pad.h:179
void SetText(const wxString &aText)
Display a text.
void SetEnd(const wxPoint &aEnd)
Definition: pcb_shape.h:137
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:1504
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:113
int copyPadSettings(const TOOL_EVENT &aEvent)
Push pad settings from a pad to other pads on board or footprint.
Definition: pad_tool.cpp:153
void SetAnchorPadShape(PAD_SHAPE aShape)
Set the shape of the anchor pad for custom shaped pads.
Definition: pad.h:205