KiCad PCB EDA Suite
router_tool.cpp
Go to the documentation of this file.
1 /*
2  * KiRouter - a push-and-(sometimes-)shove PCB router
3  *
4  * Copyright (C) 2013-2017 CERN
5  * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
6  * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
7  *
8  * This program is free software: you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation, either version 3 of the License, or (at your
11  * option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include <wx/numdlg.h>
23 
24 #include <core/optional.h>
25 #include <functional>
26 using namespace std::placeholders;
27 
28 #include "class_draw_panel_gal.h"
29 #include "class_board.h"
30 
31 #include <pcb_edit_frame.h>
32 #include <id.h>
33 #include <macros.h>
34 #include <pcbnew_id.h>
35 #include <view/view.h>
36 #include <view/view_controls.h>
37 #include <pcb_layer_widget.h>
38 #include <pcb_painter.h>
42 #include <base_units.h>
43 #include <hotkeys.h>
44 #include <confirm.h>
45 #include <bitmaps.h>
46 #include <collectors.h>
47 
48 #include <tool/context_menu.h>
49 #include <tool/tool_manager.h>
50 #include <tool/tool_settings.h>
51 #include <tool/grid_menu.h>
52 
53 #include <tool/zoom_menu.h>
54 #include <tools/pcb_actions.h>
55 #include <tools/selection_tool.h>
56 #include <tools/edit_tool.h>
57 #include <tools/grid_helper.h>
58 #include <tools/tool_event_utils.h>
59 
60 #include "router_tool.h"
61 #include "pns_segment.h"
62 #include "pns_router.h"
63 
64 using namespace KIGFX;
65 
70 {
71  // Via type
72  VIA_MASK = 0x03,
73  VIA = 0x00,
74  BLIND_VIA = 0x01,
75  MICROVIA = 0x02,
76 
77  // Select layer
79 };
80 
81 
82 TOOL_ACTION PCB_ACTIONS::routerActivateSingle( "pcbnew.InteractiveRouter.SingleTrack",
84  _( "Interactive Router (Single Tracks)" ),
85  _( "Run push & shove router (single tracks)" ), ps_router_xpm, AF_ACTIVATE );
86 
87 TOOL_ACTION PCB_ACTIONS::routerActivateDiffPair( "pcbnew.InteractiveRouter.DiffPair",
89  _( "Interactive Router (Differential Pairs)" ),
90  _( "Run push & shove router (differential pairs)" ), ps_diff_pair_xpm, AF_ACTIVATE );
91 
92 TOOL_ACTION PCB_ACTIONS::routerActivateSettingsDialog( "pcbnew.InteractiveRouter.SettingsDialog",
94  _( "Interactive Router Settings..." ),
95  _( "Open Interactive Router settings" ), tools_xpm );
96 
97 TOOL_ACTION PCB_ACTIONS::routerActivateDpDimensionsDialog( "pcbnew.InteractiveRouter.DpDimensionsDialog",
98  AS_GLOBAL, 0,
99  _( "Differential Pair Dimension Settings..." ),
100  _( "Open Differential Pair Dimension settings" ),
101  ps_diff_pair_gap_xpm );
102 
103 TOOL_ACTION PCB_ACTIONS::routerActivateTuneSingleTrace( "pcbnew.LengthTuner.TuneSingleTrack",
105  _( "Tune length of a single track" ), "", ps_tune_length_xpm, AF_ACTIVATE );
106 
107 TOOL_ACTION PCB_ACTIONS::routerActivateTuneDiffPair( "pcbnew.LengthTuner.TuneDiffPair",
109  _( "Tune length of a differential pair" ), "", NULL, AF_ACTIVATE );
110 
111 TOOL_ACTION PCB_ACTIONS::routerActivateTuneDiffPairSkew( "pcbnew.LengthTuner.TuneDiffPairSkew",
113  _( "Tune skew of a differential pair" ), "", NULL, AF_ACTIVATE );
114 
115 TOOL_ACTION PCB_ACTIONS::routerInlineDrag( "pcbnew.InteractiveRouter.InlineDrag",
116  AS_CONTEXT, 0,
117  _( "Drag Track/Via" ), _( "Drags tracks and vias without breaking connections" ),
118  drag_xpm );
119 
120 TOOL_ACTION PCB_ACTIONS::inlineBreakTrack( "pcbnew.InteractiveRouter.InlineBreakTrack",
121  AS_GLOBAL, 0,
122  _( "Break Track" ),
123  _( "Splits the track segment into two segments connected at the cursor position." ),
124  break_line_xpm );
125 
126 TOOL_ACTION PCB_ACTIONS::breakTrack( "pcbnew.InteractiveRouter.BreakTrack",
127  AS_GLOBAL, 0,
128  _( "Break Track" ),
129  _( "Splits the track segment into two segments connected at the cursor position." ),
130  break_line_xpm );
131 
132 TOOL_ACTION PCB_ACTIONS::drag45Degree( "pcbnew.InteractiveRouter.Drag45Degree",
134  _( "Drag (45 degree mode)" ),
135  _( "Drags the track segment while keeping connected tracks at 45 degrees." ),
136  drag_segment_withslope_xpm );
137 
138 TOOL_ACTION PCB_ACTIONS::dragFreeAngle( "pcbnew.InteractiveRouter.DragFreeAngle",
140  _( "Drag (free angle)" ),
141  _( "Drags the nearest joint in the track without restricting the track angle." ),
142  move_xpm );
143 
144 static const TOOL_ACTION ACT_NewTrack( "pcbnew.InteractiveRouter.NewTrack", AS_CONTEXT,
146  _( "New Track" ), _( "Starts laying a new track." ), add_tracks_xpm );
147 
148 static const TOOL_ACTION ACT_EndTrack( "pcbnew.InteractiveRouter.EndTrack", AS_CONTEXT, WXK_END,
149  _( "End Track" ), _( "Stops laying the current track." ), checked_ok_xpm );
150 
151 static const TOOL_ACTION ACT_AutoEndRoute( "pcbnew.InteractiveRouter.AutoEndRoute", AS_CONTEXT, 'F',
152  _( "Auto-end Track" ), _( "Automagically finishes currently routed track." ) );
153 
154 static const TOOL_ACTION ACT_PlaceThroughVia( "pcbnew.InteractiveRouter.PlaceVia",
156  _( "Place Through Via" ),
157  _( "Adds a through-hole via at the end of currently routed track." ),
158  via_xpm, AF_NONE,
159  (void*) VIA_ACTION_FLAGS::VIA );
160 
161 static const TOOL_ACTION ACT_PlaceBlindVia( "pcbnew.InteractiveRouter.PlaceBlindVia",
163  _( "Place Blind/Buried Via" ),
164  _( "Adds a blind or buried via at the end of currently routed track."),
165  via_buried_xpm, AF_NONE,
166  (void*) VIA_ACTION_FLAGS::BLIND_VIA );
167 
168 static const TOOL_ACTION ACT_PlaceMicroVia( "pcbnew.InteractiveRouter.PlaceMicroVia",
170  _( "Place Microvia" ), _( "Adds a microvia at the end of currently routed track." ),
171  via_microvia_xpm, AF_NONE,
172  (void*) VIA_ACTION_FLAGS::MICROVIA );
173 
175  "pcbnew.InteractiveRouter.SelLayerAndPlaceVia",
177  _( "Select Layer and Place Through Via..." ),
178  _( "Select a layer, then add a through-hole via at the end of currently routed track." ),
179  select_w_layer_xpm, AF_NONE,
181 
183  "pcbnew.InteractiveRouter.SelLayerAndPlaceBlindVia",
185  _( "Select Layer and Place Blind/Buried Via..." ),
186  _( "Select a layer, then add a blind or buried via at the end of currently routed track."),
187  select_w_layer_xpm, AF_NONE,
189 
190 static const TOOL_ACTION ACT_CustomTrackWidth( "pcbnew.InteractiveRouter.CustomTrackViaSize",
192  _( "Custom Track/Via Size..." ),
193  _( "Shows a dialog for changing the track width and via size." ),
194  width_track_xpm );
195 
196 static const TOOL_ACTION ACT_SwitchPosture( "pcbnew.InteractiveRouter.SwitchPosture", AS_CONTEXT,
198  _( "Switch Track Posture" ),
199  _( "Switches posture of the currently routed track." ),
200  change_entry_orient_xpm );
201 
203  TOOL_BASE( "pcbnew.InteractiveRouter" )
204 {
205 }
206 
207 
209 {
210 public:
212  m_frame( aFrame )
213  {
214  SetIcon( width_track_via_xpm );
215  SetTitle( _( "Select Track/Via Width" ) );
216  }
217 
218 protected:
219  CONTEXT_MENU* create() const override
220  {
221  return new TRACK_WIDTH_MENU( m_frame );
222  }
223 
224  void update() override
225  {
226  EDA_UNITS_T units = m_frame.GetUserUnits();
228  bool useIndex = !bds.m_UseConnectedTrackWidth &&
229  !bds.UseCustomTrackViaSize();
230  wxString msg;
231 
232  Clear();
233 
234  Append( ID_POPUP_PCB_SELECT_AUTO_WIDTH, _( "Use Starting Track Width" ),
235  _( "Route using the width of the starting track." ), wxITEM_CHECK );
238 
239  Append( ID_POPUP_PCB_SELECT_USE_NETCLASS_VALUES, _( "Use Net Class Values" ),
240  _( "Use track and via sizes from the net class" ), wxITEM_CHECK );
242  useIndex && bds.GetTrackWidthIndex() == 0 && bds.GetViaSizeIndex() == 0 );
243 
244  Append( ID_POPUP_PCB_SELECT_CUSTOM_WIDTH, _( "Use Custom Values..." ),
245  _( "Specify custom track and via sizes" ), wxITEM_CHECK );
247 
248  AppendSeparator();
249 
250  // Append the list of tracks & via sizes
251  for( unsigned i = 0; i < bds.m_TrackWidthList.size(); i++ )
252  {
253  int width = bds.m_TrackWidthList[i];
254 
255  if( i == 0 )
256  msg = _( "Track netclass width" );
257  else
258  msg.Printf( _( "Track %s" ), MessageTextFromValue( units, width, true ) );
259 
260  int menuIdx = ID_POPUP_PCB_SELECT_WIDTH1 + i;
261  Append( menuIdx, msg, wxEmptyString, wxITEM_CHECK );
262  Check( menuIdx, useIndex && bds.GetTrackWidthIndex() == i );
263  }
264 
265  AppendSeparator();
266 
267  for( unsigned i = 0; i < bds.m_ViasDimensionsList.size(); i++ )
268  {
270 
271  if( i == 0 )
272  msg = _( "Via netclass values" );
273  else
274  {
275  if( via.m_Drill > 0 )
276  msg.Printf( _("Via %s, drill %s" ),
277  MessageTextFromValue( units, via.m_Diameter, true ),
278  MessageTextFromValue( units, via.m_Drill, true ) );
279  else
280  msg.Printf( _( "Via %s" ), MessageTextFromValue( units, via.m_Diameter, true ) );
281  }
282 
283  int menuIdx = ID_POPUP_PCB_SELECT_VIASIZE1 + i;
284  Append( menuIdx, msg, wxEmptyString, wxITEM_CHECK );
285  Check( menuIdx, useIndex && bds.GetViaSizeIndex() == i );
286  }
287  }
288 
289  OPT_TOOL_EVENT eventHandler( const wxMenuEvent& aEvent ) override
290  {
292  int id = aEvent.GetId();
293 
294  // On Windows, this handler can be called with an event ID not existing in any
295  // menuitem, so only set flags when we have an ID match.
296 
298  {
299  bds.UseCustomTrackViaSize( true );
300  bds.m_UseConnectedTrackWidth = false;
302  }
303  else if( id == ID_POPUP_PCB_SELECT_AUTO_WIDTH )
304  {
305  bds.UseCustomTrackViaSize( false );
306  bds.m_UseConnectedTrackWidth = true;
307  }
309  {
310  bds.UseCustomTrackViaSize( false );
311  bds.m_UseConnectedTrackWidth = false;
312  bds.SetViaSizeIndex( 0 );
313  bds.SetTrackWidthIndex( 0 );
314  }
316  {
317  bds.UseCustomTrackViaSize( false );
318  bds.m_UseConnectedTrackWidth = false;
320  }
322  {
323  bds.UseCustomTrackViaSize( false );
324  bds.m_UseConnectedTrackWidth = false;
326  }
327 
328  return OPT_TOOL_EVENT( PCB_ACTIONS::trackViaSizeChanged.MakeEvent() );
329  }
330 
331 private:
333 };
334 
335 
337 {
338 public:
340  m_frame( aFrame )
341  {
342  SetIcon( width_track_via_xpm );
343  SetTitle( _( "Select Differential Pair Dimensions" ) );
344  }
345 
346 protected:
347  CONTEXT_MENU* create() const override
348  {
349  return new DIFF_PAIR_MENU( m_frame );
350  }
351 
352  void update() override
353  {
354  EDA_UNITS_T units = m_frame.GetUserUnits();
356 
357  Clear();
358 
359  Append( ID_POPUP_PCB_SELECT_USE_NETCLASS_DIFFPAIR, _( "Use Net Class Values" ),
360  _( "Use differential pair dimensions from the net class" ), wxITEM_CHECK );
362  !bds.UseCustomDiffPairDimensions() && bds.GetDiffPairIndex() == 0 );
363 
364  Append( ID_POPUP_PCB_SELECT_CUSTOM_DIFFPAIR, _( "Use Custom Values..." ),
365  _( "Specify custom differential pair dimensions" ), wxITEM_CHECK );
367 
368  AppendSeparator();
369 
370  // Append the list of differential pair dimensions
371 
372  // Drop index 0 which is the current netclass dimensions (which are handled above)
373  for( unsigned i = 1; i < bds.m_DiffPairDimensionsList.size(); ++i )
374  {
376  wxString msg;
377 
378  msg << _( "Width " ) << MessageTextFromValue( units, diffPair.m_Width, true );
379 
380  if( diffPair.m_Gap > 0 )
381  msg << _( ", gap " ) << MessageTextFromValue( units, diffPair.m_Gap, true );
382 
383  if( diffPair.m_ViaGap > 0 )
384  msg << _( ", via gap " ) << MessageTextFromValue( units, diffPair.m_ViaGap, true );
385 
386  int menuIdx = ID_POPUP_PCB_SELECT_DIFFPAIR1 + i - 1;
387  Append( menuIdx, msg, wxEmptyString, wxITEM_CHECK );
388  Check( menuIdx, !bds.UseCustomDiffPairDimensions() && bds.GetDiffPairIndex() == i );
389  }
390  }
391 
392  OPT_TOOL_EVENT eventHandler( const wxMenuEvent& aEvent ) override
393  {
395  int id = aEvent.GetId();
396 
397  // On Windows, this handler can be called with an event ID not existing in any
398  // menuitem, so only set flags when we have an ID match.
399 
401  {
402  bds.UseCustomDiffPairDimensions( true );
403  TOOL_MANAGER* toolManager = m_frame.GetToolManager();
405  }
407  {
408  bds.UseCustomDiffPairDimensions( false );
409  bds.SetDiffPairIndex( 0 );
410  }
412  {
413  bds.UseCustomDiffPairDimensions( false );
414  // remember that the menu doesn't contain index 0 (which is the netclass values)
416  }
417 
418  return OPT_TOOL_EVENT( PCB_ACTIONS::trackViaSizeChanged.MakeEvent() );
419  }
420 
421 private:
423 };
424 
425 
427 {
428 public:
430  m_frame( aFrame ), m_mode( aMode ), m_trackViaMenu( aFrame ), m_diffPairMenu( aFrame ),
431  m_zoomMenu( &aFrame ), m_gridMenu( &aFrame )
432  {
433  SetTitle( _( "Interactive Router" ) );
434 
436 
437  AppendSeparator();
438 
439  Add( ACT_NewTrack );
440  Add( ACT_EndTrack );
442 
445 
446 // Add( ACT_AutoEndRoute ); // fixme: not implemented yet. Sorry.
453 
454  AppendSeparator();
455 
456  Add( &m_trackViaMenu );
457 
459  Add( &m_diffPairMenu );
460 
462 
463  AppendSeparator();
464 
465  Add( &m_zoomMenu );
466  Add( &m_gridMenu );
467  }
468 
469 private:
470  CONTEXT_MENU* create() const override
471  {
472  return new ROUTER_TOOL_MENU( m_frame, m_mode );
473  }
474 
481 };
482 
483 
485 {
487 }
488 
489 
491 {
493  return true;
494 }
495 
496 
498 {
499  if( aReason == RUN )
500  TOOL_BASE::Reset( aReason );
501 }
502 
503 
505 {
506 #ifdef DEBUG
507  if( aEvent.IsKeyPressed() )
508  {
509  switch( aEvent.KeyCode() )
510  {
511  case '0':
512  wxLogTrace( "PNS", "saving drag/route log...\n" );
513  m_router->DumpLog();
514  break;
515  }
516  }
517 #endif
518 }
519 
520 
522 {
523  int tl = getView()->GetTopLayer();
524 
525  if( m_startItem )
526  {
527  const LAYER_RANGE& ls = m_startItem->Layers();
528 
529  if( ls.Overlaps( tl ) )
530  return tl;
531  else
532  return ls.Start();
533  }
534 
535  return tl;
536 }
537 
538 
540 {
541  int al = frame()->GetActiveLayer();
542  int cl = m_router->GetCurrentLayer();
543 
544  if( cl != al )
545  {
546  m_router->SwitchLayer( al );
547  }
548 
549  OPT<int> newLayer = m_router->Sizes().PairedLayer( cl );
550 
551  if( !newLayer )
552  newLayer = m_router->Sizes().GetLayerTop();
553 
554  m_router->SwitchLayer( *newLayer );
555  frame()->SetActiveLayer( ToLAYER_ID( *newLayer ) );
556 }
557 
558 
559 static VIATYPE_T getViaTypeFromFlags( int aFlags )
560 {
561  switch( aFlags & VIA_ACTION_FLAGS::VIA_MASK )
562  {
563  case VIA_ACTION_FLAGS::VIA: return VIA_THROUGH;
566  default:
567  wxASSERT_MSG( false, "Unhandled via type" );
568  return VIA_THROUGH;
569  }
570 }
571 
572 
574 {
575  const int actViaFlags = aEvent.Parameter<intptr_t>();
576 
577  VIATYPE_T viaType = getViaTypeFromFlags( actViaFlags );
578  const bool selectLayer = actViaFlags & VIA_ACTION_FLAGS::SELECT_LAYER;
579 
581 
582  const int layerCount = bds.GetCopperLayerCount();
583  int currentLayer = m_router->GetCurrentLayer();
586 
588 
589  // ask the user for a target layer
590  PCB_LAYER_ID targetLayer = UNDEFINED_LAYER;
591 
592  if( selectLayer )
593  {
594  wxPoint dlgPosition = wxGetMousePosition();
595 
596  targetLayer = frame()->SelectLayer( static_cast<PCB_LAYER_ID>( currentLayer ),
597  LSET::AllNonCuMask(), dlgPosition );
598  }
599 
600  // fixme: P&S supports more than one fixed layer pair. Update the dialog?
601  sizes.ClearLayerPairs();
602 
603  if( !m_router->IsPlacingVia() )
604  {
605  // Cannot place microvias or blind vias if not allowed (obvious)
606  if( ( viaType == VIA_BLIND_BURIED ) && ( !bds.m_BlindBuriedViaAllowed ) )
607  {
608  DisplayError( frame(), _( "Blind/buried vias have to be enabled in the design settings." ) );
609  return false;
610  }
611 
612  if( ( viaType == VIA_MICROVIA ) && ( !bds.m_MicroViasAllowed ) )
613  {
614  DisplayError( frame(), _( "Microvias have to be enabled in the design settings." ) );
615  return false;
616  }
617 
618  // Can only place through vias on 2-layer boards
619  if( ( viaType != VIA_THROUGH ) && ( layerCount <= 2 ) )
620  {
621  DisplayError( frame(), _( "Only through vias are allowed on 2 layer boards." ) );
622  return false;
623  }
624 
625  // Can only place microvias if we're on an outer layer, or directly adjacent to one
626  if( ( viaType == VIA_MICROVIA ) && ( currentLayer > In1_Cu ) && ( currentLayer < layerCount - 2 ) )
627  {
628  DisplayError( frame(), _( "Microvias can be placed only between the outer layers " \
629  "(F.Cu/B.Cu) and the ones directly adjacent to them." ) );
630  return false;
631  }
632  }
633 
634  // Convert blind/buried via to a through hole one, if it goes through all layers
635  if( viaType == VIA_BLIND_BURIED && ( ( currentLayer == B_Cu ) || ( currentLayer == F_Cu ) )
636  && ( ( pairTop == B_Cu && pairBottom == F_Cu )
637  || ( pairTop == F_Cu && pairBottom == B_Cu ) ) )
638  {
639  viaType = VIA_THROUGH;
640  }
641 
642  switch( viaType )
643  {
644  case VIA_THROUGH:
645  sizes.SetViaDiameter( bds.GetCurrentViaSize() );
646  sizes.SetViaDrill( bds.GetCurrentViaDrill() );
647 
648  if( targetLayer != UNDEFINED_LAYER )
649  {
650  // go from the current layer to the chosen layer
651  sizes.AddLayerPair( currentLayer, targetLayer );
652  }
653  else
654  {
655  // use the default layer pair
656  sizes.AddLayerPair( pairTop, pairBottom );
657  }
658  break;
659 
660  case VIA_MICROVIA:
661  sizes.SetViaDiameter( bds.GetCurrentMicroViaSize() );
662  sizes.SetViaDrill( bds.GetCurrentMicroViaDrill() );
663 
664  wxASSERT_MSG( !selectLayer, "Unexpected select layer for microvia (microvia layers are implicit)" );
665 
666  if( currentLayer == F_Cu || currentLayer == In1_Cu )
667  {
668  // front-side microvia
669  sizes.AddLayerPair( F_Cu, In1_Cu );
670  }
671  else if( currentLayer == B_Cu || currentLayer == layerCount - 2 )
672  {
673  // back-side microvia
674  sizes.AddLayerPair( B_Cu, layerCount - 2 );
675  }
676  else
677  {
678  wxASSERT_MSG( false, "Invalid layer pair for microvia (must be on or adjacent to an outer layer)" );
679  }
680  break;
681 
682  case VIA_BLIND_BURIED:
683  sizes.SetViaDiameter( bds.GetCurrentViaSize() );
684  sizes.SetViaDrill( bds.GetCurrentViaDrill() );
685 
686  if( targetLayer != UNDEFINED_LAYER )
687  {
688  // go directly to the user specified layer
689  sizes.AddLayerPair( currentLayer, targetLayer );
690  }
691  else
692  {
693  if( currentLayer == pairTop || currentLayer == pairBottom )
694  {
695  // the current layer is on the defined layer pair,
696  // swap to the other side
697  sizes.AddLayerPair( pairTop, pairBottom );
698  }
699  else
700  {
701  // the current layer is not part of the current layer pair,
702  // so fallback and swap to the top layer of the pair by default
703  sizes.AddLayerPair( pairTop, currentLayer );
704  }
705  }
706  break;
707 
708  default:
709  wxASSERT( false );
710  break;
711  }
712 
713  sizes.SetViaType( viaType );
714 
715  m_router->UpdateSizes( sizes );
717 
718  if( m_router->RoutingInProgress() )
719  updateEndItem( aEvent );
720  else
721  updateStartItem( aEvent );
722 
723  m_router->Move( m_endSnapPoint, m_endItem ); // refresh
724 
725  return 0;
726 }
727 
728 
730 {
731  int routingLayer = getStartLayer( m_startItem );
732 
733  if( !IsCopperLayer( routingLayer ) )
734  {
735  DisplayError( frame(), _( "Tracks on Copper layers only" ) );
736  return false;
737  }
738 
739  frame()->SetActiveLayer( ToLAYER_ID( routingLayer ) );
740 
741  // Force layer visible
742  frame()->GetLayerManager()->SetLayerVisible( routingLayer, true );
743 
744  // for some reason I don't understand, GetNetclass() may return null sometimes...
745  if( m_startItem && m_startItem->Net() >= 0 &&
747  {
748  highlightNet( true, m_startItem->Net() );
749  // Update track width and via size shown in main toolbar comboboxes
750  frame()->SetCurrentNetClass( m_startItem->Parent()->GetNetClass()->GetName() );
751  }
752  else
754 
755  controls()->ForceCursorPosition( false );
756  controls()->SetAutoPan( true );
757 
758  PNS::SIZES_SETTINGS sizes( m_router->Sizes() );
759 
760  sizes.Init( board(), m_startItem );
761  sizes.AddLayerPair( frame()->GetScreen()->m_Route_Layer_TOP,
762  frame()->GetScreen()->m_Route_Layer_BOTTOM );
763  m_router->UpdateSizes( sizes );
764 
765  if( !m_router->StartRouting( m_startSnapPoint, m_startItem, routingLayer ) )
766  {
768  highlightNet( false );
769  controls()->SetAutoPan( false );
770  return false;
771  }
772 
773  m_endItem = NULL;
775 
776  frame()->UndoRedoBlock( true );
777 
778  return true;
779 }
780 
781 
783 {
785 
786  controls()->SetAutoPan( false );
787  controls()->ForceCursorPosition( false );
788  frame()->UndoRedoBlock( false );
789  highlightNet( false );
790 
791  return true;
792 }
793 
794 
796 {
797  if( !prepareInteractive() )
798  return;
799 
800  while( OPT_TOOL_EVENT evt = Wait() )
801  {
802  // Don't crash if we missed an operation that cancelled routing.
803  wxCHECK2( m_router->RoutingInProgress(), break );
804 
805  handleCommonEvents( *evt );
806 
807  if( evt->IsMotion() )
808  {
809  m_router->SetOrthoMode( evt->Modifier( MD_CTRL ) );
810  updateEndItem( *evt );
812  }
813  else if( evt->IsClick( BUT_LEFT ) || evt->IsAction( &ACT_NewTrack ) )
814  {
815  updateEndItem( *evt );
816  bool needLayerSwitch = m_router->IsPlacingVia();
817  bool forceFinish = evt->Modifier( MD_SHIFT );
818 
819 
820  if( m_router->FixRoute( m_endSnapPoint, m_endItem, forceFinish ) )
821  break;
822 
823  if( needLayerSwitch )
825 
826  // Synchronize the indicated layer
828  updateEndItem( *evt );
830  m_startItem = NULL;
831  }
832  else if( evt->IsAction( &ACT_SwitchPosture ) )
833  {
835  updateEndItem( *evt );
836  m_router->Move( m_endSnapPoint, m_endItem ); // refresh
837  }
838  else if( evt->IsAction( &PCB_ACTIONS::layerChanged ) )
839  {
840  m_router->SwitchLayer( frame()->GetActiveLayer() );
841  updateEndItem( *evt );
842  m_router->Move( m_endSnapPoint, m_endItem ); // refresh
843  }
844  else if( evt->IsAction( &ACT_EndTrack ) )
845  {
846  bool still_routing = true;
847  while( still_routing )
848  still_routing = m_router->FixRoute( m_endSnapPoint, m_endItem );
849  break;
850  }
851  else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt )
852  || evt->IsUndoRedo()
853  || evt->IsAction( &PCB_ACTIONS::routerInlineDrag ) )
854  break;
855  }
856 
858 }
859 
860 
862 {
864  DIALOG_PNS_DIFF_PAIR_DIMENSIONS settingsDlg( frame(), sizes );
865 
866  if( settingsDlg.ShowModal() == wxID_OK )
867  {
868  m_router->UpdateSizes( sizes );
869  m_savedSizes = sizes;
870 
872  bds.SetCustomDiffPairWidth( sizes.DiffPairWidth() );
873  bds.SetCustomDiffPairGap( sizes.DiffPairGap() );
875  }
876 
877  return 0;
878 }
879 
880 
882 {
883  DIALOG_PNS_SETTINGS settingsDlg( frame(), m_router->Settings() );
884 
885  if( settingsDlg.ShowModal() == wxID_OK )
887 
888  return 0;
889 }
890 
891 
893 {
900 
906 
909 }
910 
911 
913 {
914  frame()->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Route Track" ) );
916 }
917 
918 
920 {
921  frame()->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Router Differential Pair" ) );
923 }
924 
925 
927 {
929  {
931  }
932 }
933 
934 
936 {
937  PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>();
938 
939  // Deselect all items
941 
942  Activate();
943 
944  m_router->SetMode( aMode );
945 
946  VIEW_CONTROLS* ctls = getViewControls();
947  ctls->ShowCursor( true );
948  ctls->ForceCursorPosition( false );
950 
951  std::unique_ptr<ROUTER_TOOL_MENU> ctxMenu( new ROUTER_TOOL_MENU( *frame, aMode ) );
952  SetContextMenu( ctxMenu.get() );
953 
954  // Main loop: keep receiving events
955  while( OPT_TOOL_EVENT evt = Wait() )
956  {
958  {
959  break; // Finish
960  }
961  else if( evt->Action() == TA_UNDO_REDO_PRE )
962  {
963  m_router->ClearWorld();
964  }
965  else if( evt->Action() == TA_UNDO_REDO_POST || evt->Action() == TA_MODEL_CHANGE )
966  {
967  m_router->SyncWorld();
968  }
969  else if( evt->IsMotion() )
970  {
971  updateStartItem( *evt );
972  }
973  else if( evt->IsAction( &PCB_ACTIONS::dragFreeAngle ) )
974  {
975  updateStartItem( *evt, true );
977  }
978  else if( evt->IsAction( &PCB_ACTIONS::drag45Degree ) )
979  {
980  updateStartItem( *evt, true );
982  }
983  else if( evt->IsAction( &PCB_ACTIONS::breakTrack ) )
984  {
985  updateStartItem( *evt, true );
986  breakTrack( );
987  }
988  else if( evt->IsClick( BUT_LEFT ) || evt->IsAction( &ACT_NewTrack ) )
989  {
990  updateStartItem( *evt );
991 
992  if( evt->Modifier( MD_CTRL ) )
994  else
995  performRouting();
996  }
997  else if( evt->IsAction( &ACT_PlaceThroughVia ) )
998  {
1000  }
1001  }
1002 
1004  SetContextMenu( nullptr );
1005 
1006  // Store routing settings till the next invocation
1009 
1010  return 0;
1011 }
1012 
1013 
1015 {
1016  VIEW_CONTROLS* ctls = getViewControls();
1017 
1018  if( m_startItem && m_startItem->IsLocked() )
1019  {
1020  KIDIALOG dlg( frame(), _( "The selected item is locked." ), _( "Confirmation" ),
1021  wxOK | wxCANCEL | wxICON_WARNING );
1022  dlg.SetOKLabel( _( "Drag Anyway" ) );
1023  dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
1024 
1025  if( dlg.ShowModal() == wxID_CANCEL )
1026  return;
1027  }
1028 
1029  m_gridHelper->SetAuxAxes( true, m_startSnapPoint, true );
1030  bool dragStarted = m_router->StartDragging( m_startSnapPoint, m_startItem, aMode );
1031 
1032  if( !dragStarted )
1033  return;
1034 
1035  if( m_startItem && m_startItem->Net() >= 0 )
1036  highlightNet( true, m_startItem->Net() );
1037 
1038  ctls->SetAutoPan( true );
1039 
1040  frame()->UndoRedoBlock( true );
1041 
1042  while( OPT_TOOL_EVENT evt = Wait() )
1043  {
1044  ctls->ForceCursorPosition( false );
1045 
1046  if( evt->IsMotion() )
1047  {
1048  updateEndItem( *evt );
1050  }
1051  else if( evt->IsClick( BUT_LEFT ) )
1052  {
1054  break;
1055  }
1056  else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsUndoRedo() )
1057  {
1058  break;
1059  }
1060 
1061  handleCommonEvents( *evt );
1062  }
1063 
1064  if( m_router->RoutingInProgress() )
1065  m_router->StopRouting();
1066 
1067  m_startItem = nullptr;
1068 
1069  frame()->UndoRedoBlock( false );
1070  ctls->SetAutoPan( false );
1071  ctls->ForceCursorPosition( false );
1072  highlightNet( false );
1073 }
1074 
1075 
1077 {
1078  /*
1079  * If the collection contains a trivial line corner (two connected segments)
1080  * or a non-fanout-via (a via with no more than two connected segments), then
1081  * trim the collection down to a single item (which one won't matter since
1082  * they're all connected).
1083  */
1084 
1085  // First make sure we've got something that *might* match.
1086  int vias = aCollector.CountType( PCB_VIA_T );
1087  int traces = aCollector.CountType( PCB_TRACE_T );
1088 
1089  if( vias > 1 || traces > 2 || vias + traces < 1 )
1090  return;
1091 
1092  // Fetch first TRACK (via or trace) as our reference
1093  TRACK* reference = nullptr;
1094 
1095  for( int i = 0; !reference && i < aCollector.GetCount(); i++ )
1096  reference = dynamic_cast<TRACK*>( aCollector[i] );
1097 
1098  int refNet = reference->GetNetCode();
1099 
1100  wxPoint refPoint( aPt.x, aPt.y );
1101  STATUS_FLAGS flags = reference->IsPointOnEnds( refPoint, -1 );
1102 
1103  if( flags & STARTPOINT )
1104  refPoint = reference->GetStart();
1105  else if( flags & ENDPOINT )
1106  refPoint = reference->GetEnd();
1107 
1108  // Check all items to ensure that any TRACKs are co-terminus with the reference and on
1109  // the same net.
1110  for( int i = 0; i < aCollector.GetCount(); i++ )
1111  {
1112  TRACK* neighbor = dynamic_cast<TRACK*>( aCollector[i] );
1113 
1114  if( neighbor && neighbor != reference )
1115  {
1116  if( neighbor->GetNetCode() != refNet )
1117  return;
1118 
1119  if( neighbor->GetStart() != refPoint && neighbor->GetEnd() != refPoint )
1120  return;
1121  }
1122  }
1123 
1124  // Selection meets criteria; trim it to the reference item.
1125  aCollector.Empty();
1126  aCollector.Append( reference );
1127 }
1128 
1129 
1131 {
1133  const auto& selection = m_toolMgr->GetTool<SELECTION_TOOL>()->GetSelection();
1134 
1135  if( selection.Size() == 1 )
1136  {
1137  const BOARD_CONNECTED_ITEM* item = static_cast<const BOARD_CONNECTED_ITEM*>( selection.Front() );
1138 
1139  if( item->Type() == PCB_TRACE_T || item->Type() == PCB_VIA_T )
1140  return true;
1141  }
1142 
1143  return false;
1144 }
1145 
1146 
1148 {
1149  const auto& selection = m_toolMgr->GetTool<SELECTION_TOOL>()->GetSelection();
1150 
1151  if( selection.Empty() )
1153 
1154  if( selection.Size() != 1 )
1155  return 0;
1156 
1157  const BOARD_CONNECTED_ITEM* item = static_cast<const BOARD_CONNECTED_ITEM*>( selection.Front() );
1158 
1159  if( item->Type() != PCB_TRACE_T && item->Type() != PCB_VIA_T )
1160  return 0;
1161 
1162  Activate();
1163 
1165  m_router->SyncWorld();
1167 
1168  if( m_startItem && m_startItem->IsLocked() )
1169  {
1170  KIDIALOG dlg( frame(), _( "The selected item is locked." ), _( "Confirmation" ),
1171  wxOK | wxCANCEL | wxICON_WARNING );
1172  dlg.SetOKLabel( _( "Drag Anyway" ) );
1173  dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
1174 
1175  if( dlg.ShowModal() == wxID_CANCEL )
1176  return 0;
1177  }
1178 
1179  VECTOR2I p0 = controls()->GetCursorPosition( false );
1180  auto p = snapToItem( true, m_startItem, p0 );
1181  m_gridHelper->SetAuxAxes( true, p, true );
1182  int dragMode = aEvent.Parameter<int64_t> ();
1183 
1184  bool dragStarted = m_router->StartDragging( p, m_startItem, dragMode );
1185 
1186  if( !dragStarted )
1187  return 0;
1188 
1189  controls()->ShowCursor( true );
1190  controls()->ForceCursorPosition( false );
1191  controls()->SetAutoPan( true );
1192  frame()->UndoRedoBlock( true );
1193 
1194  while( OPT_TOOL_EVENT evt = Wait() )
1195  {
1196  if( evt->IsCancel() )
1197  {
1198  break;
1199  }
1200  else if( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) )
1201  {
1202  updateEndItem( *evt );
1204  }
1205  else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
1206  {
1207  updateEndItem( *evt );
1209  break;
1210  }
1211  }
1212 
1213  if( m_router->RoutingInProgress() )
1214  m_router->StopRouting();
1215 
1216  controls()->SetAutoPan( false );
1217  controls()->ForceCursorPosition( false );
1218  frame()->UndoRedoBlock( false );
1219 
1220  return 0;
1221 }
1222 
1223 
1225 {
1226  const auto& selection = m_toolMgr->GetTool<SELECTION_TOOL>()->GetSelection();
1227 
1228  if( selection.Size() != 1 )
1229  return 0;
1230 
1231  const BOARD_CONNECTED_ITEM* item = static_cast<const BOARD_CONNECTED_ITEM*>( selection.Front() );
1232 
1233  if( item->Type() != PCB_TRACE_T )
1234  return 0;
1235 
1236  Init();
1237  Activate();
1238 
1240  m_router->SyncWorld();
1242  m_startSnapPoint = snapToItem( true, m_startItem, controls()->GetCursorPosition() );
1243 
1244 
1245  if( m_startItem && m_startItem->IsLocked() )
1246  {
1247  KIDIALOG dlg( frame(), _( "The selected item is locked." ), _( "Confirmation" ),
1248  wxOK | wxCANCEL | wxICON_WARNING );
1249  dlg.SetOKLabel( _( "Break Track" ) );
1250  dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
1251 
1252  if( dlg.ShowModal() == wxID_CANCEL )
1253  return 0;
1254  }
1255 
1256  frame()->UndoRedoBlock( true );
1257  breakTrack();
1258 
1259  if( m_router->RoutingInProgress() )
1260  m_router->StopRouting();
1261 
1262  frame()->UndoRedoBlock( false );
1263 
1264  return 0;
1265 }
1266 
1267 
1269 {
1271  DIALOG_TRACK_VIA_SIZE sizeDlg( frame(), bds );
1272 
1273  if( sizeDlg.ShowModal() )
1274  {
1275  bds.UseCustomTrackViaSize( true );
1277  }
1278 
1279  return 0;
1280 }
1281 
1282 
1284 {
1285  PNS::SIZES_SETTINGS sizes( m_router->Sizes() );
1286  sizes.ImportCurrent( board()->GetDesignSettings() );
1287  m_router->UpdateSizes( sizes );
1288 
1289  // Changing the track width can affect the placement, so call the
1290  // move routine without changing the destination
1292 
1293  return 0;
1294 }
void Empty()
Function Empty sets the list to empty.
Definition: collector.h:123
CONTEXT_MENU * create() const override
Returns an instance of this class. It has to be overridden in inheriting classes.
static TOOL_ACTION selectionClear
Clears the current selection.
Definition: pcb_actions.h:53
int mainLoop(PNS::ROUTER_MODE aMode)
const wxString & FailureReason() const
Definition: pns_router.h:214
int GetCurrentMicroViaSize()
Function GetCurrentMicroViaSize.
virtual void ShowCursor(bool aEnabled)
Function ShowCursor() Enables or disables display of cursor.
Class ITEM.
Definition: pns_item.h:53
Struct VIA_DIMENSION is a small helper container to handle a stock of specific vias each with unique ...
OPT_TOOL_EVENT eventHandler(const wxMenuEvent &aEvent) override
Event handler stub.
BOARD_CONNECTED_ITEM * Parent() const
Function Parent()
Definition: pns_item.h:159
void DoNotShowCheckbox(wxString file, int line)
Shows the 'do not show again' checkbox
Definition: confirm.cpp:61
void SetTrackWidthIndex(unsigned aIndex)
Function SetTrackWidthIndex sets the current track width list index to aIndex.
KIGFX::VIEW_CONTROLS * controls() const
Definition: pcb_tool.h:138
int GetNetCode() const
Function GetNetCode.
virtual void SetToolID(int aId, int aCursor, const wxString &aToolMsg) override
Set the tool command ID to aId and sets the cursor to aCursor.
PCB_EDIT_FRAME & m_frame
GRID_HELPER * m_gridHelper
Definition: pns_tool_base.h:76
int GetCurrentViaDrill() const
Function GetCurrentViaDrill.
int DpDimensionsDialog(const TOOL_EVENT &aEvent)
Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
Definition: class_module.h:57
Normal via
Definition: router_tool.cpp:74
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: confirm.h:44
bool finishInteractive()
void SetCustomDiffPairViaGap(int aGap)
Function SetCustomDiffPairViaGap Sets custom via gap for differential pairs (i.e.
blind/buried via
Definition: router_tool.cpp:75
Implementation of conversion functions that require both schematic and board internal units.
This file is part of the common library.
std::vector< int > m_TrackWidthList
const wxPoint & GetStart() const
Definition: class_track.h:126
Class CONTEXT_MENU.
Definition: context_menu.h:44
int GetCurrentMicroViaDrill()
Function GetCurrentMicroViaDrill.
VIEW_CONTROLS class definition.
std::vector< DIFF_PAIR_DIMENSION > m_DiffPairDimensionsList
VECTOR2I m_startSnapPoint
Definition: pns_tool_base.h:70
int InlineDrag(const TOOL_EVENT &aEvent)
Class SELECTION_TOOL.
static const TOOL_ACTION ACT_NewTrack("pcbnew.InteractiveRouter.NewTrack", AS_CONTEXT, TOOL_ACTION::LegacyHotKey(HK_ADD_NEW_TRACK), _("New Track"), _("Starts laying a new track."), add_tracks_xpm)
Class BOARD to handle a board.
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
STATUS_FLAGS IsPointOnEnds(const wxPoint &point, int min_dist=0)
Function IsPointOnEnds returns STARTPOINT if point if near (dist = min_dist) start point,...
int RouteSingleTrace(const TOOL_EVENT &aEvent)
static TOOL_ACTION dragFreeAngle
Definition: pcb_actions.h:142
const SELECTION & selection() const
Definition: pcb_tool.cpp:251
Tool is invoked after being inactive.
Definition: tool_base.h:82
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
void UseCustomDiffPairDimensions(bool aEnabled)
Function UseCustomDiffPairDimensions Enables/disables custom differential pair dimensions.
static LSET AllNonCuMask()
Function AllNonCuMask returns a mask holding all layer minus CU layers.
Definition: lset.cpp:699
static TOOL_ACTION cancelInteractive
Definition: actions.h:45
SIZES_SETTINGS m_savedSizes
Stores sizes settings between router invocations.
Definition: pns_tool_base.h:67
void SyncWorld()
Definition: pns_router.cpp:91
OPT_TOOL_EVENT Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Function Wait()
bool IsPlacingVia() const
Definition: pns_router.cpp:495
Microvia
Definition: router_tool.cpp:78
bool IsKeyPressed() const
Definition: tool_event.h:335
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:125
bool Overlaps(const LAYER_RANGE &aOther) const
Definition: pns_layerset.h:68
static int LegacyHotKey(int aHotKey)
Creates a hot key code that refers to a legacy hot key setting, instead of a particular key.
Definition: tool_action.h:174
static const TOOL_ACTION ACT_PlaceBlindVia("pcbnew.InteractiveRouter.PlaceBlindVia", AS_CONTEXT, TOOL_ACTION::LegacyHotKey(HK_ADD_BLIND_BURIED_VIA), _("Place Blind/Buried Via"), _("Adds a blind or buried via at the end of currently routed track."), via_buried_xpm, AF_NONE,(void *) VIA_ACTION_FLAGS::BLIND_VIA)
static TOOL_ACTION trackViaSizeChanged
Definition: pcb_actions.h:299
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:539
static TOOL_ACTION drag45Degree
Definition: pcb_actions.h:141
TRACK_WIDTH_MENU(PCB_EDIT_FRAME &aFrame)
static const TOOL_ACTION ACT_PlaceThroughVia("pcbnew.InteractiveRouter.PlaceVia", AS_CONTEXT, TOOL_ACTION::LegacyHotKey(HK_ADD_THROUGH_VIA), _("Place Through Via"), _("Adds a through-hole via at the end of currently routed track."), via_xpm, AF_NONE,(void *) VIA_ACTION_FLAGS::VIA)
static TOOL_ACTION routerActivateSingle
Activation of the Push and Shove router.
Definition: pcb_actions.h:203
void UndoRedoBlock(bool aBlock=true)
Function UndoRedoBlock Enables/disable undo and redo operations.
void SetViaDrill(int aDrill)
SIZES_SETTINGS & Sizes()
Definition: pns_router.h:206
VIATYPE_T
Definition: class_track.h:50
bool SetCurrentNetClass(const wxString &aNetClassName)
Function SetCurrentNetClass Must be called after a netclass selection (or after a netclass parameter ...
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
void SwitchLayer(int layer)
Definition: pns_router.cpp:432
int CountType(KICAD_T aType)
Function CountType counts the number of items matching aType.
Definition: collector.h:265
void breakTrack()
Class BOARD_CONNECTED_ITEM is a base class derived from BOARD_ITEM for items that can be connected an...
ROUTER_TOOL_MENU(PCB_EDIT_FRAME &aFrame, PNS::ROUTER_MODE aMode)
static TOOL_ACTION routerActivateTuneSingleTrace
Activation of the Push and Shove router (tune single line mode)
Definition: pcb_actions.h:209
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Function Go()
void SetOrthoMode(bool aEnable)
Definition: pns_router.cpp:504
Struct DIFF_PAIR_DIMENSION is a small helper container to handle a stock of specific differential pai...
const VECTOR2I snapToItem(bool aEnabled, ITEM *aItem, VECTOR2I aP)
void ToggleViaPlacement()
Definition: pns_router.cpp:445
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
void handleCommonEvents(const TOOL_EVENT &evt)
Pcbnew hotkeys.
GRID_MENU m_gridMenu
wxMenuItem * Add(const wxString &aLabel, int aId, const BITMAP_OPAQUE *aIcon=NULL)
Function Add() Adds an entry to the menu.
This file contains miscellaneous commonly used macros and functions.
void ClearWorld()
Definition: pns_router.cpp:100
int Start() const
Definition: pns_layerset.h:83
void Append(EDA_ITEM *item)
Function Append adds an item to the end of the list.
Definition: collector.h:133
TOOL_MANAGER * GetToolManager() const
Return the tool manager instance, if any.
Definition: draw_frame.h:941
wxString MessageTextFromValue(EDA_UNITS_T aUnits, int aValue, bool aUseMils)
Definition: base_units.cpp:125
virtual PCB_LAYER_ID GetActiveLayer() const
Function GetActiveLayer returns the active layer.
virtual void updateStartItem(const TOOL_EVENT &aEvent, bool aIgnorePads=false)
void SetViaSizeIndex(unsigned aIndex)
Function SetViaSizeIndex sets the current via size list index to aIndex.
int onViaCommand(const TOOL_EVENT &aEvent)
Class TOOL_MANAGER.
Definition: tool_manager.h:49
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:114
virtual void Reset(RESET_REASON aReason)=0
Function Reset() Brings the tool to a known, initial state.
int RouteDiffPair(const TOOL_EVENT &aEvent)
virtual void updateEndItem(const TOOL_EVENT &aEvent)
bool prepareInteractive()
PCB_LAYER_ID
A quick note on layer IDs:
void performRouting()
CONTEXT_MENU * create() const override
Returns an instance of this class. It has to be overridden in inheriting classes.
void BreakSegment(ITEM *aItem, const VECTOR2I &aP)
Definition: pns_router.cpp:525
static TOOL_ACTION routerActivateTuneDiffPairSkew
Activation of the Push and Shove router (skew tuning mode)
Definition: pcb_actions.h:215
static const char Default[]
the name of the default NETCLASS
Definition: netclass.h:80
void update() override
Update menu state stub.
unsigned GetViaSizeIndex() const
Function GetViaSizeIndex.
BOARD * board() const
Definition: pcb_tool.h:140
int Net() const
Function Net()
Definition: pns_item.h:179
EDA_UNITS_T GetUserUnits() const override
Return the user units currently in use.
Definition: draw_frame.h:291
CONTEXT_MENU * create() const override
Returns an instance of this class. It has to be overridden in inheriting classes.
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:387
virtual int GetTopLayer() const
Definition: view.cpp:850
void SetCustomDiffPairWidth(int aWidth)
Function SetCustomDiffPairWidth Sets custom track width for differential pairs (i....
Class TOOL_EVENT.
Definition: tool_event.h:168
PNS::ROUTER_MODE m_mode
ITEM * m_startItem
Definition: pns_tool_base.h:68
bool FixRoute(const VECTOR2I &aP, ITEM *aItem, bool aForceFinish=false)
Definition: pns_router.cpp:370
OPT_TOOL_EVENT eventHandler(const wxMenuEvent &aEvent) override
Event handler stub.
unsigned GetTrackWidthIndex() const
Function GetTrackWidthIndex.
DIFF_PAIR_MENU(PCB_EDIT_FRAME &aFrame)
static const TOOL_ACTION ACT_SwitchPosture("pcbnew.InteractiveRouter.SwitchPosture", AS_CONTEXT, TOOL_ACTION::LegacyHotKey(HK_SWITCH_TRACK_POSTURE), _("Switch Track Posture"), _("Switches posture of the currently routed track."), change_entry_orient_xpm)
ZOOM_MENU m_zoomMenu
void Init(BOARD *aBoard, ITEM *aStartItem=NULL, int aNet=-1)
unsigned STATUS_FLAGS
Definition: base_struct.h:147
ROUTER * m_router
Definition: pns_tool_base.h:78
void SetContextMenu(CONTEXT_MENU *aMenu, CONTEXT_MENU_TRIGGER aTrigger=CMENU_BUTTON)
Function SetContextMenu()
bool CanInlineDrag()
void Load(const TOOL_SETTINGS &where)
Class VIEW_CONTROLS is an interface for classes handling user events controlling the view behaviour (...
PCB_LAYER_ID m_Route_Layer_BOTTOM
Definition: pcb_screen.h:46
void switchLayerOnViaPlacement()
PCB_EDIT_FRAME & m_frame
virtual void ForceCursorPosition(bool aEnabled, const VECTOR2D &aPosition=VECTOR2D(0, 0))
Function ForceCursorPosition() Places the cursor immediately at a given point.
PCB_LAYER_WIDGET * GetLayerManager()
static TOOL_ACTION routerActivateTuneDiffPair
Activation of the Push and Shove router (diff pair tuning mode)
Definition: pcb_actions.h:212
bool m_BlindBuriedViaAllowed
true to allow blind/buried vias
void Clear()
Function Clear() Removes all the entries from the menu (as well as its title).
ROUTING_SETTINGS m_savedSettings
Stores routing settings between router invocations.
Definition: pns_tool_base.h:66
int SettingsDialog(const TOOL_EVENT &aEvent)
void SetDiffPairIndex(unsigned aIndex)
Function SetDiffPairIndex.
int CustomTrackWidthDialog(const TOOL_EVENT &aEvent)
void SetCustomDiffPairGap(int aGap)
Function SetCustomDiffPairGap Sets custom gap for differential pairs (i.e.
void ImportCurrent(BOARD_DESIGN_SETTINGS &aSettings)
static const TOOL_ACTION ACT_PlaceMicroVia("pcbnew.InteractiveRouter.PlaceMicroVia", AS_CONTEXT, TOOL_ACTION::LegacyHotKey(HK_ADD_MICROVIA), _("Place Microvia"), _("Adds a microvia at the end of currently routed track."), via_microvia_xpm, AF_NONE,(void *) VIA_ACTION_FLAGS::MICROVIA)
bool IsCancelInteractive(const TOOL_EVENT &aEvt)
Function IsCancelInteractive()
All active tools
Definition: tool_event.h:144
void Move(const VECTOR2I &aP, ITEM *aItem)
Definition: pns_router.cpp:231
TOOL_SETTINGS & GetSettings()
Definition: tool_base.cpp:77
int onTrackViaSizeChanged(const TOOL_EVENT &aEvent)
static TOOL_ACTION routerInlineDrag
Activation of the Push and Shove router (inline dragging mode)
Definition: pcb_actions.h:223
bool StartRouting(const VECTOR2I &aP, ITEM *aItem, int aLayer)
Definition: pns_router.cpp:176
KIGFX::VIEW * getView() const
Function getView()
Definition: tool_base.cpp:35
virtual void SetAutoPan(bool aEnabled)
Function SetAutoPan Turns on/off auto panning (this feature is used when there is a tool active (eg.
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:116
static TOOL_ACTION inlineBreakTrack
Breaks track when router is not activated.
Definition: pcb_actions.h:139
static TOOL_ACTION breakTrack
Break a single track into two segments at the cursor.
Definition: pcb_actions.h:136
void StopRouting()
Definition: pns_router.cpp:395
void SetIcon(const BITMAP_OPAQUE *aIcon)
Function SetIcon() Assigns an icon for the entry.
virtual void highlightNet(bool aEnabled, int aNetcode=-1)
static const TOOL_ACTION ACT_CustomTrackWidth("pcbnew.InteractiveRouter.CustomTrackViaSize", AS_CONTEXT, TOOL_ACTION::LegacyHotKey(HK_CUSTOM_TRACK_WIDTH), _("Custom Track/Via Size..."), _("Shows a dialog for changing the track width and via size."), width_track_xpm)
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
virtual void SetNoToolSelected()
Select the ID_NO_TOOL_SELECTED id tool (Idle tool)
ROUTER_MODE
Definition: pns_router.h:64
PCB_EDIT_FRAME & m_frame
int GetCurrentViaSize() const
Function GetCurrentViaSize.
void SetViaType(VIATYPE_T aViaType)
void Save(TOOL_SETTINGS &where) const
static TOOL_ACTION layerChanged
Definition: pcb_actions.h:291
void UpdateSizes(const SIZES_SETTINGS &aSizes)
Applies stored settings.
Definition: pns_router.cpp:314
void SetMode(ROUTER_MODE aMode)
Definition: pns_router.cpp:513
void update() override
Update menu state stub.
static TOOL_ACTION routerActivateSettingsDialog
Activation of the Push and Shove settings dialogs.
Definition: pcb_actions.h:218
static const TOOL_ACTION ACT_SelLayerAndPlaceThroughVia("pcbnew.InteractiveRouter.SelLayerAndPlaceVia", AS_CONTEXT, TOOL_ACTION::LegacyHotKey(HK_SEL_LAYER_AND_ADD_THROUGH_VIA), _("Select Layer and Place Through Via..."), _("Select a layer, then add a through-hole via at the end of currently routed track."), select_w_layer_xpm, AF_NONE,(void *)(VIA_ACTION_FLAGS::VIA|VIA_ACTION_FLAGS::SELECT_LAYER))
VECTOR2I m_endSnapPoint
Definition: pns_tool_base.h:74
std::shared_ptr< NETCLASS > GetNetClass() const
Function GetNetClass returns the NETCLASS for this item.
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:245
Class TOOL_BASE.
Definition: tool_base.h:68
void SetTitle(const wxString &aTitle) override
Function SetTitle() Sets title for the context menu.
Class TOOL_ACTION.
Definition: tool_action.h:46
size_t i
Definition: json11.cpp:597
bool StartDragging(const VECTOR2I &aP, ITEM *aItem, int aDragMode=DM_ANY)
Definition: pns_router.cpp:127
#define ENDPOINT
Definition: base_struct.h:120
static void NeighboringSegmentFilter(const VECTOR2I &aPt, GENERAL_COLLECTOR &aCollector)
void performDragging(int aMode=PNS::DM_ANY)
bool OfKind(int aKindMask) const
Function OfKind()
Definition: pns_item.h:132
Class PCB_EDIT_FRAME is the main frame for Pcbnew.
TOOL_EVENT MakeEvent() const
Function HasHotKey() Checks if the action has a hot key assigned.
Definition: tool_action.h:104
int Size() const
Returns the number of selected parts.
Definition: selection.h:122
void SetAuxAxes(bool aEnable, const VECTOR2I &aOrigin=VECTOR2I(0, 0), bool aEnableDiagonal=false)
bool IsLocked() const
Definition: pns_item.h:343
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
int InlineBreakTrack(const TOOL_EVENT &aEvent)
ITEM * FindItemByParent(const BOARD_CONNECTED_ITEM *aParent)
Definition: pns_node.cpp:1329
PCB_EDIT_FRAME * frame() const
Definition: pcb_tool.h:139
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:80
const wxPoint & GetEnd() const
Definition: class_track.h:123
std::vector< VIA_DIMENSION > m_ViasDimensionsList
boost::optional< T > OPT
Definition: optional.h:7
int ShowModal() override
Definition: confirm.cpp:103
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
void Activate()
Function Activate() Runs the tool.
Implementing DIALOG_TRACK_VIA_SIZE_BASE.
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
unsigned GetDiffPairIndex() const
Function GetDiffPairIndex.
void AddLayerPair(int aL1, int aL2)
static const TOOL_ACTION ACT_EndTrack("pcbnew.InteractiveRouter.EndTrack", AS_CONTEXT, WXK_END, _("End Track"), _("Stops laying the current track."), checked_ok_xpm)
void DumpLog()
Definition: pns_router.cpp:472
static const TOOL_ACTION ACT_SelLayerAndPlaceBlindVia("pcbnew.InteractiveRouter.SelLayerAndPlaceBlindVia", AS_CONTEXT, TOOL_ACTION::LegacyHotKey(HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA), _("Select Layer and Place Blind/Buried Via..."), _("Select a layer, then add a blind or buried via at the end of currently routed track."), select_w_layer_xpm, AF_NONE,(void *)(VIA_ACTION_FLAGS::BLIND_VIA|VIA_ACTION_FLAGS::SELECT_LAYER))
static VIATYPE_T getViaTypeFromFlags(int aFlags)
bool m_MicroViasAllowed
true to allow micro vias
void SetLayerVisible(LAYER_NUM aLayer, bool isVisible)
Function SetLayerVisible sets aLayer visible or not.
BOARD * GetBoard() const
static const TOOL_ACTION ACT_AutoEndRoute("pcbnew.InteractiveRouter.AutoEndRoute", AS_CONTEXT, 'F', _("Auto-end Track"), _("Automagically finishes currently routed track."))
KIGFX::VIEW_CONTROLS * getViewControls() const
Function getViewControls()
Definition: tool_base.cpp:41
void FlipPosture()
Definition: pns_router.cpp:423
DIFF_PAIR_MENU m_diffPairMenu
bool RoutingInProgress() const
Definition: pns_router.cpp:112
int KeyCode() const
Definition: tool_event.h:330
void SetViaDiameter(int aDiameter)
int getStartLayer(const PNS::ITEM *aItem)
TRACK_WIDTH_MENU m_trackViaMenu
static TOOL_ACTION routerActivateDiffPair
Activation of the Push and Shove router (differential pair mode)
Definition: pcb_actions.h:206
NODE * GetWorld() const
Definition: pns_router.h:143
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:243
int GetCopperLayerCount() const
Function GetCopperLayerCount.
OPT< int > PairedLayer(int aLayerId)
PCB_LAYER_ID SelectLayer(PCB_LAYER_ID aDefaultLayer, LSET aNotAllowedLayersMask=LSET(), wxPoint aDlgPosition=wxDefaultPosition)
Install the dialog box for layer selection.
Definition: sel_layer.cpp:205
virtual void SetActiveLayer(PCB_LAYER_ID aLayer) override
Function SetActiveLayer will change the currently active layer to aLayer and also update the PCB_LAYE...
ROUTING_SETTINGS & Settings()
Definition: pns_router.h:187
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:813
VIA_ACTION_FLAGS
Flags used by via tool actions.
Definition: router_tool.cpp:69
EDA_UNITS_T
Definition: common.h:160
static TOOL_ACTION selectionCursor
Select a single item under the cursor position.
Definition: pcb_actions.h:50
Class LAYER_RANGE.
Definition: pns_layerset.h:32
const LAYER_RANGE & Layers() const
Function Layers()
Definition: pns_item.h:214
PCB_LAYER_ID m_Route_Layer_TOP
Definition: pcb_screen.h:45
void UseCustomTrackViaSize(bool aEnabled)
Function UseCustomTrackViaSize Enables/disables custom track/via size settings.
VECTOR2D GetCursorPosition() const
Returns the current cursor position in world coordinates.
EDA_ITEM * Front() const
Definition: selection.h:152
OPT< TOOL_EVENT > OPT_TOOL_EVENT
Definition: tool_event.h:495
KICAD_T Type() const
Function Type()
Definition: base_struct.h:201
Class BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.
#define STARTPOINT
Definition: base_struct.h:119
static TOOL_ACTION layerToggle
Definition: pcb_actions.h:289
int GetCurrentLayer() const
Definition: pns_router.cpp:464
static TOOL_ACTION routerActivateDpDimensionsDialog
Definition: pcb_actions.h:219