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 #include <status_popup.h>
51 #include "grid_helper.h"
52 
54 
55 #include <class_board.h>
56 #include <class_edge_mod.h>
57 #include <class_pcb_text.h>
58 #include <class_dimension.h>
59 #include <class_zone.h>
60 #include <class_module.h>
61 
62 #include <tools/selection_tool.h>
63 #include <tools/tool_event_utils.h>
65 
67 
68 // Drawing tool actions
69 TOOL_ACTION PCB_ACTIONS::drawLine( "pcbnew.InteractiveDrawing.line",
71  _( "Draw Line" ), _( "Draw a line" ), NULL, AF_ACTIVATE );
72 
73 TOOL_ACTION PCB_ACTIONS::drawGraphicPolygon( "pcbnew.InteractiveDrawing.graphicPolygon",
75  _( "Draw Graphic Polygon" ), _( "Draw a graphic polygon" ), NULL, AF_ACTIVATE );
76 
77 TOOL_ACTION PCB_ACTIONS::drawCircle( "pcbnew.InteractiveDrawing.circle",
79  _( "Draw Circle" ), _( "Draw a circle" ), NULL, AF_ACTIVATE );
80 
81 TOOL_ACTION PCB_ACTIONS::drawArc( "pcbnew.InteractiveDrawing.arc",
83  _( "Draw Arc" ), _( "Draw an arc" ), NULL, AF_ACTIVATE );
84 
85 TOOL_ACTION PCB_ACTIONS::placeText( "pcbnew.InteractiveDrawing.text",
87  _( "Add Text" ), _( "Add a text" ), NULL, AF_ACTIVATE );
88 
89 TOOL_ACTION PCB_ACTIONS::drawDimension( "pcbnew.InteractiveDrawing.dimension",
91  _( "Add Dimension" ), _( "Add a dimension" ), NULL, AF_ACTIVATE );
92 
93 TOOL_ACTION PCB_ACTIONS::drawZone( "pcbnew.InteractiveDrawing.zone",
95  _( "Add Filled Zone" ), _( "Add a filled zone" ), NULL, AF_ACTIVATE );
96 
97 TOOL_ACTION PCB_ACTIONS::drawVia( "pcbnew.InteractiveDrawing.via",
99  _( "Add Vias" ), _( "Add free-standing vias" ), NULL, AF_ACTIVATE );
100 
101 TOOL_ACTION PCB_ACTIONS::drawZoneKeepout( "pcbnew.InteractiveDrawing.keepout",
103  _( "Add Keepout Area" ), _( "Add a keepout area" ), NULL, AF_ACTIVATE );
104 
105 TOOL_ACTION PCB_ACTIONS::drawZoneCutout( "pcbnew.InteractiveDrawing.zoneCutout",
107  _( "Add a Zone Cutout" ), _( "Add a cutout area of an existing zone" ),
108  add_zone_cutout_xpm, AF_ACTIVATE );
109 
110 TOOL_ACTION PCB_ACTIONS::drawSimilarZone( "pcbnew.InteractiveDrawing.similarZone",
112  _( "Add a Similar Zone" ), _( "Add a zone with the same settings as an existing zone" ),
113  add_zone_xpm, AF_ACTIVATE );
114 
115 TOOL_ACTION PCB_ACTIONS::placeDXF( "pcbnew.InteractiveDrawing.placeDXF",
117  "Place DXF", "", NULL, AF_ACTIVATE );
118 
119 TOOL_ACTION PCB_ACTIONS::setAnchor( "pcbnew.InteractiveDrawing.setAnchor",
121  _( "Place the Footprint Anchor" ), _( "Place the footprint anchor" ),
122  NULL, AF_ACTIVATE );
123 
124 TOOL_ACTION PCB_ACTIONS::incWidth( "pcbnew.InteractiveDrawing.incWidth",
126  _( "Increase Line Width" ), _( "Increase the line width" ) );
127 
128 TOOL_ACTION PCB_ACTIONS::decWidth( "pcbnew.InteractiveDrawing.decWidth",
130  _( "Decrease Line Width" ), _( "Decrease the line width" ) );
131 
132 TOOL_ACTION PCB_ACTIONS::arcPosture( "pcbnew.InteractiveDrawing.arcPosture",
134  _( "Switch Arc Posture" ), _( "Switch the arc posture" ) );
135 
136 /*
137  * Contextual actions
138  */
139 
140 static TOOL_ACTION deleteLastPoint( "pcbnew.InteractiveDrawing.deleteLastPoint",
141  AS_CONTEXT, WXK_BACK,
142  _( "Delete Last Point" ), _( "Delete the last point added to the current item" ),
143  undo_xpm );
144 
145 static TOOL_ACTION closeZoneOutline( "pcbnew.InteractiveDrawing.closeZoneOutline",
146  AS_CONTEXT, 0,
147  _( "Close Zone Outline" ), _( "Close the outline of a zone in progress" ),
148  checked_ok_xpm );
149 
150 
152  PCB_TOOL( "pcbnew.InteractiveDrawing" ),
153  m_view( nullptr ), m_controls( nullptr ),
154  m_board( nullptr ), m_frame( nullptr ), m_mode( MODE::NONE ),
155  m_lineWidth( 1 ),
156  m_menu( *this )
157 {
158 }
159 
160 
162 {
163 }
164 
165 
167 {
168  auto activeToolFunctor = [ this ] ( const SELECTION& aSel ) {
169  return m_mode != MODE::NONE;
170  };
171 
172  // some interactive drawing tools can undo the last point
173  auto canUndoPoint = [ this ] ( const SELECTION& aSel ) {
174  return m_mode == MODE::ARC || m_mode == MODE::ZONE;
175  };
176 
177  // functor for zone-only actions
178  auto zoneActiveFunctor = [this ] ( const SELECTION& aSel ) {
179  return m_mode == MODE::ZONE;
180  };
181 
182  auto& ctxMenu = m_menu.GetMenu();
183 
184  // cancel current toool goes in main context menu at the top if present
185  ctxMenu.AddItem( ACTIONS::cancelInteractive, activeToolFunctor, 1000 );
186 
187  // tool-specific actions
188  ctxMenu.AddItem( closeZoneOutline, zoneActiveFunctor, 1000 );
189  ctxMenu.AddItem( deleteLastPoint, canUndoPoint, 1000 );
190 
191  ctxMenu.AddSeparator( activeToolFunctor, 1000 );
192 
193  // Type-specific sub-menus will be added for us by other tools
194  // For example, zone fill/unfill is provided by the PCB control tool
195 
196  // Finally, add the standard zoom/grid items
197  m_menu.AddStandardSubMenus( *getEditFrame<PCB_BASE_FRAME>() );
198 
199  return true;
200 }
201 
202 
204 {
205  // Init variables used by every drawing tool
206  m_view = getView();
208  m_board = getModel<BOARD>();
209  m_frame = getEditFrame<PCB_BASE_EDIT_FRAME>();
210 }
211 
212 
214 {
215  return m_mode;
216 }
217 
218 
219 int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
220 {
221  if( m_editModules && !m_frame->GetModel() )
222  return 0;
223 
225  DRAWSEGMENT* line = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
226 
227  OPT<VECTOR2D> startingPoint;
228  BOARD_COMMIT commit( m_frame );
229 
230  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::LINE );
231 
233  wxCURSOR_PENCIL, _( "Add graphic line" ) );
235 
236  while( drawSegment( S_SEGMENT, line, startingPoint ) )
237  {
238  if( line )
239  {
240  commit.Add( line );
241  commit.Push( _( "Draw a line segment" ) );
242  startingPoint = VECTOR2D( line->GetEnd() );
243  }
244  else
245  {
246  startingPoint = NULLOPT;
247  }
248 
249  line = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
250  }
251 
253 
254  return 0;
255 }
256 
257 
259 {
260  if( m_editModules && !m_frame->GetModel() )
261  return 0;
262 
264  DRAWSEGMENT* circle = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
265  BOARD_COMMIT commit( m_frame );
266 
267  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::CIRCLE );
268 
270  wxCURSOR_PENCIL, _( "Add graphic circle" ) );
272 
273  while( drawSegment( S_CIRCLE, circle ) )
274  {
275  if( circle )
276  {
277  commit.Add( circle );
278  commit.Push( _( "Draw a circle" ) );
279  }
280 
281  circle = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
282  }
283 
285 
286  return 0;
287 }
288 
289 
290 int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
291 {
292  if( m_editModules && !m_frame->GetModel() )
293  return 0;
294 
296  DRAWSEGMENT* arc = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
297  BOARD_COMMIT commit( m_frame );
298 
299  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ARC );
300 
302  wxCURSOR_PENCIL, _( "Add graphic arc" ) );
304 
305  while( drawArc( arc ) )
306  {
307  if( arc )
308  {
309  commit.Add( arc );
310  commit.Push( _( "Draw an arc" ) );
311  }
312 
313  arc = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
314  }
315 
317 
318  return 0;
319 }
320 
321 
323 {
324  if( m_editModules && !m_frame->GetModel() )
325  return 0;
326 
327  BOARD_ITEM* text = NULL;
328  const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings();
330  SELECTION& selection = selTool->GetSelection();
331  BOARD_COMMIT commit( m_frame );
332 
334  m_controls->ShowCursor( true );
335  m_controls->SetSnapping( true );
336  // do not capture or auto-pan until we start placing some text
337 
338  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::TEXT );
339 
340  Activate();
342  wxCURSOR_PENCIL, _( "Add text" ) );
343 
344  bool reselect = false;
345 
346  // Main loop: keep receiving events
347  while( OPT_TOOL_EVENT evt = Wait() )
348  {
349  VECTOR2I cursorPos = m_controls->GetCursorPosition();
350 
351  if( reselect && text )
353 
355  {
356  if( text )
357  {
359 
360  // Delete the old text and have another try
361  delete text;
362  text = NULL;
363 
364  m_controls->SetAutoPan( false );
365  m_controls->CaptureCursor( false );
366  m_controls->ShowCursor( true );
367  }
368  else
369  break;
370 
371  if( evt->IsActivate() ) // now finish unconditionally
372  break;
373  }
374  else if( evt->IsClick( BUT_RIGHT ) )
375  {
377  }
378  else if( evt->IsClick( BUT_LEFT ) )
379  {
380  if( !text )
381  {
382  // Init the new item attributes
383  if( m_editModules )
384  {
385  TEXTE_MODULE* textMod = new TEXTE_MODULE( (MODULE*) m_frame->GetModel() );
386 
387  textMod->SetLayer( m_frame->GetActiveLayer() );
388  textMod->SetTextSize( dsnSettings.m_ModuleTextSize );
389  textMod->SetThickness( dsnSettings.m_ModuleTextWidth );
390  textMod->SetTextPos( wxPoint( cursorPos.x, cursorPos.y ) );
391 
392  DIALOG_EDIT_FPTEXT textDialog( m_frame, m_frame, textMod, NULL );
393  bool placing;
394 
395  RunMainStack([&]() {
396  placing = textDialog.ShowModal() && ( textMod->GetText().Length() > 0 );
397  } );
398 
399  if( placing )
400  text = textMod;
401  else
402  delete textMod;
403  }
404  else
405  {
406  TEXTE_PCB* textPcb = new TEXTE_PCB( m_frame->GetModel() );
407  // TODO we have to set IS_NEW, otherwise InstallTextPCB.. creates an undo entry :| LEGACY_CLEANUP
408  textPcb->SetFlags( IS_NEW );
409 
411  textPcb->SetLayer( layer );
412 
413  // Set the mirrored option for layers on the BACK side of the board
414  if( IsBackLayer( layer ) )
415  textPcb->SetMirrored( true );
416 
417  textPcb->SetTextSize( dsnSettings.m_PcbTextSize );
418  textPcb->SetThickness( dsnSettings.m_PcbTextWidth );
419  textPcb->SetTextPos( wxPoint( cursorPos.x, cursorPos.y ) );
420 
421  RunMainStack([&]() {
422  getEditFrame<PCB_EDIT_FRAME>()->InstallTextPCBOptionsFrame( textPcb, NULL );
423  } );
424 
425  if( textPcb->GetText().IsEmpty() )
426  delete textPcb;
427  else
428  text = textPcb;
429  }
430 
431  if( text == NULL )
432  continue;
433 
434  m_controls->CaptureCursor( true );
435  m_controls->SetAutoPan( true );
436 
438  }
439  else
440  {
441  text->ClearFlags();
443 
444  commit.Add( text );
445  commit.Push( _( "Place a text" ) );
446 
447  m_controls->CaptureCursor( false );
448  m_controls->SetAutoPan( false );
449  m_controls->ShowCursor( true );
450 
451  text = NULL;
452  }
453  }
454  else if( text && evt->IsMotion() )
455  {
456  text->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
457  selection.SetReferencePoint( cursorPos );
458  m_view->Update( &selection );
459  frame()->SetMsgPanel( text );
460  }
461 
462  else if( text && evt->IsAction( &PCB_ACTIONS::properties ) )
463  {
464  // Calling 'Properties' action clears the selection, so we need to restore it
465  reselect = true;
466  }
467  }
468 
469  frame()->SetMsgPanel( board() );
471 
472  return 0;
473 }
474 
475 
477 {
478  VECTOR2I lineVector( dimension->GetEnd() - dimension->GetOrigin() );
479  double angle = lineVector.Angle();
480  double newAngle = KiROUND( angle / M_PI_4 ) * M_PI_4;
481  VECTOR2I newLineVector = lineVector.Rotate( newAngle - angle );
482 
483  dimension->SetEnd( dimension->GetOrigin() + static_cast<wxPoint>( newLineVector ) );
484 }
485 
486 
488 {
489  if( m_editModules && !m_frame->GetModel() )
490  return 0;
491 
492  DIMENSION* dimension = NULL;
493  BOARD_COMMIT commit( m_frame );
494  int maxThickness;
495 
496  // Add a VIEW_GROUP that serves as a preview for the new item
497  SELECTION preview;
498 
499  m_view->Add( &preview );
500 
502  m_controls->ShowCursor( true );
503  m_controls->SetSnapping( true );
504 
505  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::DIMENSION );
506 
507  Activate();
508  m_frame->SetToolID( ID_PCB_DIMENSION_BUTT, wxCURSOR_PENCIL, _( "Add dimension" ) );
510 
511  enum DIMENSION_STEPS
512  {
513  SET_ORIGIN = 0,
514  SET_END,
515  SET_HEIGHT,
516  FINISHED
517  };
518  int step = SET_ORIGIN;
519 
520  // Main loop: keep receiving events
521  while( OPT_TOOL_EVENT evt = Wait() )
522  {
523  VECTOR2I cursorPos = m_controls->GetCursorPosition();
524 
526  {
527  if( step != SET_ORIGIN ) // start from the beginning
528  {
529  preview.Clear();
530 
531  delete dimension;
532  step = SET_ORIGIN;
533  }
534  else
535  break;
536 
537  if( evt->IsActivate() ) // now finish unconditionally
538  break;
539  }
540  else if( evt->IsAction( &PCB_ACTIONS::incWidth ) && step != SET_ORIGIN )
541  {
543  dimension->SetWidth( m_lineWidth );
544  m_view->Update( &preview );
545  frame()->SetMsgPanel( dimension );
546  }
547  else if( evt->IsAction( &PCB_ACTIONS::decWidth ) && step != SET_ORIGIN )
548  {
549  if( m_lineWidth > WIDTH_STEP )
550  {
552  dimension->SetWidth( m_lineWidth );
553  m_view->Update( &preview );
554  frame()->SetMsgPanel( dimension );
555  }
556  }
557  else if( evt->IsClick( BUT_RIGHT ) )
558  {
560  }
561  else if( evt->IsClick( BUT_LEFT ) )
562  {
563  switch( step )
564  {
565  case SET_ORIGIN:
566  {
567  PCB_LAYER_ID layer = getDrawingLayer();
568 
569  if( layer == Edge_Cuts ) // dimensions are not allowed on EdgeCuts
570  layer = Dwgs_User;
571 
572  // Init the new item attributes
573  dimension = new DIMENSION( m_board );
574  dimension->SetLayer( layer );
575  dimension->SetOrigin( wxPoint( cursorPos.x, cursorPos.y ) );
576  dimension->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
578 
580  maxThickness = Clamp_Text_PenSize( width, dimension->Text().GetTextSize() );
581 
582  if( width > maxThickness )
583  width = maxThickness;
584 
585  dimension->Text().SetThickness( width );
586  dimension->SetWidth( width );
587  dimension->AdjustDimensionDetails();
588 
589  preview.Add( dimension );
590  frame()->SetMsgPanel( dimension );
591 
592  m_controls->SetAutoPan( true );
593  m_controls->CaptureCursor( true );
594  }
595  break;
596 
597  case SET_END:
598  dimension->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
599 
600  if( !!evt->Modifier( MD_CTRL ) )
601  constrainDimension( dimension );
602 
603  // Dimensions that have origin and end in the same spot are not valid
604  if( dimension->GetOrigin() == dimension->GetEnd() )
605  --step;
606 
607  break;
608 
609  case SET_HEIGHT:
610  {
611  if( wxPoint( cursorPos.x, cursorPos.y ) != dimension->GetPosition() )
612  {
613  assert( dimension->GetOrigin() != dimension->GetEnd() );
614  assert( dimension->GetWidth() > 0 );
615 
616  preview.Remove( dimension );
617 
618  commit.Add( dimension );
619  commit.Push( _( "Draw a dimension" ) );
620  }
621  }
622  break;
623  }
624 
625  if( ++step == FINISHED )
626  {
627  step = SET_ORIGIN;
628  m_controls->SetAutoPan( false );
629  m_controls->CaptureCursor( false );
630  }
631  }
632  else if( evt->IsMotion() )
633  {
634  switch( step )
635  {
636  case SET_END:
637  dimension->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
638 
639  if( !!evt->Modifier( MD_CTRL ) )
640  constrainDimension( dimension );
641 
642  break;
643 
644  case SET_HEIGHT:
645  {
646  // Calculating the direction of travel perpendicular to the selected axis
647  double angle = dimension->GetAngle() + ( M_PI / 2 );
648 
649  wxPoint pos( cursorPos.x, cursorPos.y );
650  wxPoint delta( pos - dimension->m_featureLineDO );
651  double height = ( delta.x * cos( angle ) ) + ( delta.y * sin( angle ) );
652  dimension->SetHeight( height );
653  }
654  break;
655  }
656 
657  // Show a preview of the item
658  m_view->Update( &preview );
659  if( step )
660  frame()->SetMsgPanel( dimension );
661  else
662  frame()->SetMsgPanel( board() );
663  }
664  }
665 
666  if( step != SET_ORIGIN )
667  delete dimension;
668 
669  m_view->Remove( &preview );
670  frame()->SetMsgPanel( board() );
672 
673  return 0;
674 }
675 
676 
677 int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
678 {
679  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ZONE );
680 
681  m_frame->SetToolID( ID_PCB_ZONES_BUTT, wxCURSOR_PENCIL, _( "Add zones" ) );
682 
683  return drawZone( false, ZONE_MODE::ADD );
684 }
685 
686 
688 {
689  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::KEEPOUT );
690 
691  m_frame->SetToolID( ID_PCB_KEEPOUT_AREA_BUTT, wxCURSOR_PENCIL, _( "Add keepout" ) );
692 
693  return drawZone( true, ZONE_MODE::ADD );
694 }
695 
696 
698 {
699  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ZONE );
700 
701  m_frame->SetToolID( ID_PCB_ZONES_BUTT, wxCURSOR_PENCIL, _( "Add zone cutout" ) );
702 
703  return drawZone( false, ZONE_MODE::CUTOUT );
704 }
705 
706 
708 {
709  if( m_editModules && !m_frame->GetModel() )
710  return 0;
711 
712  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::GRAPHIC_POLYGON );
713 
715  wxCURSOR_PENCIL, _( "Add graphic polygon" ) );
716 
717  return drawZone( false, ZONE_MODE::GRAPHIC_POLYGON );
718 }
719 
720 
722 {
723  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ZONE );
724 
725  m_frame->SetToolID( ID_PCB_ZONES_BUTT, wxCURSOR_PENCIL, _( "Add similar zone" ) );
726 
727  return drawZone( false, ZONE_MODE::SIMILAR );
728 }
729 
730 
731 int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
732 {
733  if( !m_frame->GetModel() )
734  return 0;
735 
736  DIALOG_DXF_IMPORT dlg( m_frame );
737  int dlgResult = dlg.ShowModal();
738 
739  const std::list<BOARD_ITEM*>& list = dlg.GetImportedItems();
740 
741  if( dlgResult != wxID_OK || list.empty() )
742  return 0;
743 
744  VECTOR2I cursorPos = m_controls->GetCursorPosition();
745  VECTOR2I delta = cursorPos - list.front()->GetPosition();
746 
747  // Add a VIEW_GROUP that serves as a preview for the new item
748  SELECTION preview;
749  BOARD_COMMIT commit( m_frame );
750 
751  // Build the undo list & add items to the current view
752  for( auto item : list )
753  {
754  assert( item->Type() == PCB_LINE_T || item->Type() == PCB_TEXT_T );
755  preview.Add( item );
756  }
757 
758  BOARD_ITEM* firstItem = static_cast<BOARD_ITEM*>( preview.Front() );
759  m_view->Add( &preview );
760 
762  m_controls->ShowCursor( true );
763  m_controls->SetSnapping( true );
764 
765  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::DXF );
766 
767  Activate();
768 
769  // Main loop: keep receiving events
770  while( OPT_TOOL_EVENT evt = Wait() )
771  {
772  cursorPos = m_controls->GetCursorPosition();
773 
774  if( evt->IsMotion() )
775  {
776  delta = cursorPos - firstItem->GetPosition();
777 
778  for( auto item : preview )
779  static_cast<BOARD_ITEM*>( item )->Move( wxPoint( delta.x, delta.y ) );
780 
781  m_view->Update( &preview );
782  }
783  else if( evt->Category() == TC_COMMAND )
784  {
785  // TODO it should be handled by EDIT_TOOL, so add items and select?
786  if( TOOL_EVT_UTILS::IsRotateToolEvt( *evt ) )
787  {
788  const auto rotationPoint = wxPoint( cursorPos.x, cursorPos.y );
789  const auto rotationAngle = TOOL_EVT_UTILS::GetEventRotationAngle(
790  *m_frame, *evt );
791 
792  for( auto item : preview )
793  {
794  static_cast<BOARD_ITEM*>( item )->Rotate( rotationPoint, rotationAngle );
795  }
796 
797  m_view->Update( &preview );
798  }
799  else if( evt->IsAction( &PCB_ACTIONS::flip ) )
800  {
801  for( auto item : preview )
802  static_cast<BOARD_ITEM*>( item )->Flip( wxPoint( cursorPos.x, cursorPos.y ) );
803 
804  m_view->Update( &preview );
805  }
806  else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
807  {
808  preview.FreeItems();
809  break;
810  }
811  }
812  else if( evt->IsClick( BUT_RIGHT ) )
813  {
815  }
816  else if( evt->IsClick( BUT_LEFT ) )
817  {
818  // Place the drawing
820 
821  for( auto item : preview )
822  {
823  if( m_editModules )
824  {
825  // Modules use different types for the same things,
826  // so we need to convert imported items to appropriate classes.
827  BOARD_ITEM* converted = NULL;
828 
829  switch( item->Type() )
830  {
831  case PCB_TEXT_T:
832  {
833  TEXTE_PCB* text = static_cast<TEXTE_PCB*>( item );
834  TEXTE_MODULE* textMod = new TEXTE_MODULE( (MODULE*) parent );
835 
836  // Assignment operator also copies the item PCB_TEXT_T type,
837  // so it cannot be added to a module which handles PCB_MODULE_TEXT_T
838  textMod->SetText( text->GetText() );
839 #if 0
840  textMod->SetTextSize( text->GetTextSize() );
841  textMod->SetThickness( text->GetThickness() );
842  textMod->SetOrientation( text->GetTextAngle() );
843  textMod->SetTextPos( text->GetTextPos() );
844  textMod->SetTextSize( text->GetTextSize() );
845  textMod->SetVisible( text->GetVisible() );
846  textMod->SetMirrored( text->IsMirrored() );
847  textMod->SetItalic( text->IsItalic() );
848  textMod->SetBold( text->IsBold() );
849  textMod->SetHorizJustify( text->GetHorizJustify() );
850  textMod->SetVertJustify( text->GetVertJustify() );
851  textMod->SetMultilineAllowed( text->IsMultilineAllowed() );
852 #else
853  textMod->EDA_TEXT::SetEffects( *text );
854  textMod->SetLocalCoord(); // using changed SetTexPos() via SetEffects()
855 #endif
856  converted = textMod;
857  break;
858  }
859 
860  case PCB_LINE_T:
861  {
862  DRAWSEGMENT* seg = static_cast<DRAWSEGMENT*>( item );
863  EDGE_MODULE* modSeg = new EDGE_MODULE( (MODULE*) parent );
864 
865  // Assignment operator also copies the item PCB_LINE_T type,
866  // so it cannot be added to a module which handles PCB_MODULE_EDGE_T
867  modSeg->SetWidth( seg->GetWidth() );
868  modSeg->SetStart( seg->GetStart() );
869  modSeg->SetEnd( seg->GetEnd() );
870  modSeg->SetAngle( seg->GetAngle() );
871  modSeg->SetShape( seg->GetShape() );
872  modSeg->SetType( seg->GetType() );
873  modSeg->SetBezControl1( seg->GetBezControl1() );
874  modSeg->SetBezControl2( seg->GetBezControl2() );
875  modSeg->SetBezierPoints( seg->GetBezierPoints() );
876  modSeg->SetPolyShape( seg->GetPolyShape() );
877  modSeg->SetLocalCoord();
878  converted = modSeg;
879  break;
880  }
881 
882  default:
883  assert( false );
884  break;
885  }
886 
887  if( converted )
888  converted->SetLayer( static_cast<BOARD_ITEM*>( item )->GetLayer() );
889 
890  delete item;
891  item = converted;
892  }
893 
894  if( item )
895  commit.Add( item );
896  }
897 
898  commit.Push( _( "Place a DXF drawing" ) );
899  break;
900  }
901  }
902 
903  preview.Clear();
904  m_view->Remove( &preview );
905 
906  return 0;
907 }
908 
909 
911 {
912  assert( m_editModules );
913 
914  if( !m_frame->GetModel() )
915  return 0;
916 
917  SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ANCHOR );
918 
919  Activate();
920  m_frame->SetToolID( ID_MODEDIT_ANCHOR_TOOL, wxCURSOR_PENCIL,
921  _( "Place the footprint anchor" ) );
922 
923  m_controls->ShowCursor( true );
924  m_controls->SetSnapping( true );
925  m_controls->SetAutoPan( true );
926  m_controls->CaptureCursor( false );
927 
928  while( OPT_TOOL_EVENT evt = Wait() )
929  {
930  if( evt->IsClick( BUT_LEFT ) )
931  {
933  BOARD_COMMIT commit( m_frame );
934  commit.Modify( module );
935 
936  // set the new relative internal local coordinates of footprint items
937  VECTOR2I cursorPos = m_controls->GetCursorPosition();
938  wxPoint moveVector = module->GetPosition() - wxPoint( cursorPos.x, cursorPos.y );
939  module->MoveAnchorPosition( moveVector );
940 
941  commit.Push( _( "Move the footprint reference anchor" ) );
942 
943  // Usually, we do not need to change twice the anchor position,
944  // so deselect the active tool
945  break;
946  }
947  else if( evt->IsClick( BUT_RIGHT ) )
948  {
950  }
951  else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
952  break;
953  }
954 
956 
957  return 0;
958 }
959 
960 
961 bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic,
962  OPT<VECTOR2D> aStartingPoint )
963 {
964  // Only two shapes are currently supported
965  assert( aShape == S_SEGMENT || aShape == S_CIRCLE );
966 
967  DRAWSEGMENT line45;
968 
969  // Add a VIEW_GROUP that serves as a preview for the new item
970  SELECTION preview;
971  m_view->Add( &preview );
972 
974  m_controls->ShowCursor( true );
975  m_controls->SetSnapping( true );
976 
977  Activate();
978 
979  bool direction45 = false; // 45 degrees only mode
980  bool started = false;
981  bool IsOCurseurSet = ( m_frame->GetScreen()->m_O_Curseur != wxPoint( 0, 0 ) );
982  VECTOR2I cursorPos = m_controls->GetCursorPosition();
983 
984  if( aStartingPoint )
985  {
986  // Init the new item attributes
987  aGraphic->SetShape( (STROKE_T) aShape );
988  aGraphic->SetWidth( m_lineWidth );
989  aGraphic->SetStart( wxPoint( aStartingPoint->x, aStartingPoint->y ) );
990  aGraphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
991  aGraphic->SetLayer( getDrawingLayer() );
992 
993  if( aShape == S_SEGMENT )
994  line45 = *aGraphic; // used only for direction 45 mode with lines
995 
996  preview.Add( aGraphic );
997  m_controls->SetAutoPan( true );
998  m_controls->CaptureCursor( true );
999 
1000  if( !IsOCurseurSet )
1001  m_frame->GetScreen()->m_O_Curseur = wxPoint( aStartingPoint->x, aStartingPoint->y );
1002 
1003  started = true;
1004  }
1005 
1006  // Main loop: keep receiving events
1007  while( OPT_TOOL_EVENT evt = Wait() )
1008  {
1009  cursorPos = m_controls->GetCursorPosition();
1010 
1011  // 45 degree angle constraint enabled with an option and toggled with Ctrl
1012  const bool limit45 = ( frame()->Settings().m_use45DegreeGraphicSegments != !!( evt->Modifier( MD_CTRL ) ) );
1013 
1014  if( direction45 != limit45 && started && aShape == S_SEGMENT )
1015  {
1016  direction45 = limit45;
1017 
1018  if( direction45 )
1019  {
1020  preview.Add( &line45 );
1021  make45DegLine( aGraphic, &line45 );
1022  }
1023  else
1024  {
1025  preview.Remove( &line45 );
1026  aGraphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
1027  }
1028 
1029  m_view->Update( &preview );
1030  frame()->SetMsgPanel( aGraphic );
1031  }
1032 
1034  {
1035  preview.Clear();
1036  m_view->Update( &preview );
1037  delete aGraphic;
1038  aGraphic = NULL;
1039  if( !IsOCurseurSet )
1040  m_frame->GetScreen()->m_O_Curseur = wxPoint( 0, 0 );
1041  break;
1042  }
1043  else if( evt->IsAction( &PCB_ACTIONS::layerChanged ) )
1044  {
1045  aGraphic->SetLayer( getDrawingLayer() );
1046  m_view->Update( &preview );
1047  frame()->SetMsgPanel( aGraphic );
1048  }
1049  else if( evt->IsClick( BUT_RIGHT ) )
1050  {
1052  }
1053  else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) )
1054  {
1055  if( !started )
1056  {
1057  // Init the new item attributes
1058  aGraphic->SetShape( (STROKE_T) aShape );
1059  aGraphic->SetWidth( m_lineWidth );
1060  aGraphic->SetStart( wxPoint( cursorPos.x, cursorPos.y ) );
1061  aGraphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
1062  aGraphic->SetLayer( getDrawingLayer() );
1063 
1064  if( !IsOCurseurSet )
1065  m_frame->GetScreen()->m_O_Curseur = wxPoint( cursorPos.x, cursorPos.y );
1066 
1067  if( aShape == S_SEGMENT )
1068  line45 = *aGraphic; // used only for direction 45 mode with lines
1069 
1070  preview.Add( aGraphic );
1071  frame()->SetMsgPanel( aGraphic );
1072  m_controls->SetAutoPan( true );
1073  m_controls->CaptureCursor( true );
1074 
1075  started = true;
1076  }
1077  else
1078  {
1079  if( aGraphic->GetEnd() == aGraphic->GetStart()
1080  || ( evt->IsDblClick( BUT_LEFT ) && aShape == S_SEGMENT ) )
1081  // User has clicked twice in the same spot
1082  {
1083  // a clear sign that the current drawing is finished
1084  // Now we have to add the helper line as well, unless it is zero-length
1085  if( direction45 && line45.GetStart() != aGraphic->GetStart() )
1086  {
1087  BOARD_ITEM_CONTAINER* parent = m_frame->GetModel();
1088  DRAWSEGMENT* l = m_editModules ? new EDGE_MODULE( (MODULE*) parent )
1089  : new DRAWSEGMENT;
1090 
1091  // Copy coordinates, layer, etc.
1092  *static_cast<DRAWSEGMENT*>( l ) = line45;
1093  l->SetEnd( aGraphic->GetStart() );
1094 
1095  BOARD_COMMIT commit( m_frame );
1096  commit.Add( l );
1097  commit.Push( _( "Draw a line" ) );
1098  }
1099 
1100  delete aGraphic;
1101  aGraphic = NULL;
1102  }
1103 
1104  preview.Clear();
1105  break;
1106  }
1107  }
1108  else if( evt->IsMotion() )
1109  {
1110  // 45 degree lines
1111  if( direction45 && aShape == S_SEGMENT )
1112  make45DegLine( aGraphic, &line45 );
1113  else
1114  aGraphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
1115 
1116  m_view->Update( &preview );
1117 
1118  if( started )
1119  frame()->SetMsgPanel( aGraphic );
1120  else
1121  frame()->SetMsgPanel( board() );
1122  }
1123  else if( evt->IsAction( &PCB_ACTIONS::incWidth ) )
1124  {
1126  aGraphic->SetWidth( m_lineWidth );
1127  line45.SetWidth( m_lineWidth );
1128  m_view->Update( &preview );
1129  frame()->SetMsgPanel( aGraphic );
1130  }
1131  else if( evt->IsAction( &PCB_ACTIONS::decWidth ) && ( m_lineWidth > WIDTH_STEP ) )
1132  {
1134  aGraphic->SetWidth( m_lineWidth );
1135  line45.SetWidth( m_lineWidth );
1136  m_view->Update( &preview );
1137  frame()->SetMsgPanel( aGraphic );
1138  }
1139  else if( evt->IsAction( &PCB_ACTIONS::resetCoords ) )
1140  {
1141  IsOCurseurSet = true;
1142  }
1143  }
1144 
1145  if( !IsOCurseurSet ) // reset the relative coordinte if it was not set before
1146  m_frame->GetScreen()->m_O_Curseur = wxPoint( 0, 0 );
1147 
1148  m_view->Remove( &preview );
1149  frame()->SetMsgPanel( board() );
1150  m_controls->SetAutoPan( false );
1151  m_controls->CaptureCursor( false );
1152 
1153  return started;
1154 }
1155 
1156 
1162  DRAWSEGMENT& aArc )
1163 {
1164  auto vec = aMgr.GetOrigin();
1165 
1166  aArc.SetCenter( { vec.x, vec.y } );
1167 
1168  vec = aMgr.GetStartRadiusEnd();
1169  aArc.SetArcStart( { vec.x, vec.y } );
1170 
1171  aArc.SetAngle( RAD2DECIDEG( -aMgr.GetSubtended() ) );
1172 }
1173 
1174 
1176 {
1178 
1179  // Arc geometric construction manager
1181 
1182  // Arc drawing assistant overlay
1183  KIGFX::PREVIEW::ARC_ASSISTANT arcAsst( arcManager );
1184 
1185  // Add a VIEW_GROUP that serves as a preview for the new item
1186  SELECTION preview;
1187  m_view->Add( &preview );
1188  m_view->Add( &arcAsst );
1189 
1190  m_controls->ShowCursor( true );
1191  m_controls->SetSnapping( true );
1192 
1193  Activate();
1194 
1195  bool firstPoint = false;
1196 
1197  // Main loop: keep receiving events
1198  while( OPT_TOOL_EVENT evt = Wait() )
1199  {
1200  const VECTOR2I cursorPos = m_controls->GetCursorPosition();
1201 
1202  if( evt->IsClick( BUT_LEFT ) )
1203  {
1204  if( !firstPoint )
1205  {
1206  m_controls->SetAutoPan( true );
1207  m_controls->CaptureCursor( true );
1208 
1209  PCB_LAYER_ID layer = getDrawingLayer();
1210 
1211  // Init the new item attributes
1212  // (non-geometric, those are handled by the manager)
1213  aGraphic->SetShape( S_ARC );
1214  aGraphic->SetWidth( m_lineWidth );
1215  aGraphic->SetLayer( layer );
1216 
1217  preview.Add( aGraphic );
1218  firstPoint = true;
1219  }
1220 
1221  arcManager.AddPoint( cursorPos, true );
1222  }
1223  else if( evt->IsAction( &deleteLastPoint ) )
1224  {
1225  arcManager.RemoveLastPoint();
1226  }
1227  else if( evt->IsMotion() )
1228  {
1229  // set angle snap
1230  arcManager.SetAngleSnap( evt->Modifier( MD_CTRL ) );
1231 
1232  // update, but don't step the manager state
1233  arcManager.AddPoint( cursorPos, false );
1234  }
1235  else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
1236  {
1237  preview.Clear();
1238  delete aGraphic;
1239  aGraphic = nullptr;
1240  break;
1241  }
1242  else if( evt->IsClick( BUT_RIGHT ) )
1243  {
1245  }
1246  else if( evt->IsAction( &PCB_ACTIONS::incWidth ) )
1247  {
1249  aGraphic->SetWidth( m_lineWidth );
1250  m_view->Update( &preview );
1251  frame()->SetMsgPanel( aGraphic );
1252  }
1253  else if( evt->IsAction( &PCB_ACTIONS::decWidth ) && m_lineWidth > WIDTH_STEP )
1254  {
1256  aGraphic->SetWidth( m_lineWidth );
1257  m_view->Update( &preview );
1258  frame()->SetMsgPanel( aGraphic );
1259  }
1260  else if( evt->IsAction( &PCB_ACTIONS::arcPosture ) )
1261  {
1262  arcManager.ToggleClockwise();
1263  }
1264 
1265  if( arcManager.IsComplete() )
1266  {
1267  break;
1268  }
1269  else if( arcManager.HasGeometryChanged() )
1270  {
1271  updateArcFromConstructionMgr( arcManager, *aGraphic );
1272  m_view->Update( &preview );
1273  m_view->Update( &arcAsst );
1274 
1275  if(firstPoint)
1276  frame()->SetMsgPanel( aGraphic );
1277  else
1278  frame()->SetMsgPanel( board() );
1279  }
1280  }
1281 
1282  preview.Remove( aGraphic );
1283  m_view->Remove( &arcAsst );
1284  m_view->Remove( &preview );
1285  frame()->SetMsgPanel( board() );
1286  m_controls->SetAutoPan( false );
1287  m_controls->CaptureCursor( false );
1288 
1289  return !arcManager.IsReset();
1290 }
1291 
1292 
1294 {
1295  aZone = nullptr;
1296 
1297  // not an action that needs a source zone
1298  if( aMode == ZONE_MODE::ADD || aMode == ZONE_MODE::GRAPHIC_POLYGON )
1299  return true;
1300 
1302  const SELECTION& selection = selTool->GetSelection();
1303 
1304  if( selection.Empty() )
1306 
1307  // we want a single zone
1308  if( selection.Size() != 1 )
1309  return false;
1310 
1311  aZone = dyn_cast<ZONE_CONTAINER*>( selection[0] );
1312 
1313  // expected a zone, but didn't get one
1314  if( !aZone )
1315  return false;
1316 
1317  return true;
1318 }
1319 
1320 
1322 {
1323  auto& controls = *getViewControls();
1324  bool started = false;
1325 
1326  STATUS_TEXT_POPUP status( m_frame );
1327  status.SetTextColor( wxColour( 255, 0, 0 ) );
1328  status.SetText( _( "Self-intersecting polygons are not allowed" ) );
1329 
1330  while( OPT_TOOL_EVENT evt = Wait() )
1331  {
1332  VECTOR2I cursorPos = controls.GetCursorPosition();
1333 
1335  {
1336  // pre-empted by another tool, give up
1337  // cancelled without an inprogress polygon, give up
1338  if( !polyGeomMgr.IsPolygonInProgress() || evt->IsActivate() )
1339  {
1340  break;
1341  }
1342 
1343  polyGeomMgr.Reset();
1344  // start again
1345  started = false;
1346 
1347  controls.SetAutoPan( false );
1348  controls.CaptureCursor( false );
1349  }
1350  else if( evt->IsClick( BUT_RIGHT ) )
1351  {
1353  }
1354  // events that lock in nodes
1355  else if( evt->IsClick( BUT_LEFT )
1356  || evt->IsDblClick( BUT_LEFT )
1357  || evt->IsAction( &closeZoneOutline ) )
1358  {
1359  // Check if it is double click / closing line (so we have to finish the zone)
1360  const bool endPolygon = evt->IsDblClick( BUT_LEFT )
1361  || evt->IsAction( &closeZoneOutline )
1362  || polyGeomMgr.NewPointClosesOutline( cursorPos );
1363 
1364  if( endPolygon )
1365  {
1366  polyGeomMgr.SetFinished();
1367  polyGeomMgr.Reset();
1368 
1369  // ready to start again
1370  started = false;
1371  controls.SetAutoPan( false );
1372  controls.CaptureCursor( false );
1373  }
1374 
1375  // adding a corner
1376  else if( polyGeomMgr.AddPoint( cursorPos ) )
1377  {
1378  if( !started )
1379  {
1380  started = true;
1381  controls.SetAutoPan( true );
1382  controls.CaptureCursor( true );
1383  }
1384  }
1385 
1386  }
1387  else if( evt->IsAction( &deleteLastPoint ) )
1388  {
1389  polyGeomMgr.DeleteLastCorner();
1390 
1391  if( !polyGeomMgr.IsPolygonInProgress() )
1392  {
1393  // report finished as an empty shape
1394  polyGeomMgr.SetFinished();
1395 
1396  // start again
1397  started = false;
1398  controls.SetAutoPan( false );
1399  controls.CaptureCursor( false );
1400  }
1401  }
1402  else if( polyGeomMgr.IsPolygonInProgress()
1403  && ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
1404  {
1405  polyGeomMgr.SetCursorPosition( cursorPos, evt->Modifier( MD_CTRL )
1408 
1409  if( polyGeomMgr.IsSelfIntersecting( true ) )
1410  {
1411  wxPoint p = wxGetMousePosition() + wxPoint( 20, 20 );
1412  status.Move( p );
1413  status.Popup( m_frame );
1414  status.Expire( 1500 );
1415  }
1416  else
1417  {
1418  status.Hide();
1419  }
1420  }
1421  } // end while
1422 }
1423 
1424 
1425 int DRAWING_TOOL::drawZone( bool aKeepout, ZONE_MODE aMode )
1426 {
1427  // get a source zone, if we need one. We need it for:
1428  // ZONE_MODE::CUTOUT (adding a hole to the source zone)
1429  // ZONE_MODE::SIMILAR (creating a new zone using settings of source zone
1430  ZONE_CONTAINER* sourceZone = nullptr;
1431 
1432  if( !getSourceZoneForAction( aMode, sourceZone ) )
1433  return 0;
1434 
1436 
1437  params.m_keepout = aKeepout;
1438  params.m_mode = aMode;
1439  params.m_sourceZone = sourceZone;
1440 
1441  ZONE_CREATE_HELPER zoneTool( *this, params );
1442 
1443  // the geometry manager which handles the zone geometry, and
1444  // hands the calculated points over to the zone creator tool
1445  POLYGON_GEOM_MANAGER polyGeomMgr( zoneTool );
1446 
1447  Activate(); // register for events
1448 
1449  auto& controls = *getViewControls();
1450 
1452 
1453  controls.ShowCursor( true );
1454  controls.SetSnapping( true );
1455 
1456  runPolygonEventLoop( polyGeomMgr );
1457 
1459 
1460  return 0;
1461 }
1462 
1463 
1464 void DRAWING_TOOL::make45DegLine( DRAWSEGMENT* aSegment, DRAWSEGMENT* aHelper ) const
1465 {
1466  VECTOR2I cursorPos = m_controls->GetCursorPosition();
1467  VECTOR2I origin( aSegment->GetStart() );
1468  DIRECTION_45 direction( origin - cursorPos );
1469  SHAPE_LINE_CHAIN newChain = direction.BuildInitialTrace( origin, cursorPos );
1470 
1471  if( newChain.PointCount() > 2 )
1472  {
1473  aSegment->SetEnd( wxPoint( newChain.Point( -2 ).x, newChain.Point( -2 ).y ) );
1474  aHelper->SetStart( wxPoint( newChain.Point( -2 ).x, newChain.Point( -2 ).y ) );
1475  aHelper->SetEnd( wxPoint( newChain.Point( -1 ).x, newChain.Point( -1 ).y ) );
1476  }
1477  else
1478  {
1479  aSegment->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
1480  aHelper->SetStart( wxPoint( cursorPos.x, cursorPos.y ) );
1481  aHelper->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
1482  }
1483 }
1484 
1485 
1486 int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
1487 {
1488  struct VIA_PLACER : public INTERACTIVE_PLACER_BASE
1489  {
1490  GRID_HELPER m_gridHelper;
1491 
1492  VIA_PLACER( PCB_EDIT_FRAME* aFrame ) : m_gridHelper( aFrame )
1493  {}
1494 
1495  TRACK* findTrack( VIA* aVia )
1496  {
1497  const LSET lset = aVia->GetLayerSet();
1498 
1499  for( TRACK* track : m_board->Tracks() )
1500  {
1501  if( !(track->GetLayerSet() & lset ).any() )
1502  continue;
1503 
1504  if( TestSegmentHit( aVia->GetPosition(), track->GetStart(), track->GetEnd(),
1505  ( track->GetWidth() + aVia->GetWidth() ) / 2 ) )
1506  return track;
1507  }
1508 
1509  return nullptr;
1510  }
1511 
1512  int findStitchedZoneNet( VIA* aVia )
1513  {
1514  const auto pos = aVia->GetPosition();
1515  const auto lset = aVia->GetLayerSet();
1516 
1517  for( auto mod : m_board->Modules() )
1518  {
1519  for( D_PAD* pad : mod->Pads() )
1520  {
1521  if( pad->HitTest( pos ) && ( pad->GetLayerSet() & lset ).any() )
1522  return -1;
1523  }
1524  }
1525 
1526  std::vector<ZONE_CONTAINER*> foundZones;
1527 
1528  for( auto zone : m_board->Zones() )
1529  {
1530  if( zone->HitTestFilledArea( pos ) )
1531  {
1532  foundZones.push_back( zone );
1533  }
1534  }
1535 
1536  std::sort( foundZones.begin(), foundZones.end(),
1537  [] ( const ZONE_CONTAINER* a, const ZONE_CONTAINER* b ) {
1538  return a->GetLayer() < b->GetLayer();
1539  } );
1540 
1541  // first take the net of the active layer
1542  for( auto z : foundZones )
1543  {
1544  if( m_frame->GetActiveLayer() == z->GetLayer() )
1545  return z->GetNetCode();
1546  }
1547 
1548  // none? take the topmost visible layer
1549  for( auto z : foundZones )
1550  {
1551  if( m_board->IsLayerVisible( z->GetLayer() ) )
1552  return z->GetNetCode();
1553  }
1554 
1555  return -1;
1556  }
1557 
1558  void SnapItem( BOARD_ITEM *aItem ) override
1559  {
1560  // If you place a Via on a track but not on its centerline, the current
1561  // connectivity algorithm will require us to put a kink in the track when
1562  // we break it (so that each of the two segments ends on the via center).
1563  // That's not ideal, and is in fact probably worse than forcing snap in
1564  // this situation.
1565 
1566 // bool do_snap = ( m_frame->Settings().m_magneticTracks == CAPTURE_CURSOR_IN_TRACK_TOOL
1567 // || m_frame->Settings().m_magneticTracks == CAPTURE_ALWAYS );
1568  bool do_snap = true;
1569 
1570  if( m_modifiers & MD_SHIFT )
1571  do_snap = !do_snap;
1572 
1573  if( do_snap )
1574  {
1575  auto via = static_cast<VIA*>( aItem );
1576  wxPoint pos = via->GetPosition();
1577  TRACK* track = findTrack( via );
1578 
1579  if( track )
1580  {
1581  SEG trackSeg( track->GetStart(), track->GetEnd() );
1582  VECTOR2I snap = m_gridHelper.AlignToSegment( pos, trackSeg );
1583 
1584  aItem->SetPosition( wxPoint( snap.x, snap.y ) );
1585  }
1586  }
1587  }
1588 
1589  void PlaceItem( BOARD_ITEM* aItem, BOARD_COMMIT& aCommit ) override
1590  {
1591  auto via = static_cast<VIA*>( aItem );
1592  int newNet;
1593  TRACK* track = findTrack( via );
1594 
1595  if( track )
1596  {
1597  aCommit.Modify( track );
1598  TRACK* newTrack = dynamic_cast<TRACK*>( track->Clone() );
1599  track->SetEnd( via->GetPosition() );
1600  newTrack->SetStart( via->GetPosition() );
1601  aCommit.Add( newTrack );
1602 
1603  newNet = track->GetNetCode();
1604  }
1605  else
1606  newNet = findStitchedZoneNet( via );
1607 
1608  if( newNet > 0 )
1609  via->SetNetCode( newNet );
1610 
1611  aCommit.Add( aItem );
1612  }
1613 
1614  std::unique_ptr<BOARD_ITEM> CreateItem() override
1615  {
1616  auto& ds = m_board->GetDesignSettings();
1617  VIA* via = new VIA( m_board );
1618 
1619  via->SetNetCode( 0 );
1620  via->SetViaType( ds.m_CurrentViaType );
1621 
1622  // for microvias, the size and hole will be changed later.
1623  via->SetWidth( ds.GetCurrentViaSize() );
1624  via->SetDrill( ds.GetCurrentViaDrill() );
1625 
1626  // Usual via is from copper to component.
1627  // layer pair is B_Cu and F_Cu.
1628  via->SetLayerPair( B_Cu, F_Cu );
1629 
1630  PCB_LAYER_ID first_layer = m_frame->GetActiveLayer();
1631  PCB_LAYER_ID last_layer;
1632 
1633  // prepare switch to new active layer:
1634  if( first_layer != m_frame->GetScreen()->m_Route_Layer_TOP )
1635  last_layer = m_frame->GetScreen()->m_Route_Layer_TOP;
1636  else
1637  last_layer = m_frame->GetScreen()->m_Route_Layer_BOTTOM;
1638 
1639  // Adjust the actual via layer pair
1640  switch( via->GetViaType() )
1641  {
1642  case VIA_BLIND_BURIED:
1643  via->SetLayerPair( first_layer, last_layer );
1644  break;
1645 
1646  case VIA_MICROVIA: // from external to the near neighbor inner layer
1647  {
1648  PCB_LAYER_ID last_inner_layer =
1649  ToLAYER_ID( ( m_board->GetCopperLayerCount() - 2 ) );
1650 
1651  if( first_layer == B_Cu )
1652  last_layer = last_inner_layer;
1653  else if( first_layer == F_Cu )
1654  last_layer = In1_Cu;
1655  else if( first_layer == last_inner_layer )
1656  last_layer = B_Cu;
1657  else if( first_layer == In1_Cu )
1658  last_layer = F_Cu;
1659 
1660  // else error: will be removed later
1661  via->SetLayerPair( first_layer, last_layer );
1662 
1663  // Update diameter and hole size, which where set previously
1664  // for normal vias
1665  NETINFO_ITEM* net = via->GetNet();
1666 
1667  if( net )
1668  {
1669  via->SetWidth( net->GetMicroViaSize() );
1670  via->SetDrill( net->GetMicroViaDrillSize() );
1671  }
1672  }
1673  break;
1674 
1675  default:
1676  break;
1677  }
1678 
1679  return std::unique_ptr<BOARD_ITEM>( via );
1680  }
1681  };
1682 
1683  VIA_PLACER placer( frame() );
1684 
1685  frame()->SetToolID( ID_PCB_DRAW_VIA_BUTT, wxCURSOR_PENCIL, _( "Add vias" ) );
1686 
1687  doInteractiveItemPlacement( &placer, _( "Place via" ),
1689 
1690  frame()->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
1691 
1692  return 0;
1693 }
1694 
1695 
1697 {
1711 }
1712 
1713 
1714 int DRAWING_TOOL::getSegmentWidth( unsigned int aLayer ) const
1715 {
1716  assert( m_board );
1717 
1718  if( aLayer == Edge_Cuts )
1720  else if( m_editModules )
1722  else
1724 }
1725 
1726 
1728 {
1729  PCB_LAYER_ID layer = m_frame->GetActiveLayer();
1730 
1731  if( IsCopperLayer( layer ) )
1732  {
1733  if( layer == F_Cu )
1734  layer = F_SilkS;
1735  else if( layer == B_Cu )
1736  layer = B_SilkS;
1737  else
1738  layer = Dwgs_User;
1739 
1740  m_frame->SetActiveLayer( layer );
1741  }
1742 
1743  return layer;
1744 }
1745 
1746 
1747 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.
void SetTextColor(const wxColour &aColor)
Change text color.
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:84
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:276
void SetViaType(VIATYPE_T aViaType)
Definition: class_track.h:461
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:106
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...
void SetEnd(const wxPoint &aEnd)
Definition: class_track.h:118
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 STATUS_TEXT_POPUP.
Definition: status_popup.h:77
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:287
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:147
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:364
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:175
static TOOL_ACTION properties
Activation of the edit tool.
Definition: pcb_actions.h:108
void SetVisible(bool aVisible)
Definition: eda_text.h:173
VECTOR2I AlignToSegment(const VECTOR2I &aPoint, const SEG &aSeg)
OPT_TOOL_EVENT Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Function Wait()
VECTOR2< T > Rotate(double aAngle) const
Function Rotate rotates the vector by a given angle.
Definition: vector2d.h:372
virtual EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
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
const wxPoint & GetEnd() const
Definition: class_track.h:119
Add a new zone with the same settings as an existing one.
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:74
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:274
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:109
static bool m_use45DegreeGraphicSegments
DIMENSION class definition.
KIGFX::VIEW_CONTROLS * controls() const
Definition: pcb_tool.h:135
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:167
Unconstrained point-to-point
void SetOrigin(const wxPoint &aOrigin)
Function SetOrigin Sets a new origin of the crossbar line.
Class LSET is a set of PCB_LAYER_IDs.
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:264
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:253
const wxPoint & GetEnd()
Function GetEnd.
VIATYPE_T GetViaType() const
Definition: class_track.h:460
VECTOR2< double > VECTOR2D
Definition: vector2d.h:588
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Function SetMsgPanel clears the message panel and populates it with the contents of aList...
Definition: draw_frame.cpp:831
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 wxPoint & GetStart() const
Definition: class_track.h:122
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:136
Class TOOL_EVENT.
Definition: tool_event.h:162
unsigned int m_lineWidth
Stores the current line width for multisegment drawing.
Definition: drawing_tool.h:281
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:535
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.
virtual void Popup(wxWindow *aFocus=nullptr)
MODULE * module() const
Definition: pcb_tool.h:138
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:275
SHAPE_POLY_SET & GetPolyShape()
const SELECTION & selection() const
Definition: pcb_tool.cpp:221
int GetType() const
virtual void SetActiveLayer(PCB_LAYER_ID aLayer)
Function SetActiveLayer will change the currently active layer to aLayer.
virtual void Move(const wxPoint &aWhere)
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:1499
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
void Expire(int aMsecs)
Hides the popup after a specified time.
const wxPoint GetPosition() const override
Definition: class_track.h:432
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:277
bool m_editModules
Definition: pcb_tool.h:144
void DeleteLastCorner()
Remove the last-added point from the polygon.
KIGFX::VIEW * getView() const
Function getView()
Definition: tool_base.cpp:35
int GetNetCode() const
Function GetNetCode.
static TOOL_ACTION drawCircle
Activation of the drawing tool (circle)
Definition: pcb_actions.h:145
Definition: seg.h:36
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:615
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()
bool IsSelfIntersecting(bool aIncludeLeaderPts) const
Checks whether the locked points constitute a self-intersecting outline.
int SetAnchor(const TOOL_EVENT &aEvent)
Function SetAnchor() Places the footprint anchor (only in module editor).
ZONE_CONTAINERS & Zones()
Definition: class_board.h:255
void constrainDimension(DIMENSION *dimension)
Function constrainDimension() Forces the dimension lime to be drawn on multiple of 45 degrees...
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.
int GetWidth() const
Definition: class_track.h:116
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:468
This class is an adjuct helper to the DRAWING_TOOL interactive tool, which handles incoming geometry ...
Class PCB_EDIT_FRAME is the main frame for Pcbnew.
Class SELECTION_AREA.
Definition: arc_assistant.h:38
void Reset()
Clear the manager state and start again.
int GetWidth() const
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true, bool aSetDirtyBit=true) override
Executes the changes.
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:265
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
void SetStart(const wxPoint &aStart)
Definition: class_track.h:121
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:252
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:334
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
bool TestSegmentHit(const wxPoint &aRefPoint, wxPoint aStart, wxPoint aEnd, int aDist)
Function TestSegmentHit test for hit on line segment i.e.
Definition: trigo.cpp:122
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:182
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.
void SetText(const wxString &aText)
Display a text.
TOOL_MENU m_menu
Menu model displayed by the tool.
Definition: drawing_tool.h:284
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:454
void SetBezControl1(const wxPoint &aPoint)
virtual void SetText(const wxString &aText)
Definition: eda_text.h:139
BOARD * board() const
Definition: pcb_tool.h:137
void SetWidth(int aWidth)
virtual void Remove(EDA_ITEM *aItem)
Definition: selection.h:79