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/tool_event_utils.h>
58 
59 #include "router_tool.h"
60 #include "pns_segment.h"
61 #include "pns_router.h"
62 
63 using namespace KIGFX;
64 
69 {
70  // Via type
71  VIA_MASK = 0x03,
72  VIA = 0x00,
73  BLIND_VIA = 0x01,
74  MICROVIA = 0x02,
75 
76  // Select layer
78 };
79 
80 
81 TOOL_ACTION PCB_ACTIONS::routerActivateSingle( "pcbnew.InteractiveRouter.SingleTrack",
83  _( "Interactive Router (Single Tracks)" ),
84  _( "Run push & shove router (single tracks)" ), ps_router_xpm, AF_ACTIVATE );
85 
86 TOOL_ACTION PCB_ACTIONS::routerActivateDiffPair( "pcbnew.InteractiveRouter.DiffPair",
88  _( "Interactive Router (Differential Pairs)" ),
89  _( "Run push & shove router (differential pairs)" ), ps_diff_pair_xpm, AF_ACTIVATE );
90 
91 TOOL_ACTION PCB_ACTIONS::routerActivateSettingsDialog( "pcbnew.InteractiveRouter.SettingsDialog",
93  _( "Interactive Router Settings..." ),
94  _( "Open Interactive Router settings" ), tools_xpm );
95 
96 TOOL_ACTION PCB_ACTIONS::routerActivateDpDimensionsDialog( "pcbnew.InteractiveRouter.DpDimensionsDialog",
97  AS_GLOBAL, 0,
98  _( "Differential Pair Dimension Settings..." ),
99  _( "Open Differential Pair Dimension settings" ),
100  ps_diff_pair_gap_xpm );
101 
102 TOOL_ACTION PCB_ACTIONS::routerActivateTuneSingleTrace( "pcbnew.LengthTuner.TuneSingleTrack",
104  _( "Tune length of a single track" ), "", ps_tune_length_xpm, AF_ACTIVATE );
105 
106 TOOL_ACTION PCB_ACTIONS::routerActivateTuneDiffPair( "pcbnew.LengthTuner.TuneDiffPair",
108  _( "Tune length of a differential pair" ), "", NULL, AF_ACTIVATE );
109 
110 TOOL_ACTION PCB_ACTIONS::routerActivateTuneDiffPairSkew( "pcbnew.LengthTuner.TuneDiffPairSkew",
112  _( "Tune skew of a differential pair" ), "", NULL, AF_ACTIVATE );
113 
114 TOOL_ACTION PCB_ACTIONS::routerInlineDrag( "pcbnew.InteractiveRouter.InlineDrag",
115  AS_CONTEXT, 0,
116  _( "Drag Track/Via" ), _( "Drags tracks and vias without breaking connections" ),
117  drag_xpm );
118 
119 TOOL_ACTION PCB_ACTIONS::breakTrack( "pcbnew.InteractiveRouter.BreakTrack",
120  AS_GLOBAL, 0,
121  _( "Break Track" ),
122  _( "Splits the track segment into two segments connected at the cursor position." ),
123  break_line_xpm );
124 
125 TOOL_ACTION PCB_ACTIONS::drag45Degree( "pcbnew.InteractiveRouter.Drag45Degree",
127  _( "Drag (45 degree mode)" ),
128  _( "Drags the track segment while keeping connected tracks at 45 degrees." ),
129  drag_segment_withslope_xpm );
130 
131 TOOL_ACTION PCB_ACTIONS::dragFreeAngle( "pcbnew.InteractiveRouter.DragFreeAngle",
133  _( "Drag (free angle)" ),
134  _( "Drags the nearest joint in the track without restricting the track angle." ),
135  move_xpm );
136 
137 static const TOOL_ACTION ACT_NewTrack( "pcbnew.InteractiveRouter.NewTrack", AS_CONTEXT,
139  _( "New Track" ), _( "Starts laying a new track." ), add_tracks_xpm );
140 
141 static const TOOL_ACTION ACT_EndTrack( "pcbnew.InteractiveRouter.EndTrack", AS_CONTEXT, WXK_END,
142  _( "End Track" ), _( "Stops laying the current track." ), checked_ok_xpm );
143 
144 static const TOOL_ACTION ACT_AutoEndRoute( "pcbnew.InteractiveRouter.AutoEndRoute", AS_CONTEXT, 'F',
145  _( "Auto-end Track" ), _( "Automagically finishes currently routed track." ) );
146 
147 static const TOOL_ACTION ACT_PlaceThroughVia( "pcbnew.InteractiveRouter.PlaceVia",
149  _( "Place Through Via" ),
150  _( "Adds a through-hole via at the end of currently routed track." ),
151  via_xpm, AF_NONE,
152  (void*) VIA_ACTION_FLAGS::VIA );
153 
154 static const TOOL_ACTION ACT_PlaceBlindVia( "pcbnew.InteractiveRouter.PlaceBlindVia",
156  _( "Place Blind/Buried Via" ),
157  _( "Adds a blind or buried via at the end of currently routed track."),
158  via_buried_xpm, AF_NONE,
159  (void*) VIA_ACTION_FLAGS::BLIND_VIA );
160 
161 static const TOOL_ACTION ACT_PlaceMicroVia( "pcbnew.InteractiveRouter.PlaceMicroVia",
163  _( "Place Microvia" ), _( "Adds a microvia at the end of currently routed track." ),
164  via_microvia_xpm, AF_NONE,
165  (void*) VIA_ACTION_FLAGS::MICROVIA );
166 
168  "pcbnew.InteractiveRouter.SelLayerAndPlaceVia",
170  _( "Select Layer and Place Through Via..." ),
171  _( "Select a layer, then add a through-hole via at the end of currently routed track." ),
172  select_w_layer_xpm, AF_NONE,
174 
176  "pcbnew.InteractiveRouter.SelLayerAndPlaceBlindVia",
178  _( "Select Layer and Place Blind/Buried Via..." ),
179  _( "Select a layer, then add a blind or buried via at the end of currently routed track."),
180  select_w_layer_xpm, AF_NONE,
182 
183 static const TOOL_ACTION ACT_CustomTrackWidth( "pcbnew.InteractiveRouter.CustomTrackViaSize",
185  _( "Custom Track/Via Size..." ),
186  _( "Shows a dialog for changing the track width and via size." ),
187  width_track_xpm );
188 
189 static const TOOL_ACTION ACT_SwitchPosture( "pcbnew.InteractiveRouter.SwitchPosture", AS_CONTEXT,
191  _( "Switch Track Posture" ),
192  _( "Switches posture of the currently routed track." ),
193  change_entry_orient_xpm );
194 
196  TOOL_BASE( "pcbnew.InteractiveRouter" )
197 {
198 }
199 
200 
202 {
203 public:
205  m_frame( aFrame )
206  {
207  SetIcon( width_track_via_xpm );
208  SetTitle( _( "Select Track/Via Width" ) );
209  }
210 
211 protected:
212  CONTEXT_MENU* create() const override
213  {
214  return new TRACK_WIDTH_MENU( m_frame );
215  }
216 
217  void update() override
218  {
219  EDA_UNITS_T units = m_frame.GetUserUnits();
220  BOARD_DESIGN_SETTINGS& bds = m_frame.GetBoard()->GetDesignSettings();
221  bool useIndex = !bds.m_UseConnectedTrackWidth &&
222  !bds.UseCustomTrackViaSize();
223  wxString msg;
224 
225  Clear();
226 
227  Append( ID_POPUP_PCB_SELECT_AUTO_WIDTH, _( "Use Starting Track Width" ),
228  _( "Route using the width of the starting track." ), wxITEM_CHECK );
231 
232  Append( ID_POPUP_PCB_SELECT_USE_NETCLASS_VALUES, _( "Use Net Class Values" ),
233  _( "Use track and via sizes from the net class" ), wxITEM_CHECK );
235  useIndex && bds.GetTrackWidthIndex() == 0 && bds.GetViaSizeIndex() == 0 );
236 
237  Append( ID_POPUP_PCB_SELECT_CUSTOM_WIDTH, _( "Use Custom Values..." ),
238  _( "Specify custom track and via sizes" ), wxITEM_CHECK );
240 
241  AppendSeparator();
242 
243  // Append the list of tracks & via sizes
244  for( unsigned i = 0; i < bds.m_TrackWidthList.size(); i++ )
245  {
246  int width = bds.m_TrackWidthList[i];
247 
248  if( i == 0 )
249  msg = _( "Track netclass width" );
250  else
251  msg = _( "Track " ) + MessageTextFromValue( units, width, true );
252 
253  int menuIdx = ID_POPUP_PCB_SELECT_WIDTH1 + i;
254  Append( menuIdx, msg, wxEmptyString, wxITEM_CHECK );
255  Check( menuIdx, useIndex && bds.GetTrackWidthIndex() == i );
256  }
257 
258  AppendSeparator();
259 
260  for( unsigned i = 0; i < bds.m_ViasDimensionsList.size(); i++ )
261  {
263 
264  if( i == 0 )
265  msg = _( "Via netclass values" );
266  else
267  {
268  msg = _( "Via " ) + MessageTextFromValue( units, via.m_Diameter, true );
269 
270  if( via.m_Drill > 0 )
271  msg << _(", drill " ) << MessageTextFromValue( units, via.m_Drill, true );
272  }
273 
274  int menuIdx = ID_POPUP_PCB_SELECT_VIASIZE1 + i;
275  Append( menuIdx, msg, wxEmptyString, wxITEM_CHECK );
276  Check( menuIdx, useIndex && bds.GetViaSizeIndex() == i );
277  }
278  }
279 
280  OPT_TOOL_EVENT eventHandler( const wxMenuEvent& aEvent ) override
281  {
282  BOARD_DESIGN_SETTINGS &bds = m_frame.GetBoard()->GetDesignSettings();
283  int id = aEvent.GetId();
284 
285  // On Windows, this handler can be called with an event ID not existing in any
286  // menuitem, so only set flags when we have an ID match.
287 
289  {
290  bds.UseCustomTrackViaSize( true );
291  bds.m_UseConnectedTrackWidth = false;
292  m_frame.GetToolManager()->RunAction( ACT_CustomTrackWidth, true );
293  }
294  else if( id == ID_POPUP_PCB_SELECT_AUTO_WIDTH )
295  {
296  bds.UseCustomTrackViaSize( false );
297  bds.m_UseConnectedTrackWidth = true;
298  }
300  {
301  bds.UseCustomTrackViaSize( false );
302  bds.m_UseConnectedTrackWidth = false;
303  bds.SetViaSizeIndex( 0 );
304  bds.SetTrackWidthIndex( 0 );
305  }
307  {
308  bds.UseCustomTrackViaSize( false );
309  bds.m_UseConnectedTrackWidth = false;
311  }
313  {
314  bds.UseCustomTrackViaSize( false );
315  bds.m_UseConnectedTrackWidth = false;
317  }
318 
319  return OPT_TOOL_EVENT( PCB_ACTIONS::trackViaSizeChanged.MakeEvent() );
320  }
321 
322 private:
324 };
325 
326 
328 {
329 public:
331  m_frame( aFrame )
332  {
333  SetIcon( width_track_via_xpm );
334  SetTitle( _( "Select Differential Pair Dimensions" ) );
335  }
336 
337 protected:
338  CONTEXT_MENU* create() const override
339  {
340  return new DIFF_PAIR_MENU( m_frame );
341  }
342 
343  void update() override
344  {
345  EDA_UNITS_T units = m_frame.GetUserUnits();
346  const BOARD_DESIGN_SETTINGS& bds = m_frame.GetBoard()->GetDesignSettings();
347 
348  Clear();
349 
350  Append( ID_POPUP_PCB_SELECT_USE_NETCLASS_DIFFPAIR, _( "Use Net Class Values" ),
351  _( "Use differential pair dimensions from the net class" ), wxITEM_CHECK );
353  !bds.UseCustomDiffPairDimensions() && bds.GetDiffPairIndex() == 0 );
354 
355  Append( ID_POPUP_PCB_SELECT_CUSTOM_DIFFPAIR, _( "Use Custom Values..." ),
356  _( "Specify custom differential pair dimensions" ), wxITEM_CHECK );
358 
359  AppendSeparator();
360 
361  // Append the list of differential pair dimensions
362 
363  // Drop index 0 which is the current netclass dimensions (which are handled above)
364  for( unsigned i = 1; i < bds.m_DiffPairDimensionsList.size(); ++i )
365  {
367  wxString msg;
368 
369  msg << _( "Width " ) << MessageTextFromValue( units, diffPair.m_Width, true );
370 
371  if( diffPair.m_Gap > 0 )
372  msg << _( ", gap " ) << MessageTextFromValue( units, diffPair.m_Gap, true );
373 
374  if( diffPair.m_ViaGap > 0 )
375  msg << _( ", via gap " ) << MessageTextFromValue( units, diffPair.m_ViaGap, true );
376 
377  int menuIdx = ID_POPUP_PCB_SELECT_DIFFPAIR1 + i - 1;
378  Append( menuIdx, msg, wxEmptyString, wxITEM_CHECK );
379  Check( menuIdx, !bds.UseCustomDiffPairDimensions() && bds.GetDiffPairIndex() == i );
380  }
381  }
382 
383  OPT_TOOL_EVENT eventHandler( const wxMenuEvent& aEvent ) override
384  {
385  BOARD_DESIGN_SETTINGS &bds = m_frame.GetBoard()->GetDesignSettings();
386  int id = aEvent.GetId();
387 
388  // On Windows, this handler can be called with an event ID not existing in any
389  // menuitem, so only set flags when we have an ID match.
390 
392  {
393  bds.UseCustomDiffPairDimensions( true );
394  TOOL_MANAGER* toolManager = m_frame.GetToolManager();
396  }
398  {
399  bds.UseCustomDiffPairDimensions( false );
400  bds.SetDiffPairIndex( 0 );
401  }
403  {
404  bds.UseCustomDiffPairDimensions( false );
405  // remember that the menu doesn't contain index 0 (which is the netclass values)
407  }
408 
409  return OPT_TOOL_EVENT( PCB_ACTIONS::trackViaSizeChanged.MakeEvent() );
410  }
411 
412 private:
414 };
415 
416 
418 {
419 public:
421  m_frame( aFrame ), m_mode( aMode ), m_trackViaMenu( aFrame ), m_diffPairMenu( aFrame ),
422  m_zoomMenu( &aFrame ), m_gridMenu( &aFrame )
423  {
424  SetTitle( _( "Interactive Router" ) );
425 
427 
428  AppendSeparator();
429 
430  Add( ACT_NewTrack );
431  Add( ACT_EndTrack );
433 
436 
437 // Add( ACT_AutoEndRoute ); // fixme: not implemented yet. Sorry.
438  Add( ACT_PlaceThroughVia );
439  Add( ACT_PlaceBlindVia );
440  Add( ACT_PlaceMicroVia );
443  Add( ACT_SwitchPosture );
444 
445  AppendSeparator();
446 
447  Add( &m_trackViaMenu );
448 
449  if( m_mode == PNS::PNS_MODE_ROUTE_DIFF_PAIR )
450  Add( &m_diffPairMenu );
451 
453 
454  AppendSeparator();
455 
456  Add( &m_zoomMenu );
457  Add( &m_gridMenu );
458  }
459 
460 private:
461  CONTEXT_MENU* create() const override
462  {
463  return new ROUTER_TOOL_MENU( m_frame, m_mode );
464  }
465 
472 };
473 
474 
476 {
478 }
479 
480 
482 {
484  return true;
485 }
486 
487 
489 {
490  if( aReason == RUN )
491  TOOL_BASE::Reset( aReason );
492 }
493 
494 
496 {
497 #ifdef DEBUG
498  if( aEvent.IsKeyPressed() )
499  {
500  switch( aEvent.KeyCode() )
501  {
502  case '0':
503  wxLogTrace( "PNS", "saving drag/route log...\n" );
504  m_router->DumpLog();
505  break;
506  }
507  }
508 #endif
509 }
510 
511 
513 {
514  int tl = getView()->GetTopLayer();
515 
516  if( m_startItem )
517  {
518  const LAYER_RANGE& ls = m_startItem->Layers();
519 
520  if( ls.Overlaps( tl ) )
521  return tl;
522  else
523  return ls.Start();
524  }
525 
526  return tl;
527 }
528 
529 
531 {
532  int al = frame()->GetActiveLayer();
533  int cl = m_router->GetCurrentLayer();
534 
535  if( cl != al )
536  {
537  m_router->SwitchLayer( al );
538  }
539 
540  OPT<int> newLayer = m_router->Sizes().PairedLayer( cl );
541 
542  if( !newLayer )
543  newLayer = m_router->Sizes().GetLayerTop();
544 
545  m_router->SwitchLayer( *newLayer );
546  frame()->SetActiveLayer( ToLAYER_ID( *newLayer ) );
547 }
548 
549 
550 static VIATYPE_T getViaTypeFromFlags( int aFlags )
551 {
552  switch( aFlags & VIA_ACTION_FLAGS::VIA_MASK )
553  {
554  case VIA_ACTION_FLAGS::VIA: return VIA_THROUGH;
557  default:
558  wxASSERT_MSG( false, "Unhandled via type" );
559  return VIA_THROUGH;
560  }
561 }
562 
563 
565 {
566  const int actViaFlags = aEvent.Parameter<intptr_t>();
567 
568  VIATYPE_T viaType = getViaTypeFromFlags( actViaFlags );
569  const bool selectLayer = actViaFlags & VIA_ACTION_FLAGS::SELECT_LAYER;
570 
572 
573  const int layerCount = bds.GetCopperLayerCount();
574  int currentLayer = m_router->GetCurrentLayer();
577 
579 
580  // ask the user for a target layer
581  PCB_LAYER_ID targetLayer = UNDEFINED_LAYER;
582 
583  if( selectLayer )
584  {
585  wxPoint dlgPosition = wxGetMousePosition();
586 
587  targetLayer = frame()->SelectLayer( static_cast<PCB_LAYER_ID>( currentLayer ),
588  LSET::AllNonCuMask(), dlgPosition );
589  }
590 
591  // fixme: P&S supports more than one fixed layer pair. Update the dialog?
592  sizes.ClearLayerPairs();
593 
594  if( !m_router->IsPlacingVia() )
595  {
596  // Cannot place microvias or blind vias if not allowed (obvious)
597  if( ( viaType == VIA_BLIND_BURIED ) && ( !bds.m_BlindBuriedViaAllowed ) )
598  {
599  DisplayError( frame(), _( "Blind/buried vias have to be enabled in the design settings." ) );
600  return false;
601  }
602 
603  if( ( viaType == VIA_MICROVIA ) && ( !bds.m_MicroViasAllowed ) )
604  {
605  DisplayError( frame(), _( "Microvias have to be enabled in the design settings." ) );
606  return false;
607  }
608 
609  // Can only place through vias on 2-layer boards
610  if( ( viaType != VIA_THROUGH ) && ( layerCount <= 2 ) )
611  {
612  DisplayError( frame(), _( "Only through vias are allowed on 2 layer boards." ) );
613  return false;
614  }
615 
616  // Can only place microvias if we're on an outer layer, or directly adjacent to one
617  if( ( viaType == VIA_MICROVIA ) && ( currentLayer > In1_Cu ) && ( currentLayer < layerCount - 2 ) )
618  {
619  DisplayError( frame(), _( "Microvias can be placed only between the outer layers " \
620  "(F.Cu/B.Cu) and the ones directly adjacent to them." ) );
621  return false;
622  }
623  }
624 
625  // Convert blind/buried via to a through hole one, if it goes through all layers
626  if( viaType == VIA_BLIND_BURIED && ( ( currentLayer == B_Cu ) || ( currentLayer == F_Cu ) )
627  && ( ( pairTop == B_Cu && pairBottom == F_Cu )
628  || ( pairTop == F_Cu && pairBottom == B_Cu ) ) )
629  {
630  viaType = VIA_THROUGH;
631  }
632 
633  switch( viaType )
634  {
635  case VIA_THROUGH:
636  sizes.SetViaDiameter( bds.GetCurrentViaSize() );
637  sizes.SetViaDrill( bds.GetCurrentViaDrill() );
638 
639  if( targetLayer != UNDEFINED_LAYER )
640  {
641  // go from the current layer to the chosen layer
642  sizes.AddLayerPair( currentLayer, targetLayer );
643  }
644  else
645  {
646  // use the default layer pair
647  sizes.AddLayerPair( pairTop, pairBottom );
648  }
649  break;
650 
651  case VIA_MICROVIA:
652  sizes.SetViaDiameter( bds.GetCurrentMicroViaSize() );
653  sizes.SetViaDrill( bds.GetCurrentMicroViaDrill() );
654 
655  wxASSERT_MSG( !selectLayer, "Unexpected select layer for microvia (microvia layers are implicit)" );
656 
657  if( currentLayer == F_Cu || currentLayer == In1_Cu )
658  {
659  // front-side microvia
660  sizes.AddLayerPair( F_Cu, In1_Cu );
661  }
662  else if( currentLayer == B_Cu || currentLayer == layerCount - 2 )
663  {
664  // back-side microvia
665  sizes.AddLayerPair( B_Cu, layerCount - 2 );
666  }
667  else
668  {
669  wxASSERT_MSG( false, "Invalid layer pair for microvia (must be on or adjacent to an outer layer)" );
670  }
671  break;
672 
673  case VIA_BLIND_BURIED:
674  sizes.SetViaDiameter( bds.GetCurrentViaSize() );
675  sizes.SetViaDrill( bds.GetCurrentViaDrill() );
676 
677  if( targetLayer != UNDEFINED_LAYER )
678  {
679  // go directly to the user specified layer
680  sizes.AddLayerPair( currentLayer, targetLayer );
681  }
682  else
683  {
684  if( currentLayer == pairTop || currentLayer == pairBottom )
685  {
686  // the current layer is on the defined layer pair,
687  // swap to the other side
688  sizes.AddLayerPair( pairTop, pairBottom );
689  }
690  else
691  {
692  // the current layer is not part of the current layer pair,
693  // so fallback and swap to the top layer of the pair by default
694  sizes.AddLayerPair( pairTop, currentLayer );
695  }
696  }
697  break;
698 
699  default:
700  wxASSERT( false );
701  break;
702  }
703 
704  sizes.SetViaType( viaType );
705 
706  m_router->UpdateSizes( sizes );
708 
709  if( m_router->RoutingInProgress() )
710  updateEndItem( aEvent );
711  else
712  updateStartItem( aEvent );
713 
714  m_router->Move( m_endSnapPoint, m_endItem ); // refresh
715 
716  return 0;
717 }
718 
719 
721 {
722  int routingLayer = getStartLayer( m_startItem );
723 
724  if( !IsCopperLayer( routingLayer ) )
725  {
726  DisplayError( frame(), _( "Tracks on Copper layers only" ) );
727  return false;
728  }
729 
730  frame()->SetActiveLayer( ToLAYER_ID( routingLayer ) );
731 
732  // Force layer visible
733  frame()->GetLayerManager()->SetLayerVisible( routingLayer, true );
734 
735  // for some reason I don't understand, GetNetclass() may return null sometimes...
736  if( m_startItem && m_startItem->Net() >= 0 &&
738  {
739  highlightNet( true, m_startItem->Net() );
740  // Update track width and via size shown in main toolbar comboboxes
741  frame()->SetCurrentNetClass( m_startItem->Parent()->GetNetClass()->GetName() );
742  }
743  else
745 
746  controls()->ForceCursorPosition( false );
747  controls()->SetAutoPan( true );
748 
749  PNS::SIZES_SETTINGS sizes( m_router->Sizes() );
750 
751  sizes.Init( board(), m_startItem );
752  sizes.AddLayerPair( frame()->GetScreen()->m_Route_Layer_TOP,
753  frame()->GetScreen()->m_Route_Layer_BOTTOM );
754  m_router->UpdateSizes( sizes );
755 
756  if( !m_router->StartRouting( m_startSnapPoint, m_startItem, routingLayer ) )
757  {
759  highlightNet( false );
760  controls()->SetAutoPan( false );
761  return false;
762  }
763 
764  m_endItem = NULL;
766 
767  frame()->UndoRedoBlock( true );
768 
769  return true;
770 }
771 
772 
774 {
776 
777  controls()->SetAutoPan( false );
778  controls()->ForceCursorPosition( false );
779  frame()->UndoRedoBlock( false );
780  highlightNet( false );
781 
782  return true;
783 }
784 
785 
787 {
788  if( !prepareInteractive() )
789  return;
790 
791  while( OPT_TOOL_EVENT evt = Wait() )
792  {
793  // Don't crash if we missed an operation that cancelled routing.
794  wxCHECK2( m_router->RoutingInProgress(), break );
795 
796  if( evt->IsMotion() )
797  {
798  m_router->SetOrthoMode( evt->Modifier( MD_CTRL ) );
799  updateEndItem( *evt );
801  }
802  else if( evt->IsClick( BUT_LEFT ) || evt->IsAction( &ACT_NewTrack ) )
803  {
804  updateEndItem( *evt );
805  bool needLayerSwitch = m_router->IsPlacingVia();
806  bool forceFinish = evt->Modifier( MD_SHIFT );
807 
808 
809  if( m_router->FixRoute( m_endSnapPoint, m_endItem, forceFinish ) )
810  break;
811 
812  if( needLayerSwitch )
814 
815  // Synchronize the indicated layer
817  updateEndItem( *evt );
819  m_startItem = NULL;
820  }
821  else if( evt->IsAction( &ACT_SwitchPosture ) )
822  {
824  updateEndItem( *evt );
825  m_router->Move( m_endSnapPoint, m_endItem ); // refresh
826  }
827  else if( evt->IsAction( &PCB_ACTIONS::layerChanged ) )
828  {
829  m_router->SwitchLayer( frame()->GetActiveLayer() );
830  updateEndItem( *evt );
831  m_router->Move( m_endSnapPoint, m_endItem ); // refresh
832  }
833  else if( evt->IsAction( &ACT_EndTrack ) )
834  {
835  bool still_routing = true;
836  while( still_routing )
837  still_routing = m_router->FixRoute( m_endSnapPoint, m_endItem );
838  break;
839  }
840  else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt )
841  || evt->IsUndoRedo()
842  || evt->IsAction( &PCB_ACTIONS::routerInlineDrag ) )
843  break;
844  }
845 
847 }
848 
849 
851 {
853  DIALOG_PNS_DIFF_PAIR_DIMENSIONS settingsDlg( frame(), sizes );
854 
855  if( settingsDlg.ShowModal() == wxID_OK )
856  {
857  m_router->UpdateSizes( sizes );
858  m_savedSizes = sizes;
859 
861  bds.SetCustomDiffPairWidth( sizes.DiffPairWidth() );
862  bds.SetCustomDiffPairGap( sizes.DiffPairGap() );
864  }
865 
866  return 0;
867 }
868 
869 
871 {
872  DIALOG_PNS_SETTINGS settingsDlg( frame(), m_router->Settings() );
873 
874  if( settingsDlg.ShowModal() == wxID_OK )
876 
877  return 0;
878 }
879 
880 
882 {
888 
894 
897 }
898 
899 
901 {
902  frame()->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Route Track" ) );
904 }
905 
906 
908 {
909  frame()->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Router Differential Pair" ) );
911 }
912 
913 
915 {
917  {
919  }
920 }
921 
922 
924 {
925  PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>();
926 
927  // Deselect all items
929 
930  Activate();
931 
932  m_router->SetMode( aMode );
933 
934  VIEW_CONTROLS* ctls = getViewControls();
935  ctls->ShowCursor( true );
936  ctls->ForceCursorPosition( false );
938 
939  std::unique_ptr<ROUTER_TOOL_MENU> ctxMenu( new ROUTER_TOOL_MENU( *frame, aMode ) );
940  SetContextMenu( ctxMenu.get() );
941 
942  // Main loop: keep receiving events
943  while( OPT_TOOL_EVENT evt = Wait() )
944  {
946  {
947  break; // Finish
948  }
949  else if( evt->Action() == TA_UNDO_REDO_PRE )
950  {
951  m_router->ClearWorld();
952  }
953  else if( evt->Action() == TA_UNDO_REDO_POST || evt->Action() == TA_MODEL_CHANGE )
954  {
955  m_router->SyncWorld();
956  }
957  else if( evt->IsMotion() )
958  {
959  updateStartItem( *evt );
960  }
961  else if( evt->IsAction( &PCB_ACTIONS::dragFreeAngle ) )
962  {
963  updateStartItem( *evt, true );
965  }
966  else if( evt->IsAction( &PCB_ACTIONS::drag45Degree ) )
967  {
968  updateStartItem( *evt, true );
970  }
971  else if( evt->IsAction( &PCB_ACTIONS::breakTrack ) )
972  {
973  updateStartItem( *evt, true );
974  breakTrack( );
975  }
976  else if( evt->IsClick( BUT_LEFT ) || evt->IsAction( &ACT_NewTrack ) )
977  {
978  updateStartItem( *evt );
979 
980  if( evt->Modifier( MD_CTRL ) )
982  else
983  performRouting();
984  }
985  else if( evt->IsAction( &ACT_PlaceThroughVia ) )
986  {
988  }
989  }
990 
991  frame->SetNoToolSelected();
992  SetContextMenu( nullptr );
993 
994  // Store routing settings till the next invocation
997 
998  return 0;
999 }
1000 
1001 
1003 {
1004  VIEW_CONTROLS* ctls = getViewControls();
1005 
1006  if( m_startItem && m_startItem->IsLocked() )
1007  {
1008  KIDIALOG dlg( frame(), _( "The selected item is locked." ), _( "Confirmation" ),
1009  wxOK | wxCANCEL | wxICON_WARNING );
1010  dlg.SetOKLabel( _( "Drag Anyway" ) );
1011  dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
1012 
1013  if( dlg.ShowModal() == wxID_CANCEL )
1014  return;
1015  }
1016 
1017  bool dragStarted = m_router->StartDragging( m_startSnapPoint, m_startItem, aMode );
1018 
1019  if( !dragStarted )
1020  return;
1021 
1022  if( m_startItem && m_startItem->Net() >= 0 )
1023  highlightNet( true, m_startItem->Net() );
1024 
1025  ctls->SetAutoPan( true );
1026 
1027  frame()->UndoRedoBlock( true );
1028 
1029  while( OPT_TOOL_EVENT evt = Wait() )
1030  {
1031  ctls->ForceCursorPosition( false );
1032 
1033  if( evt->IsMotion() )
1034  {
1035  updateEndItem( *evt );
1037  }
1038  else if( evt->IsClick( BUT_LEFT ) )
1039  {
1041  break;
1042  }
1043  else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt )
1044  || evt->IsUndoRedo() )
1045  break;
1046 
1047  handleCommonEvents( *evt );
1048  }
1049 
1050  if( m_router->RoutingInProgress() )
1051  m_router->StopRouting();
1052 
1053  m_startItem = nullptr;
1054 
1055  frame()->UndoRedoBlock( false );
1056  ctls->SetAutoPan( false );
1057  ctls->ForceCursorPosition( false );
1058  highlightNet( false );
1059 }
1060 
1061 
1063 {
1064  /*
1065  * If the collection contains a trivial line corner (two connected segments)
1066  * or a non-fanout-via (a via with no more than two connected segments), then
1067  * trim the collection down to a single item (which one won't matter since
1068  * they're all connected).
1069  */
1070 
1071  // First make sure we've got something that *might* match.
1072  int vias = aCollector.CountType( PCB_VIA_T );
1073  int traces = aCollector.CountType( PCB_TRACE_T );
1074 
1075  if( vias > 1 || traces > 2 || vias + traces < 1 )
1076  return;
1077 
1078  // Fetch first TRACK (via or trace) as our reference
1079  TRACK* reference = nullptr;
1080 
1081  for( int i = 0; !reference && i < aCollector.GetCount(); i++ )
1082  reference = dynamic_cast<TRACK*>( aCollector[i] );
1083 
1084  int refNet = reference->GetNetCode();
1085 
1086  wxPoint refPoint( aPt.x, aPt.y );
1087  STATUS_FLAGS flags = reference->IsPointOnEnds( refPoint, -1 );
1088 
1089  if( flags & STARTPOINT )
1090  refPoint = reference->GetStart();
1091  else if( flags & ENDPOINT )
1092  refPoint = reference->GetEnd();
1093 
1094  // Check all items to ensure that any TRACKs are co-terminus with the reference and on
1095  // the same net.
1096  for( int i = 0; i < aCollector.GetCount(); i++ )
1097  {
1098  TRACK* neighbor = dynamic_cast<TRACK*>( aCollector[i] );
1099 
1100  if( neighbor && neighbor != reference )
1101  {
1102  if( neighbor->GetNetCode() != refNet )
1103  return;
1104 
1105  if( neighbor->GetStart() != refPoint && neighbor->GetEnd() != refPoint )
1106  return;
1107  }
1108  }
1109 
1110  // Selection meets criteria; trim it to the reference item.
1111  aCollector.Empty();
1112  aCollector.Append( reference );
1113 }
1114 
1115 
1117 {
1119  const auto& selection = m_toolMgr->GetTool<SELECTION_TOOL>()->GetSelection();
1120 
1121  if( selection.Size() == 1 )
1122  {
1123  const BOARD_CONNECTED_ITEM* item = static_cast<const BOARD_CONNECTED_ITEM*>( selection.Front() );
1124 
1125  if( item->Type() == PCB_TRACE_T || item->Type() == PCB_VIA_T )
1126  return true;
1127  }
1128 
1129  return false;
1130 }
1131 
1132 
1134 {
1135  const auto& selection = m_toolMgr->GetTool<SELECTION_TOOL>()->GetSelection();
1136 
1137  if( selection.Empty() )
1139 
1140  if( selection.Size() != 1 )
1141  return 0;
1142 
1143  const BOARD_CONNECTED_ITEM* item = static_cast<const BOARD_CONNECTED_ITEM*>( selection.Front() );
1144 
1145  if( item->Type() != PCB_TRACE_T && item->Type() != PCB_VIA_T )
1146  return 0;
1147 
1148  Activate();
1149 
1151  m_router->SyncWorld();
1153 
1154  if( m_startItem && m_startItem->IsLocked() )
1155  {
1156  KIDIALOG dlg( frame(), _( "The selected item is locked." ), _( "Confirmation" ),
1157  wxOK | wxCANCEL | wxICON_WARNING );
1158  dlg.SetOKLabel( _( "Drag Anyway" ) );
1159  dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
1160 
1161  if( dlg.ShowModal() == wxID_CANCEL )
1162  return 0;
1163  }
1164 
1166 
1167  int dragMode = aEvent.Parameter<int64_t> ();
1168 
1169  bool dragStarted = m_router->StartDragging( p0, m_startItem, dragMode );
1170 
1171  if( !dragStarted )
1172  return 0;
1173 
1174  controls()->ShowCursor( true );
1175  controls()->ForceCursorPosition( false );
1176  controls()->SetAutoPan( true );
1177  frame()->UndoRedoBlock( true );
1178 
1179  while( OPT_TOOL_EVENT evt = Wait() )
1180  {
1181  if( evt->IsCancel() )
1182  {
1183  break;
1184  }
1185  else if( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) )
1186  {
1187  updateEndItem( *evt );
1189  }
1190  else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
1191  {
1192  updateEndItem( *evt );
1194  break;
1195  }
1196  }
1197 
1198  if( m_router->RoutingInProgress() )
1199  m_router->StopRouting();
1200 
1201  controls()->SetAutoPan( false );
1202  controls()->ForceCursorPosition( false );
1203  frame()->UndoRedoBlock( false );
1204 
1205  return 0;
1206 }
1207 
1208 
1210 {
1212  DIALOG_TRACK_VIA_SIZE sizeDlg( frame(), bds );
1213 
1214  if( sizeDlg.ShowModal() )
1215  {
1216  bds.UseCustomTrackViaSize( true );
1218  }
1219 
1220  return 0;
1221 }
1222 
1223 
1225 {
1226  PNS::SIZES_SETTINGS sizes( m_router->Sizes() );
1227  sizes.ImportCurrent( board()->GetDesignSettings() );
1228  m_router->UpdateSizes( sizes );
1229 
1230  return 0;
1231 }
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)
int GetCurrentMicroViaSize()
Function GetCurrentMicroViaSize.
virtual void ShowCursor(bool aEnabled)
Function ShowCursor() Enables or disables display of cursor.
Class ITEM.
Definition: pns_item.h:53
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:114
KICAD_T Type() const
Function Type()
Definition: base_struct.h:201
Struct VIA_DIMENSION is a small helper container to handle a stock of specific vias each with unique ...
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:116
OPT_TOOL_EVENT eventHandler(const wxMenuEvent &aEvent) override
Event handler stub.
virtual int GetTopLayer() const
Definition: view.cpp:848
void DoNotShowCheckbox(wxString file, int line)
Shows the &#39;do not show again&#39; checkbox
Definition: confirm.cpp:60
void SetTrackWidthIndex(unsigned aIndex)
Function SetTrackWidthIndex sets the current track width list index to aIndex.
int GetCurrentViaDrill() const
Function GetCurrentViaDrill.
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
int DpDimensionsDialog(const TOOL_EVENT &aEvent)
Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
Definition: class_module.h:58
const LAYER_RANGE & Layers() const
Function Layers()
Definition: pns_item.h:209
Normal via
Definition: router_tool.cpp:73
Helper class to create more flexible dialogs, including &#39;do not show again&#39; 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:74
Implementation of conversion functions that require both schematic and board internal units...
This file is part of the common library.
const wxString & FailureReason() const
Definition: pns_router.h:214
std::vector< int > m_TrackWidthList
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:137
Tool is invoked after being inactive.
Definition: tool_base.h:82
EDA_ITEM * Front() const
Definition: selection.h:152
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:696
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()
Microvia
Definition: router_tool.cpp:77
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:125
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)
BOARD * GetBoard() const
static TOOL_ACTION trackViaSizeChanged
Definition: pcb_actions.h:294
static TOOL_ACTION drag45Degree
Definition: pcb_actions.h:136
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:198
void UndoRedoBlock(bool aBlock=true)
Function UndoRedoBlock Enables/disable undo and redo operations.
void SetViaDrill(int aDrill)
bool IsPlacingVia() const
Definition: pns_router.cpp:492
SIZES_SETTINGS & Sizes()
Definition: pns_router.h:206
VIATYPE_T
Definition: class_track.h:50
bool IsKeyPressed() const
Definition: tool_event.h:335
int KeyCode() const
Definition: tool_event.h:330
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:429
int CountType(KICAD_T aType)
Function CountType counts the number of items matching aType.
Definition: collector.h:265
void breakTrack()
int GetCurrentViaSize() const
Function GetCurrentViaSize.
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:204
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:501
Struct DIFF_PAIR_DIMENSION is a small helper container to handle a stock of specific differential pai...
const wxPoint & GetEnd() const
Definition: class_track.h:119
NODE * GetWorld() const
Definition: pns_router.h:143
void ToggleViaPlacement()
Definition: pns_router.cpp:442
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
This file contains miscellaneous commonly used macros and functions.
void ClearWorld()
Definition: pns_router.cpp:100
unsigned GetViaSizeIndex() const
Function GetViaSizeIndex.
void Append(EDA_ITEM *item)
Function Append adds an item to the end of the list.
Definition: collector.h:133
bool RoutingInProgress() const
Definition: pns_router.cpp:112
bool OfKind(int aKindMask) const
Function OfKind()
Definition: pns_item.h:132
wxString MessageTextFromValue(EDA_UNITS_T aUnits, int aValue, bool aUseMils)
Definition: base_units.cpp:125
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
KIGFX::VIEW_CONTROLS * controls() const
Definition: pcb_tool.h:138
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:
bool IsLocked() const
Definition: pns_item.h:338
int GetCopperLayerCount() const
Function GetCopperLayerCount.
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:522
static TOOL_ACTION routerActivateTuneDiffPairSkew
Activation of the Push and Shove router (skew tuning mode)
Definition: pcb_actions.h:210
std::shared_ptr< NETCLASS > GetNetClass() const
Function GetNetClass returns the NETCLASS for this item.
static const char Default[]
the name of the default NETCLASS
Definition: netclass.h:80
void update() override
Update menu state stub.
const wxPoint & GetStart() const
Definition: class_track.h:122
CONTEXT_MENU * create() const override
Returns an instance of this class. It has to be overridden in inheriting classes. ...
VECTOR2D GetCursorPosition() const
Returns the current cursor position in world coordinates.
void SetCustomDiffPairWidth(int aWidth)
Function SetCustomDiffPairWidth Sets custom track width for differential pairs (i.e.
PCB_EDIT_FRAME * frame() const
Definition: pcb_tool.h:139
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:367
OPT_TOOL_EVENT eventHandler(const wxMenuEvent &aEvent) override
Event handler stub.
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:77
void SetContextMenu(CONTEXT_MENU *aMenu, CONTEXT_MENU_TRIGGER aTrigger=CMENU_BUTTON)
Function SetContextMenu()
bool CanInlineDrag()
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:538
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
int DiffPairViaGap() const
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:207
bool m_BlindBuriedViaAllowed
true to allow blind/buried vias
const SELECTION & selection() const
Definition: pcb_tool.cpp:245
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)
int Start() const
Definition: pns_layerset.h:83
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:228
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:218
bool StartRouting(const VECTOR2I &aP, ITEM *aItem, int aLayer)
Definition: pns_router.cpp:173
bool Overlaps(const LAYER_RANGE &aOther) const
Definition: pns_layerset.h:68
virtual void SetAutoPan(bool aEnabled)
Function SetAutoPan Turns on/off auto panning (this feature is used when there is a tool active (eg...
KIGFX::VIEW_CONTROLS * getViewControls() const
Function getViewControls()
Definition: tool_base.cpp:41
KIGFX::VIEW * getView() const
Function getView()
Definition: tool_base.cpp:35
static TOOL_ACTION breakTrack
Definition: pcb_actions.h:135
void StopRouting()
Definition: pns_router.cpp:392
int GetNetCode() const
Function GetNetCode.
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
void SetViaType(VIATYPE_T aViaType)
static TOOL_ACTION layerChanged
Definition: pcb_actions.h:286
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:387
TOOL_EVENT MakeEvent() const
Function HasHotKey() Checks if the action has a hot key assigned.
Definition: tool_action.h:104
void UpdateSizes(const SIZES_SETTINGS &aSizes)
Applies stored settings.
Definition: pns_router.cpp:311
void SetMode(ROUTER_MODE aMode)
Definition: pns_router.cpp:510
void update() override
Update menu state stub.
unsigned GetDiffPairIndex() const
Function GetDiffPairIndex.
static TOOL_ACTION routerActivateSettingsDialog
Activation of the Push and Shove settings dialogs.
Definition: pcb_actions.h:213
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:73
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
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)
Class PCB_EDIT_FRAME is the main frame for Pcbnew.
int Net() const
Function Net()
Definition: pns_item.h:179
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
ITEM * FindItemByParent(const BOARD_CONNECTED_ITEM *aParent)
Definition: pns_node.cpp:1329
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:80
std::vector< VIA_DIMENSION > m_ViasDimensionsList
boost::optional< T > OPT
Definition: optional.h:7
unsigned GetTrackWidthIndex() const
Function GetTrackWidthIndex.
int ShowModal() override
Definition: confirm.cpp:102
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.
int GetCurrentLayer() const
Definition: pns_router.cpp:461
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
void AddLayerPair(int aL1, int aL2)
int Size() const
Returns the number of selected parts.
Definition: selection.h:122
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:469
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)
void Save(TOOL_SETTINGS &where) const
bool m_MicroViasAllowed
true to allow micro vias
void SetLayerVisible(LAYER_NUM aLayer, bool isVisible)
Function SetLayerVisible sets aLayer visible or not.
static const TOOL_ACTION ACT_AutoEndRoute("pcbnew.InteractiveRouter.AutoEndRoute", AS_CONTEXT, 'F', _("Auto-end Track"), _("Automagically finishes currently routed track."))
void FlipPosture()
Definition: pns_router.cpp:420
DIFF_PAIR_MENU m_diffPairMenu
int DiffPairWidth() const
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:201
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:245
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
virtual PCB_LAYER_ID GetActiveLayer() const
Function GetActiveLayer returns the active layer.
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:810
VIA_ACTION_FLAGS
Flags used by via tool actions.
Definition: router_tool.cpp:68
EDA_UNITS_T
Definition: common.h:159
static TOOL_ACTION selectionCursor
Select a single item under the cursor position.
Definition: pcb_actions.h:50
BOARD_CONNECTED_ITEM * Parent() const
Function Parent()
Definition: pns_item.h:159
Class LAYER_RANGE.
Definition: pns_layerset.h:32
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.
OPT< TOOL_EVENT > OPT_TOOL_EVENT
Definition: tool_event.h:495
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:284
BOARD * board() const
Definition: pcb_tool.h:140
static TOOL_ACTION routerActivateDpDimensionsDialog
Definition: pcb_actions.h:214