KiCad PCB EDA Suite
ee_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) 2019 CERN
5  * Copyright (C) 2019-2020 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 
26 #include <class_libentry.h>
27 #include <core/typeinfo.h>
28 #include <ee_actions.h>
29 #include <ee_collectors.h>
30 #include <ee_selection_tool.h>
31 #include <eeschema_id.h> // For MAX_SELECT_ITEM_IDS
32 #include <lib_edit_frame.h>
33 #include <lib_item.h>
34 #include <lib_view_frame.h>
35 #include <math/util.h>
36 #include <menus_helpers.h>
37 #include <painter.h>
39 #include <sch_base_frame.h>
40 #include <sch_component.h>
41 #include <sch_edit_frame.h>
42 #include <sch_field.h>
43 #include <sch_item.h>
44 #include <sch_line.h>
45 #include <sch_sheet.h>
46 #include <schematic.h>
47 #include <tool/tool_event.h>
48 #include <tool/tool_manager.h>
50 #include <view/view.h>
51 #include <view/view_controls.h>
52 #include <view/view_group.h>
53 
54 
55 SELECTION_CONDITION EE_CONDITIONS::Empty = [] (const SELECTION& aSelection )
56 {
57  return aSelection.Empty();
58 };
59 
60 
61 SELECTION_CONDITION EE_CONDITIONS::Idle = [] (const SELECTION& aSelection )
62 {
63  return ( !aSelection.Front() || aSelection.Front()->GetEditFlags() == 0 );
64 };
65 
66 
68 {
69  return ( aSelection.Front() && aSelection.Front()->GetEditFlags() == 0 );
70 };
71 
72 
74 {
75  if( aSel.GetSize() == 1 )
76  {
77  SCH_COMPONENT* comp = dynamic_cast<SCH_COMPONENT*>( aSel.Front() );
78 
79  if( comp )
80  return !comp->GetPartRef() || !comp->GetPartRef()->IsPower();
81  }
82 
83  return false;
84 };
85 
86 
88 {
89  if( aSel.GetSize() == 1 )
90  {
91  SCH_COMPONENT* comp = dynamic_cast<SCH_COMPONENT*>( aSel.Front() );
92 
93  if( comp )
94  return comp->GetPartRef() && comp->GetPartRef()->HasConversion();
95  }
96 
97  return false;
98 };
99 
100 
102 {
103  if( aSel.GetSize() == 1 )
104  {
105  SCH_COMPONENT* comp = dynamic_cast<SCH_COMPONENT*>( aSel.Front() );
106 
107  if( comp )
108  return comp->GetPartRef() && comp->GetPartRef()->GetUnitCount() >= 2;
109  }
110 
111  return false;
112 };
113 
114 
115 #define HITTEST_THRESHOLD_PIXELS 5
116 
117 
119  TOOL_INTERACTIVE( "eeschema.InteractiveSelection" ),
120  m_frame( nullptr ),
121  m_additive( false ),
122  m_subtractive( false ),
123  m_exclusive_or( false ),
124  m_multiple( false ),
125  m_skip_heuristics( false ),
126  m_isLibEdit( false ),
127  m_isLibView( false ),
128  m_unit( 0 ),
129  m_convert( 0 )
130 {
131 }
132 
133 
135 {
136  getView()->Remove( &m_selection );
137 }
138 
140 
142 {
143  m_frame = getEditFrame<SCH_BASE_FRAME>();
144 
145  LIB_VIEW_FRAME* libViewFrame = dynamic_cast<LIB_VIEW_FRAME*>( m_frame );
146  LIB_EDIT_FRAME* libEditFrame = dynamic_cast<LIB_EDIT_FRAME*>( m_frame );
147 
148  if( libEditFrame )
149  {
150  m_isLibEdit = true;
151  m_unit = libEditFrame->GetUnit();
152  m_convert = libEditFrame->GetConvert();
153  }
154  else
155  m_isLibView = libViewFrame != nullptr;
156 
157 
158  static KICAD_T wireOrBusTypes[] = { SCH_LINE_LOCATE_WIRE_T, SCH_LINE_LOCATE_BUS_T, EOT };
159 
160  auto wireSelection = E_C::MoreThan( 0 ) && E_C::OnlyType( SCH_LINE_LOCATE_WIRE_T );
161  auto busSelection = E_C::MoreThan( 0 ) && E_C::OnlyType( SCH_LINE_LOCATE_BUS_T );
162  auto wireOrBusSelection = E_C::MoreThan( 0 ) && E_C::OnlyTypes( wireOrBusTypes );
163  auto sheetSelection = E_C::Count( 1 ) && E_C::OnlyType( SCH_SHEET_T );
164  auto schEditCondition = [this] ( const SELECTION& aSel ) {
165  return !m_isLibEdit && !m_isLibView;
166  };
167  auto belowRootSheetCondition =
168  [&]( const SELECTION& aSel )
169  {
170  SCH_EDIT_FRAME* schEditFrame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
171 
172  return ( schEditFrame&&
173  schEditFrame->GetCurrentSheet().Last() !=
174  &schEditFrame->Schematic().Root() );
175  };
176 
177  auto havePartCondition =
178  [&]( const SELECTION& sel )
179  {
180  return m_isLibEdit && static_cast<LIB_EDIT_FRAME*>( m_frame )->GetCurPart();
181  };
182 
183  auto& menu = m_menu.GetMenu();
184 
185  menu.AddItem( EE_ACTIONS::enterSheet, sheetSelection && EE_CONDITIONS::Idle, 1 );
186  menu.AddItem( EE_ACTIONS::explicitCrossProbe, sheetSelection && EE_CONDITIONS::Idle, 1 );
187  menu.AddItem( EE_ACTIONS::leaveSheet, belowRootSheetCondition, 1 );
188 
189  menu.AddSeparator( 100 );
190  menu.AddItem( EE_ACTIONS::drawWire, schEditCondition && EE_CONDITIONS::Empty, 100 );
191  menu.AddItem( EE_ACTIONS::drawBus, schEditCondition && EE_CONDITIONS::Empty, 100 );
192 
193  menu.AddSeparator( 100 );
195 
196  menu.AddSeparator( 100 );
198 
199  menu.AddSeparator( 200 );
200  menu.AddItem( EE_ACTIONS::selectConnection, wireOrBusSelection && EE_CONDITIONS::Idle, 250 );
201  menu.AddItem( EE_ACTIONS::placeJunction, wireOrBusSelection && EE_CONDITIONS::Idle, 250 );
202  menu.AddItem( EE_ACTIONS::placeLabel, wireOrBusSelection && EE_CONDITIONS::Idle, 250 );
203  menu.AddItem( EE_ACTIONS::placeGlobalLabel, wireOrBusSelection && EE_CONDITIONS::Idle, 250 );
204  menu.AddItem( EE_ACTIONS::placeHierLabel, wireOrBusSelection && EE_CONDITIONS::Idle, 250 );
205  menu.AddItem( EE_ACTIONS::breakWire, wireSelection && EE_CONDITIONS::Idle, 250 );
206  menu.AddItem( EE_ACTIONS::breakBus, busSelection && EE_CONDITIONS::Idle, 250 );
207  menu.AddItem( EE_ACTIONS::importSheetPin, sheetSelection && EE_CONDITIONS::Idle, 250 );
208 
209  menu.AddSeparator( 400 );
210  menu.AddItem( EE_ACTIONS::symbolProperties, havePartCondition && EE_CONDITIONS::Empty, 400 );
211  menu.AddItem( EE_ACTIONS::pinTable, havePartCondition && EE_CONDITIONS::Empty, 400 );
212 
213  menu.AddSeparator( 1000 );
215 
216  return true;
217 }
218 
219 
221 {
222  m_frame = getEditFrame<SCH_BASE_FRAME>();
223 
224  if( aReason == TOOL_BASE::MODEL_RELOAD )
225  {
226  // Remove pointers to the selected items from containers without changing their
227  // properties (as they are already deleted while a new sheet is loaded)
228  m_selection.Clear();
229  getView()->GetPainter()->GetSettings()->SetHighlight( false );
230 
231  LIB_EDIT_FRAME* libEditFrame = dynamic_cast<LIB_EDIT_FRAME*>( m_frame );
232  LIB_VIEW_FRAME* libViewFrame = dynamic_cast<LIB_VIEW_FRAME*>( m_frame );
233 
234  if( libEditFrame )
235  {
236  m_isLibEdit = true;
237  m_unit = libEditFrame->GetUnit();
238  m_convert = libEditFrame->GetConvert();
239  }
240  else
241  m_isLibView = libViewFrame != nullptr;
242  }
243  else
244  // Restore previous properties of selected items and remove them from containers
245  ClearSelection();
246 
247  // Reinsert the VIEW_GROUP, in case it was removed from the VIEW
248  getView()->Remove( &m_selection );
249  getView()->Add( &m_selection );
250 }
251 
252 
254 {
255  ACTION_MENU* actionMenu = aEvent.Parameter<ACTION_MENU*>();
256  CONDITIONAL_MENU* conditionalMenu = dynamic_cast<CONDITIONAL_MENU*>( actionMenu );
257 
258  if( conditionalMenu )
259  conditionalMenu->Evaluate( m_selection );
260 
261  if( actionMenu )
262  actionMenu->UpdateAll();
263 
264  return 0;
265 }
266 
267 
269 {
270  SCH_MARKER_T,
275  SCH_LINE_T,
276  SCH_BITMAP_T,
277  SCH_TEXT_T,
278  SCH_LABEL_T,
281  SCH_FIELD_T,
284  SCH_SHEET_T,
285  EOT
286 };
287 
288 
290 {
291  LIB_ARC_T,
292  LIB_CIRCLE_T,
293  LIB_TEXT_T,
296  LIB_BEZIER_T,
297  LIB_PIN_T,
298  LIB_FIELD_T,
299  EOT
300 };
301 
302 
304 {
305 
306  // Main loop: keep receiving events
307  while( TOOL_EVENT* evt = Wait() )
308  {
309  if( m_frame->ToolStackIsEmpty() )
310  m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
311 
313 
314  if( evt->Modifier( MD_SHIFT ) && evt->Modifier( MD_CTRL ) )
315  m_subtractive = true;
316  else if( evt->Modifier( MD_SHIFT ) )
317  m_additive = true;
318  else if( evt->Modifier( MD_CTRL ) )
319  m_exclusive_or = true;
320 
321  // Is the user requesting that the selection list include all possible
322  // items without removing less likely selection candidates
323  m_skip_heuristics = !!evt->Modifier( MD_ALT );
324 
325  // Single click? Select single object
326  if( evt->IsClick( BUT_LEFT ) )
327  {
328  if( auto schframe = dynamic_cast<SCH_EDIT_FRAME*>( m_frame ) )
329  schframe->FocusOnItem( nullptr );
330 
331  SelectPoint( evt->Position(), EE_COLLECTOR::AllItems, nullptr, nullptr, false,
333  }
334 
335  // right click? if there is any object - show the context menu
336  else if( evt->IsClick( BUT_RIGHT ) )
337  {
338  bool selectionCancelled = false;
339 
340  if( m_selection.Empty() ||
341  !m_selection.GetBoundingBox().Contains( wxPoint( evt->Position() ) ) )
342  {
343  ClearSelection();
344  SelectPoint( evt->Position(), EE_COLLECTOR::AllItems, nullptr,
345  &selectionCancelled );
346  m_selection.SetIsHover( true );
347  }
348 
349  if( !selectionCancelled )
351  }
352 
353  // double click? Display the properties window
354  else if( evt->IsDblClick( BUT_LEFT ) )
355  {
356  if( auto schframe = dynamic_cast<SCH_EDIT_FRAME*>( m_frame ) )
357  schframe->FocusOnItem( nullptr );
358 
359  if( m_selection.Empty() )
360  SelectPoint( evt->Position());
361 
362  EDA_ITEM* item = m_selection.Front();
363 
364  if( item && item->Type() == SCH_SHEET_T )
366  else
368  }
369 
370  // drag with LMB? Select multiple objects (or at least draw a selection box) or drag them
371  else if( evt->IsDrag( BUT_LEFT ) )
372  {
373  if( auto schframe = dynamic_cast<SCH_EDIT_FRAME*>( m_frame ) )
374  schframe->FocusOnItem( nullptr );
375 
377  {
378  selectMultiple();
379  }
380  else
381  {
382  // selection is empty? try to start dragging the item under the point where drag
383  // started
384  if( m_isLibEdit && m_selection.Empty() )
386  else if( m_selection.Empty() )
388 
389  // Check if dragging has started within any of selected items bounding box
390  if( selectionContains( evt->Position() ) )
391  {
392  // Yes -> run the move tool and wait till it finishes
393  if( m_isLibEdit )
394  m_toolMgr->InvokeTool( "eeschema.SymbolMoveTool" );
395  else
396  m_toolMgr->InvokeTool( "eeschema.InteractiveMove" );
397  }
398  else
399  {
400  // No -> drag a selection box
401  selectMultiple();
402  }
403  }
404  }
405 
406  // context sub-menu selection? Handle unit selection or bus unfolding
407  else if( evt->Category() == TC_COMMAND && evt->Action() == TA_CHOICE_MENU_CHOICE )
408  {
409  if( evt->GetCommandId().get() >= ID_POPUP_SCH_SELECT_UNIT_CMP
410  && evt->GetCommandId().get() <= ID_POPUP_SCH_SELECT_UNIT_CMP_MAX )
411  {
412  SCH_COMPONENT* component = dynamic_cast<SCH_COMPONENT*>( m_selection.Front() );
413  int unit = evt->GetCommandId().get() - ID_POPUP_SCH_SELECT_UNIT_CMP;
414 
415  if( component )
416  static_cast<SCH_EDIT_FRAME*>( m_frame )->SelectUnit( component, unit );
417  }
418  else if( evt->GetCommandId().get() >= ID_POPUP_SCH_UNFOLD_BUS
419  && evt->GetCommandId().get() <= ID_POPUP_SCH_UNFOLD_BUS_END )
420  {
421  wxString* net = new wxString( *evt->Parameter<wxString*>() );
423  }
424 
425  }
426 
427  else if( evt->IsCancelInteractive() )
428  {
429  if( auto schframe = dynamic_cast<SCH_EDIT_FRAME*>( m_frame ) )
430  schframe->FocusOnItem( nullptr );
431 
432  ClearSelection();
433  }
434 
435  else if( evt->Action() == TA_UNDO_REDO_PRE )
436  {
437  if( auto schframe = dynamic_cast<SCH_EDIT_FRAME*>( m_frame ) )
438  schframe->FocusOnItem( nullptr );
439 
440  ClearSelection();
441  }
442 
443  else
444  evt->SetPassEvent();
445  }
446 
447  return 0;
448 }
449 
450 
452 {
453  return m_selection;
454 }
455 
456 
457 bool EE_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, const KICAD_T* aFilterList,
458  EDA_ITEM** aItem, bool* aSelectionCancelledFlag, bool aCheckLocked, bool aAdd,
459  bool aSubtract, bool aExclusiveOr )
460 {
461  EE_COLLECTOR collector;
462 
463  collector.m_Threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
464 
465  if( m_isLibEdit )
466  {
467  auto part = static_cast<LIB_EDIT_FRAME*>( m_frame )->GetCurPart();
468 
469  if( !part )
470  return false;
471 
472  collector.Collect( part->GetDrawItems(), aFilterList, (wxPoint) aWhere, m_unit, m_convert );
473  }
474  else
475  collector.Collect( m_frame->GetScreen(), aFilterList, (wxPoint) aWhere, m_unit, m_convert );
476 
477  // Post-process collected items
478  for( int i = collector.GetCount() - 1; i >= 0; --i )
479  {
480  if( !Selectable( collector[ i ] ) )
481  {
482  collector.Remove( i );
483  continue;
484  }
485 
486  if( aCheckLocked && collector[ i ]->IsLocked() )
487  {
488  collector.Remove( i );
489  continue;
490  }
491 
492  // SelectPoint, unlike other selection routines, can select line ends
493  if( collector[ i ]->Type() == SCH_LINE_T )
494  {
495  SCH_LINE* line = (SCH_LINE*) collector[ i ];
496  line->ClearFlags( STARTPOINT | ENDPOINT );
497 
498  if( HitTestPoints( line->GetStartPoint(), (wxPoint) aWhere, collector.m_Threshold ) )
499  line->SetFlags( STARTPOINT );
500  else if (HitTestPoints( line->GetEndPoint(), (wxPoint) aWhere, collector.m_Threshold ) )
501  line->SetFlags( ENDPOINT );
502  else
503  line->SetFlags( STARTPOINT | ENDPOINT );
504  }
505  }
506 
508 
509  // Apply some ugly heuristics to avoid disambiguation menus whenever possible
510  if( collector.GetCount() > 1 && !m_skip_heuristics )
511  {
512  GuessSelectionCandidates( collector, aWhere );
513  }
514 
515  // If still more than one item we're going to have to ask the user.
516  if( collector.GetCount() > 1 )
517  {
518  collector.m_MenuTitle = _( "Clarify Selection" );
519  // Must call selectionMenu via RunAction() to avoid event-loop contention
520  m_toolMgr->RunAction( EE_ACTIONS::selectionMenu, true, &collector );
521 
522  if( collector.m_MenuCancelled )
523  {
524  if( aSelectionCancelledFlag )
525  *aSelectionCancelledFlag = true;
526 
527  return false;
528  }
529  }
530 
531  if( !aAdd && !aSubtract && !aExclusiveOr )
532  ClearSelection();
533 
534  bool anyAdded = false;
535  bool anySubtracted = false;
536 
537  if( collector.GetCount() > 0 )
538  {
539  for( int i = 0; i < collector.GetCount(); ++i )
540  {
541  if( aSubtract || ( aExclusiveOr && collector[i]->IsSelected() ) )
542  {
543  unselect( collector[i] );
544  anySubtracted = true;
545  }
546  else
547  {
548  select( collector[i] );
549  anyAdded = true;
550  }
551  }
552  }
553 
554  if( anyAdded )
555  {
557 
558  if( aItem && collector.GetCount() == 1 )
559  *aItem = collector[0];
560 
561  return true;
562  }
563  else if( anySubtracted )
564  {
566  return true;
567  }
568 
569  return false;
570 }
571 
572 
574 {
575  // There are certain parent/child and enclosure combinations that can be handled
576  // automatically.
577 
578  // Prefer exact hits to sloppy ones
579  int exactHits = 0;
580 
581  for( int i = collector.GetCount() - 1; i >= 0; --i )
582  {
583  EDA_ITEM* item = collector[ i ];
584 
585  if( item->HitTest( (wxPoint) aPos, 0 ) )
586  exactHits++;
587  }
588 
589  if( exactHits > 0 && exactHits < collector.GetCount() )
590  {
591  for( int i = collector.GetCount() - 1; i >= 0; --i )
592  {
593  EDA_ITEM* item = collector[ i ];
594 
595  if( !item->HitTest( (wxPoint) aPos, 0 ) )
596  collector.Remove( item );
597  }
598  }
599 
600  // Prefer a non-sheet to a sheet
601  for( int i = 0; collector.GetCount() == 2 && i < 2; ++i )
602  {
603  EDA_ITEM* item = collector[ i ];
604  EDA_ITEM* other = collector[ ( i + 1 ) % 2 ];
605 
606  if( item->Type() != SCH_SHEET_T && other->Type() == SCH_SHEET_T )
607  collector.Remove( other );
608  }
609 
610  // Prefer a symbol to a pin or the opposite, when both a symbol and a pin are selected
611  // We need to be able to select only a pin:
612  // - to display its characteristics (especially if an ERC is attached to the pin)
613  // - for cross probing, to select the corresponding pad.
614  // Note also the case happens only in schematic editor. In symbol editor, the symbol
615  // itself is never selected
616  for( int i = 0; collector.GetCount() == 2 && i < 2; ++i )
617  {
618  EDA_ITEM* item = collector[ i ];
619  EDA_ITEM* other = collector[ ( i + 1 ) % 2 ];
620 
621  if( item->Type() == SCH_COMPONENT_T && other->Type() == SCH_PIN_T )
622  {
624  collector.Remove( other );
625  else
626  collector.Remove( item );
627  }
628  }
629 
630  // Prefer a field to a symbol
631  for( int i = 0; collector.GetCount() == 2 && i < 2; ++i )
632  {
633  EDA_ITEM* item = collector[ i ];
634  EDA_ITEM* other = collector[ ( i + 1 ) % 2 ];
635 
636  if( item->Type() == SCH_FIELD_T && other->Type() == SCH_COMPONENT_T )
637  collector.Remove( other );
638  }
639 
640  // No need for multiple wires at a single point; if there's a junction select that;
641  // otherwise any of the wires will do
642  bool junction = false;
643  bool wiresOnly = true;
644 
645  for( EDA_ITEM* item : collector )
646  {
647  if( item->Type() == SCH_JUNCTION_T )
648  junction = true;
649  else if( item->Type() != SCH_LINE_T )
650  wiresOnly = false;
651  }
652 
653  if( wiresOnly )
654  {
655  for( int j = collector.GetCount() - 1; j >= 0; --j )
656  {
657  if( junction && collector[ j ]->Type() != SCH_JUNCTION_T )
658  collector.Remove( j );
659  else if( !junction && j > 0 )
660  collector.Remove( j );
661  }
662  }
663 }
664 
665 
667 {
668  if( m_selection.Empty() )
669  {
670  VECTOR2D cursorPos = getViewControls()->GetCursorPosition( true );
671 
672  ClearSelection();
673  SelectPoint( cursorPos, aFilterList );
674  m_selection.SetIsHover( true );
676  }
677  else // Trim an existing selection by aFilterList
678  {
679  for( int i = (int) m_selection.GetSize() - 1; i >= 0; --i )
680  {
681  EDA_ITEM* item = (EDA_ITEM*) m_selection.GetItem( i );
682 
683  if( !item->IsType( aFilterList ) )
684  {
685  unselect( item );
687  }
688  }
689  }
690 
692 
693  return m_selection;
694 }
695 
696 
698 {
699  VECTOR2I refP( 0, 0 );
700 
701  if( m_selection.Size() > 0 )
702  {
703  if( m_isLibEdit )
704  refP = static_cast<LIB_ITEM*>( m_selection.GetTopLeftItem() )->GetPosition();
705  else
706  refP = static_cast<SCH_ITEM*>( m_selection.GetTopLeftItem() )->GetPosition();
707  }
708 
710 }
711 
712 
714 {
715  bool cancelled = false; // Was the tool cancelled while it was running?
716  m_multiple = true; // Multiple selection mode is active
717  KIGFX::VIEW* view = getView();
718 
720  view->Add( &area );
721 
722  while( TOOL_EVENT* evt = Wait() )
723  {
724  if( evt->IsCancelInteractive() || evt->IsActivate() )
725  {
726  cancelled = true;
727  break;
728  }
729 
730  if( evt->IsDrag( BUT_LEFT ) )
731  {
733  ClearSelection();
734 
735  // Start drawing a selection box
736  area.SetOrigin( evt->DragOrigin() );
737  area.SetEnd( evt->Position() );
738  area.SetAdditive( m_additive );
741 
742  view->SetVisible( &area, true );
743  view->Update( &area );
744  getViewControls()->SetAutoPan( true );
745  }
746 
747  if( evt->IsMouseUp( BUT_LEFT ) )
748  {
749  getViewControls()->SetAutoPan( false );
750 
751  // End drawing the selection box
752  view->SetVisible( &area, false );
753 
754  // Mark items within the selection box as selected
755  std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems;
756  std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> sheetPins;
757 
758  // Filter the view items based on the selection box
759  BOX2I selectionBox = area.ViewBBox();
760  view->Query( selectionBox, selectedItems ); // Get the list of selected items
761 
762  // Sheet pins aren't in the view; add them by hand
763  for( KIGFX::VIEW::LAYER_ITEM_PAIR& pair : selectedItems )
764  {
765  SCH_SHEET* sheet = dynamic_cast<SCH_SHEET*>( pair.first );
766 
767  if( sheet )
768  {
769  int layer = pair.second;
770 
771  for( SCH_SHEET_PIN* pin : sheet->GetPins() )
772  sheetPins.emplace_back( KIGFX::VIEW::LAYER_ITEM_PAIR( pin, layer ) );
773  }
774  }
775 
776  selectedItems.insert( selectedItems.end(), sheetPins.begin(), sheetPins.end() );
777 
778  int width = area.GetEnd().x - area.GetOrigin().x;
779  int height = area.GetEnd().y - area.GetOrigin().y;
780 
781  /* Selection mode depends on direction of drag-selection:
782  * Left > Right : Select objects that are fully enclosed by selection
783  * Right > Left : Select objects that are crossed by selection
784  */
785  bool windowSelection = width >= 0;
786  bool anyAdded = false;
787  bool anySubtracted = false;
788 
789  if( view->IsMirroredX() )
790  windowSelection = !windowSelection;
791 
792  // Construct an EDA_RECT to determine EDA_ITEM selection
793  EDA_RECT selectionRect( (wxPoint) area.GetOrigin(), wxSize( width, height ) );
794 
795  selectionRect.Normalize();
796 
797  for( KIGFX::VIEW::LAYER_ITEM_PAIR& pair : selectedItems )
798  {
799  EDA_ITEM* item = dynamic_cast<EDA_ITEM*>( pair.first );
800 
801  if( item && Selectable( item ) && item->HitTest( selectionRect, windowSelection ) )
802  {
803  if( m_subtractive || ( m_exclusive_or && item->IsSelected() ) )
804  {
805  unselect( item );
806  anySubtracted = true;
807  }
808  else
809  {
810  select( item );
811  item->SetFlags( STARTPOINT | ENDPOINT );
812  anyAdded = true;
813  }
814  }
815  }
816 
817  m_selection.SetIsHover( false );
818 
819  // Inform other potentially interested tools
820  if( anyAdded )
822 
823  if( anySubtracted )
825 
826  break; // Stop waiting for events
827  }
828  }
829 
830  getViewControls()->SetAutoPan( false );
831 
832  // Stop drawing the selection box
833  view->Remove( &area );
834  m_multiple = false; // Multiple selection mode is inactive
835 
836  if( !cancelled )
838 
839  return cancelled;
840 }
841 
842 
843 static KICAD_T nodeTypes[] =
844 {
846  SCH_PIN_T,
851  SCH_LABEL_T,
856  EOT
857 };
858 
859 
861 {
862  EE_COLLECTOR collector;
863 
864  //TODO(snh): Reimplement after exposing KNN interface
865  int thresholdMax = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
866 
867  for( int threshold : { 0, thresholdMax/2, thresholdMax } )
868  {
869  collector.m_Threshold = threshold;
870  collector.Collect( m_frame->GetScreen(), nodeTypes, (wxPoint) aPosition );
871 
872  if( collector.GetCount() > 0 )
873  break;
874  }
875 
876  return collector.GetCount() ? collector[ 0 ] : nullptr;
877 }
878 
879 
881 {
882  VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !aEvent.Modifier( MD_ALT ) );
883 
884  SelectPoint( cursorPos, nodeTypes );
885 
886  return 0;
887 }
888 
889 
891 {
892  static KICAD_T wiresAndBuses[] = { SCH_LINE_LOCATE_WIRE_T, SCH_LINE_LOCATE_BUS_T, EOT };
893 
894  RequestSelection( wiresAndBuses );
895 
896  if( m_selection.Empty() )
897  return 0;
898 
899  SCH_LINE* line = (SCH_LINE*) m_selection.Front();
900  EDA_ITEMS items;
901 
903  auto conns = m_frame->GetScreen()->MarkConnections( line );
904 
905  for( auto item : conns )
906  select( item );
907 
908  if( m_selection.GetSize() > 1 )
910 
911  return 0;
912 }
913 
914 
916 {
917  AddItemToSel( aEvent.Parameter<EDA_ITEM*>() );
918  m_selection.SetIsHover( false );
919  return 0;
920 }
921 
922 
923 void EE_SELECTION_TOOL::AddItemToSel( EDA_ITEM* aItem, bool aQuietMode )
924 {
925  if( aItem )
926  {
927  select( aItem );
928 
929  // Inform other potentially interested tools
930  if( !aQuietMode )
932  }
933 }
934 
935 
937 {
938  AddItemsToSel( aEvent.Parameter<EDA_ITEMS*>(), false );
939  m_selection.SetIsHover( false );
940  return 0;
941 }
942 
943 
944 void EE_SELECTION_TOOL::AddItemsToSel( EDA_ITEMS* aList, bool aQuietMode )
945 {
946  if( aList )
947  {
948  for( EDA_ITEM* item : *aList )
949  select( item );
950 
951  // Inform other potentially interested tools
952  if( !aQuietMode )
954  }
955 }
956 
957 
959 {
960  RemoveItemFromSel( aEvent.Parameter<EDA_ITEM*>() );
961  m_selection.SetIsHover( false );
962  return 0;
963 }
964 
965 
966 void EE_SELECTION_TOOL::RemoveItemFromSel( EDA_ITEM* aItem, bool aQuietMode )
967 {
968  if( aItem )
969  {
970  unselect( aItem );
971 
972  // Inform other potentially interested tools
973  if( !aQuietMode )
975  }
976 }
977 
978 
980 {
981  RemoveItemsFromSel( aEvent.Parameter<EDA_ITEMS*>(), false );
982  m_selection.SetIsHover( false );
983  return 0;
984 }
985 
986 
987 void EE_SELECTION_TOOL::RemoveItemsFromSel( EDA_ITEMS* aList, bool aQuietMode )
988 {
989  if( aList )
990  {
991  for( EDA_ITEM* item : *aList )
992  unselect( item );
993 
994  // Inform other potentially interested tools
995  if( !aQuietMode )
997  }
998 }
999 
1000 
1002 {
1003  highlight( aItem, BRIGHTENED );
1004 }
1005 
1006 
1008 {
1009  unhighlight( aItem, BRIGHTENED );
1010 }
1011 
1012 
1014 {
1015  ClearSelection();
1016 
1017  return 0;
1018 }
1019 
1020 
1022 {
1023  m_selection.Clear();
1024 
1025  if( m_isLibEdit )
1026  {
1027  LIB_PART* start = static_cast<LIB_EDIT_FRAME*>( m_frame )->GetCurPart();
1028 
1029  for( LIB_ITEM& item : start->GetDrawItems() )
1030  {
1031  if( item.IsSelected() )
1032  select( static_cast<EDA_ITEM*>( &item ) );
1033  }
1034  }
1035  else
1036  {
1037  for( auto item : m_frame->GetScreen()->Items() )
1038  {
1039  // If the field and component are selected, only use the component
1040  if( item->IsSelected() )
1041  {
1042  select( item );
1043  }
1044  else
1045  {
1046  if( item->Type() == SCH_COMPONENT_T )
1047  {
1048  for( SCH_FIELD& field : static_cast<SCH_COMPONENT*>( item )->GetFields() )
1049  {
1050  if( field.IsSelected() )
1051  select( &field );
1052  }
1053  }
1054 
1055  if( item->Type() == SCH_SHEET_T )
1056  {
1057  for( SCH_FIELD& field : static_cast<SCH_SHEET*>( item )->GetFields() )
1058  {
1059  if( field.IsSelected() )
1060  select( &field );
1061  }
1062 
1063  for( SCH_SHEET_PIN* pin : static_cast<SCH_SHEET*>( item )->GetPins() )
1064  {
1065  if( pin->IsSelected() )
1066  select( pin );
1067  }
1068  }
1069 
1070  }
1071  }
1072  }
1073 
1075 
1076  // Inform other potentially interested tools
1078 }
1079 
1080 
1082 {
1083  EE_COLLECTOR* collector = aEvent.Parameter<EE_COLLECTOR*>();
1084 
1085  if( !doSelectionMenu( collector ) )
1086  collector->m_MenuCancelled = true;
1087 
1088  return 0;
1089 }
1090 
1091 
1093 {
1094  EDA_ITEM* current = nullptr;
1095  ACTION_MENU menu( true );
1096  bool selectAll = false;
1097 
1098  int limit = std::min( MAX_SELECT_ITEM_IDS, aCollector->GetCount() );
1099 
1100  for( int i = 0; i < limit; ++i )
1101  {
1102  wxString text;
1103  EDA_ITEM* item = ( *aCollector )[i];
1104  text = item->GetSelectMenuText( m_frame->GetUserUnits() );
1105 
1106  wxString menuText = wxString::Format( "&%d. %s\t%d", i + 1, text, i + 1 );
1107  menu.Add( menuText, i + 1, item->GetMenuImage() );
1108  }
1109 
1110  menu.AppendSeparator();
1111  menu.Add( _( "Select &All\tA" ), limit + 1, net_highlight_schematic_xpm );
1112 
1113  if( aCollector->m_MenuTitle.Length() )
1114  menu.SetTitle( aCollector->m_MenuTitle );
1115 
1116  menu.SetIcon( info_xpm );
1117  menu.DisplayTitle( true );
1118  SetContextMenu( &menu, CMENU_NOW );
1119 
1120  while( TOOL_EVENT* evt = Wait() )
1121  {
1122  if( evt->Action() == TA_CHOICE_MENU_UPDATE )
1123  {
1124  if( selectAll )
1125  {
1126  for( int i = 0; i < aCollector->GetCount(); ++i )
1127  unhighlight( ( *aCollector )[i], BRIGHTENED );
1128  }
1129  else if( current )
1130  {
1131  unhighlight( current, BRIGHTENED );
1132  }
1133 
1134  int id = *evt->GetCommandId();
1135 
1136  // User has pointed an item, so show it in a different way
1137  if( id > 0 && id <= limit )
1138  {
1139  current = ( *aCollector )[id - 1];
1140  highlight( current, BRIGHTENED );
1141  }
1142  else
1143  {
1144  current = nullptr;
1145  }
1146 
1147  // User has pointed on the "Select All" option
1148  if( id == limit + 1 )
1149  {
1150  for( int i = 0; i < aCollector->GetCount(); ++i )
1151  highlight( ( *aCollector )[i], BRIGHTENED );
1152  selectAll = true;
1153  }
1154  else
1155  {
1156  selectAll = false;
1157  }
1158  }
1159  else if( evt->Action() == TA_CHOICE_MENU_CHOICE )
1160  {
1161  if( selectAll )
1162  {
1163  for( int i = 0; i < aCollector->GetCount(); ++i )
1164  unhighlight( ( *aCollector )[i], BRIGHTENED );
1165  }
1166  else if( current )
1167  unhighlight( current, BRIGHTENED );
1168 
1169  OPT<int> id = evt->GetCommandId();
1170 
1171  // User has selected the "Select All" option
1172  if( id == limit + 1 )
1173  {
1174  selectAll = true;
1175  current = nullptr;
1176  }
1177  // User has selected an item, so this one will be returned
1178  else if( id && ( *id > 0 ) && ( *id <= limit ) )
1179  {
1180  selectAll = false;
1181  current = ( *aCollector )[*id - 1];
1182  }
1183  else
1184  {
1185  selectAll = false;
1186  current = nullptr;
1187  }
1188 
1189  break;
1190  }
1191 
1192  getView()->UpdateItems();
1193  m_frame->GetCanvas()->Refresh();
1194  }
1195 
1196  if( selectAll )
1197  return true;
1198  else if( current )
1199  {
1200  unhighlight( current, BRIGHTENED );
1201 
1202  getView()->UpdateItems();
1203  m_frame->GetCanvas()->Refresh();
1204 
1205  aCollector->Empty();
1206  aCollector->Append( current );
1207  return true;
1208  }
1209 
1210  return false;
1211 }
1212 
1213 
1214 bool EE_SELECTION_TOOL::Selectable( const EDA_ITEM* aItem, bool checkVisibilityOnly ) const
1215 {
1216  // NOTE: in the future this is where eeschema layer/itemtype visibility will be handled
1217  LIB_EDIT_FRAME* symbeditFrame = dynamic_cast< LIB_EDIT_FRAME* >( m_frame );
1218 
1219  switch( aItem->Type() )
1220  {
1221  case SCH_PIN_T:
1222  if( !static_cast<const SCH_PIN*>( aItem )->IsVisible() && !m_frame->GetShowAllPins() )
1223  return false;
1224  break;
1225 
1226  case LIB_PART_T: // In libedit we do not want to select the symbol itself.
1227  return false;
1228 
1229  case LIB_FIELD_T: // LIB_FIELD object can always be edited.
1230  break;
1231 
1232  case LIB_ARC_T:
1233  case LIB_CIRCLE_T:
1234  case LIB_TEXT_T:
1235  case LIB_RECTANGLE_T:
1236  case LIB_POLYLINE_T:
1237  case LIB_BEZIER_T:
1238  case LIB_PIN_T:
1239  {
1240  if( symbeditFrame )
1241  {
1242  LIB_ITEM* lib_item = (LIB_ITEM*) aItem;
1243 
1244  if( lib_item->GetUnit() && lib_item->GetUnit() != symbeditFrame->GetUnit() )
1245  return false;
1246 
1247  if( lib_item->GetConvert() && lib_item->GetConvert() != symbeditFrame->GetConvert() )
1248  return false;
1249  }
1250 
1251  break;
1252  }
1253 
1254  case SCH_MARKER_T: // Always selectable
1255  return true;
1256 
1257  default: // Suppress warnings
1258  break;
1259  }
1260 
1261  return true;
1262 }
1263 
1264 
1266 {
1267  if( m_selection.Empty() )
1268  return;
1269 
1270  while( m_selection.GetSize() )
1272 
1273  getView()->Update( &m_selection );
1274 
1275  m_selection.SetIsHover( false );
1277 
1278  // Inform other potentially interested tools
1280 }
1281 
1282 
1284 {
1285  highlight( aItem, SELECTED, &m_selection );
1286 }
1287 
1288 
1290 {
1291  unhighlight( aItem, SELECTED, &m_selection );
1292 }
1293 
1294 
1295 void EE_SELECTION_TOOL::highlight( EDA_ITEM* aItem, int aMode, EE_SELECTION* aGroup )
1296 {
1297  KICAD_T itemType = aItem->Type();
1298 
1299  if( aMode == SELECTED )
1300  aItem->SetSelected();
1301  else if( aMode == BRIGHTENED )
1302  aItem->SetBrightened();
1303 
1304  if( aGroup )
1305  aGroup->Add( aItem );
1306 
1307  // Highlight pins and fields. (All the other component children are currently only
1308  // represented in the LIB_PART and will inherit the settings of the parent component.)
1309  if( itemType == SCH_COMPONENT_T )
1310  {
1311  if( auto schframe = dynamic_cast<SCH_EDIT_FRAME*>( m_frame ) )
1312  {
1313  SCH_PIN_PTRS pins = static_cast<SCH_COMPONENT*>( aItem )->GetSchPins(
1314  &schframe->GetCurrentSheet() );
1315 
1316  for( SCH_PIN* pin : pins )
1317  {
1318  if( aMode == SELECTED )
1319  pin->SetSelected();
1320  else if( aMode == BRIGHTENED )
1321  pin->SetBrightened();
1322  }
1323  }
1324 
1325  for( SCH_FIELD& field : static_cast<SCH_COMPONENT*>( aItem )->GetFields() )
1326  {
1327  if( aMode == SELECTED )
1328  field.SetSelected();
1329  else if( aMode == BRIGHTENED )
1330  field.SetBrightened();
1331  }
1332  }
1333  else if( itemType == SCH_SHEET_T )
1334  {
1335  for( SCH_FIELD& field : static_cast<SCH_SHEET*>( aItem )->GetFields() )
1336  {
1337  if( aMode == SELECTED )
1338  field.SetSelected();
1339  else if( aMode == BRIGHTENED )
1340  field.SetBrightened();
1341  }
1342 
1343  for( SCH_SHEET_PIN* pin : static_cast<SCH_SHEET*>( aItem )->GetPins() )
1344  {
1345  if( aMode == SELECTED )
1346  pin->SetSelected();
1347  else if( aMode == BRIGHTENED )
1348  pin->SetBrightened();
1349  }
1350  }
1351 
1352  if( itemType == SCH_PIN_T || itemType == SCH_FIELD_T || itemType == SCH_SHEET_PIN_T )
1353  getView()->Update( aItem->GetParent() );
1354  else
1355  getView()->Update( aItem );
1356 }
1357 
1358 
1359 void EE_SELECTION_TOOL::unhighlight( EDA_ITEM* aItem, int aMode, EE_SELECTION* aGroup )
1360 {
1361  KICAD_T itemType = aItem->Type();
1362 
1363  if( aMode == SELECTED )
1364  aItem->ClearSelected();
1365  else if( aMode == BRIGHTENED )
1366  aItem->ClearBrightened();
1367 
1368  if( aGroup )
1369  aGroup->Remove( aItem );
1370 
1371  // Unhighlight pins and fields. (All the other component children are currently only
1372  // represented in the LIB_PART.)
1373  if( itemType == SCH_COMPONENT_T )
1374  {
1375  if( auto schframe = dynamic_cast<SCH_EDIT_FRAME*>( m_frame ) )
1376  {
1377  SCH_PIN_PTRS pins = static_cast<SCH_COMPONENT*>( aItem )->GetSchPins(
1378  &schframe->GetCurrentSheet() );
1379 
1380  for( SCH_PIN* pin : pins )
1381  {
1382  if( aMode == SELECTED )
1383  pin->ClearSelected();
1384  else if( aMode == BRIGHTENED )
1385  pin->ClearBrightened();
1386  }
1387  }
1388 
1389  for( SCH_FIELD& field : static_cast<SCH_COMPONENT*>( aItem )->GetFields() )
1390  {
1391  if( aMode == SELECTED )
1392  field.ClearSelected();
1393  else if( aMode == BRIGHTENED )
1394  field.ClearBrightened();
1395  }
1396  }
1397  else if( itemType == SCH_SHEET_T )
1398  {
1399  for( SCH_FIELD& field : static_cast<SCH_SHEET*>( aItem )->GetFields() )
1400  {
1401  if( aMode == SELECTED )
1402  field.ClearSelected();
1403  else if( aMode == BRIGHTENED )
1404  field.ClearBrightened();
1405  }
1406 
1407  for( SCH_SHEET_PIN* pin : static_cast<SCH_SHEET*>( aItem )->GetPins() )
1408  {
1409  if( aMode == SELECTED )
1410  pin->ClearSelected();
1411  else if( aMode == BRIGHTENED )
1412  pin->ClearBrightened();
1413  }
1414  }
1415 
1416  if( itemType == SCH_PIN_T || itemType == SCH_FIELD_T || itemType == SCH_SHEET_PIN_T )
1417  getView()->Update( aItem->GetParent() );
1418  else
1419  getView()->Update( aItem );
1420 }
1421 
1422 
1424 {
1425  const unsigned GRIP_MARGIN = 20;
1426  VECTOR2I margin = getView()->ToWorld( VECTOR2I( GRIP_MARGIN, GRIP_MARGIN ), false );
1427 
1428  // Check if the point is located within any of the currently selected items bounding boxes
1429  for( auto item : m_selection )
1430  {
1431  BOX2I itemBox = item->ViewBBox();
1432  itemBox.Inflate( margin.x, margin.y ); // Give some margin for gripping an item
1433 
1434  if( itemBox.Contains( aPoint ) )
1435  return true;
1436  }
1437 
1438  return false;
1439 }
1440 
1441 
1443 {
1445 
1450 
1456 }
1457 
1458 
void Empty()
Function Empty sets the list to empty.
Definition: collector.h:109
void ClearReferencePoint()
Definition: selection.h:250
static TOOL_ACTION pinTable
Definition: ee_actions.h:145
static TOOL_ACTION properties
Definition: ee_actions.h:120
SCH_FIELD instances are attached to a component and provide a place for the component's value,...
Definition: sch_field.h:52
void AddStandardSubMenus(TOOL_MENU &aMenu)
Function CreateBasicMenu.
std::vector< SCH_PIN * > SCH_PIN_PTRS
Definition: sch_component.h:71
wxMenuItem * Add(const wxString &aLabel, int aId, const BITMAP_OPAQUE *aIcon)
Function Add() Adds a wxWidgets-style entry to the menu.
static const TOOL_EVENT SelectedEvent
Definition: actions.h:202
void SetEnd(VECTOR2I aEnd)
Set the current end of the rectangle (the corner that moves with the cursor.
TOOL_MENU m_menu
functions below are not yet implemented - their interface may change
bool selectionContains(const VECTOR2I &aPoint) const
Function selectionContains()
int m_Threshold
Definition: collector.h:66
int UpdateMenu(const TOOL_EVENT &aEvent)
virtual void Clear() override
Function Clear() Removes all the stored items from the group.
Definition: selection.h:95
static bool IsDrawingWire(const SELECTION &aSelection)
#define MAX_SELECT_ITEM_IDS
The maximum number of items in the clarify selection context menu.
Definition: eeschema_id.h:37
TOOL_EVENT * Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Function Wait()
static TOOL_ACTION breakBus
Definition: ee_actions.h:134
static SELECTION_CONDITION SingleSymbol
int GetConvert() const
wxPoint GetStartPoint() const
Definition: sch_line.h:94
bool IsSelected() const
Definition: base_struct.h:203
Model changes (required full reload)
Definition: tool_base.h:82
static const TOOL_EVENT UnselectedEvent
Definition: actions.h:203
SCH_SHEET * Last() const
Function Last returns a pointer to the last sheet of the list One can see the others sheet as the "pa...
ACTION_MENU.
Definition: action_menu.h:44
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:475
void SetOrigin(VECTOR2I aOrigin)
Set the origin of the rectange (the fixed corner)
void ClearSelected()
Definition: base_struct.h:211
static SELECTION_CONDITION MoreThan(int aNumber)
Function MoreThan Creates a functor that tests if the number of selected items is greater than the va...
void Collect(SCH_SCREEN *aScreen, const KICAD_T aFilterList[], const wxPoint &aPos, int aUnit=0, int aConvert=0)
Function Collect scans a EDA_ITEM using this class's Inspector method, which does the collection.
void SetCurrentCursor(wxStockCursor aStockCursorID)
Function SetCurrentCursor Set the current cursor shape for this panel.
static TOOL_ACTION addItemsToSel
Selects a list of items (specified as the event parameter)
Definition: ee_actions.h:63
VIEW_CONTROLS class definition.
static SELECTION_CONDITION OnlyTypes(const KICAD_T aTypes[])
Function OnlyTypes Creates a functor that tests if the selected items are only of given types.
CONDITIONAL_MENU & GetMenu()
Function GetMenu.
Definition: tool_menu.cpp:46
static TOOL_ACTION placeHierLabel
Definition: ee_actions.h:87
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:219
static TOOL_ACTION placeJunction
Definition: ee_actions.h:83
static TOOL_ACTION selectConnection
If current selection is a wire or bus, expand to entire connection.
Definition: ee_actions.h:53
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
virtual void Remove(VIEW_ITEM *aItem)
Function Remove() Removes a VIEW_ITEM from the view.
Definition: view.cpp:376
static SELECTION_CONDITION IdleSelection
bool selectMultiple()
Function selectMultiple() Handles drawing a selection box that allows one to select many items at the...
static TOOL_ACTION unfoldBus
Definition: ee_actions.h:81
void SetBrightened()
Definition: base_struct.h:209
#define HITTEST_THRESHOLD_PIXELS
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:140
void SetExclusiveOr(bool aExclusiveOr)
EE_COLLECTOR.
Definition: ee_collectors.h:42
bool Selectable(const EDA_ITEM *aItem, bool checkVisibilityOnly=false) const
Function Selectable() Checks conditions for an item to be selected.
int AddItemsToSel(const TOOL_EVENT &aEvent)
void select(EDA_ITEM *aItem)
Function select() Takes necessary action mark an item as selected.
Schematic editor (Eeschema) main window.
void UpdateAll()
Function UpdateAll() Runs update handlers for the menu and its submenus.
static TOOL_ACTION removeItemsFromSel
Definition: ee_actions.h:64
static SELECTION_CONDITION Idle
static SELECTION_CONDITION Count(int aNumber)
Function Count Creates a functor that tests if the number of selected items is equal to the value giv...
void SetContextMenu(ACTION_MENU *aMenu, CONTEXT_MENU_TRIGGER aTrigger=CMENU_BUTTON)
Function SetContextMenu()
VECTOR2< int > VECTOR2I
Definition: vector2d.h:594
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Function Go()
bool Contains(const wxPoint &aPoint) const
Function Contains.
void Remove(int aIndex)
Function Remove removes the item at aIndex (first position is 0);.
Definition: collector.h:129
bool InvokeTool(TOOL_ID aToolId)
Function InvokeTool() Calls a tool by sending a tool activation event to tool of given ID.
Symbol library viewer main window.
search types array terminator (End Of Types)
Definition: typeinfo.h:82
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
PAINTER * GetPainter() const
Function GetPainter() Returns the painter object used by the view for drawing VIEW_ITEMS.
Definition: view.h:199
void GuessSelectionCandidates(EE_COLLECTOR &collector, const VECTOR2I &aPos)
Apply heuristics to try and determine a single object when multiple are found under the cursor.
The base class for drawable items used by schematic library components.
Definition: lib_item.h:61
static TOOL_ACTION breakWire
Definition: ee_actions.h:133
void SetIsHover(bool aIsHover)
Definition: selection.h:66
virtual void Add(EDA_ITEM *aItem)
Definition: selection.h:76
const KICAD_T movableSymbolItems[]
static TOOL_ACTION leaveSheet
Definition: ee_actions.h:176
void ClearBrightened()
Definition: base_struct.h:212
static TOOL_ACTION removeItemFromSel
Definition: ee_actions.h:60
void Append(EDA_ITEM *item)
Function Append adds an item to the end of the list.
Definition: collector.h:119
void SetAdditive(bool aAdditive)
bool m_MenuCancelled
Definition: collector.h:69
EE_SELECTION & GetSelection()
Function GetSelection()
EESCHEMA_SETTINGS * eeconfig() const
EE_SELECTION & RequestSelection(const KICAD_T *aFilterList=EE_COLLECTOR::AllItems)
Function RequestSelection()
virtual bool HitTest(const wxPoint &aPosition, int aAccuracy=0) const
Function HitTest tests if aPosition is contained within or on the bounding box of an item.
Definition: base_struct.h:307
void updateReferencePoint()
Sets the reference point to the anchor of the top-left item.
static SELECTION_CONDITION SingleDeMorganSymbol
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:100
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
#define SELECTED
Definition: base_struct.h:124
int SelectNode(const TOOL_EVENT &aEvent)
Select node under cursor
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.h:245
int GetUnit() const
Definition: lib_item.h:295
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
void BrightenItem(EDA_ITEM *aItem)
void highlight(EDA_ITEM *aItem, int aHighlightMode, EE_SELECTION *aGroup=nullptr)
Function highlight() Highlights the item visually.
int GetUnit() const
static SELECTION_CONDITION Empty
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:232
static TOOL_ACTION addItemToSel
Selects an item (specified as the event parameter).
Definition: ee_actions.h:59
void SetSelected()
Definition: base_struct.h:208
static TOOL_ACTION drawWire
Definition: ee_actions.h:79
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagates an event to tools that requested events of matching type(s).
LIB_ITEMS_CONTAINER & GetDrawItems()
Return a reference to the draw item list.
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
Definition: base_struct.h:587
static TOOL_ACTION explicitCrossProbe
Definition: ee_actions.h:186
Class LIB_PIN definition.
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:435
static TOOL_ACTION symbolProperties
Definition: ee_actions.h:144
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
void SetIcon(const BITMAP_OPAQUE *aIcon)
Function SetIcon() Assigns an icon for the entry.
Definition: action_menu.cpp:70
bool Contains(const Vec &aPoint) const
Function Contains.
Definition: box2.h:150
TOOL_EVENT.
Definition: tool_event.h:171
const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers.
SCHEMATIC & Schematic() const
Define a library symbol object.
bool ToolStackIsEmpty()
Definition: tools_holder.h:84
const BITMAP_OPAQUE net_highlight_schematic_xpm[1]
#define BRIGHTENED
item is drawn with a bright contour
Definition: base_struct.h:139
EDA_ITEM * GetParent() const
Definition: base_struct.h:195
bool GetDragSelects() const
Indicates that a drag should draw a selection rectangle, even when started over an item.
Definition: tools_holder.h:101
VIEW_GROUP extends VIEW_ITEM by possibility of grouping items into a single object.
int SelectConnection(const TOOL_EVENT &aEvent)
If node selected then expand to connection, otherwise select connection under cursor
static const TOOL_EVENT ClearedEvent
Definition: actions.h:204
virtual bool IsType(const KICAD_T aScanTypes[]) const
Function IsType Checks whether the item is one of the listed types.
Definition: base_struct.h:262
std::function< bool(const SELECTION &)> SELECTION_CONDITION
Functor type that checks a specific condition for selected items.
void UpdateItems()
Function UpdateItems() Iterates through the list of items that asked for updating and updates them.
Definition: view.cpp:1421
static TOOL_ACTION selectionActivate
Activation of the selection tool.
Definition: ee_actions.h:46
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet.h:84
static TOOL_ACTION importSheetPin
Definition: ee_actions.h:90
static TOOL_ACTION clearSelection
Clears the current selection.
Definition: ee_actions.h:56
std::unique_ptr< LIB_PART > & GetPartRef()
static TOOL_ACTION updateMenu
Definition: actions.h:162
static SELECTION_CONDITION SingleMultiUnitSymbol
virtual KIGFX::VIEW_ITEM * GetItem(unsigned int aIdx) const override
Definition: selection.h:105
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:1540
int GetConvert() const
Definition: lib_item.h:298
const BITMAP_OPAQUE info_xpm[1]
Definition: info.cpp:75
void UnbrightenItem(EDA_ITEM *aItem)
EDA_ITEM * GetNode(VECTOR2I aPosition)
Find (but don't select) node under cursor
KIGFX::VIEW * getView() const
Function getView()
Definition: tool_base.cpp:36
virtual void SetAutoPan(bool aEnabled)
Function SetAutoPan Turns on/off auto panning (this feature is used when there is a tool active (eg.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:121
static bool IsDrawingBus(const SELECTION &aSelection)
static TOOL_ACTION drawBus
Definition: ee_actions.h:80
wxString m_MenuTitle
Definition: collector.h:68
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:216
bool IsMirroredX() const
Function IsMirroredX() Returns true if view is flipped across the X axis.
Definition: view.h:230
void SetSubtractive(bool aSubtractive)
virtual unsigned int GetSize() const override
Function GetSize() Returns the number of stored items.
Definition: selection.h:100
std::vector< SCH_SHEET_PIN * > & GetPins()
Definition: sch_sheet.h:362
int Modifier(int aMask=MD_MODIFIER_MASK) const
Returns information about key modifiers state (Ctrl, Alt, etc.)
Definition: tool_event.h:342
static TOOL_ACTION placeLabel
Definition: ee_actions.h:85
int RemoveItemFromSel(const TOOL_EVENT &aEvent)
void Normalize()
Function Normalize ensures that the height ant width are positive.
void unselect(EDA_ITEM *aItem)
Function unselect() Takes necessary action mark an item as unselected.
EDA_ITEM * GetTopLeftItem(bool onlyModules=false) const override
virtual RENDER_SETTINGS * GetSettings()=0
Function GetAdapter Returns pointer to current settings that are going to be used when drawing items.
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:301
SCH_SHEET & Root() const
Definition: schematic.h:97
static KICAD_T nodeTypes[]
The symbol library editor main window.
void SetTitle(const wxString &aTitle) override
Function SetTitle() Sets title for the menu.
Definition: action_menu.cpp:88
int AddItemToSel(const TOOL_EVENT &aEvent)
void SetHighlight(bool aEnabled, int aNetcode=-1, bool aMulti=false)
Function SetHighlight Turns on/off highlighting - it may be done for the active layer or the specifie...
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:37
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
virtual bool GetShowAllPins() const
Allow some frames to show/hide hidden pins.
bool SelectPoint(const VECTOR2I &aWhere, const KICAD_T *aFilterList=EE_COLLECTOR::AllItems, EDA_ITEM **aItem=nullptr, bool *aSelectionCancelledFlag=nullptr, bool aCheckLocked=false, bool aAdd=false, bool aSubtract=false, bool aExclusiveOr=false)
Function SelectPoint() Selects one or all items pointed by the parameter aWhere.
#define _(s)
Definition: 3d_actions.cpp:33
int SelectionMenu(const TOOL_EVENT &aEvent)
Function SelectionMenu() Shows a popup menu to trim the COLLECTOR passed as aEvent's parameter down t...
bool doSelectionMenu(EE_COLLECTOR *aItems)
Allows the selection of a single item from a list via pop-up menu.
SCH_BASE_FRAME * m_frame
virtual wxString GetSelectMenuText(EDA_UNITS aUnits) const
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
std::pair< VIEW_ITEM *, int > LAYER_ITEM_PAIR
Definition: view.h:66
bool HitTestPoints(const wxPoint &pointA, const wxPoint &pointB, double threshold)
Test, if two points are near each other.
Definition: trigo.h:166
static TOOL_ACTION selectionMenu
Runs a selection menu to select from a list of items.
Definition: ee_actions.h:67
EE_RTREE & Items()
Definition: sch_screen.h:162
#define ENDPOINT
ends. (Used to support dragging.)
Definition: base_struct.h:123
static SELECTION_CONDITION OnlyType(KICAD_T aType)
Function OnlyType Creates a functor that tests if the selected items are only of given type.
void RebuildSelection()
Rebuilds the selection from the EDA_ITEMs' selection flags.
EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
static const KICAD_T AllItems[]
Definition: ee_collectors.h:45
int Size() const
Returns the number of selected parts.
Definition: selection.h:127
Schematic symbol object.
Definition: sch_component.h:88
static TOOL_ACTION selectNode
Select the junction, wire or bus segment under the cursor.
Definition: ee_actions.h:49
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:68
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:159
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:79
static TOOL_ACTION enterSheet
Definition: ee_actions.h:175
boost::optional< T > OPT
Definition: optional.h:7
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:233
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Sets the item visibility.
Definition: view.cpp:1486
SCH_SHEET_PATH & GetCurrentSheet() const
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:346
void setTransitions() override
Sets up handlers for various events.
void ClearDrawingState()
Clear the state flags of all the items in the screen.
Definition: sch_screen.cpp:819
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:452
KIGFX::VIEW_CONTROLS * getViewControls() const
Function getViewControls()
Definition: tool_base.cpp:42
VIEW.
Definition: view.h:61
static TOOL_ACTION placeGlobalLabel
Definition: ee_actions.h:86
static TOOL_ACTION finishBus
Definition: ee_actions.h:96
int RemoveItemsFromSel(const TOOL_EVENT &aEvent)
virtual BITMAP_DEF GetMenuImage() const
Function GetMenuImage returns a pointer to an image to be used in menus.
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Function AddItem()
EE_SELECTION m_selection
EDA_RECT GetBoundingBox() const
Definition: selection.h:156
void ShowContextMenu(SELECTION &aSelection)
Function ShowContextMenu.
Definition: tool_menu.cpp:59
static TOOL_ACTION finishWire
Definition: ee_actions.h:95
void unhighlight(EDA_ITEM *aItem, int aHighlightMode, EE_SELECTION *aGroup=nullptr)
Function unhighlight() Unhighlights the item visually.
EDA_UNITS GetUserUnits() const
Return the user units currently in use.
VECTOR2D GetCursorPosition() const
Returns the current cursor position in world coordinates.
EDA_ITEM * Front() const
Definition: selection.h:184
const KICAD_T movableSchematicItems[]
KICAD_T Type() const
Function Type()
Definition: base_struct.h:193
int Main(const TOOL_EVENT &aEvent)
Function Main()
#define STARTPOINT
When a line is selected, these flags indicate which.
Definition: base_struct.h:122
void DisplayTitle(bool aDisplay=true)
Function DisplayTitle() Decides whether a title for a pop up menu should be displayed.
Definition: action_menu.cpp:99
std::set< SCH_ITEM * > MarkConnections(SCH_LINE *aSegment)
Return all wires and junctions connected to aSegment which are not connected any component pin.
Definition: sch_screen.cpp:326
virtual void Remove(EDA_ITEM *aItem)
Definition: selection.h:87
wxPoint GetEndPoint() const
Definition: sch_line.h:97