KiCad PCB EDA Suite
gerbview/tools/selection_tool.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2017 Jon Evans <jon@craftyjon.com>
5  * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software: you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation, either version 3 of the License, or (at your
10  * option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include <limits>
22 
23 #include <functional>
24 using namespace std::placeholders;
25 
26 #include <base_struct.h>
27 #include <bitmaps.h>
28 
29 #include <gerber_collectors.h>
30 
31 #include <class_draw_panel_gal.h>
32 #include <view/view.h>
33 #include <view/view_controls.h>
34 #include <view/view_group.h>
35 #include <painter.h>
36 #include <bitmaps.h>
37 #include <hotkeys.h>
38 
39 #include <tool/tool_event.h>
40 #include <tool/tool_manager.h>
44 
45 #include <gerbview_id.h>
46 #include <gerbview_painter.h>
47 
48 #include "selection_tool.h"
49 #include "gerbview_actions.h"
50 
51 // Selection tool actions
52 TOOL_ACTION GERBVIEW_ACTIONS::selectionActivate( "gerbview.InteractiveSelection",
53  AS_GLOBAL, 0,
54  "", "", NULL, AF_ACTIVATE ); // No description, it is not supposed to be shown anywhere
55 
56 TOOL_ACTION GERBVIEW_ACTIONS::selectionCursor( "gerbview.InteractiveSelection.Cursor",
57  AS_GLOBAL, 0,
58  "", "" ); // No description, it is not supposed to be shown anywhere
59 
60 TOOL_ACTION GERBVIEW_ACTIONS::selectItem( "gerbview.InteractiveSelection.SelectItem",
61  AS_GLOBAL, 0,
62  "", "" ); // No description, it is not supposed to be shown anywhere
63 
64 TOOL_ACTION GERBVIEW_ACTIONS::unselectItem( "gerbview.InteractiveSelection.UnselectItem",
65  AS_GLOBAL, 0,
66  "", "" ); // No description, it is not supposed to be shown anywhere
67 
68 TOOL_ACTION GERBVIEW_ACTIONS::selectionClear( "gerbview.InteractiveSelection.Clear",
69  AS_GLOBAL, 0,
70  "", "" ); // No description, it is not supposed to be shown anywhere
71 
72 TOOL_ACTION GERBVIEW_ACTIONS::measureTool( "gerbview.InteractiveSelection.measureTool",
74  _( "Measure Tool" ), _( "Interactively measure distance between points" ),
75  nullptr, AF_ACTIVATE );
76 
77 
79 {
80 public:
82  {
83  SetIcon( net_highlight_schematic_xpm );
84  SetTitle( _( "Highlight" ) );
85  }
86 
87 private:
88 
89  void update() override
90  {
91  bool addSeparator = false;
92 
93  const auto& selection = getToolManager()->GetTool<GERBVIEW_SELECTION_TOOL>()->GetSelection();
94 
95  if( selection.Size() == 1 )
96  {
97  auto item = static_cast<GERBER_DRAW_ITEM*>( selection[0] );
98  const auto& net_attr = item->GetNetAttributes();
99 
100  if( ( net_attr.m_NetAttribType & GBR_NETLIST_METADATA::GBR_NETINFO_PAD ) ||
101  ( net_attr.m_NetAttribType & GBR_NETLIST_METADATA::GBR_NETINFO_CMP ) )
102  {
103  auto menuEntry = Add( GERBVIEW_ACTIONS::highlightComponent );
104  menuEntry->SetItemLabel( wxString::Format( _( "Highlight Items of Component \"%s\"" ),
105  GetChars( net_attr.m_Cmpref ) ) );
106  addSeparator = true;
107  }
108 
109  if( ( net_attr.m_NetAttribType & GBR_NETLIST_METADATA::GBR_NETINFO_NET ) )
110  {
111  auto menuEntry = Add( GERBVIEW_ACTIONS::highlightNet );
112  menuEntry->SetItemLabel( wxString::Format( _( "Highlight Items of Net \"%s\"" ),
113  GetChars( net_attr.m_Netname ) ) );
114  addSeparator = true;
115  }
116 
117  D_CODE* apertDescr = item->GetDcodeDescr();
118 
119  if( apertDescr && !apertDescr->m_AperFunction.IsEmpty() )
120  {
121  auto menuEntry = Add( GERBVIEW_ACTIONS::highlightAttribute );
122  menuEntry->SetItemLabel( wxString::Format( _( "Highlight Aperture Type \"%s\"" ),
123  GetChars( apertDescr->m_AperFunction ) ) );
124  addSeparator = true;
125  }
126  }
127 
128  if( addSeparator )
129  AppendSeparator();
130 
132  }
133 
134  CONTEXT_MENU* create() const override
135  {
136  return new HIGHLIGHT_MENU();
137  }
138 };
139 
140 
142  TOOL_INTERACTIVE( "gerbview.InteractiveSelection" ),
143  m_frame( NULL ), m_additive( false ), m_subtractive( false ),
144  m_multiple( false ),
145  m_menu( *this )
146 {
147  // these members are initialized to avoid warnings about non initialized vars
148  m_preliminary = true;
149 }
150 
151 
153 {
154  getView()->Remove( &m_selection );
155 }
156 
157 
159 {
160  auto selectMenu = std::make_shared<HIGHLIGHT_MENU>();
161  selectMenu->SetTool( this );
162  m_menu.AddSubMenu( selectMenu );
163 
164  auto& menu = m_menu.GetMenu();
165 
166  menu.AddMenu( selectMenu.get(), false );
167  menu.AddSeparator( SELECTION_CONDITIONS::ShowAlways, 1000 );
168 
169  m_menu.AddStandardSubMenus( *getEditFrame<GERBVIEW_FRAME>() );
170 
171  return true;
172 }
173 
174 
176 {
177  m_frame = getEditFrame<GERBVIEW_FRAME>();
178  m_preliminary = true;
179 
180  if( aReason == TOOL_BASE::MODEL_RELOAD )
181  {
182  // Remove pointers to the selected items from containers
183  // without changing their properties (as they are already deleted
184  // while a new file is loaded)
185  m_selection.Clear();
186  getView()->GetPainter()->GetSettings()->SetHighlight( false );
187  }
188  else
189  // Restore previous properties of selected items and remove them from containers
190  clearSelection();
191 
192  // Reinsert the VIEW_GROUP, in case it was removed from the VIEW
193  getView()->Remove( &m_selection );
194  getView()->Add( &m_selection );
195 }
196 
197 
199 {
200  // Main loop: keep receiving events
201  while( OPT_TOOL_EVENT evt = Wait() )
202  {
203  // This is kind of hacky: activate RMB drag on any event.
204  // There doesn't seem to be any other good way to tell when another tool
205  // is canceled and control returns to the selection tool, except by the
206  // fact that the selection tool starts to get events again.
208  {
209  getViewControls()->SetAdditionalPanButtons( false, true );
210  }
211 
212  // Disable RMB pan for other tools; they can re-enable if desired
213  if( evt->IsActivate() )
214  {
215  getViewControls()->SetAdditionalPanButtons( false, false );
216  }
217 
218  // single click? Select single object
219  if( evt->IsClick( BUT_LEFT ) )
220  {
221  if( !m_additive )
222  clearSelection();
223 
224  selectPoint( evt->Position() );
225  }
226 
227  // right click? if there is any object - show the context menu
228  else if( evt->IsClick( BUT_RIGHT ) )
229  {
230  if( m_selection.Empty() )
231  {
232  selectPoint( evt->Position() );
233  m_selection.SetIsHover( true );
234  }
235 
237  }
238 
239  else if( evt->IsCancel() || evt->Action() == TA_UNDO_REDO_PRE )
240  {
241  clearSelection();
242  }
243 
244  else if( evt->Action() == TA_CONTEXT_MENU_CLOSED )
245  {
246  m_menu.CloseContextMenu( evt );
247  }
248  }
249 
250  // This tool is supposed to be active forever
251  assert( false );
252 
253  return 0;
254 }
255 
256 
258 {
259  return m_selection;
260 }
261 
262 
264 {
265  if( aItem->IsSelected() )
266  {
267  unselect( aItem );
268 
269  // Inform other potentially interested tools
271  }
272  else
273  {
274  if( !m_additive )
275  clearSelection();
276 
277  // Prevent selection of invisible or inactive items
278  if( selectable( aItem ) )
279  {
280  select( aItem );
281 
282  // Inform other potentially interested tools
284  }
285  }
286 
288 }
289 
290 
291 bool GERBVIEW_SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag )
292 {
293  EDA_ITEM* item = NULL;
294  GERBER_COLLECTOR collector;
295  EDA_ITEM* model = getModel<EDA_ITEM>();
296 
297  collector.Collect( model, GERBER_COLLECTOR::AllItems, wxPoint( aWhere.x, aWhere.y ) );
298 
299  bool anyCollected = collector.GetCount() != 0;
300 
301  // Remove unselectable items
302  for( int i = collector.GetCount() - 1; i >= 0; --i )
303  {
304  if( !selectable( collector[i] ) )
305  collector.Remove( i );
306  }
307 
308  switch( collector.GetCount() )
309  {
310  case 0:
311  if( !m_additive && anyCollected )
312  clearSelection();
313 
314  return false;
315 
316  case 1:
317  toggleSelection( collector[0] );
318 
319  return true;
320 
321  default:
322  // Let's see if there is still disambiguation in selection..
323  if( collector.GetCount() == 1 )
324  {
325  toggleSelection( collector[0] );
326 
327  return true;
328  }
329  else if( collector.GetCount() > 1 )
330  {
331  if( aOnDrag )
333 
334  item = disambiguationMenu( &collector );
335 
336  if( item )
337  {
338  toggleSelection( item );
339 
340  return true;
341  }
342  }
343  break;
344  }
345 
346  return false;
347 }
348 
349 
350 bool GERBVIEW_SELECTION_TOOL::selectCursor( bool aSelectAlways )
351 {
352  if( aSelectAlways || m_selection.Empty() )
353  {
354  clearSelection();
355  selectPoint( getViewControls()->GetCursorPosition( false ) );
356  }
357 
358  return !m_selection.Empty();
359 }
360 
361 
363 {
364  bool cancelled = false; // Was the tool cancelled while it was running?
365  m_multiple = true; // Multiple selection mode is active
366  KIGFX::VIEW* view = getView();
367  getViewControls()->SetAutoPan( true );
368 
370  view->Add( &area );
371 
372  while( OPT_TOOL_EVENT evt = Wait() )
373  {
374  if( evt->IsCancel() )
375  {
376  cancelled = true;
377  break;
378  }
379 
380  if( evt->IsDrag( BUT_LEFT ) )
381  {
382 
383  // Start drawing a selection box
384  area.SetOrigin( evt->DragOrigin() );
385  area.SetEnd( evt->Position() );
386  area.SetAdditive( m_additive );
388 
389  view->SetVisible( &area, true );
390  view->Update( &area );
391  }
392 
393  if( evt->IsMouseUp( BUT_LEFT ) )
394  {
395  // End drawing the selection box
396  view->SetVisible( &area, false );
397 
398  // Mark items within the selection box as selected
399  std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems;
400 
401  // Filter the view items based on the selection box
402  BOX2I selectionBox = area.ViewBBox();
403  view->Query( selectionBox, selectedItems ); // Get the list of selected items
404 
405  std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR>::iterator it, it_end;
406 
407  int width = area.GetEnd().x - area.GetOrigin().x;
408  int height = area.GetEnd().y - area.GetOrigin().y;
409 
410  // Construct an EDA_RECT to determine EDA_ITEM selection
411  EDA_RECT selectionRect( wxPoint( area.GetOrigin().x, area.GetOrigin().y ),
412  wxSize( width, height ) );
413 
414  selectionRect.Normalize();
415 
416  for( it = selectedItems.begin(), it_end = selectedItems.end(); it != it_end; ++it )
417  {
418  auto item = static_cast<GERBER_DRAW_ITEM*>( it->first );
419 
420  if( !item || !selectable( item ) )
421  continue;
422 
423  /* Selection mode depends on direction of drag-selection:
424  * Left > Right : Select objects that are fully enclosed by selection
425  * Right > Left : Select objects that are crossed by selection
426  */
427 
428  if( width >= 0 )
429  {
430  if( selectionBox.Contains( item->ViewBBox() ) )
431  {
432  if( m_subtractive )
433  unselect( item );
434  else
435  select( item );
436  }
437  }
438  else
439  {
440  if( item->HitTest( selectionRect ) )
441  {
442  if( m_subtractive )
443  unselect( item );
444  else
445  select( item );
446  }
447 
448  }
449  }
450 
451  if( m_selection.Size() == 1 )
452  m_frame->SetCurItem( static_cast<GERBER_DRAW_ITEM*>( m_selection.Front() ) );
453  else
454  m_frame->SetCurItem( NULL );
455 
456  // Inform other potentially interested tools
457  if( !m_selection.Empty() )
459 
460  break; // Stop waiting for events
461  }
462  }
463 
464  // Stop drawing the selection box
465  view->Remove( &area );
466  m_multiple = false; // Multiple selection mode is inactive
467  getViewControls()->SetAutoPan( false );
468 
469  return cancelled;
470 }
471 
472 
474 {
481 }
482 
483 
485 {
486  if( m_selection.Empty() ) // Try to find an item that could be modified
487  {
488  selectCursor( true );
489 
490  clearSelection();
491  return 0;
492  }
493 
494  return 0;
495 }
496 
497 
499 {
500  clearSelection();
501 
502  return 0;
503 }
504 
505 
507 {
508  std::vector<EDA_ITEM*>* items = aEvent.Parameter<std::vector<EDA_ITEM*>*>();
509 
510  if( items )
511  {
512  // Perform individual selection of each item
513  // before processing the event.
514  for( auto item : *items )
515  {
516  select( item );
517  }
518 
520  }
521 
522  return 0;
523 }
524 
525 
527 {
528  // Check if there is an item to be selected
529  EDA_ITEM* item = aEvent.Parameter<EDA_ITEM*>();
530 
531  if( item )
532  {
533  select( item );
534 
535  // Inform other potentially interested tools
537  }
538 
539  return 0;
540 }
541 
542 
544 {
545  std::vector<EDA_ITEM*>* items = aEvent.Parameter<std::vector<EDA_ITEM*>*>();
546 
547  if( items )
548  {
549  // Perform individual unselection of each item
550  // before processing the event
551  for( auto item : *items )
552  {
553  unselect( item );
554  }
555 
557  }
558 
559  return 0;
560 }
561 
562 
564 {
565  // Check if there is an item to be selected
566  EDA_ITEM* item = aEvent.Parameter<EDA_ITEM*>();
567 
568  if( item )
569  {
570  unselect( item );
571 
572  // Inform other potentially interested tools
574  }
575 
576  return 0;
577 }
578 
579 
581 {
582  if( m_selection.Empty() )
583  return;
584 
585  for( auto item : m_selection )
586  unselectVisually( static_cast<EDA_ITEM*>( item ) );
587 
588  m_selection.Clear();
589 
590  m_frame->SetCurItem( NULL );
591 
592  // Inform other potentially interested tools
594 }
595 
596 
598 {
599  //Should recalculate the view to zoom in on the selection
600  auto selectionBox = m_selection.ViewBBox();
601  auto canvas = m_frame->GetGalCanvas();
602  auto view = getView();
603 
604  VECTOR2D screenSize = view->ToWorld( canvas->GetClientSize(), false );
605 
606  if( !( selectionBox.GetWidth() == 0 ) || !( selectionBox.GetHeight() == 0 ) )
607  {
608  VECTOR2D vsize = selectionBox.GetSize();
609  double scale = view->GetScale() / std::max( fabs( vsize.x / screenSize.x ),
610  fabs( vsize.y / screenSize.y ) );
611  view->SetScale( scale );
612  view->SetCenter( selectionBox.Centre() );
613  view->Add( &m_selection );
614  }
615 
617 }
618 
619 
621 {
622  EDA_ITEM* current = NULL;
623  KIGFX::VIEW_GROUP highlightGroup;
624  CONTEXT_MENU menu;
625 
626  highlightGroup.SetLayer( LAYER_SELECT_OVERLAY );
627  getView()->Add( &highlightGroup );
628 
629  int limit = std::min( 10, aCollector->GetCount() );
630 
631  for( int i = 0; i < limit; ++i )
632  {
633  wxString text;
634  EDA_ITEM* item = ( *aCollector )[i];
635  text = item->GetSelectMenuText( m_frame->GetUserUnits() );
636  menu.Add( text, i + 1, item->GetMenuImage() );
637  }
638 
639  menu.SetTitle( _( "Clarify selection" ) );
640  menu.SetIcon( info_xpm );
641  menu.DisplayTitle( true );
642  SetContextMenu( &menu, CMENU_NOW );
643 
644  while( OPT_TOOL_EVENT evt = Wait() )
645  {
646  if( evt->Action() == TA_CONTEXT_MENU_UPDATE )
647  {
648  if( current )
649  {
650  current->ClearBrightened();
651  getView()->Hide( current, false );
652  highlightGroup.Remove( current );
654  }
655 
656  int id = *evt->GetCommandId();
657 
658  // User has pointed an item, so show it in a different way
659  if( id > 0 && id <= limit )
660  {
661  current = ( *aCollector )[id - 1];
662  current->SetBrightened();
663  getView()->Hide( current, true );
664  highlightGroup.Add( current );
666  }
667  else
668  {
669  current = NULL;
670  }
671  }
672  else if( evt->Action() == TA_CONTEXT_MENU_CHOICE )
673  {
674  OPT<int> id = evt->GetCommandId();
675 
676  // User has selected an item, so this one will be returned
677  if( id && ( *id > 0 ) )
678  current = ( *aCollector )[*id - 1];
679  else
680  current = NULL;
681 
682  break;
683  }
684  }
685 
686  if( current && current->IsBrightened() )
687  {
688  current->ClearBrightened();
689  getView()->Hide( current, false );
691  }
692 
693  getView()->Remove( &highlightGroup );
694 
695  return current;
696 }
697 
698 
700 {
701  auto item = static_cast<const GERBER_DRAW_ITEM*>( aItem );
702 
703  if( item->GetLayerPolarity() )
704  {
705  // Don't allow selection of invisible negative items
706  auto rs = static_cast<KIGFX::GERBVIEW_RENDER_SETTINGS*>( getView()->GetPainter()->GetSettings() );
707  if( !rs->IsShowNegativeItems() )
708  return false;
709  }
710 
711  return getEditFrame<GERBVIEW_FRAME>()->IsLayerVisible( item->GetLayer() );
712 }
713 
714 
716 {
717  if( aItem->IsSelected() )
718  {
719  return;
720  }
721 
722  m_selection.Add( aItem );
723  getView()->Add( &m_selection );
724  selectVisually( aItem );
725 
726  if( m_selection.Size() == 1 )
727  {
728  // Set as the current item, so the information about selection is displayed
729  m_frame->SetCurItem( static_cast<GERBER_DRAW_ITEM*>( aItem ), true );
730  }
731  else if( m_selection.Size() == 2 ) // Check only for 2, so it will not be
732  { // called for every next selected item
733  // If multiple items are selected, do not show the information about the selected item
734  m_frame->SetCurItem( NULL, true );
735  }
736 }
737 
738 
740 {
741  if( !aItem->IsSelected() )
742  return;
743 
744  unselectVisually( aItem );
745  m_selection.Remove( aItem );
746 
747  if( m_selection.Empty() )
748  {
749  m_frame->SetCurItem( NULL );
750  getView()->Remove( &m_selection );
751  }
752 }
753 
754 
756 {
757  // Move the item's layer to the front
758  int layer = static_cast<GERBER_DRAW_ITEM*>( aItem )->GetLayer();
759  m_frame->SetActiveLayer( layer, true );
760 
761  // Hide the original item, so it is shown only on overlay
762  aItem->SetSelected();
763  getView()->Hide( aItem, true );
764 
765  getView()->Update( &m_selection );
766 }
767 
768 
770 {
771  // Restore original item visibility
772  aItem->ClearSelected();
773  getView()->Hide( aItem, false );
774  getView()->Update( aItem, KIGFX::ALL );
775 
776  getView()->Update( &m_selection );
777 }
778 
779 
781 {
782  const unsigned GRIP_MARGIN = 20;
783  VECTOR2D margin = getView()->ToWorld( VECTOR2D( GRIP_MARGIN, GRIP_MARGIN ), false );
784 
785  // Check if the point is located within any of the currently selected items bounding boxes
786  for( auto item : m_selection )
787  {
788  BOX2I itemBox = item->ViewBBox();
789  itemBox.Inflate( margin.x, margin.y ); // Give some margin for gripping an item
790 
791  if( itemBox.Contains( aPoint ) )
792  return true;
793  }
794 
795  return false;
796 }
797 
798 
800 {
801  auto& view = *getView();
802  auto& controls = *getViewControls();
803  auto previous_settings = controls.GetSettings();
804 
805  Activate();
806  m_frame->SetToolID( ID_TB_MEASUREMENT_TOOL, wxCURSOR_PENCIL,
807  _( "Measure distance" ) );
808 
810  KIGFX::PREVIEW::RULER_ITEM ruler( twoPtMgr, m_frame->GetUserUnits() );
811 
812  view.Add( &ruler );
813  view.SetVisible( &ruler, false );
814 
815  bool originSet = false;
816 
817  controls.ShowCursor( true );
818  controls.SetSnapping( true );
819  controls.SetAdditionalPanButtons( false, true );
820 
821  while( auto evt = Wait() )
822  {
823  const VECTOR2I cursorPos = controls.GetCursorPosition();
824 
825  if( evt->IsCancel() || evt->IsActivate() )
826  {
827  break;
828  }
829 
830  // click or drag starts
831  else if( !originSet &&
832  ( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) )
833  {
834  if( !evt->IsDrag( BUT_LEFT ) )
835  {
836  twoPtMgr.SetOrigin( cursorPos );
837  twoPtMgr.SetEnd( cursorPos );
838  }
839 
840  controls.CaptureCursor( true );
841  controls.SetAutoPan( true );
842 
843  originSet = true;
844  }
845 
846  else if( !originSet && evt->IsMotion() )
847  {
848  // make sure the origin is set before a drag starts
849  // otherwise you can miss a step
850  twoPtMgr.SetOrigin( cursorPos );
851  twoPtMgr.SetEnd( cursorPos );
852  }
853 
854  // second click or mouse up after drag ends
855  else if( originSet &&
856  ( evt->IsClick( BUT_LEFT ) || evt->IsMouseUp( BUT_LEFT ) ) )
857  {
858  originSet = false;
859 
860  controls.SetAutoPan( false );
861  controls.CaptureCursor( false );
862 
863  view.SetVisible( &ruler, false );
864  }
865 
866  // move or drag when origin set updates rules
867  else if( originSet &&
868  ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
869  {
870  twoPtMgr.SetAngleSnap( evt->Modifier( MD_CTRL ) );
871  twoPtMgr.SetEnd( cursorPos );
872 
873  view.SetVisible( &ruler, true );
874  view.Update( &ruler, KIGFX::GEOMETRY );
875  }
876 
877  else if( evt->IsClick( BUT_RIGHT ) )
878  {
880  }
881  }
882 
883  view.SetVisible( &ruler, false );
884  view.Remove( &ruler );
885 
886  controls.ApplySettings( previous_settings );
887 
889 
890  return 0;
891 }
892 
893 
895 {
896  VECTOR2I centre;
897 
898  if( Size() == 1 )
899  {
900  centre = static_cast<GERBER_DRAW_ITEM*>( Front() )->GetPosition();
901  }
902  else
903  {
904  EDA_RECT bbox = Front()->GetBoundingBox();
905  auto i = m_items.begin();
906  ++i;
907 
908  for( ; i != m_items.end(); ++i )
909  {
910  bbox.Merge( (*i)->GetBoundingBox() );
911  }
912 
913  centre = bbox.Centre();
914  }
915 
916  return centre;
917 }
918 
919 
920 const BOX2I SELECTION::ViewBBox() const
921 {
922  EDA_RECT eda_bbox;
923 
924  if( Size() == 1 )
925  {
926  eda_bbox = Front()->GetBoundingBox();
927  }
928  else if( Size() > 1 )
929  {
930  eda_bbox = Front()->GetBoundingBox();
931  auto i = m_items.begin();
932  ++i;
933 
934  for( ; i != m_items.end(); ++i )
935  {
936  eda_bbox.Merge( (*i)->GetBoundingBox() );
937  }
938  }
939 
940  return BOX2I( eda_bbox.GetOrigin(), eda_bbox.GetSize() );
941 }
942 
943 
945 {
946  std::vector<VIEW_ITEM*> items;
947 
948  for( auto item : m_items )
949  items.push_back( item );
950 
951  return items;
952 }
953 
954 
955 
956 const TOOL_EVENT GERBVIEW_SELECTION_TOOL::SelectedEvent( TC_MESSAGE, TA_ACTION, "gerbview.InteractiveSelection.selected" );
957 const TOOL_EVENT GERBVIEW_SELECTION_TOOL::UnselectedEvent( TC_MESSAGE, TA_ACTION, "gerbview.InteractiveSelection.unselected" );
958 const TOOL_EVENT GERBVIEW_SELECTION_TOOL::ClearedEvent( TC_MESSAGE, TA_ACTION, "gerbview.InteractiveSelection.cleared" );
static bool ShowAlways(const SELECTION &aSelection)
Function ShowAlways The default condition function (always returns true).
void Hide(VIEW_ITEM *aItem, bool aHide=true)
Temporarily hides the item in the view (e.g.
Definition: view.cpp:1497
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:114
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:116
static TOOL_ACTION selectionClear
Clears the current selection.
BOX2< VECTOR2I > BOX2I
Definition: box2.h:520
void SetEnd(VECTOR2I aEnd)
Set the current end of the rectangle (the corner that moves with the cursor.
virtual void Clear() override
Function Clear() Removes all the stored items from the group.
Definition: selection.h:90
void ForceRefresh()
Function ForceRefresh() Forces a redraw.
SELECTION & GetSelection()
Function GetSelection()
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
const wxPoint GetOrigin() const
Definition: eda_rect.h:112
void Merge(const EDA_RECT &aRect)
Function Merge modifies the position and size of the rectangle in order to contain aRect...
bool IsBrightened() const
Definition: base_struct.h:227
bool selectPoint(const VECTOR2I &aWhere, bool aOnDrag=false)
Function selectPoint() Selects an item pointed by the parameter aWhere.
virtual int Query(const BOX2I &aRect, std::vector< LAYER_ITEM_PAIR > &aResult) const
Function Query() Finds all visible items that touch or are within the rectangle aRect.
Definition: view.cpp:450
Model changes (required full reload)
Definition: tool_base.h:83
print info associated to a component (TO.C attribute)
void update() override
Update menu state stub.
const wxSize GetSize() const
Definition: eda_rect.h:101
void SetOrigin(VECTOR2I aOrigin)
Set the origin of the rectange (the fixed corner)
void ClearSelected()
Definition: base_struct.h:234
Class CONTEXT_MENU.
Definition: context_menu.h:44
VIEW_CONTROLS class definition.
Class GERBER_COLLECTOR is intended for use when the right click button is pressed, or when the plain "arrow" tool is in effect.
void SetCurItem(GERBER_DRAW_ITEM *aItem, bool aDisplayInfo=true)
Function SetCurItem sets the currently selected item and displays it in the MsgPanel.
virtual const VIEW_GROUP::ITEMS updateDrawList() const override
Definition: selection.cpp:140
bool m_preliminary
Determines if the selection is preliminary or final.
EDA_ITEM * disambiguationMenu(GERBER_COLLECTOR *aItems)
Function disambiguationMenu() Handles the menu that allows one to select one of many items in case th...
SELECTION m_selection
Current state of selection.
Class TWO_POINT_GEOMETRY_MANAGER.
bool Contains(const Vec &aPoint) const
Function Contains.
Definition: box2.h:149
CONDITIONAL_MENU & GetMenu()
Function GetMenu.
Definition: tool_menu.cpp:49
EDA_ITEM * Front() const
Definition: selection.h:152
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
VECTOR2D ToWorld(const VECTOR2D &aCoord, bool aAbsolute=true) const
Function ToWorld() Converts a screen space point/vector to a point/vector in world space coordinates...
Definition: view.cpp:473
virtual void Remove(VIEW_ITEM *aItem)
Function Remove() Removes a VIEW_ITEM from the view.
Definition: view.cpp:374
void AddSubMenu(std::shared_ptr< CONTEXT_MENU > aSubMenu)
Function CreateSubMenu.
Definition: tool_menu.cpp:55
int CursorSelection(const TOOL_EVENT &aEvent)
Select a single item under cursor event handler.
static TOOL_ACTION selectionCursor
Select a single item under the cursor position.
void SetActiveLayer(int aLayer, bool doLayerWidgetUpdate=true)
Function SetActiveLayer will change the currently active layer to aLayer and also update the GERBER_L...
void SetBrightened()
Definition: base_struct.h:232
OPT_TOOL_EVENT Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Function Wait()
bool IsSelected() const
Definition: base_struct.h:224
void selectVisually(EDA_ITEM *aItem)
Function selectVisually() Marks item as selected, but does not add it to the ITEMS_PICKED_LIST.
int Main(const TOOL_EVENT &aEvent)
Function Main()
static int LegacyHotKey(int aHotKey)
Creates a hot key code that refers to a legacy hot key setting, instead of a particular key...
Definition: tool_action.h:174
static const TOOL_EVENT UnselectedEvent
Event sent after an item is unselected.
virtual wxString GetSelectMenuText(EDA_UNITS_T aUnits) const
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
Item needs to be redrawn.
Definition: view_item.h:61
static TOOL_ACTION selectItem
Selects an item (specified as the event parameter).
static const KICAD_T AllItems[]
A scan list for all selectable gerber items.
static TOOL_ACTION highlightNet
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Function Go()
void Remove(int aIndex)
Function Remove removes the item at aIndex (first position is 0);.
Definition: collector.h:143
CONTEXT_MENU * create() const override
Returns an instance of this class. It has to be overridden in inheriting classes. ...
Pcbnew hotkeys.
void SetIsHover(bool aIsHover)
Definition: selection.h:64
wxMenuItem * Add(const wxString &aLabel, int aId, const BITMAP_OPAQUE *aIcon=NULL)
Function Add() Adds an entry to the menu.
virtual void Add(EDA_ITEM *aItem)
Definition: selection.h:74
void ClearBrightened()
Definition: base_struct.h:236
bool selectable(const EDA_ITEM *aItem) const
Function selectable() Checks conditions for an item to be selected.
int UnselectItem(const TOOL_EVENT &aEvent)
Item unselection event handler.
static TOOL_ACTION measureTool
void setTransitions() override
Sets up handlers for various events.
const BOX2I ViewBBox() const override
Function ViewBBox() Returns the bounding box for all stored items covering all its layers...
Definition: selection.cpp:132
void AddStandardSubMenus(EDA_DRAW_FRAME &aFrame)
Function CreateBasicMenu.
Definition: tool_menu.cpp:95
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
void Collect(EDA_ITEM *aItem, const KICAD_T aScanList[], const wxPoint &aRefPos)
Function Collect scans an EDA_ITEM using this class&#39;s Inspector method, which does the collection...
VECTOR2< double > VECTOR2D
Definition: vector2d.h:586
void SetSelected()
Definition: base_struct.h:230
bool m_additive
Flag saying if items should be added to the current selection or rather replace it.
void MarkTargetDirty(int aTarget)
Function MarkTargetDirty() Sets or clears target &#39;dirty&#39; flag.
Definition: view.h:596
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagates an event to tools that requested events of matching type(s).
static TOOL_ACTION highlightAttribute
EDA_UNITS_T GetUserUnits() const override
Return the user units currently in use.
Definition: draw_frame.h:284
bool selectionContains(const VECTOR2I &aPoint) const
Function selectionContains() Checks if the given point is placed within any of selected items&#39; boundi...
Class TOOL_EVENT.
Definition: tool_event.h:168
const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers. ...
void SetOrigin(const VECTOR2I &aOrigin)
Set the origin of the ruler (the fixed end)
void SetContextMenu(CONTEXT_MENU *aMenu, CONTEXT_MENU_TRIGGER aTrigger=CMENU_BUTTON)
Function SetContextMenu()
Items that may change while the view stays the same (noncached)
Definition: definitions.h:43
virtual void Remove(VIEW_ITEM *aItem)
Function Remove() Removes an item from the group.
Definition: view_group.cpp:61
VIEW_GROUP extends VIEW_ITEM by possibility of grouping items into a single object.
Class RULER_ITEM.
Definition: ruler_item.h:43
void unselect(EDA_ITEM *aItem)
Function unselect() Takes necessary action mark an item as unselected.
void zoomFitSelection(void)
Zooms the screen to center and fit the current selection.
void unselectVisually(EDA_ITEM *aItem)
Function unselectVisually() Marks item as selected, but does not add it to the ITEMS_PICKED_LIST.
wxPoint Centre() const
Definition: eda_rect.h:60
virtual void SetToolID(int aId, int aCursor, const wxString &aToolMsg)
Set the tool command ID to aId and sets the cursor to aCursor.
PAINTER * GetPainter() const
Function GetPainter() Returns the painter object used by the view for drawing VIEW_ITEMS.
Definition: view.h:199
virtual void Add(VIEW_ITEM *aItem)
Function Add() Adds an item to the group.
Definition: view_group.cpp:55
All active tools
Definition: tool_event.h:144
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:1530
Class GERBVIEW_RENDER_SETTINGS Stores GerbView specific render settings.
GERBVIEW_FRAME * m_frame
Pointer to the parent frame.
virtual void SetLayer(int aLayer)
Function SetLayer() Sets layer used to draw the group.
Definition: view_group.h:115
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
wxString m_AperFunction
the aperture attribute (created by a TA.AperFunction command) attached to the D_CODE ...
Definition: dcode.h:105
void toggleSelection(EDA_ITEM *aItem)
Function toggleSelection() Changes selection status of a given item.
int SelectItems(const TOOL_EVENT &aEvent)
Multiple item selection event handler
KIGFX::VIEW * getView() const
Function getView()
Definition: tool_base.cpp:35
std::vector< VIEW_ITEM * > ITEMS
Definition: view_group.h:45
void SetIcon(const BITMAP_OPAQUE *aIcon)
Function SetIcon() Assigns an icon for the entry.
void Normalize()
Function Normalize ensures that the height ant width are positive.
static const TOOL_EVENT ClearedEvent
Event sent after selection is cleared.
int MeasureTool(const TOOL_EVENT &aEvent)
Launches a tool to measure between points
void SetAdditionalPanButtons(bool aLeft=false, bool aRight=false)
virtual void SetNoToolSelected()
Select the ID_NO_TOOL_SELECTED id tool (Idle tool)
int SelectItem(const TOOL_EVENT &aEvent)
Item selection event handler.
virtual RENDER_SETTINGS * GetSettings()=0
Function GetSettings Returns pointer to current settings that are going to be used when drawing items...
const GBR_NETLIST_METADATA & GetNetAttributes() const
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:300
Class GERBVIEW_SELECTION_TOOL.
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:387
const int scale
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
void CloseContextMenu(OPT_TOOL_EVENT &evt)
Function CloseContextMenu.
Definition: tool_menu.cpp:82
Class D_CODE holds a gerber DCODE (also called Aperture) definition.
Definition: dcode.h:82
void AddMenu(CONTEXT_MENU *aMenu, bool aExpand=false, const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Function AddMenu()
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
#define max(a, b)
Definition: auxiliary.h:86
static TOOL_ACTION highlightClear
void SetSubtractive(bool aSubtractive)
int UnselectItems(const TOOL_EVENT &aEvent)
Multiple item unselection event handler
static TOOL_ACTION selectionActivate
Activation of the selection tool.
static TOOL_ACTION unselectItem
Unselects an item (specified as the event parameter).
int GetToolId() const
Definition: draw_frame.h:519
bool selectCursor(bool aSelectAlways=false)
Function selectCursor() Selects an item under the cursor unless there is something already selected o...
void SetTitle(const wxString &aTitle) override
Function SetTitle() Sets title for the context menu.
Class TOOL_ACTION.
Definition: tool_action.h:46
size_t i
Definition: json11.cpp:597
Class EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
currently selected items overlay
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:154
static const TOOL_EVENT SelectedEvent
Event sent after an item is selected.
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:80
void select(EDA_ITEM *aItem)
Function select() Takes necessary action mark an item as selected.
boost::optional< T > OPT
Definition: optional.h:7
static bool GetLayer(MODEL_VRML &aModel, LAYER_NUM layer, VRML_LAYER **vlayer)
void clearSelection()
Function clearSelection() Clears the current selection.
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Sets the item visibility.
Definition: view.cpp:1476
void Activate()
Function Activate() Runs the tool.
TOOL_MENU m_menu
Menu model displayed by the tool.
print info associated to a flashed pad (TO.P attribute)
Class SELECTION_AREA.
EDA_DRAW_PANEL_GAL * GetGalCanvas() const
Return a pointer to GAL-based canvas of given EDA draw frame.
Definition: draw_frame.h:921
int Size() const
Returns the number of selected parts.
Definition: selection.h:122
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:344
void DisplayTitle(bool aDisplay=true)
Function DisplayTitle() Decides whether a title for a pop up menu should be displayed.
bool m_multiple
Flag saying if multiple selection mode is active.
int ClearSelection(const TOOL_EVENT &aEvent)
Clear current selection event handler.
Basic classes for most KiCad items.
Class VIEW.
Definition: view.h:61
void SetAdditive(bool aAdditive)
bool selectMultiple()
Function selectMultiple() Handles drawing a selection box that allows one to select many items at the...
VECTOR2I GetCenter() const
Returns the center point of the selection area bounding box.
Definition: selection.cpp:67
void SetHighlight(bool aEnabled, int aNetcode=-1)
Function SetHighlight Turns on/off highlighting - it may be done for the active layer or the specifie...
Definition: painter.h:140
print info associated to a net (TO.N attribute)
void ShowContextMenu(SELECTION &aSelection)
Function ShowContextMenu.
Definition: tool_menu.cpp:62
bool m_subtractive
Flag saying if items should be removed from the current selection.
virtual BITMAP_DEF GetMenuImage() const
Function GetMenuImage returns a pointer to an image to be used in menus.
void SetEnd(const VECTOR2I &aEnd)
Set the current end of the rectangle (the end that moves with the cursor.
OPT< TOOL_EVENT > OPT_TOOL_EVENT
Definition: tool_event.h:495
#define min(a, b)
Definition: auxiliary.h:85
Color has changed.
Definition: view_item.h:57
static TOOL_ACTION highlightComponent
virtual void Remove(EDA_ITEM *aItem)
Definition: selection.h:82