KiCad PCB EDA Suite
drawing_tool.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2014-2017 CERN
5  * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
6  * @author Maciej Suminski <maciej.suminski@cern.ch>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 #include "drawing_tool.h"
27 #include "pcb_actions.h"
28 
29 #include <pcb_edit_frame.h>
30 #include <class_draw_panel_gal.h>
31 #include <project.h>
32 #include <id.h>
33 #include <pcbnew_id.h>
34 #include <confirm.h>
37 
38 #include <view/view_group.h>
39 #include <view/view_controls.h>
40 #include <view/view.h>
42 #include <tool/tool_manager.h>
43 #include <geometry/direction45.h>
44 #include <ratsnest_data.h>
45 #include <board_commit.h>
46 #include <scoped_set_reset.h>
47 #include <bitmaps.h>
48 #include <hotkeys.h>
49 #include <painter.h>
50 
52 
53 #include <class_board.h>
54 #include <class_edge_mod.h>
55 #include <class_pcb_text.h>
56 #include <class_dimension.h>
57 #include <class_zone.h>
58 #include <class_module.h>
59 
60 #include <tools/selection_tool.h>
61 #include <tools/tool_event_utils.h>
63 
65 
66 // Drawing tool actions
67 TOOL_ACTION PCB_ACTIONS::drawLine( "pcbnew.InteractiveDrawing.line",
68  AS_GLOBAL, 0,
69  _( "Draw Line" ), _( "Draw a line" ), NULL, AF_ACTIVATE );
70 
71 TOOL_ACTION PCB_ACTIONS::drawGraphicPolygon( "pcbnew.InteractiveDrawing.graphicPolygon",
72  AS_GLOBAL, 0,
73  _( "Draw Graphic Polygon" ), _( "Draw a graphic polygon" ), NULL, AF_ACTIVATE );
74 
75 TOOL_ACTION PCB_ACTIONS::drawCircle( "pcbnew.InteractiveDrawing.circle",
76  AS_GLOBAL, 0,
77  _( "Draw Circle" ), _( "Draw a circle" ), NULL, AF_ACTIVATE );
78 
79 TOOL_ACTION PCB_ACTIONS::drawArc( "pcbnew.InteractiveDrawing.arc",
80  AS_GLOBAL, 0,
81  _( "Draw Arc" ), _( "Draw an arc" ), NULL, AF_ACTIVATE );
82 
83 TOOL_ACTION PCB_ACTIONS::placeText( "pcbnew.InteractiveDrawing.text",
84  AS_GLOBAL, 0,
85  _( "Add Text" ), _( "Add a text" ), NULL, AF_ACTIVATE );
86 
87 TOOL_ACTION PCB_ACTIONS::drawDimension( "pcbnew.InteractiveDrawing.dimension",
88  AS_GLOBAL, 0,
89  _( "Add Dimension" ), _( "Add a dimension" ), NULL, AF_ACTIVATE );
90 
91 TOOL_ACTION PCB_ACTIONS::drawZone( "pcbnew.InteractiveDrawing.zone",
92  AS_GLOBAL, 0,
93  _( "Add Filled Zone" ), _( "Add a filled zone" ), NULL, AF_ACTIVATE );
94 
95 TOOL_ACTION PCB_ACTIONS::drawVia( "pcbnew.InteractiveDrawing.via",
96  AS_GLOBAL, 0,
97  _( "Add Vias" ), _( "Add free-stanging vias" ), NULL, AF_ACTIVATE );
98 
99 TOOL_ACTION PCB_ACTIONS::drawZoneKeepout( "pcbnew.InteractiveDrawing.keepout",
100  AS_GLOBAL, 0,
101  _( "Add Keepout Area" ), _( "Add a keepout area" ), NULL, AF_ACTIVATE );
102 
103 TOOL_ACTION PCB_ACTIONS::drawZoneCutout( "pcbnew.InteractiveDrawing.zoneCutout",
104  AS_GLOBAL, 0,
105  _( "Add a Zone Cutout" ), _( "Add a cutout area of an existing zone" ),
106  add_zone_cutout_xpm, AF_ACTIVATE );
107 
108 TOOL_ACTION PCB_ACTIONS::drawSimilarZone( "pcbnew.InteractiveDrawing.similarZone",
109  AS_GLOBAL, 0,
110  _( "Add a Similar Zone" ), _( "Add a zone with the same settings as an existing zone" ),
111  add_zone_xpm, AF_ACTIVATE );
112 
113 TOOL_ACTION PCB_ACTIONS::placeDXF( "pcbnew.InteractiveDrawing.placeDXF",
114  AS_GLOBAL, 0,
115  "Place DXF", "", NULL, AF_ACTIVATE );
116 
117 TOOL_ACTION PCB_ACTIONS::setAnchor( "pcbnew.InteractiveDrawing.setAnchor",
118  AS_GLOBAL, 0,
119  _( "Place the Footprint Anchor" ), _( "Place the footprint anchor" ),
120  NULL, AF_ACTIVATE );
121 
122 TOOL_ACTION PCB_ACTIONS::incWidth( "pcbnew.InteractiveDrawing.incWidth",
123  AS_CONTEXT, '+',
124  _( "Increase Line Width" ), _( "Increase the line width" ) );
125 
126 TOOL_ACTION PCB_ACTIONS::decWidth( "pcbnew.InteractiveDrawing.decWidth",
127  AS_CONTEXT, '-',
128  _( "Decrease Line Width" ), _( "Decrease the line width" ) );
129 
130 TOOL_ACTION PCB_ACTIONS::arcPosture( "pcbnew.InteractiveDrawing.arcPosture",
132  _( "Switch Arc Posture" ), _( "Switch the arc posture" ) );
133 
134 /*
135  * Contextual actions
136  */
137 
138 static TOOL_ACTION deleteLastPoint( "pcbnew.InteractiveDrawing.deleteLastPoint",
139  AS_CONTEXT, WXK_BACK,
140  _( "Delete Last Point" ), _( "Delete the last point added to the current item" ),
141  undo_xpm );
142 
143 static TOOL_ACTION closeZoneOutline( "pcbnew.InteractiveDrawing.closeZoneOutline",
144  AS_CONTEXT, 0,
145  _( "Close Zone Outline" ), _( "Close the outline of a zone in progress" ),
146  checked_ok_xpm );
147 
148 
150  PCB_TOOL( "pcbnew.InteractiveDrawing" ),
151  m_view( nullptr ), m_controls( nullptr ),
152  m_board( nullptr ), m_frame( nullptr ), m_mode( MODE::NONE ),
153  m_lineWidth( 1 ),
154  m_menu( *this )
155 {
156 }
157 
158 
160 {
161 }
162 
163 
165 {
166  auto activeToolFunctor = [ this ] ( const SELECTION& aSel ) {
167  return m_mode != MODE::NONE;
168  };
169 
170  // some interactive drawing tools can undo the last point
171  auto canUndoPoint = [ this ] ( const SELECTION& aSel ) {
172  return m_mode == MODE::ARC || m_mode == MODE::ZONE;
173  };
174 
175  // functor for zone-only actions
176  auto zoneActiveFunctor = [this ] ( const SELECTION& aSel ) {
177  return m_mode == MODE::ZONE;
178  };
179 
180  auto& ctxMenu = m_menu.GetMenu();
181 
182  // cancel current toool goes in main context menu at the top if present
183  ctxMenu.AddItem( ACTIONS::cancelInteractive, activeToolFunctor, 1000 );
184 
185  // tool-specific actions
186  ctxMenu.AddItem( closeZoneOutline, zoneActiveFunctor, 1000 );
187  ctxMenu.AddItem( deleteLastPoint, canUndoPoint, 1000 );
188 
189  ctxMenu.AddSeparator( activeToolFunctor, 1000 );
190 
191  // Type-specific sub-menus will be added for us by other tools
192  // For example, zone fill/unfill is provided by the PCB control tool
193 
194  // Finally, add the standard zoom/grid items
195  m_menu.AddStandardSubMenus( *getEditFrame<PCB_BASE_FRAME>() );
196 
197  return true;
198 }
199 
200 
202 {
203  // Init variables used by every drawing tool
204  m_view = getView();
206  m_board = getModel<BOARD>();
207  m_frame = getEditFrame<PCB_BASE_EDIT_FRAME>();
208 }
209 
210 
212 {
213  return m_mode;
214 }
215 
216 
217 int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
218 {
220  DRAWSEGMENT* line = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
221 
222  OPT<VECTOR2D> startingPoint;
223  BOARD_COMMIT commit( m_frame );
224 
225  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::LINE );
226 
228  wxCURSOR_PENCIL, _( "Add graphic line" ) );
230 
231  while( drawSegment( S_SEGMENT, line, startingPoint ) )
232  {
233  if( line )
234  {
235  commit.Add( line );
236  commit.Push( _( "Draw a line segment" ) );
237  startingPoint = VECTOR2D( line->GetEnd() );
238  }
239  else
240  {
241  startingPoint = NULLOPT;
242  }
243 
244  line = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
245  }
246 
248 
249  return 0;
250 }
251 
252 
254 {
256  DRAWSEGMENT* circle = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
257  BOARD_COMMIT commit( m_frame );
258 
259  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::CIRCLE );
260 
262  wxCURSOR_PENCIL, _( "Add graphic circle" ) );
264 
265  while( drawSegment( S_CIRCLE, circle ) )
266  {
267  if( circle )
268  {
269  commit.Add( circle );
270  commit.Push( _( "Draw a circle" ) );
271  }
272 
273  circle = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
274  }
275 
277 
278  return 0;
279 }
280 
281 
282 int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
283 {
285  DRAWSEGMENT* arc = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
286  BOARD_COMMIT commit( m_frame );
287 
288  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ARC );
289 
291  wxCURSOR_PENCIL, _( "Add graphic arc" ) );
293 
294  while( drawArc( arc ) )
295  {
296  if( arc )
297  {
298  commit.Add( arc );
299  commit.Push( _( "Draw an arc" ) );
300  }
301 
302  arc = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
303  }
304 
306 
307  return 0;
308 }
309 
310 
312 {
313  BOARD_ITEM* text = NULL;
314  const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings();
316  SELECTION& selection = selTool->GetSelection();
317  BOARD_COMMIT commit( m_frame );
318 
320  m_controls->ShowCursor( true );
321  m_controls->SetSnapping( true );
322  // do not capture or auto-pan until we start placing some text
323 
324  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::TEXT );
325 
326  Activate();
328  wxCURSOR_PENCIL, _( "Add text" ) );
329 
330  bool reselect = false;
331 
332  // Main loop: keep receiving events
333  while( OPT_TOOL_EVENT evt = Wait() )
334  {
335  VECTOR2I cursorPos = m_controls->GetCursorPosition();
336 
337  if( reselect && text )
339 
341  {
342  if( text )
343  {
345 
346  // Delete the old text and have another try
347  delete text;
348  text = NULL;
349 
350  m_controls->SetAutoPan( false );
351  m_controls->CaptureCursor( false );
352  m_controls->ShowCursor( true );
353  }
354  else
355  break;
356 
357  if( evt->IsActivate() ) // now finish unconditionally
358  break;
359  }
360  else if( evt->IsClick( BUT_RIGHT ) )
361  {
363  }
364  else if( evt->IsClick( BUT_LEFT ) )
365  {
366  if( !text )
367  {
368  // Init the new item attributes
369  if( m_editModules )
370  {
371  TEXTE_MODULE* textMod = new TEXTE_MODULE( (MODULE*) m_frame->GetModel() );
372 
373  textMod->SetLayer( m_frame->GetActiveLayer() );
374  textMod->SetTextSize( dsnSettings.m_ModuleTextSize );
375  textMod->SetThickness( dsnSettings.m_ModuleTextWidth );
376  textMod->SetTextPos( wxPoint( cursorPos.x, cursorPos.y ) );
377 
378  DIALOG_EDIT_FPTEXT textDialog( m_frame, m_frame, textMod, NULL );
379  bool placing;
380 
381  RunMainStack([&]() {
382  placing = textDialog.ShowModal() && ( textMod->GetText().Length() > 0 );
383  } );
384 
385  if( placing )
386  text = textMod;
387  else
388  delete textMod;
389  }
390  else
391  {
392  TEXTE_PCB* textPcb = new TEXTE_PCB( m_frame->GetModel() );
393  // TODO we have to set IS_NEW, otherwise InstallTextPCB.. creates an undo entry :| LEGACY_CLEANUP
394  textPcb->SetFlags( IS_NEW );
395 
397  textPcb->SetLayer( layer );
398 
399  // Set the mirrored option for layers on the BACK side of the board
400  if( IsBackLayer( layer ) )
401  textPcb->SetMirrored( true );
402 
403  textPcb->SetTextSize( dsnSettings.m_PcbTextSize );
404  textPcb->SetThickness( dsnSettings.m_PcbTextWidth );
405  textPcb->SetTextPos( wxPoint( cursorPos.x, cursorPos.y ) );
406 
407  RunMainStack([&]() {
408  getEditFrame<PCB_EDIT_FRAME>()->InstallTextPCBOptionsFrame( textPcb, NULL );
409  } );
410 
411  if( textPcb->GetText().IsEmpty() )
412  delete textPcb;
413  else
414  text = textPcb;
415  }
416 
417  if( text == NULL )
418  continue;
419 
420  m_controls->CaptureCursor( true );
421  m_controls->SetAutoPan( true );
422 
424  }
425  else
426  {
427  text->ClearFlags();
429 
430  commit.Add( text );
431  commit.Push( _( "Place a text" ) );
432 
433  m_controls->CaptureCursor( false );
434  m_controls->SetAutoPan( false );
435  m_controls->ShowCursor( true );
436 
437  text = NULL;
438  }
439  }
440  else if( text && evt->IsMotion() )
441  {
442  text->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
443  selection.SetReferencePoint( cursorPos );
444  m_view->Update( &selection );
445  }
446 
447  else if( text && evt->IsAction( &PCB_ACTIONS::properties ) )
448  {
449  // Calling 'Properties' action clears the selection, so we need to restore it
450  reselect = true;
451  }
452  }
453 
455 
456  return 0;
457 }
458 
459 
461 {
462  DIMENSION* dimension = NULL;
463  BOARD_COMMIT commit( m_frame );
464  int maxThickness;
465 
466  // Add a VIEW_GROUP that serves as a preview for the new item
467  SELECTION preview;
468 
469  m_view->Add( &preview );
470 
472  m_controls->ShowCursor( true );
473  m_controls->SetSnapping( true );
474 
475  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::DIMENSION );
476 
477  Activate();
478  m_frame->SetToolID( ID_PCB_DIMENSION_BUTT, wxCURSOR_PENCIL, _( "Add dimension" ) );
480 
481  enum DIMENSION_STEPS
482  {
483  SET_ORIGIN = 0,
484  SET_END,
485  SET_HEIGHT,
486  FINISHED
487  };
488  int step = SET_ORIGIN;
489 
490  // Main loop: keep receiving events
491  while( OPT_TOOL_EVENT evt = Wait() )
492  {
493  VECTOR2I cursorPos = m_controls->GetCursorPosition();
494 
496  {
497  if( step != SET_ORIGIN ) // start from the beginning
498  {
499  preview.Clear();
500 
501  delete dimension;
502  step = SET_ORIGIN;
503  }
504  else
505  break;
506 
507  if( evt->IsActivate() ) // now finish unconditionally
508  break;
509  }
510  else if( evt->IsAction( &PCB_ACTIONS::incWidth ) && step != SET_ORIGIN )
511  {
513  dimension->SetWidth( m_lineWidth );
514  m_view->Update( &preview );
515  }
516  else if( evt->IsAction( &PCB_ACTIONS::decWidth ) && step != SET_ORIGIN )
517  {
518  if( m_lineWidth > WIDTH_STEP )
519  {
521  dimension->SetWidth( m_lineWidth );
522  m_view->Update( &preview );
523  }
524  }
525  else if( evt->IsClick( BUT_RIGHT ) )
526  {
528  }
529  else if( evt->IsClick( BUT_LEFT ) )
530  {
531  switch( step )
532  {
533  case SET_ORIGIN:
534  {
535  PCB_LAYER_ID layer = getDrawingLayer();
536 
537  if( layer == Edge_Cuts ) // dimensions are not allowed on EdgeCuts
538  layer = Dwgs_User;
539 
540  // Init the new item attributes
541  dimension = new DIMENSION( m_board );
542  dimension->SetLayer( layer );
543  dimension->SetOrigin( wxPoint( cursorPos.x, cursorPos.y ) );
544  dimension->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
546 
548  maxThickness = Clamp_Text_PenSize( width, dimension->Text().GetTextSize() );
549 
550  if( width > maxThickness )
551  width = maxThickness;
552 
553  dimension->Text().SetThickness( width );
554  dimension->SetWidth( width );
555  dimension->AdjustDimensionDetails();
556 
557  preview.Add( dimension );
558 
559  m_controls->SetAutoPan( true );
560  m_controls->CaptureCursor( true );
561  }
562  break;
563 
564  case SET_END:
565  dimension->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
566 
567  // Dimensions that have origin and end in the same spot are not valid
568  if( dimension->GetOrigin() == dimension->GetEnd() )
569  --step;
570 
571  break;
572 
573  case SET_HEIGHT:
574  {
575  if( wxPoint( cursorPos.x, cursorPos.y ) != dimension->GetPosition() )
576  {
577  assert( dimension->GetOrigin() != dimension->GetEnd() );
578  assert( dimension->GetWidth() > 0 );
579 
580  preview.Remove( dimension );
581 
582  commit.Add( dimension );
583  commit.Push( _( "Draw a dimension" ) );
584  }
585  }
586  break;
587  }
588 
589  if( ++step == FINISHED )
590  {
591  step = SET_ORIGIN;
592  m_controls->SetAutoPan( false );
593  m_controls->CaptureCursor( false );
594  }
595  }
596  else if( evt->IsMotion() )
597  {
598  switch( step )
599  {
600  case SET_END:
601  dimension->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
602  break;
603 
604  case SET_HEIGHT:
605  {
606  // Calculating the direction of travel perpendicular to the selected axis
607  double angle = dimension->GetAngle() + ( M_PI / 2 );
608 
609  wxPoint pos( cursorPos.x, cursorPos.y );
610  wxPoint delta( pos - dimension->m_featureLineDO );
611  double height = ( delta.x * cos( angle ) ) + ( delta.y * sin( angle ) );
612  dimension->SetHeight( height );
613  }
614  break;
615  }
616 
617  // Show a preview of the item
618  m_view->Update( &preview );
619  }
620  }
621 
622  if( step != SET_ORIGIN )
623  delete dimension;
624 
625  m_view->Remove( &preview );
627 
628  return 0;
629 }
630 
631 
632 int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
633 {
634  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ZONE );
635 
636  m_frame->SetToolID( ID_PCB_ZONES_BUTT, wxCURSOR_PENCIL, _( "Add zones" ) );
637 
638  return drawZone( false, ZONE_MODE::ADD );
639 }
640 
641 
643 {
644  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::KEEPOUT );
645 
646  m_frame->SetToolID( ID_PCB_KEEPOUT_AREA_BUTT, wxCURSOR_PENCIL, _( "Add keepout" ) );
647 
648  return drawZone( true, ZONE_MODE::ADD );
649 }
650 
651 
653 {
654  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ZONE );
655 
656  m_frame->SetToolID( ID_PCB_ZONES_BUTT, wxCURSOR_PENCIL, _( "Add zone cutout" ) );
657 
658  return drawZone( false, ZONE_MODE::CUTOUT );
659 }
660 
662 {
663  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::GRAPHIC_POLYGON );
664 
666  wxCURSOR_PENCIL, _( "Add graphic polygon" ) );
667 
668  return drawZone( false, ZONE_MODE::GRAPHIC_POLYGON );
669 }
670 
671 
673 {
674  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ZONE );
675 
676  m_frame->SetToolID( ID_PCB_ZONES_BUTT, wxCURSOR_PENCIL, _( "Add similar zone" ) );
677 
678  return drawZone( false, ZONE_MODE::SIMILAR );
679 }
680 
681 
682 int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
683 {
684  if( !m_frame->GetModel() )
685  return 0;
686 
687  DIALOG_DXF_IMPORT dlg( m_frame );
688  int dlgResult = dlg.ShowModal();
689 
690  const std::list<BOARD_ITEM*>& list = dlg.GetImportedItems();
691 
692  if( dlgResult != wxID_OK || list.empty() )
693  return 0;
694 
695  VECTOR2I cursorPos = m_controls->GetCursorPosition();
696  VECTOR2I delta = cursorPos - list.front()->GetPosition();
697 
698  // Add a VIEW_GROUP that serves as a preview for the new item
699  SELECTION preview;
700  BOARD_COMMIT commit( m_frame );
701 
702  // Build the undo list & add items to the current view
703  for( auto item : list )
704  {
705  assert( item->Type() == PCB_LINE_T || item->Type() == PCB_TEXT_T );
706  preview.Add( item );
707  }
708 
709  BOARD_ITEM* firstItem = static_cast<BOARD_ITEM*>( preview.Front() );
710  m_view->Add( &preview );
711 
713  m_controls->ShowCursor( true );
714  m_controls->SetSnapping( true );
715 
716  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::DXF );
717 
718  Activate();
719 
720  // Main loop: keep receiving events
721  while( OPT_TOOL_EVENT evt = Wait() )
722  {
723  cursorPos = m_controls->GetCursorPosition();
724 
725  if( evt->IsMotion() )
726  {
727  delta = cursorPos - firstItem->GetPosition();
728 
729  for( auto item : preview )
730  static_cast<BOARD_ITEM*>( item )->Move( wxPoint( delta.x, delta.y ) );
731 
732  m_view->Update( &preview );
733  }
734  else if( evt->Category() == TC_COMMAND )
735  {
736  // TODO it should be handled by EDIT_TOOL, so add items and select?
737  if( TOOL_EVT_UTILS::IsRotateToolEvt( *evt ) )
738  {
739  const auto rotationPoint = wxPoint( cursorPos.x, cursorPos.y );
740  const auto rotationAngle = TOOL_EVT_UTILS::GetEventRotationAngle(
741  *m_frame, *evt );
742 
743  for( auto item : preview )
744  {
745  static_cast<BOARD_ITEM*>( item )->Rotate( rotationPoint, rotationAngle );
746  }
747 
748  m_view->Update( &preview );
749  }
750  else if( evt->IsAction( &PCB_ACTIONS::flip ) )
751  {
752  for( auto item : preview )
753  static_cast<BOARD_ITEM*>( item )->Flip( wxPoint( cursorPos.x, cursorPos.y ) );
754 
755  m_view->Update( &preview );
756  }
757  else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
758  {
759  preview.FreeItems();
760  break;
761  }
762  }
763  else if( evt->IsClick( BUT_RIGHT ) )
764  {
766  }
767  else if( evt->IsClick( BUT_LEFT ) )
768  {
769  // Place the drawing
771 
772  for( auto item : preview )
773  {
774  if( m_editModules )
775  {
776  // Modules use different types for the same things,
777  // so we need to convert imported items to appropriate classes.
778  BOARD_ITEM* converted = NULL;
779 
780  switch( item->Type() )
781  {
782  case PCB_TEXT_T:
783  {
784  TEXTE_PCB* text = static_cast<TEXTE_PCB*>( item );
785  TEXTE_MODULE* textMod = new TEXTE_MODULE( (MODULE*) parent );
786 
787  // Assignment operator also copies the item PCB_TEXT_T type,
788  // so it cannot be added to a module which handles PCB_MODULE_TEXT_T
789  textMod->SetText( text->GetText() );
790 #if 0
791  textMod->SetTextSize( text->GetTextSize() );
792  textMod->SetThickness( text->GetThickness() );
793  textMod->SetOrientation( text->GetTextAngle() );
794  textMod->SetTextPos( text->GetTextPos() );
795  textMod->SetTextSize( text->GetTextSize() );
796  textMod->SetVisible( text->GetVisible() );
797  textMod->SetMirrored( text->IsMirrored() );
798  textMod->SetItalic( text->IsItalic() );
799  textMod->SetBold( text->IsBold() );
800  textMod->SetHorizJustify( text->GetHorizJustify() );
801  textMod->SetVertJustify( text->GetVertJustify() );
802  textMod->SetMultilineAllowed( text->IsMultilineAllowed() );
803 #else
804  textMod->EDA_TEXT::SetEffects( *text );
805  textMod->SetLocalCoord(); // using changed SetTexPos() via SetEffects()
806 #endif
807  converted = textMod;
808  break;
809  }
810 
811  case PCB_LINE_T:
812  {
813  DRAWSEGMENT* seg = static_cast<DRAWSEGMENT*>( item );
814  EDGE_MODULE* modSeg = new EDGE_MODULE( (MODULE*) parent );
815 
816  // Assignment operator also copies the item PCB_LINE_T type,
817  // so it cannot be added to a module which handles PCB_MODULE_EDGE_T
818  modSeg->SetWidth( seg->GetWidth() );
819  modSeg->SetStart( seg->GetStart() );
820  modSeg->SetEnd( seg->GetEnd() );
821  modSeg->SetAngle( seg->GetAngle() );
822  modSeg->SetShape( seg->GetShape() );
823  modSeg->SetType( seg->GetType() );
824  modSeg->SetBezControl1( seg->GetBezControl1() );
825  modSeg->SetBezControl2( seg->GetBezControl2() );
826  modSeg->SetBezierPoints( seg->GetBezierPoints() );
827  modSeg->SetPolyShape( seg->GetPolyShape() );
828  modSeg->SetLocalCoord();
829  converted = modSeg;
830  break;
831  }
832 
833  default:
834  assert( false );
835  break;
836  }
837 
838  if( converted )
839  converted->SetLayer( static_cast<BOARD_ITEM*>( item )->GetLayer() );
840 
841  delete item;
842  item = converted;
843  }
844 
845  if( item )
846  commit.Add( item );
847  }
848 
849  commit.Push( _( "Place a DXF drawing" ) );
850  break;
851  }
852  }
853 
854  preview.Clear();
855  m_view->Remove( &preview );
856 
857  return 0;
858 }
859 
860 
862 {
863  assert( m_editModules );
864 
865  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ANCHOR );
866 
867  Activate();
868  m_frame->SetToolID( ID_MODEDIT_ANCHOR_TOOL, wxCURSOR_PENCIL,
869  _( "Place the footprint anchor" ) );
870 
871  m_controls->ShowCursor( true );
872  m_controls->SetSnapping( true );
873  m_controls->SetAutoPan( true );
874  m_controls->CaptureCursor( false );
875 
876  while( OPT_TOOL_EVENT evt = Wait() )
877  {
878  if( evt->IsClick( BUT_LEFT ) )
879  {
881  BOARD_COMMIT commit( m_frame );
882  commit.Modify( module );
883 
884  // set the new relative internal local coordinates of footprint items
885  VECTOR2I cursorPos = m_controls->GetCursorPosition();
886  wxPoint moveVector = module->GetPosition() - wxPoint( cursorPos.x, cursorPos.y );
887  module->MoveAnchorPosition( moveVector );
888 
889  commit.Push( _( "Move the footprint reference anchor" ) );
890 
891  // Usually, we do not need to change twice the anchor position,
892  // so deselect the active tool
893  break;
894  }
895  else if( evt->IsClick( BUT_RIGHT ) )
896  {
898  }
899  else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
900  break;
901  }
902 
904 
905  return 0;
906 }
907 
908 
909 bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic,
910  OPT<VECTOR2D> aStartingPoint )
911 {
912  // Only two shapes are currently supported
913  assert( aShape == S_SEGMENT || aShape == S_CIRCLE );
914 
915  DRAWSEGMENT line45;
916 
917  // Add a VIEW_GROUP that serves as a preview for the new item
918  SELECTION preview;
919  m_view->Add( &preview );
920 
922  m_controls->ShowCursor( true );
923  m_controls->SetSnapping( true );
924 
925  Activate();
926 
927  bool direction45 = false; // 45 degrees only mode
928  bool started = false;
929  bool IsOCurseurSet = ( m_frame->GetScreen()->m_O_Curseur != wxPoint( 0, 0 ) );
930  VECTOR2I cursorPos = m_controls->GetCursorPosition();
931 
932  if( aStartingPoint )
933  {
934  // Init the new item attributes
935  aGraphic->SetShape( (STROKE_T) aShape );
936  aGraphic->SetWidth( m_lineWidth );
937  aGraphic->SetStart( wxPoint( aStartingPoint->x, aStartingPoint->y ) );
938  aGraphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
939  aGraphic->SetLayer( getDrawingLayer() );
940 
941  if( aShape == S_SEGMENT )
942  line45 = *aGraphic; // used only for direction 45 mode with lines
943 
944  preview.Add( aGraphic );
945  m_controls->SetAutoPan( true );
946  m_controls->CaptureCursor( true );
947 
948  if( !IsOCurseurSet )
949  m_frame->GetScreen()->m_O_Curseur = wxPoint( aStartingPoint->x, aStartingPoint->y );
950 
951  started = true;
952  }
953 
954  // Main loop: keep receiving events
955  while( OPT_TOOL_EVENT evt = Wait() )
956  {
957  cursorPos = m_controls->GetCursorPosition();
958 
959  // 45 degree angle constraint enabled with an option and toggled with Ctrl
960  const bool limit45 = ( frame()->Settings().m_use45DegreeGraphicSegments != !!( evt->Modifier( MD_CTRL ) ) );
961 
962  if( direction45 != limit45 && started && aShape == S_SEGMENT )
963  {
964  direction45 = limit45;
965 
966  if( direction45 )
967  {
968  preview.Add( &line45 );
969  make45DegLine( aGraphic, &line45 );
970  }
971  else
972  {
973  preview.Remove( &line45 );
974  aGraphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
975  }
976 
977  m_view->Update( &preview );
978  }
979 
981  {
982  preview.Clear();
983  m_view->Update( &preview );
984  delete aGraphic;
985  aGraphic = NULL;
986  if( !IsOCurseurSet )
987  m_frame->GetScreen()->m_O_Curseur = wxPoint( 0, 0 );
988  break;
989  }
990  else if( evt->IsAction( &PCB_ACTIONS::layerChanged ) )
991  {
992  aGraphic->SetLayer( getDrawingLayer() );
993  m_view->Update( &preview );
994  }
995  else if( evt->IsClick( BUT_RIGHT ) )
996  {
998  }
999  else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) )
1000  {
1001  if( !started )
1002  {
1003  // Init the new item attributes
1004  aGraphic->SetShape( (STROKE_T) aShape );
1005  aGraphic->SetWidth( m_lineWidth );
1006  aGraphic->SetStart( wxPoint( cursorPos.x, cursorPos.y ) );
1007  aGraphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
1008  aGraphic->SetLayer( getDrawingLayer() );
1009 
1010  if( !IsOCurseurSet )
1011  m_frame->GetScreen()->m_O_Curseur = wxPoint( cursorPos.x, cursorPos.y );
1012 
1013  if( aShape == S_SEGMENT )
1014  line45 = *aGraphic; // used only for direction 45 mode with lines
1015 
1016  preview.Add( aGraphic );
1017  m_controls->SetAutoPan( true );
1018  m_controls->CaptureCursor( true );
1019 
1020  started = true;
1021  }
1022  else
1023  {
1024  if( aGraphic->GetEnd() == aGraphic->GetStart()
1025  || ( evt->IsDblClick( BUT_LEFT ) && aShape == S_SEGMENT ) )
1026  // User has clicked twice in the same spot
1027  {
1028  // a clear sign that the current drawing is finished
1029  // Now we have to add the helper line as well
1030  if( direction45 )
1031  {
1032  BOARD_ITEM_CONTAINER* parent = m_frame->GetModel();
1033  DRAWSEGMENT* l = m_editModules ? new EDGE_MODULE( (MODULE*) parent )
1034  : new DRAWSEGMENT;
1035 
1036  // Copy coordinates, layer, etc.
1037  *static_cast<DRAWSEGMENT*>( l ) = line45;
1038  l->SetEnd( aGraphic->GetStart() );
1039 
1040  BOARD_COMMIT commit( m_frame );
1041  commit.Add( l );
1042  commit.Push( _( "Draw a line" ) );
1043  }
1044 
1045  delete aGraphic;
1046  aGraphic = NULL;
1047  }
1048 
1049  preview.Clear();
1050  break;
1051  }
1052  }
1053  else if( evt->IsMotion() )
1054  {
1055  // 45 degree lines
1056  if( direction45 && aShape == S_SEGMENT )
1057  make45DegLine( aGraphic, &line45 );
1058  else
1059  aGraphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
1060 
1061  m_view->Update( &preview );
1062  }
1063  else if( evt->IsAction( &PCB_ACTIONS::incWidth ) )
1064  {
1066  aGraphic->SetWidth( m_lineWidth );
1067  line45.SetWidth( m_lineWidth );
1068  m_view->Update( &preview );
1069  }
1070  else if( evt->IsAction( &PCB_ACTIONS::decWidth ) && ( m_lineWidth > WIDTH_STEP ) )
1071  {
1073  aGraphic->SetWidth( m_lineWidth );
1074  line45.SetWidth( m_lineWidth );
1075  m_view->Update( &preview );
1076  }
1077  else if( evt->IsAction( &PCB_ACTIONS::resetCoords ) )
1078  {
1079  IsOCurseurSet = true;
1080  }
1081  }
1082 
1083  if( !IsOCurseurSet ) // reset the relative coordinte if it was not set before
1084  m_frame->GetScreen()->m_O_Curseur = wxPoint( 0, 0 );
1085 
1086  m_view->Remove( &preview );
1087  m_controls->SetAutoPan( false );
1088  m_controls->CaptureCursor( false );
1089 
1090  return started;
1091 }
1092 
1093 
1099  DRAWSEGMENT& aArc )
1100 {
1101  auto vec = aMgr.GetOrigin();
1102 
1103  aArc.SetCenter( { vec.x, vec.y } );
1104 
1105  vec = aMgr.GetStartRadiusEnd();
1106  aArc.SetArcStart( { vec.x, vec.y } );
1107 
1108  aArc.SetAngle( RAD2DECIDEG( -aMgr.GetSubtended() ) );
1109 }
1110 
1111 
1113 {
1115 
1116  // Arc geometric construction manager
1118 
1119  // Arc drawing assistant overlay
1120  KIGFX::PREVIEW::ARC_ASSISTANT arcAsst( arcManager );
1121 
1122  // Add a VIEW_GROUP that serves as a preview for the new item
1123  SELECTION preview;
1124  m_view->Add( &preview );
1125  m_view->Add( &arcAsst );
1126 
1127  m_controls->ShowCursor( true );
1128  m_controls->SetSnapping( true );
1129 
1130  Activate();
1131 
1132  bool firstPoint = false;
1133 
1134  // Main loop: keep receiving events
1135  while( OPT_TOOL_EVENT evt = Wait() )
1136  {
1137  const VECTOR2I cursorPos = m_controls->GetCursorPosition();
1138 
1139  if( evt->IsClick( BUT_LEFT ) )
1140  {
1141  if( !firstPoint )
1142  {
1143  m_controls->SetAutoPan( true );
1144  m_controls->CaptureCursor( true );
1145 
1146  PCB_LAYER_ID layer = getDrawingLayer();
1147 
1148  // Init the new item attributes
1149  // (non-geometric, those are handled by the manager)
1150  aGraphic->SetShape( S_ARC );
1151  aGraphic->SetWidth( m_lineWidth );
1152  aGraphic->SetLayer( layer );
1153 
1154  preview.Add( aGraphic );
1155  firstPoint = true;
1156  }
1157 
1158  arcManager.AddPoint( cursorPos, true );
1159  }
1160  else if( evt->IsAction( &deleteLastPoint ) )
1161  {
1162  arcManager.RemoveLastPoint();
1163  }
1164  else if( evt->IsMotion() )
1165  {
1166  // set angle snap
1167  arcManager.SetAngleSnap( evt->Modifier( MD_CTRL ) );
1168 
1169  // update, but don't step the manager state
1170  arcManager.AddPoint( cursorPos, false );
1171  }
1172  else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
1173  {
1174  preview.Clear();
1175  delete aGraphic;
1176  aGraphic = nullptr;
1177  break;
1178  }
1179  else if( evt->IsClick( BUT_RIGHT ) )
1180  {
1182  }
1183  else if( evt->IsAction( &PCB_ACTIONS::incWidth ) )
1184  {
1186  aGraphic->SetWidth( m_lineWidth );
1187  m_view->Update( &preview );
1188  }
1189  else if( evt->IsAction( &PCB_ACTIONS::decWidth ) && m_lineWidth > WIDTH_STEP )
1190  {
1192  aGraphic->SetWidth( m_lineWidth );
1193  m_view->Update( &preview );
1194  }
1195  else if( evt->IsAction( &PCB_ACTIONS::arcPosture ) )
1196  {
1197  arcManager.ToggleClockwise();
1198  }
1199 
1200  if( arcManager.IsComplete() )
1201  {
1202  break;
1203  }
1204  else if( arcManager.HasGeometryChanged() )
1205  {
1206  updateArcFromConstructionMgr( arcManager, *aGraphic );
1207  m_view->Update( &preview );
1208  m_view->Update( &arcAsst );
1209  }
1210  }
1211 
1212  preview.Remove( aGraphic );
1213  m_view->Remove( &arcAsst );
1214  m_view->Remove( &preview );
1215  m_controls->SetAutoPan( false );
1216  m_controls->CaptureCursor( false );
1217 
1218  return !arcManager.IsReset();
1219 }
1220 
1221 
1223 {
1224  aZone = nullptr;
1225 
1226  // not an action that needs a source zone
1227  if( aMode == ZONE_MODE::ADD || aMode == ZONE_MODE::GRAPHIC_POLYGON )
1228  return true;
1229 
1231  const SELECTION& selection = selTool->GetSelection();
1232 
1233  if( selection.Empty() )
1235 
1236  // we want a single zone
1237  if( selection.Size() != 1 )
1238  return false;
1239 
1240  aZone = dyn_cast<ZONE_CONTAINER*>( selection[0] );
1241 
1242  // expected a zone, but didn't get one
1243  if( !aZone )
1244  return false;
1245 
1246  return true;
1247 }
1248 
1249 
1251 {
1252  auto& controls = *getViewControls();
1253  bool started = false;
1254 
1255  while( OPT_TOOL_EVENT evt = Wait() )
1256  {
1257  VECTOR2I cursorPos = controls.GetCursorPosition();
1258 
1260  {
1261  // pre-empted by another tool, give up
1262  // cancelled without an inprogress polygon, give up
1263  if( !polyGeomMgr.IsPolygonInProgress() || evt->IsActivate() )
1264  {
1265  break;
1266  }
1267 
1268  polyGeomMgr.Reset();
1269  // start again
1270  started = false;
1271 
1272  controls.SetAutoPan( false );
1273  controls.CaptureCursor( false );
1274  }
1275  else if( evt->IsClick( BUT_RIGHT ) )
1276  {
1278  }
1279  // events that lock in nodes
1280  else if( evt->IsClick( BUT_LEFT )
1281  || evt->IsDblClick( BUT_LEFT )
1282  || evt->IsAction( &closeZoneOutline ) )
1283  {
1284  // Check if it is double click / closing line (so we have to finish the zone)
1285  const bool endPolygon = evt->IsDblClick( BUT_LEFT )
1286  || evt->IsAction( &closeZoneOutline )
1287  || polyGeomMgr.NewPointClosesOutline( cursorPos );
1288 
1289  if( endPolygon )
1290  {
1291  polyGeomMgr.SetFinished();
1292  polyGeomMgr.Reset();
1293 
1294  // ready to start again
1295  started = false;
1296  controls.SetAutoPan( false );
1297  controls.CaptureCursor( false );
1298  }
1299  // adding a corner
1300  else if( polyGeomMgr.AddPoint( cursorPos ) )
1301  {
1302  if( !started )
1303  {
1304  started = true;
1305  controls.SetAutoPan( true );
1306  controls.CaptureCursor( true );
1307  }
1308  }
1309  }
1310  else if( evt->IsAction( &deleteLastPoint ) )
1311  {
1312  polyGeomMgr.DeleteLastCorner();
1313 
1314  if( !polyGeomMgr.IsPolygonInProgress() )
1315  {
1316  // report finished as an empty shape
1317  polyGeomMgr.SetFinished();
1318 
1319  // start again
1320  started = false;
1321  controls.SetAutoPan( false );
1322  controls.CaptureCursor( false );
1323  }
1324  }
1325  else if( polyGeomMgr.IsPolygonInProgress()
1326  && ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
1327  {
1328  polyGeomMgr.SetCursorPosition( cursorPos, evt->Modifier( MD_CTRL )
1331  }
1332  } // end while
1333 }
1334 
1335 
1336 int DRAWING_TOOL::drawZone( bool aKeepout, ZONE_MODE aMode )
1337 {
1338  // get a source zone, if we need one. We need it for:
1339  // ZONE_MODE::CUTOUT (adding a hole to the source zone)
1340  // ZONE_MODE::SIMILAR (creating a new zone using settings of source zone
1341  ZONE_CONTAINER* sourceZone = nullptr;
1342 
1343  if( !getSourceZoneForAction( aMode, sourceZone ) )
1344  return 0;
1345 
1347 
1348  params.m_keepout = aKeepout;
1349  params.m_mode = aMode;
1350  params.m_sourceZone = sourceZone;
1351 
1352  ZONE_CREATE_HELPER zoneTool( *this, params );
1353 
1354  // the geometry manager which handles the zone geometry, and
1355  // hands the calculated points over to the zone creator tool
1356  POLYGON_GEOM_MANAGER polyGeomMgr( zoneTool );
1357 
1358  Activate(); // register for events
1359 
1360  auto& controls = *getViewControls();
1361 
1363 
1364  controls.ShowCursor( true );
1365  controls.SetSnapping( true );
1366 
1367  runPolygonEventLoop( polyGeomMgr );
1368 
1370 
1371  return 0;
1372 }
1373 
1374 
1375 void DRAWING_TOOL::make45DegLine( DRAWSEGMENT* aSegment, DRAWSEGMENT* aHelper ) const
1376 {
1377  VECTOR2I cursorPos = m_controls->GetCursorPosition();
1378  VECTOR2I origin( aSegment->GetStart() );
1379  DIRECTION_45 direction( origin - cursorPos );
1380  SHAPE_LINE_CHAIN newChain = direction.BuildInitialTrace( origin, cursorPos );
1381 
1382  if( newChain.PointCount() > 2 )
1383  {
1384  aSegment->SetEnd( wxPoint( newChain.Point( -2 ).x, newChain.Point( -2 ).y ) );
1385  aHelper->SetStart( wxPoint( newChain.Point( -2 ).x, newChain.Point( -2 ).y ) );
1386  aHelper->SetEnd( wxPoint( newChain.Point( -1 ).x, newChain.Point( -1 ).y ) );
1387  }
1388  else
1389  {
1390  aSegment->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
1391  aHelper->SetStart( wxPoint( cursorPos.x, cursorPos.y ) );
1392  aHelper->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
1393  }
1394 }
1395 
1396 
1397 int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
1398 {
1399  struct VIA_PLACER : public INTERACTIVE_PLACER_BASE
1400  {
1401  int findStitchedZoneNet( VIA* aVia )
1402  {
1403  const auto pos = aVia->GetPosition();
1404  const auto lset = aVia->GetLayerSet();
1405 
1406  for( auto tv : m_board->Tracks() ) // fixme: move to BOARD class?
1407  {
1408  if( tv->HitTest( pos ) && ( tv->GetLayerSet() & lset ).any() )
1409  return -1;
1410  }
1411 
1412  for( auto mod : m_board->Modules() )
1413  {
1414  for( auto pad : mod->Pads() )
1415  {
1416  if( pad->HitTest( pos ) && ( pad->GetLayerSet() & lset ).any() )
1417  return -1;
1418  }
1419  }
1420 
1421  std::vector<ZONE_CONTAINER*> foundZones;
1422 
1423  for( auto zone : m_board->Zones() )
1424  {
1425  if( zone->HitTestFilledArea( pos ) )
1426  {
1427  foundZones.push_back( zone );
1428  }
1429  }
1430 
1431  std::sort( foundZones.begin(), foundZones.end(),
1432  [] ( const ZONE_CONTAINER* a, const ZONE_CONTAINER* b ) {
1433  return a->GetLayer() < b->GetLayer();
1434  } );
1435 
1436  // first take the net of the active layer
1437  for( auto z : foundZones )
1438  {
1439  if( m_frame->GetActiveLayer() == z->GetLayer() )
1440  return z->GetNetCode();
1441  }
1442 
1443  // none? take the topmost visible layer
1444  for( auto z : foundZones )
1445  {
1446  if( m_board->IsLayerVisible( z->GetLayer() ) )
1447  return z->GetNetCode();
1448  }
1449 
1450  return -1;
1451  }
1452 
1453  bool PlaceItem( BOARD_ITEM* aItem ) override
1454  {
1455  auto via = static_cast<VIA*>( aItem );
1456  int newNet = findStitchedZoneNet( via );
1457 
1458  if( newNet > 0 )
1459  via->SetNetCode( newNet );
1460 
1461  return false;
1462  }
1463 
1464  std::unique_ptr<BOARD_ITEM> CreateItem() override
1465  {
1466  auto& ds = m_board->GetDesignSettings();
1467  VIA* via = new VIA( m_board );
1468 
1469  via->SetNetCode( 0 );
1470  via->SetViaType( ds.m_CurrentViaType );
1471 
1472  // for microvias, the size and hole will be changed later.
1473  via->SetWidth( ds.GetCurrentViaSize() );
1474  via->SetDrill( ds.GetCurrentViaDrill() );
1475 
1476  // Usual via is from copper to component.
1477  // layer pair is B_Cu and F_Cu.
1478  via->SetLayerPair( B_Cu, F_Cu );
1479 
1480  PCB_LAYER_ID first_layer = m_frame->GetActiveLayer();
1481  PCB_LAYER_ID last_layer;
1482 
1483  // prepare switch to new active layer:
1484  if( first_layer != m_frame->GetScreen()->m_Route_Layer_TOP )
1485  last_layer = m_frame->GetScreen()->m_Route_Layer_TOP;
1486  else
1487  last_layer = m_frame->GetScreen()->m_Route_Layer_BOTTOM;
1488 
1489  // Adjust the actual via layer pair
1490  switch( via->GetViaType() )
1491  {
1492  case VIA_BLIND_BURIED:
1493  via->SetLayerPair( first_layer, last_layer );
1494  break;
1495 
1496  case VIA_MICROVIA: // from external to the near neighbor inner layer
1497  {
1498  PCB_LAYER_ID last_inner_layer =
1499  ToLAYER_ID( ( m_board->GetCopperLayerCount() - 2 ) );
1500 
1501  if( first_layer == B_Cu )
1502  last_layer = last_inner_layer;
1503  else if( first_layer == F_Cu )
1504  last_layer = In1_Cu;
1505  else if( first_layer == last_inner_layer )
1506  last_layer = B_Cu;
1507  else if( first_layer == In1_Cu )
1508  last_layer = F_Cu;
1509 
1510  // else error: will be removed later
1511  via->SetLayerPair( first_layer, last_layer );
1512 
1513  // Update diameter and hole size, which where set previously
1514  // for normal vias
1515  NETINFO_ITEM* net = via->GetNet();
1516 
1517  if( net )
1518  {
1519  via->SetWidth( net->GetMicroViaSize() );
1520  via->SetDrill( net->GetMicroViaDrillSize() );
1521  }
1522  }
1523  break;
1524 
1525  default:
1526  break;
1527  }
1528 
1529  return std::unique_ptr<BOARD_ITEM>( via );
1530  }
1531  };
1532 
1533  VIA_PLACER placer;
1534 
1535  frame()->SetToolID( ID_PCB_DRAW_VIA_BUTT, wxCURSOR_PENCIL, _( "Add vias" ) );
1536 
1537  doInteractiveItemPlacement( &placer, _( "Place via" ),
1539 
1540  frame()->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
1541 
1542  return 0;
1543 }
1544 
1545 
1547 {
1561 }
1562 
1563 
1564 int DRAWING_TOOL::getSegmentWidth( unsigned int aLayer ) const
1565 {
1566  assert( m_board );
1567 
1568  if( aLayer == Edge_Cuts )
1570  else if( m_editModules )
1572  else
1574 }
1575 
1576 
1578 {
1579  PCB_LAYER_ID layer = m_frame->GetActiveLayer();
1580 
1581  if( IsCopperLayer( layer ) )
1582  {
1583  if( layer == F_Cu )
1584  layer = F_SilkS;
1585  else if( layer == B_Cu )
1586  layer = B_SilkS;
1587  else
1588  layer = Dwgs_User;
1589 
1590  m_frame->SetActiveLayer( layer );
1591  }
1592 
1593  return layer;
1594 }
1595 
1596 
1597 const unsigned int DRAWING_TOOL::WIDTH_STEP = 100000;
void SetMirrored(bool isMirrored)
Definition: eda_text.h:176
static TOOL_ACTION selectionClear
Clears the current selection.
Definition: pcb_actions.h:53
virtual void ShowCursor(bool aEnabled)
Function ShowCursor() Enables or disables display of cursor.
void SetCursorPosition(const VECTOR2I &aPos, LEADER_MODE aModifier)
Set the current cursor position.
static TOOL_ACTION drawLine
Activation of the drawing tool (line)
Definition: pcb_actions.h:139
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:60
Class ARC_GEOM_MANAGER.
COMMIT & Modify(EDA_ITEM *aItem)
Modifies a given item in the model.
Definition: commit.h:103
int DrawCircle(const TOOL_EVENT &aEvent)
Function DrawCircle() Starts interactively drawing a circle.
int Clamp_Text_PenSize(int aPenSize, int aSize, bool aBold)
Function Clamp_Text_PenSize As a rule, pen width should not be >1/4em, otherwise the character will b...
void SetShape(STROKE_T aShape)
virtual void Clear() override
Function Clear() Removes all the stored items from the group.
Definition: selection.h:81
virtual void SetToolID(int aId, int aCursor, const wxString &aToolMsg) override
Function SetToolID sets the tool command ID to aId and sets the cursor to aCursor.
const wxPoint & GetBezControl2() const
void SetPolyShape(const SHAPE_POLY_SET &aShape)
bool IsMultilineAllowed() const
Definition: eda_text.h:186
static TOOL_ACTION placeDXF
Activation of the drawing tool (placing a drawing from DXF file)
Definition: pcb_actions.h:178
void SetBezierPoints(const std::vector< wxPoint > &aPoints)
TEXTE_PCB class definition.
int DrawVia(const TOOL_EVENT &aEvent)
const wxPoint & GetTextPos() const
Definition: eda_text.h:222
static TOOL_ACTION closeZoneOutline("pcbnew.InteractiveDrawing.closeZoneOutline", AS_CONTEXT, 0, _("Close Zone Outline"), _("Close the outline of a zone in progress"), checked_ok_xpm)
virtual LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
int DrawZone(const TOOL_EVENT &aEvent)
Function DrawZone() Starts interactively drawing a zone.
BOARD * m_board
Definition: drawing_tool.h:269
void SetViaType(VIATYPE_T aViaType)
Definition: class_track.h:456
static TOOL_ACTION incWidth
Increase width of currently drawn line.
Definition: pcb_actions.h:184
bool IsItalic() const
Definition: eda_text.h:168
virtual void SetPosition(const wxPoint &aPos)=0
void SetArcStart(const wxPoint &aArcStartPoint)
Initialize the start arc point.
MODE GetDrawingMode() const
Function GetDrawingMode.
static TOOL_ACTION drawSimilarZone
Activation of the drawing tool (drawing a similar ZONE to another one)
Definition: pcb_actions.h:169
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
This file is part of the common library.
int drawZone(bool aKeepout, ZONE_MODE aMode)
Draws a polygon, that is added as a zone or a keepout area.
int m_ModuleTextWidth
Default footprint texts thickness.
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
static TOOL_ACTION drawArc
Activation of the drawing tool (arc)
Definition: pcb_actions.h:148
void SetType(int aType)
int m_ModuleSegmentWidth
Default width for all graphic lines.
int DrawLine(const TOOL_EVENT &aEvent)
Function DrawLine() Starts interactively drawing a line.
COMMIT & Add(EDA_ITEM *aItem)
Adds a new item to the model
Definition: commit.h:78
int PointCount() const
Function PointCount()
VIEW_CONTROLS class definition.
int m_PcbTextWidth
current Pcb (not module) Text width
void RunMainStack(std::function< void()> aFunc)
Function RunMainStack()
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it&#39;s a back layer.
int GetWidth() const
static TOOL_ACTION deleteLastPoint("pcbnew.InteractiveDrawing.deleteLastPoint", AS_CONTEXT, WXK_BACK, _("Delete Last Point"), _("Delete the last point added to the current item"), undo_xpm)
Class SELECTION_TOOL.
Class BOARD to handle a board.
Class that computes missing connections on a PCB.
CONDITIONAL_MENU & GetMenu()
Function GetMenu.
Definition: tool_menu.cpp:49
static const unsigned int WIDTH_STEP
Definition: drawing_tool.h:280
void SetItalic(bool isItalic)
Definition: eda_text.h:167
static TOOL_ACTION drawZoneKeepout
Activation of the drawing tool (drawing a keepout area)
Definition: pcb_actions.h:163
EDA_ITEM * Front() const
Definition: selection.h:144
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
static TOOL_ACTION cancelInteractive
Definition: actions.h:45
int GetCopperLayerCount() const
Function GetCopperLayerCount.
virtual void Remove(VIEW_ITEM *aItem)
Function Remove() Removes a VIEW_ITEM from the view.
Definition: view.cpp:339
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:221
virtual PCB_LAYER_ID GetLayer() const override
Function GetLayer returns the primary layer this item is on.
Definition: class_zone.cpp:171
static TOOL_ACTION properties
Activation of the edit tool.
Definition: pcb_actions.h:108
void SetVisible(bool aVisible)
Definition: eda_text.h:173
OPT_TOOL_EVENT Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Function Wait()
bool drawSegment(int aShape, DRAWSEGMENT *&aGraphic, OPT< VECTOR2D > aStartingPoint=NULLOPT)
Starts drawing a selected shape (i.e.
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:92
virtual void SetSnapping(bool aEnabled)
Function SetSnapping() Enables/disables snapping cursor to grid.
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:125
double RAD2DECIDEG(double rad)
Definition: trigo.h:204
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
Classes to handle copper zones.
void RemoveLastPoint()
Undo the last point, and move the manager back to the previous step.
usual segment : line with rounded ends
bool getSourceZoneForAction(ZONE_MODE aMode, ZONE_CONTAINER *&aZone)
Function getSourceZoneForAction()
static void updateArcFromConstructionMgr(const KIGFX::PREVIEW::ARC_GEOM_MANAGER &aMgr, DRAWSEGMENT &aArc)
Update an arc DRAWSEGMENT from the current state of an Arc Geometry Manager.
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:212
Parameters used to fully describe a zone creation process.
bool IsRotateToolEvt(const TOOL_EVENT &aEvt)
Function isRotateToolEvt()
wxSize m_ModuleTextSize
Default footprint texts size.
void MoveAnchorPosition(const wxPoint &aMoveVector)
Function MoveAnchorPosition Move the reference point of the footprint It looks like a move footprint:...
double GetAngle() const
Function GetAngle Returns angle of the crossbar.
void SetCenter(const wxPoint &aCenterPoint)
For arcs and circles:
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
Definition: eda_text.h:188
static TOOL_ACTION setAnchor
Activation of the drawing tool (placing the footprint anchor)
Definition: pcb_actions.h:181
wxPoint m_O_Curseur
Relative Screen cursor coordinate (on grid) in user units.
Definition: base_screen.h:185
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Function Go()
void SetBezControl2(const wxPoint &aPoint)
static TOOL_ACTION placeText
Activation of the drawing tool (text)
Definition: pcb_actions.h:151
static const int delta[8][2]
Definition: solve.cpp:112
Casted dyn_cast(From aObject)
Function dyn_cast()
Definition: typeinfo.h:61
Add a new zone with the same settings as an existing one.
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true) override
Executes the changes.
static TOOL_ACTION resetCoords
Definition: pcb_actions.h:380
void SetLayer(PCB_LAYER_ID aLayer) override
Function SetLayer sets the layer this item is on.
bool IsBold() const
Definition: eda_text.h:171
double GetTextAngle() const
Definition: eda_text.h:162
void AddPoint(const VECTOR2I &aPt, bool aLockIn)
Add a point to the construction manager.
Pcbnew hotkeys.
int GetThickness() const
Function GetThickness returns pen width.
Definition: eda_text.h:152
static TOOL_ACTION decWidth
Decrease width of currently drawn line.
Definition: pcb_actions.h:187
static TOOL_ACTION drawGraphicPolygon
Definition: pcb_actions.h:142
virtual void Add(EDA_ITEM *aItem)
Definition: selection.h:71
void SetWidth(int aWidth)
Definition: class_track.h:115
int PlaceDXF(const TOOL_EVENT &aEvent)
Function PlaceDXF() Places a drawing imported from a DXF file in module editor.
KIGFX::VIEW * m_view
Definition: drawing_tool.h:267
int getSegmentWidth(unsigned int aLayer) const
Returns the appropriate width for a segment depending on the settings.
#define IS_NEW
New item, just created.
Definition: base_struct.h:127
DIMENSION class definition.
KIGFX::VIEW_CONTROLS * controls() const
Definition: pcb_tool.h:133
PCB_LAYER_ID
A quick note on layer IDs:
int PlaceText(const TOOL_EVENT &aEvent)
Function PlaceText() Displays a dialog that allows to input text and its settings and then lets the u...
void AddStandardSubMenus(EDA_DRAW_FRAME &aFrame)
Function CreateBasicMenu.
Definition: tool_menu.cpp:95
STROKE_T GetShape() const
void FreeItems()
Function FreeItems() Frees all the items that were added to the group.
Definition: view_group.cpp:141
Unconstrained point-to-point
void SetOrigin(const wxPoint &aOrigin)
Function SetOrigin Sets a new origin of the crossbar line.
RAII class that sets an value at construction and resets it to the original value at destruction...
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:282
const auto NULLOPT
Definition: optional.h:9
static TOOL_ACTION drawDimension
Activation of the drawing tool (dimension)
Definition: pcb_actions.h:154
DLIST_ITERATOR_WRAPPER< MODULE > Modules()
Definition: class_board.h:250
const wxPoint & GetEnd()
Function GetEnd.
VIATYPE_T GetViaType() const
Definition: class_track.h:455
VECTOR2< double > VECTOR2D
Definition: vector2d.h:588
virtual void CaptureCursor(bool aEnabled)
Function CaptureCursor() Forces the cursor to stay within the drawing panel area. ...
wxSize m_PcbTextSize
current Pcb (not module) Text size
int DrawZoneKeepout(const TOOL_EVENT &aEvent)
Function DrawZoneKeepout() Starts interactively drawing a keepout area.
PCB_GENERAL_SETTINGS & Settings()
Class DIRECTION_45.
Definition: direction45.h:36
const wxPoint & GetOrigin() const
Function GetOrigin.
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:128
void SetEnd(const wxPoint &aEnd)
Function SetEnd Sets a new end of the crossbar line.
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
VECTOR2D GetCursorPosition() const
Returns the current cursor position in world coordinates.
void SetVertJustify(EDA_TEXT_VJUSTIFY_T aType)
Definition: eda_text.h:192
Arcs (with rounded ends)
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
ZONE_CONTAINER * m_sourceZone
Zone settings source (for similar and cutout zones)
PCB_EDIT_FRAME * frame() const
Definition: pcb_tool.h:134
Class TOOL_EVENT.
Definition: tool_event.h:162
unsigned int m_lineWidth
Stores the current line width for multisegment drawing.
Definition: drawing_tool.h:274
int m_DrawSegmentWidth
current graphic line width (not EDGE layer)
SELECTION & GetSelection()
Function GetSelection()
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:532
PCB_LAYER_ID m_Route_Layer_BOTTOM
Definition: pcb_screen.h:46
STROKE_T
Enum STROKE_T is the set of shapes for segments (graphic segments and tracks) which are often in the ...
bool SetNetCode(int aNetCode, bool aNoAssert=false)
Function SetNetCode sets net using a net code.
MODULE * module() const
Definition: pcb_tool.h:136
VIEW_GROUP extends VIEW_ITEM by possibility of grouping items into a single object.
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings returns the BOARD_DESIGN_SETTINGS for the BOARD owned by this frame...
const wxPoint & GetBezControl1() const
static TOOL_ACTION drawVia
Activation of the drawing tool (drawing a VIA)
Definition: pcb_actions.h:160
void SetLayerPair(PCB_LAYER_ID aTopLayer, PCB_LAYER_ID aBottomLayer)
Function SetLayerPair For a via m_Layer contains the top layer, the other layer is in m_BottomLayer...
KIGFX::VIEW_CONTROLS * m_controls
Definition: drawing_tool.h:268
SHAPE_POLY_SET & GetPolyShape()
const SELECTION & selection() const
Definition: pcb_tool.cpp:218
int GetType() const
virtual void SetActiveLayer(PCB_LAYER_ID aLayer)
Function SetActiveLayer will change the currently active layer to aLayer.
bool IsCancelInteractive(const TOOL_EVENT &aEvt)
Function IsCancelInteractive()
All active tools
Definition: tool_event.h:138
virtual void Update(VIEW_ITEM *aItem, int aUpdateFlags)
For dynamic VIEWs, informs the associated VIEW that the graphical representation of this item has cha...
Definition: view.cpp:1382
double GetSubtended() const
Get the angle of the vector leading to the end point (valid if step >= SET_ANGLE) ...
static TOOL_ACTION drawZoneCutout
Activation of the drawing tool (drawing a ZONE cutout)
Definition: pcb_actions.h:166
const wxPoint GetPosition() const override
Definition: class_track.h:427
void SetMultilineAllowed(bool aAllow)
Function SetMultiLineAllowed.
Definition: eda_text.h:185
int DrawZoneCutout(const TOOL_EVENT &aEvent)
Function DrawZoneCutout() Starts interactively drawing a zone cutout area of an existing zone...
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
void AdjustDimensionDetails(bool aDoNotChangeText=false)
Function AdjustDimensionDetails Calculate coordinates of segments used to draw the dimension...
void SetStart(const wxPoint &aStart)
DRAWING_TOOL::ZONE_MODE m_mode
The zone mode to operate in
virtual const wxPoint GetPosition() const =0
void setTransitions() override
Sets up handlers for various events.
PCB_BASE_EDIT_FRAME * m_frame
Definition: drawing_tool.h:270
bool m_editModules
Definition: pcb_tool.h:142
void DeleteLastCorner()
Remove the last-added point from the polygon.
KIGFX::VIEW * getView() const
Function getView()
Definition: tool_base.cpp:35
static TOOL_ACTION drawCircle
Activation of the drawing tool (circle)
Definition: pcb_actions.h:145
const std::vector< wxPoint > & GetBezierPoints() const
void SetLocalCoord()
Set relative coordinates from draw coordinates.
EDA_TEXT_VJUSTIFY_T GetVertJustify() const
Definition: eda_text.h:189
static TOOL_ACTION flip
Flipping of selected objects.
Definition: pcb_actions.h:102
virtual void SetNoToolSelected()
Select the ID_NO_TOOL_SELECTED id tool (Idle tool)
Definition: draw_frame.cpp:574
PCB_LAYER_ID getDrawingLayer() const
Selects a non-copper layer for drawing
MODE
The possible drawing modes of DRAWING_TOOL
Definition: drawing_tool.h:68
Class NETINFO_ITEM handles the data for a net.
Definition: netinfo.h:69
static TOOL_ACTION arcPosture
Switch posture when drawing arc.
Definition: pcb_actions.h:190
void SetLocalCoord()
Set relative coordinates.
static TOOL_ACTION layerChanged
Definition: pcb_actions.h:283
const std::list< BOARD_ITEM * > & GetImportedItems() const
Function GetImportedItems()
int SetAnchor(const TOOL_EVENT &aEvent)
Function SetAnchor() Places the footprint anchor (only in module editor).
ZONE_CONTAINERS & Zones()
Definition: class_board.h:252
double GetAngle() const
void ToggleClockwise()
Reverse the current are direction
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
Definition: eda_text.h:191
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Function AddItem()
bool IsMirrored() const
Definition: eda_text.h:177
Class SHAPE_LINE_CHAIN.
void SetHeight(int aHeight)
Function SetHeight Sets the length of feature lines.
bool NewPointClosesOutline(const VECTOR2I &aPt) const
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
TEXTE_PCB & Text()
Class TOOL_ACTION.
Definition: tool_action.h:46
static TOOL_ACTION selectItem
Selects an item (specified as the event parameter).
Definition: pcb_actions.h:56
void SetDrill(int aDrill)
Function SetDrill sets the drill value for vias.
Definition: class_track.h:463
This class is an adjuct helper to the DRAWING_TOOL interactive tool, which handles incoming geometry ...
Class SELECTION_AREA.
Definition: arc_assistant.h:38
void Reset()
Clear the manager state and start again.
int GetWidth() const
PCB_SCREEN * GetScreen() const override
Function GetScreen returns a pointer to a BASE_SCREEN or one of its derivatives.
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:80
int GetMicroViaDrillSize()
Function GetViaDrillSize returns the size of via drills used to route this net.
Definition: netinfo.h:182
boost::optional< T > OPT
Definition: optional.h:7
void SetEnd(const wxPoint &aEnd)
static bool GetLayer(MODEL_VRML &aModel, LAYER_NUM layer, VRML_LAYER **vlayer)
void SetAngle(double aAngle)
Function SetAngle sets the angle for arcs, and normalizes it within the range 0 - 360 degrees...
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:283
void Activate()
Function Activate() Runs the tool.
virtual BOARD_ITEM_CONTAINER * GetModel() const =0
Function GetModel()
int DrawGraphicPolygon(const TOOL_EVENT &aEvent)
const wxPoint GetPosition() const override
VECTOR2I & Point(int aIndex)
Function Point()
void SetAngleSnap(bool aSnap)
Set angle snapping (for the next point)
DLIST_ITERATOR_WRAPPER< TRACK > Tracks()
Definition: class_board.h:249
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:309
VECTOR2I GetOrigin() const
Get the centre point of the arc (valid when state > SET_ORIGIN)
Module description (excepted pads)
const wxSize & GetTextSize() const
Definition: eda_text.h:213
Abstract interface for BOARD_ITEMs capable of storing other items inside.
bool drawArc(DRAWSEGMENT *&aGraphic)
Starts drawing an arc.
void doInteractiveItemPlacement(INTERACTIVE_PLACER_BASE *aPlacer, const wxString &aCommitMessage, int aOptions=IPO_ROTATE|IPO_FLIP|IPO_REPEAT)
Helper function for performing a common interactive idiom: wait for a left click, place an item there...
Definition: pcb_tool.cpp:39
int m_EdgeSegmentWidth
current graphic line width (EDGE layer only)
bool m_keepout
Should create a keepout zone?
void SetWidth(int aWidth)
EDGE_MODULE class definition.
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:91
Add a new zone/keepout with fresh settings.
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
int GetMicroViaSize()
Function GetMicroViaSize returns the size of vias used to route this net.
Definition: netinfo.h:162
bool AddPoint(const VECTOR2I &aPt)
Lock in a polygon point.
int DrawSimilarZone(const TOOL_EVENT &aEvent)
Function DrawSimilarZone() Starts interactively drawing a zone with same settings as an existing zone...
int GetEventRotationAngle(const PCB_BASE_EDIT_FRAME &aFrame, const TOOL_EVENT &aEvt)
Function getEventRotationAngle()
void SetBold(bool aBold)
Definition: eda_text.h:170
wxPoint m_featureLineDO
void Flip(T &aValue)
void runPolygonEventLoop(POLYGON_GEOM_MANAGER &aPolyGeomMgr)
Run the event loop for polygon creation, sending user input on to the given POLYGON_GEOM_MANAGER for ...
void SetFinished()
Mark the polygon finished and update the client.
int DrawArc(const TOOL_EVENT &aEvent)
Function DrawArc() Starts interactively drawing an arc.
Make a cutout to an existing zone.
void ShowContextMenu(SELECTION &aSelection)
Function ShowContextMenu.
Definition: tool_menu.cpp:62
const wxPoint GetPosition() const override
Definition: class_module.h:181
virtual PCB_LAYER_ID GetActiveLayer() const
Function GetActiveLayer returns the active layer.
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:796
#define mod(a, n)
Definition: greymap.cpp:24
static TOOL_ACTION drawZone
Activation of the drawing tool (drawing a ZONE)
Definition: pcb_actions.h:157
Class DIMENSION.
Class that handles the drawing of a polygon, including management of last corner deletion and drawing...
static TOOL_ACTION selectionCursor
Select a single item under the cursor position.
Definition: pcb_actions.h:50
VECTOR2I GetStartRadiusEnd() const
Get the coordinates of the arc start
NETINFO_ITEM * GetNet() const
Function GetNet Returns NET_INFO object for a given item.
TOOL_MENU m_menu
Menu model displayed by the tool.
Definition: drawing_tool.h:277
PCB_LAYER_ID m_Route_Layer_TOP
Definition: pcb_screen.h:45
void SetThickness(int aNewThickness)
Function SetThickness sets pen width.
Definition: eda_text.h:146
void make45DegLine(DRAWSEGMENT *aSegment, DRAWSEGMENT *aHelper) const
Function make45DegLine() Forces a DRAWSEGMENT to be drawn at multiple of 45 degrees.
OPT< TOOL_EVENT > OPT_TOOL_EVENT
Definition: tool_event.h:465
int DrawDimension(const TOOL_EVENT &aEvent)
Function DrawDimension() Starts interactively drawing a dimension.
Class BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.
bool IsLayerVisible(PCB_LAYER_ID aLayer) const
Function IsLayerVisible is a proxy function that calls the correspondent function in m_BoardSettings ...
Definition: class_board.h:451
void SetBezControl1(const wxPoint &aPoint)
virtual void SetText(const wxString &aText)
Definition: eda_text.h:139
void SetWidth(int aWidth)
virtual void Remove(EDA_ITEM *aItem)
Definition: selection.h:76