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 <symbol_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_item.h>
43 #include <sch_line.h>
44 #include <sch_sheet.h>
45 #include <schematic.h>
46 #include <tool/tool_event.h>
47 #include <tool/tool_manager.h>
48 #include <tools/ee_grid_helper.h>
50 #include <trigo.h>
51 #include <view/view.h>
52 #include <view/view_controls.h>
53 
54 
56 {
57  if( aSel.GetSize() == 1 )
58  {
59  SCH_COMPONENT* comp = dynamic_cast<SCH_COMPONENT*>( aSel.Front() );
60 
61  if( comp )
62  return !comp->GetPartRef() || !comp->GetPartRef()->IsPower();
63  }
64 
65  return false;
66 };
67 
68 
70 {
71  if( aSel.GetSize() == 1 )
72  {
73  SCH_COMPONENT* comp = dynamic_cast<SCH_COMPONENT*>( aSel.Front() );
74 
75  if( comp )
76  return comp->GetPartRef() && comp->GetPartRef()->HasConversion();
77  }
78 
79  return false;
80 };
81 
82 
84 {
85  if( aSel.GetSize() == 1 )
86  {
87  SCH_COMPONENT* comp = dynamic_cast<SCH_COMPONENT*>( aSel.Front() );
88 
89  if( comp )
90  return comp->GetPartRef() && comp->GetPartRef()->GetUnitCount() >= 2;
91  }
92 
93  return false;
94 };
95 
96 
97 #define HITTEST_THRESHOLD_PIXELS 5
98 
99 
101  TOOL_INTERACTIVE( "eeschema.InteractiveSelection" ),
102  m_frame( nullptr ),
103  m_additive( false ),
104  m_subtractive( false ),
105  m_exclusive_or( false ),
106  m_multiple( false ),
107  m_skip_heuristics( false ),
108  m_nonModifiedCursor( KICURSOR::ARROW ),
109  m_isSymbolEditor( false ),
110  m_isLibView( false ),
111  m_unit( 0 ),
112  m_convert( 0 )
113 {
114  m_selection.Clear();
115 }
116 
117 
119 {
120  getView()->Remove( &m_selection );
121 }
122 
123 
125 
126 
128 {
129  m_frame = getEditFrame<SCH_BASE_FRAME>();
130 
131  LIB_VIEW_FRAME* libViewFrame = dynamic_cast<LIB_VIEW_FRAME*>( m_frame );
132  SYMBOL_EDIT_FRAME* symbolEditorFrame = dynamic_cast<SYMBOL_EDIT_FRAME*>( m_frame );
133 
134  if( symbolEditorFrame )
135  {
136  m_isSymbolEditor = true;
137  m_unit = symbolEditorFrame->GetUnit();
138  m_convert = symbolEditorFrame->GetConvert();
139  }
140  else
141  {
142  m_isLibView = libViewFrame != nullptr;
143  }
144 
145  static KICAD_T wireOrBusTypes[] = { SCH_LINE_LOCATE_WIRE_T, SCH_LINE_LOCATE_BUS_T, EOT };
146  static KICAD_T connectedTypes[] = { SCH_LINE_LOCATE_WIRE_T, SCH_LINE_LOCATE_BUS_T,
149 
150  auto wireSelection = E_C::MoreThan( 0 ) && E_C::OnlyType( SCH_LINE_LOCATE_WIRE_T );
151  auto busSelection = E_C::MoreThan( 0 ) && E_C::OnlyType( SCH_LINE_LOCATE_BUS_T );
152  auto wireOrBusSelection = E_C::MoreThan( 0 ) && E_C::OnlyTypes( wireOrBusTypes );
153  auto connectedSelection = E_C::MoreThan( 0 ) && E_C::OnlyTypes( connectedTypes );
154  auto sheetSelection = E_C::Count( 1 ) && E_C::OnlyType( SCH_SHEET_T );
155 
156  auto schEditCondition =
157  [this] ( const SELECTION& aSel )
158  {
159  return !m_isSymbolEditor && !m_isLibView;
160  };
161 
162  auto belowRootSheetCondition =
163  [&]( const SELECTION& aSel )
164  {
165  SCH_EDIT_FRAME* schEditFrame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
166 
167  return ( schEditFrame&&
168  schEditFrame->GetCurrentSheet().Last() !=
169  &schEditFrame->Schematic().Root() );
170  };
171 
172  auto havePartCondition =
173  [&]( const SELECTION& sel )
174  {
175  return m_isSymbolEditor && static_cast<SYMBOL_EDIT_FRAME*>( m_frame )->GetCurPart();
176  };
177 
178  auto& menu = m_menu.GetMenu();
179 
180  menu.AddItem( EE_ACTIONS::enterSheet, sheetSelection && EE_CONDITIONS::Idle, 1 );
181  menu.AddItem( EE_ACTIONS::explicitCrossProbe, sheetSelection && EE_CONDITIONS::Idle, 1 );
182  menu.AddItem( EE_ACTIONS::leaveSheet, belowRootSheetCondition, 1 );
183 
184  menu.AddSeparator( 100 );
185  menu.AddItem( EE_ACTIONS::drawWire, schEditCondition && EE_CONDITIONS::Empty, 100 );
186  menu.AddItem( EE_ACTIONS::drawBus, schEditCondition && EE_CONDITIONS::Empty, 100 );
187 
188  menu.AddSeparator( 100 );
190 
191  menu.AddSeparator( 100 );
193 
194  menu.AddSeparator( 200 );
195  menu.AddItem( EE_ACTIONS::selectConnection, wireOrBusSelection && EE_CONDITIONS::Idle, 250 );
196  menu.AddItem( EE_ACTIONS::placeJunction, wireOrBusSelection && EE_CONDITIONS::Idle, 250 );
197  menu.AddItem( EE_ACTIONS::placeLabel, wireOrBusSelection && EE_CONDITIONS::Idle, 250 );
198  menu.AddItem( EE_ACTIONS::placeGlobalLabel, wireOrBusSelection && EE_CONDITIONS::Idle, 250 );
199  menu.AddItem( EE_ACTIONS::placeHierLabel, wireOrBusSelection && EE_CONDITIONS::Idle, 250 );
200  menu.AddItem( EE_ACTIONS::breakWire, wireSelection && EE_CONDITIONS::Idle, 250 );
201  menu.AddItem( EE_ACTIONS::breakBus, busSelection && EE_CONDITIONS::Idle, 250 );
202  menu.AddItem( EE_ACTIONS::importSheetPin, sheetSelection && EE_CONDITIONS::Idle, 250 );
203  menu.AddItem( EE_ACTIONS::assignNetclass, connectedSelection && EE_CONDITIONS::Idle, 250 );
204  menu.AddItem( EE_ACTIONS::editPageNumber, E_C::Empty || sheetSelection, 250 );
205 
206  menu.AddSeparator( 400 );
207  menu.AddItem( EE_ACTIONS::symbolProperties, havePartCondition && EE_CONDITIONS::Empty, 400 );
208  menu.AddItem( EE_ACTIONS::pinTable, havePartCondition && EE_CONDITIONS::Empty, 400 );
209 
210  menu.AddSeparator( 1000 );
212 
213  return true;
214 }
215 
216 
218 {
219  m_frame = getEditFrame<SCH_BASE_FRAME>();
220 
221  if( aReason == TOOL_BASE::MODEL_RELOAD )
222  {
223  // Remove pointers to the selected items from containers without changing their
224  // properties (as they are already deleted while a new sheet is loaded)
225  m_selection.Clear();
226  getView()->GetPainter()->GetSettings()->SetHighlight( false );
227 
228  SYMBOL_EDIT_FRAME* libEditFrame = dynamic_cast<SYMBOL_EDIT_FRAME*>( m_frame );
229  LIB_VIEW_FRAME* libViewFrame = dynamic_cast<LIB_VIEW_FRAME*>( m_frame );
230 
231  if( libEditFrame )
232  {
233  m_isSymbolEditor = true;
234  m_unit = libEditFrame->GetUnit();
235  m_convert = libEditFrame->GetConvert();
236  }
237  else
238  m_isLibView = libViewFrame != nullptr;
239  }
240  else
241  // Restore previous properties of selected items and remove them from containers
242  ClearSelection();
243 
244  // Reinsert the VIEW_GROUP, in case it was removed from the VIEW
245  getView()->Remove( &m_selection );
246  getView()->Add( &m_selection );
247 }
248 
249 
251 {
252  ACTION_MENU* actionMenu = aEvent.Parameter<ACTION_MENU*>();
253  CONDITIONAL_MENU* conditionalMenu = dynamic_cast<CONDITIONAL_MENU*>( actionMenu );
254 
255  if( conditionalMenu )
256  conditionalMenu->Evaluate( m_selection );
257 
258  if( actionMenu )
259  actionMenu->UpdateAll();
260 
261  return 0;
262 }
263 
264 
266 {
267  SCH_MARKER_T,
272  SCH_LINE_T,
273  SCH_BITMAP_T,
274  SCH_TEXT_T,
275  SCH_LABEL_T,
278  SCH_FIELD_T,
281  SCH_SHEET_T,
282  EOT
283 };
284 
285 
287 {
288  LIB_ARC_T,
289  LIB_CIRCLE_T,
290  LIB_TEXT_T,
293  LIB_BEZIER_T,
294  LIB_PIN_T,
295  LIB_FIELD_T,
296  EOT
297 };
298 
299 
301 {
303 
304  KIID lastRolloverItem = niluuid;
305 
306  // Main loop: keep receiving events
307  while( TOOL_EVENT* evt = Wait() )
308  {
309  bool displayWireCursor = false;
310  KIID rolloverItem = niluuid;
312 
313  if( evt->Modifier( MD_SHIFT ) && evt->Modifier( MD_CTRL ) )
314  m_subtractive = true;
315  else if( evt->Modifier( MD_SHIFT ) )
316  m_additive = true;
317  else if( evt->Modifier( MD_CTRL ) )
318  m_exclusive_or = true;
319 
320  bool modifier_enabled = m_subtractive || m_additive || m_exclusive_or;
321 
322  // Is the user requesting that the selection list include all possible
323  // items without removing less likely selection candidates
324  m_skip_heuristics = !!evt->Modifier( MD_ALT );
325 
326  EE_GRID_HELPER grid( m_toolMgr );
327 
328  // Single click? Select single object
329  if( evt->IsClick( BUT_LEFT ) )
330  {
331  if( SCH_EDIT_FRAME* schframe = dynamic_cast<SCH_EDIT_FRAME*>( m_frame ) )
332  schframe->FocusOnItem( nullptr );
333 
334  EE_COLLECTOR collector;
335  bool continueSelect = true;
336 
337  // Collect items at the clicked location (doesn't select them yet)
338  if( collectHits( collector, evt->Position() ) )
339  {
340  narrowSelection( collector, evt->Position(), false );
341 
342  if( collector.GetCount() == 1 && !m_isSymbolEditor && !modifier_enabled )
343  {
344  // Check if we want to auto start wires
345  VECTOR2I snappedCursorPos = grid.BestSnapAnchor( evt->Position(), nullptr );
346 
348  && collector[0]->IsPointClickableAnchor( (wxPoint) snappedCursorPos ) )
349  {
351  auto* params = newEvt->Parameter<DRAW_SEGMENT_EVENT_PARAMS*>();
352  auto* newParams = new DRAW_SEGMENT_EVENT_PARAMS();
353 
354  *newParams= *params;
355  newParams->quitOnDraw = true;
356  newEvt->SetParameter( newParams );
357 
358  newEvt->SetMousePosition( snappedCursorPos );
359  m_toolMgr->ProcessEvent( *newEvt );
360  continueSelect = false;
361  }
362  else if( collector[0]->IsHypertext() )
363  {
364  collector[0]->DoHypertextMenu( m_frame );
365  continueSelect = false;
366  }
367  }
368  }
369 
370  if( continueSelect )
371  {
372  // If we didn't click on an anchor, we perform a normal select, pass in the
373  // items we previously collected
374  selectPoint( collector, nullptr, nullptr, m_additive, m_subtractive,
375  m_exclusive_or );
376  }
377  }
378  else if( evt->IsClick( BUT_RIGHT ) )
379  {
380  // right click? if there is any object - show the context menu
381  bool selectionCancelled = false;
382 
383  if( m_selection.Empty() ||
384  !m_selection.GetBoundingBox().Contains( (wxPoint) evt->Position() ) )
385  {
386  ClearSelection();
387  SelectPoint( evt->Position(), EE_COLLECTOR::AllItems, nullptr,
388  &selectionCancelled );
389  m_selection.SetIsHover( true );
390  }
391 
392  if( !selectionCancelled )
394  }
395  else if( evt->IsDblClick( BUT_LEFT ) )
396  {
397  // double click? Display the properties window
398  if( auto schframe = dynamic_cast<SCH_EDIT_FRAME*>( m_frame ) )
399  schframe->FocusOnItem( nullptr );
400 
401  if( m_selection.Empty() )
402  SelectPoint( evt->Position() );
403 
404  EDA_ITEM* item = m_selection.Front();
405 
406  if( item && item->Type() == SCH_SHEET_T )
408  else
410  }
411  else if( evt->IsDblClick( BUT_MIDDLE ) )
412  {
413  // Middle double click? Do zoom to fit or zoom to objects
414  if( m_exclusive_or ) // Is CTRL key down?
416  else
418  }
419  else if( evt->IsDrag( BUT_LEFT ) )
420  {
421  // drag with LMB? Select multiple objects (or at least draw a selection box) or
422  // drag them
423  if( auto schframe = dynamic_cast<SCH_EDIT_FRAME*>( m_frame ) )
424  schframe->FocusOnItem( nullptr );
425 
426  if( modifier_enabled || ( m_selection.Empty() && m_frame->GetDragSelects() ) )
427  {
428  selectMultiple();
429  }
430  else
431  {
432  // selection is empty? try to start dragging the item under the point where drag
433  // started
436  else if( m_selection.Empty() )
438 
439  // Check if dragging has started within any of selected items bounding box
440  if( selectionContains( evt->Position() ) )
441  {
442  // Yes -> run the move tool and wait till it finishes
443  if( m_isSymbolEditor )
444  {
445  auto libFrame = dynamic_cast<SYMBOL_EDIT_FRAME*>( m_frame );
446 
447  // Cannot move any derived symbol elements for now.
448  if( libFrame && libFrame->GetCurPart() && libFrame->GetCurPart()->IsRoot() )
449  m_toolMgr->InvokeTool( "eeschema.SymbolMoveTool" );
450  }
451  else
452  {
453  m_toolMgr->InvokeTool( "eeschema.InteractiveMove" );
454  }
455  }
456  else
457  {
458  // No -> drag a selection box
459  selectMultiple();
460  }
461  }
462  }
463  else if( evt->Category() == TC_COMMAND && evt->Action() == TA_CHOICE_MENU_CHOICE )
464  {
465  // context sub-menu selection? Handle unit selection or bus unfolding
466  if( evt->GetCommandId().get() >= ID_POPUP_SCH_SELECT_UNIT_CMP
467  && evt->GetCommandId().get() <= ID_POPUP_SCH_SELECT_UNIT_CMP_MAX )
468  {
469  SCH_COMPONENT* component = dynamic_cast<SCH_COMPONENT*>( m_selection.Front() );
470  int unit = evt->GetCommandId().get() - ID_POPUP_SCH_SELECT_UNIT_CMP;
471 
472  if( component )
473  static_cast<SCH_EDIT_FRAME*>( m_frame )->SelectUnit( component, unit );
474  }
475  else if( evt->GetCommandId().get() >= ID_POPUP_SCH_UNFOLD_BUS
476  && evt->GetCommandId().get() <= ID_POPUP_SCH_UNFOLD_BUS_END )
477  {
478  wxString* net = new wxString( *evt->Parameter<wxString*>() );
480  }
481 
482  }
483  else if( evt->IsCancelInteractive() )
484  {
485  if( auto schframe = dynamic_cast<SCH_EDIT_FRAME*>( m_frame ) )
486  schframe->FocusOnItem( nullptr );
487 
488  ClearSelection();
489  }
490  else if( evt->Action() == TA_UNDO_REDO_PRE )
491  {
492  if( auto schframe = dynamic_cast<SCH_EDIT_FRAME*>( m_frame ) )
493  schframe->FocusOnItem( nullptr );
494 
495  ClearSelection();
496  }
497  else if( evt->IsMotion() && !m_isSymbolEditor && m_frame->ToolStackIsEmpty() )
498  {
499  EE_COLLECTOR collector;
500 
501  // We are checking if we should display a pencil when hovering over anchors
502  // for "auto starting" wires when clicked
503  if( collectHits( collector, evt->Position() ) )
504  {
505  narrowSelection( collector, evt->Position(), false );
506 
507  if( collector.GetCount() == 1 && !modifier_enabled )
508  {
509  VECTOR2I snappedCursorPos = grid.BestSnapAnchor( evt->Position(), nullptr );
510 
512  && collector[0]->IsPointClickableAnchor( (wxPoint) snappedCursorPos ) )
513  {
514  displayWireCursor = true;
515  }
516  else if( collector[0]->IsHypertext()
517  && !collector[0]->IsSelected()
519  {
520  rolloverItem = collector[0]->m_Uuid;
521  }
522  }
523  }
524  }
525  else
526  {
527  evt->SetPassEvent();
528  }
529 
530  if( rolloverItem != lastRolloverItem )
531  {
532  EDA_ITEM* item = m_frame->GetItem( lastRolloverItem );
533 
534  if( item )
535  {
536  item->ClearFlags( IS_ROLLOVER );
537  lastRolloverItem = niluuid;
538 
539  if( item->Type() == SCH_FIELD_T )
540  m_frame->GetCanvas()->GetView()->Update( item->GetParent() );
541  else
542  m_frame->GetCanvas()->GetView()->Update( item );
543  }
544 
545  item = m_frame->GetItem( rolloverItem );
546 
547  if( item )
548  {
549  item->SetFlags( IS_ROLLOVER );
550  lastRolloverItem = rolloverItem;
551 
552  if( item->Type() == SCH_FIELD_T )
553  m_frame->GetCanvas()->GetView()->Update( item->GetParent() );
554  else
555  m_frame->GetCanvas()->GetView()->Update( item );
556  }
557  }
558 
559  if( m_frame->ToolStackIsEmpty() )
560  {
561  if( displayWireCursor )
562  {
564  }
565  else if( rolloverItem != niluuid )
566  {
568  }
569  else if( !m_selection.Empty() && !m_frame->GetDragSelects() && evt->HasPosition()
570  && selectionContains( evt->Position() ) ) //move/drag option prediction
571  {
573  }
574  else
575  {
577  }
578  }
579  }
580 
581  // Shutting down; clear the selection
582  m_selection.Clear();
583 
584  return 0;
585 }
586 
587 
588 void EE_SELECTION_TOOL::OnIdle( wxIdleEvent& aEvent )
589 {
590  if( m_frame->ToolStackIsEmpty() )
591  {
592  wxMouseState keyboardState = wxGetMouseState();
593 
595 
596  if( keyboardState.ShiftDown() && keyboardState.ControlDown() )
597  m_subtractive = true;
598  else if( keyboardState.ShiftDown() )
599  m_additive = true;
600  else if( keyboardState.ControlDown() )
601  m_exclusive_or = true;
602 
603  if( m_additive )
605  else if( m_subtractive )
607  else if( m_exclusive_or )
609  else
611  }
612 }
613 
614 
616 {
617  return m_selection;
618 }
619 
620 
621 bool EE_SELECTION_TOOL::collectHits( EE_COLLECTOR& aCollector, const VECTOR2I& aWhere,
622  const KICAD_T* aFilterList )
623 {
624  aCollector.m_Threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
625 
626  if( m_isSymbolEditor )
627  {
628  LIB_PART* part = static_cast<SYMBOL_EDIT_FRAME*>( m_frame )->GetCurPart();
629 
630  if( !part )
631  return false;
632 
633  aCollector.Collect( part->GetDrawItems(), aFilterList, (wxPoint) aWhere, m_unit,
634  m_convert );
635  }
636  else
637  {
638  aCollector.Collect( m_frame->GetScreen(), aFilterList, (wxPoint) aWhere, m_unit,
639  m_convert );
640  }
641 
642  return aCollector.GetCount() > 0;
643 }
644 
645 
647  bool aCheckLocked )
648 {
649  for( int i = collector.GetCount() - 1; i >= 0; --i )
650  {
651  if( !Selectable( collector[i] ) )
652  {
653  collector.Remove( i );
654  continue;
655  }
656 
657  if( aCheckLocked && collector[i]->IsLocked() )
658  {
659  collector.Remove( i );
660  continue;
661  }
662 
663  // SelectPoint, unlike other selection routines, can select line ends
664  if( collector[i]->Type() == SCH_LINE_T )
665  {
666  SCH_LINE* line = (SCH_LINE*) collector[i];
667  line->ClearFlags( STARTPOINT | ENDPOINT );
668 
669  if( HitTestPoints( line->GetStartPoint(), (wxPoint) aWhere, collector.m_Threshold ) )
670  line->SetFlags( STARTPOINT );
671  else if( HitTestPoints( line->GetEndPoint(), (wxPoint) aWhere, collector.m_Threshold ) )
672  line->SetFlags( ENDPOINT );
673  else
674  line->SetFlags( STARTPOINT | ENDPOINT );
675  }
676  }
677 
678  // Apply some ugly heuristics to avoid disambiguation menus whenever possible
679  if( collector.GetCount() > 1 && !m_skip_heuristics )
680  {
681  GuessSelectionCandidates( collector, aWhere );
682  }
683 }
684 
685 
687  bool* aSelectionCancelledFlag, bool aAdd, bool aSubtract,
688  bool aExclusiveOr )
689 {
691 
692  // If still more than one item we're going to have to ask the user.
693  if( aCollector.GetCount() > 1 )
694  {
695  aCollector.m_MenuTitle = wxEmptyString;
696  // Must call selectionMenu via RunAction() to avoid event-loop contention
697  m_toolMgr->RunAction( EE_ACTIONS::selectionMenu, true, &aCollector );
698 
699  if( aCollector.m_MenuCancelled )
700  {
701  if( aSelectionCancelledFlag )
702  *aSelectionCancelledFlag = true;
703 
704  return false;
705  }
706  }
707 
708  if( !aAdd && !aSubtract && !aExclusiveOr )
709  ClearSelection();
710 
711  bool anyAdded = false;
712  bool anySubtracted = false;
713 
714  if( aCollector.GetCount() > 0 )
715  {
716  for( int i = 0; i < aCollector.GetCount(); ++i )
717  {
718  if( aSubtract || ( aExclusiveOr && aCollector[i]->IsSelected() ) )
719  {
720  unselect( aCollector[i] );
721  anySubtracted = true;
722  }
723  else
724  {
725  select( aCollector[i] );
726  anyAdded = true;
727  }
728  }
729  }
730 
731  if( anyAdded )
732  {
734 
735  if( aItem && aCollector.GetCount() == 1 )
736  *aItem = aCollector[0];
737 
738  return true;
739  }
740  else if( anySubtracted )
741  {
743  return true;
744  }
745 
746  return false;
747 }
748 
749 
750 bool EE_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, const KICAD_T* aFilterList,
751  EDA_ITEM** aItem, bool* aSelectionCancelledFlag,
752  bool aCheckLocked, bool aAdd, bool aSubtract,
753  bool aExclusiveOr )
754 {
755  EE_COLLECTOR collector;
756 
757  if( !collectHits( collector, aWhere, aFilterList ) )
758  return false;
759 
760  narrowSelection( collector, aWhere, aCheckLocked );
761 
762  return selectPoint( collector, aItem, aSelectionCancelledFlag, aAdd, aSubtract, aExclusiveOr );
763 }
764 
765 
767 {
768  m_multiple = true; // Multiple selection mode is active
769  KIGFX::VIEW* view = getView();
770 
771  // hold all visible items
772  std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems;
773  std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> sheetPins;
774 
775  // Filter the view items based on the selection box
776  BOX2I selectionBox;
777 
778  selectionBox.SetMaximum();
779  view->Query( selectionBox, selectedItems ); // Get the list of selected items
780 
781  // Sheet pins aren't in the view; add them by hand
782  for( KIGFX::VIEW::LAYER_ITEM_PAIR& pair : selectedItems )
783  {
784  SCH_SHEET* sheet = dynamic_cast<SCH_SHEET*>( pair.first );
785 
786  if( sheet )
787  {
788  int layer = pair.second;
789 
790  for( SCH_SHEET_PIN* pin : sheet->GetPins() )
791  sheetPins.emplace_back( KIGFX::VIEW::LAYER_ITEM_PAIR( pin, layer ) );
792  }
793  }
794 
795  selectedItems.insert( selectedItems.end(), sheetPins.begin(), sheetPins.end() );
796 
797  for( auto& item_pair : selectedItems )
798  {
799  if( EDA_ITEM* item = dynamic_cast<EDA_ITEM*>( item_pair.first ) )
800  {
801  if( Selectable( item ) )
802  select( item );
803  }
804  }
805 
806  m_multiple = false;
807 
808  return 0;
809 }
810 
811 
813 {
814  // There are certain parent/child and enclosure combinations that can be handled
815  // automatically.
816 
817  // Prefer exact hits to sloppy ones
818  int exactHits = 0;
819 
820  for( int i = collector.GetCount() - 1; i >= 0; --i )
821  {
822  EDA_ITEM* item = collector[ i ];
823 
824  if( item->HitTest( (wxPoint) aPos, 0 ) )
825  exactHits++;
826  }
827 
828  if( exactHits > 0 && exactHits < collector.GetCount() )
829  {
830  for( int i = collector.GetCount() - 1; i >= 0; --i )
831  {
832  EDA_ITEM* item = collector[ i ];
833 
834  if( !item->HitTest( (wxPoint) aPos, 0 ) )
835  collector.Transfer( item );
836  }
837  }
838 
839  // Prefer a non-sheet to a sheet
840  for( int i = 0; collector.GetCount() == 2 && i < 2; ++i )
841  {
842  EDA_ITEM* item = collector[ i ];
843  EDA_ITEM* other = collector[ ( i + 1 ) % 2 ];
844 
845  if( item->Type() != SCH_SHEET_T && other->Type() == SCH_SHEET_T )
846  collector.Transfer( other );
847  }
848 
849  // Prefer a symbol to a pin or the opposite, when both a symbol and a pin are selected
850  // We need to be able to select only a pin:
851  // - to display its characteristics (especially if an ERC is attached to the pin)
852  // - for cross probing, to select the corresponding pad.
853  // Note also the case happens only in schematic editor. In symbol editor, the symbol
854  // itself is never selected
855  for( int i = 0; collector.GetCount() == 2 && i < 2; ++i )
856  {
857  SCH_ITEM* item = collector[i];
858  SCH_ITEM* other = collector[( i + 1 ) % 2];
859 
860  if( item->Type() == SCH_COMPONENT_T && other->Type() == SCH_PIN_T )
861  {
862  // Make sure we aren't clicking on the pin anchor itself, only the rest of the
863  // pin should select the symbol with this setting
864  // To avoid conflict with the auto-start wires option
865  EE_GRID_HELPER grid( m_toolMgr );
866  wxPoint cursorPos = wxPoint( grid.BestSnapAnchor( aPos, nullptr ) );
867 
869  && !other->IsPointClickableAnchor( cursorPos ) )
870  {
871  collector.Transfer( other );
872  }
873  else
874  {
875  collector.Transfer( item );
876  }
877  }
878  }
879 
880  // Prefer a field to a symbol
881  for( int i = 0; collector.GetCount() == 2 && i < 2; ++i )
882  {
883  EDA_ITEM* item = collector[ i ];
884  EDA_ITEM* other = collector[ ( i + 1 ) % 2 ];
885 
886  if( item->Type() == SCH_FIELD_T && other->Type() == SCH_COMPONENT_T )
887  collector.Transfer( other );
888  }
889 
890  // No need for multiple wires at a single point; if there's a junction select that;
891  // otherwise any of the wires will do
892  bool junction = false;
893  bool wiresOnly = true;
894 
895  for( EDA_ITEM* item : collector )
896  {
897  if( item->Type() == SCH_JUNCTION_T )
898  junction = true;
899  else if( item->Type() != SCH_LINE_T )
900  wiresOnly = false;
901  }
902 
903  if( wiresOnly )
904  {
905  for( int j = collector.GetCount() - 1; j >= 0; --j )
906  {
907  if( junction && collector[ j ]->Type() != SCH_JUNCTION_T )
908  collector.Transfer( j );
909  else if( !junction && j > 0 )
910  collector.Transfer( j );
911  }
912  }
913 
914  // Construct a tight box (1/2 height and width) around the center of the closest item.
915  // All items which exist at least partly outside this box have sufficient other areas
916  // for selection and can be dropped.
917  EDA_ITEM* closest = nullptr;
918  int closestDist = INT_MAX;
919 
920  for( EDA_ITEM* item : collector )
921  {
922  int dist = EuclideanNorm( item->GetBoundingBox().GetCenter() - (wxPoint) aPos );
923 
924  if( dist < closestDist )
925  {
926  closestDist = dist;
927  closest = item;
928  }
929  }
930 
931  if( closest ) // Don't try and get a tight bbox if nothing is near the mouse pointer
932  {
933  EDA_RECT tightBox = closest->GetBoundingBox();
934  tightBox.Inflate( -tightBox.GetWidth() / 4, -tightBox.GetHeight() / 4 );
935 
936  for( int i = collector.GetCount() - 1; i >= 0; --i )
937  {
938  EDA_ITEM* item = collector[i];
939 
940  if( item == closest )
941  continue;
942 
943  if( !item->HitTest( tightBox, true ) )
944  collector.Transfer( item );
945  }
946  }
947 }
948 
949 
951 {
952  if( m_selection.Empty() )
953  {
954  VECTOR2D cursorPos = getViewControls()->GetCursorPosition( true );
955 
956  ClearSelection();
957  SelectPoint( cursorPos, aFilterList );
958  m_selection.SetIsHover( true );
960  }
961  else // Trim an existing selection by aFilterList
962  {
963  for( int i = (int) m_selection.GetSize() - 1; i >= 0; --i )
964  {
965  EDA_ITEM* item = (EDA_ITEM*) m_selection.GetItem( i );
966 
967  if( !item->IsType( aFilterList ) )
968  {
969  unselect( item );
971  }
972  }
973  }
974 
976 
977  return m_selection;
978 }
979 
980 
982 {
983  VECTOR2I refP( 0, 0 );
984 
985  if( m_selection.Size() > 0 )
986  {
987  if( m_isSymbolEditor )
988  refP = static_cast<LIB_ITEM*>( m_selection.GetTopLeftItem() )->GetPosition();
989  else
990  refP = static_cast<SCH_ITEM*>( m_selection.GetTopLeftItem() )->GetPosition();
991  }
992 
994 }
995 
996 
998 {
999  bool cancelled = false; // Was the tool canceled while it was running?
1000  m_multiple = true; // Multiple selection mode is active
1001  KIGFX::VIEW* view = getView();
1002 
1004  view->Add( &area );
1005 
1006  while( TOOL_EVENT* evt = Wait() )
1007  {
1008  int width = area.GetEnd().x - area.GetOrigin().x;
1009 
1010  /* Selection mode depends on direction of drag-selection:
1011  * Left > Right : Select objects that are fully enclosed by selection
1012  * Right > Left : Select objects that are crossed by selection
1013  */
1014  bool windowSelection = width >= 0;
1015 
1016  if( view->IsMirroredX() )
1017  windowSelection = !windowSelection;
1018 
1020  windowSelection ? KICURSOR::SELECT_WINDOW : KICURSOR::SELECT_LASSO );
1021 
1022  if( evt->IsCancelInteractive() || evt->IsActivate() )
1023  {
1024  cancelled = true;
1025  break;
1026  }
1027 
1028  if( evt->IsDrag( BUT_LEFT ) )
1029  {
1030  if( !m_additive && !m_subtractive && !m_exclusive_or )
1031  ClearSelection();
1032 
1033  // Start drawing a selection box
1034  area.SetOrigin( evt->DragOrigin() );
1035  area.SetEnd( evt->Position() );
1036  area.SetAdditive( m_additive );
1037  area.SetSubtractive( m_subtractive );
1039 
1040  view->SetVisible( &area, true );
1041  view->Update( &area );
1042  getViewControls()->SetAutoPan( true );
1043  }
1044 
1045  if( evt->IsMouseUp( BUT_LEFT ) )
1046  {
1047  getViewControls()->SetAutoPan( false );
1048 
1049  // End drawing the selection box
1050  view->SetVisible( &area, false );
1051 
1052  // Mark items within the selection box as selected
1053  std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems;
1054  std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> sheetPins;
1055 
1056  // Filter the view items based on the selection box
1057  BOX2I selectionBox = area.ViewBBox();
1058  view->Query( selectionBox, selectedItems ); // Get the list of selected items
1059 
1060  // Sheet pins aren't in the view; add them by hand
1061  for( KIGFX::VIEW::LAYER_ITEM_PAIR& pair : selectedItems )
1062  {
1063  SCH_SHEET* sheet = dynamic_cast<SCH_SHEET*>( pair.first );
1064 
1065  if( sheet )
1066  {
1067  int layer = pair.second;
1068 
1069  for( SCH_SHEET_PIN* pin : sheet->GetPins() )
1070  sheetPins.emplace_back( KIGFX::VIEW::LAYER_ITEM_PAIR( pin, layer ) );
1071  }
1072  }
1073 
1074  selectedItems.insert( selectedItems.end(), sheetPins.begin(), sheetPins.end() );
1075 
1076  int height = area.GetEnd().y - area.GetOrigin().y;
1077 
1078  bool anyAdded = false;
1079  bool anySubtracted = false;
1080 
1081  // Construct an EDA_RECT to determine EDA_ITEM selection
1082  EDA_RECT selectionRect( (wxPoint) area.GetOrigin(), wxSize( width, height ) );
1083 
1084  selectionRect.Normalize();
1085 
1086  for( KIGFX::VIEW::LAYER_ITEM_PAIR& pair : selectedItems )
1087  {
1088  EDA_ITEM* item = dynamic_cast<EDA_ITEM*>( pair.first );
1089 
1090  if( item && Selectable( item ) && item->HitTest( selectionRect, windowSelection ) )
1091  {
1092  if( m_subtractive || ( m_exclusive_or && item->IsSelected() ) )
1093  {
1094  unselect( item );
1095  anySubtracted = true;
1096  }
1097  else
1098  {
1099  select( item );
1100  item->SetFlags( STARTPOINT | ENDPOINT );
1101  anyAdded = true;
1102  }
1103  }
1104  }
1105 
1106  m_selection.SetIsHover( false );
1107 
1108  // Inform other potentially interested tools
1109  if( anyAdded )
1111 
1112  if( anySubtracted )
1114 
1115  break; // Stop waiting for events
1116  }
1117  }
1118 
1119  getViewControls()->SetAutoPan( false );
1120 
1121  // Stop drawing the selection box
1122  view->Remove( &area );
1123  m_multiple = false; // Multiple selection mode is inactive
1124 
1125  if( !cancelled )
1127 
1128  return cancelled;
1129 }
1130 
1131 
1132 static KICAD_T nodeTypes[] =
1133 {
1135  SCH_PIN_T,
1140  SCH_LABEL_T,
1145  EOT
1146 };
1147 
1148 
1150 {
1151  EE_COLLECTOR collector;
1152 
1153  //TODO(snh): Reimplement after exposing KNN interface
1154  int thresholdMax = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
1155 
1156  for( int threshold : { 0, thresholdMax/2, thresholdMax } )
1157  {
1158  collector.m_Threshold = threshold;
1159  collector.Collect( m_frame->GetScreen(), nodeTypes, (wxPoint) aPosition );
1160 
1161  if( collector.GetCount() > 0 )
1162  break;
1163  }
1164 
1165  return collector.GetCount() ? collector[ 0 ] : nullptr;
1166 }
1167 
1168 
1170 {
1171  VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !aEvent.Modifier( MD_ALT ) );
1172 
1173  SelectPoint( cursorPos, nodeTypes );
1174 
1175  return 0;
1176 }
1177 
1178 
1180 {
1181  static KICAD_T wiresAndBuses[] = { SCH_LINE_LOCATE_WIRE_T, SCH_LINE_LOCATE_BUS_T, EOT };
1182 
1183  RequestSelection( wiresAndBuses );
1184 
1185  if( m_selection.Empty() )
1186  return 0;
1187 
1188  SCH_LINE* line = (SCH_LINE*) m_selection.Front();
1189  EDA_ITEMS items;
1190 
1192  auto conns = m_frame->GetScreen()->MarkConnections( line );
1193 
1194  for( auto item : conns )
1195  select( item );
1196 
1197  if( m_selection.GetSize() > 1 )
1199 
1200  return 0;
1201 }
1202 
1203 
1205 {
1206  AddItemToSel( aEvent.Parameter<EDA_ITEM*>() );
1207  m_selection.SetIsHover( false );
1208  return 0;
1209 }
1210 
1211 
1212 void EE_SELECTION_TOOL::AddItemToSel( EDA_ITEM* aItem, bool aQuietMode )
1213 {
1214  if( aItem )
1215  {
1216  select( aItem );
1217 
1218  // Inform other potentially interested tools
1219  if( !aQuietMode )
1221  }
1222 }
1223 
1224 
1226 {
1227  AddItemsToSel( aEvent.Parameter<EDA_ITEMS*>(), false );
1228  m_selection.SetIsHover( false );
1229  return 0;
1230 }
1231 
1232 
1233 void EE_SELECTION_TOOL::AddItemsToSel( EDA_ITEMS* aList, bool aQuietMode )
1234 {
1235  if( aList )
1236  {
1237  for( EDA_ITEM* item : *aList )
1238  select( item );
1239 
1240  // Inform other potentially interested tools
1241  if( !aQuietMode )
1243  }
1244 }
1245 
1246 
1248 {
1249  RemoveItemFromSel( aEvent.Parameter<EDA_ITEM*>() );
1250  m_selection.SetIsHover( false );
1251  return 0;
1252 }
1253 
1254 
1255 void EE_SELECTION_TOOL::RemoveItemFromSel( EDA_ITEM* aItem, bool aQuietMode )
1256 {
1257  if( aItem )
1258  {
1259  unselect( aItem );
1260 
1261  // Inform other potentially interested tools
1262  if( !aQuietMode )
1264  }
1265 }
1266 
1267 
1269 {
1270  RemoveItemsFromSel( aEvent.Parameter<EDA_ITEMS*>(), false );
1271  m_selection.SetIsHover( false );
1272  return 0;
1273 }
1274 
1275 
1276 void EE_SELECTION_TOOL::RemoveItemsFromSel( EDA_ITEMS* aList, bool aQuietMode )
1277 {
1278  if( aList )
1279  {
1280  for( EDA_ITEM* item : *aList )
1281  unselect( item );
1282 
1283  // Inform other potentially interested tools
1284  if( !aQuietMode )
1286  }
1287 }
1288 
1289 
1291 {
1292  highlight( aItem, BRIGHTENED );
1293 }
1294 
1295 
1297 {
1298  unhighlight( aItem, BRIGHTENED );
1299 }
1300 
1301 
1303 {
1304  ClearSelection();
1305 
1306  return 0;
1307 }
1308 
1309 
1311 {
1312  m_selection.Clear();
1313 
1314  if( m_isSymbolEditor )
1315  {
1316  LIB_PART* start = static_cast<SYMBOL_EDIT_FRAME*>( m_frame )->GetCurPart();
1317 
1318  for( LIB_ITEM& item : start->GetDrawItems() )
1319  {
1320  if( item.IsSelected() )
1321  select( static_cast<EDA_ITEM*>( &item ) );
1322  }
1323  }
1324  else
1325  {
1326  for( SCH_ITEM* item : m_frame->GetScreen()->Items() )
1327  {
1328  // If the field and component are selected, only use the component
1329  if( item->IsSelected() )
1330  {
1331  select( item );
1332  }
1333  else
1334  {
1335  item->RunOnChildren(
1336  [&]( SCH_ITEM* aChild )
1337  {
1338  if( aChild->IsSelected() )
1339  select( aChild );
1340  } );
1341  }
1342  }
1343  }
1344 
1346 
1347  // Inform other potentially interested tools
1349 }
1350 
1351 
1353 {
1354  EE_COLLECTOR* collector = aEvent.Parameter<EE_COLLECTOR*>();
1355 
1356  if( !doSelectionMenu( collector ) )
1357  collector->m_MenuCancelled = true;
1358 
1359  return 0;
1360 }
1361 
1362 
1364 {
1365  EDA_ITEM* current = nullptr;
1366  bool selectAll = false;
1367  bool expandSelection = false;
1368 
1369  do
1370  {
1372  if( expandSelection )
1373  aCollector->Combine();
1374 
1375  expandSelection = false;
1376 
1377  int limit = std::min( 9, aCollector->GetCount() );
1378  ACTION_MENU menu( true );
1379 
1380  for( int i = 0; i < limit; ++i )
1381  {
1382  wxString text;
1383  EDA_ITEM* item = ( *aCollector )[i];
1384  text = item->GetSelectMenuText( m_frame->GetUserUnits() );
1385 
1386  wxString menuText = wxString::Format( "&%d. %s\t%d", i + 1, text, i + 1 );
1387  menu.Add( menuText, i + 1, item->GetMenuImage() );
1388  }
1389 
1390  menu.AppendSeparator();
1391  menu.Add( _( "Select &All\tA" ), limit + 1, net_highlight_schematic_xpm );
1392 
1393  if( !expandSelection && aCollector->HasAdditionalItems() )
1394  menu.Add( _( "&Expand Selection\tE" ), limit + 2, nullptr );
1395 
1396  if( aCollector->m_MenuTitle.Length() )
1397  {
1398  menu.SetTitle( aCollector->m_MenuTitle );
1399  menu.SetIcon( info_xpm );
1400  menu.DisplayTitle( true );
1401  }
1402  else
1403  {
1404  menu.DisplayTitle( false );
1405  }
1406 
1407  SetContextMenu( &menu, CMENU_NOW );
1408 
1409  while( TOOL_EVENT* evt = Wait() )
1410  {
1411  if( evt->Action() == TA_CHOICE_MENU_UPDATE )
1412  {
1413  if( selectAll )
1414  {
1415  for( int i = 0; i < aCollector->GetCount(); ++i )
1416  unhighlight( ( *aCollector )[i], BRIGHTENED );
1417  }
1418  else if( current )
1419  {
1420  unhighlight( current, BRIGHTENED );
1421  }
1422 
1423  int id = *evt->GetCommandId();
1424 
1425  // User has pointed an item, so show it in a different way
1426  if( id > 0 && id <= limit )
1427  {
1428  current = ( *aCollector )[id - 1];
1429  highlight( current, BRIGHTENED );
1430  }
1431  else
1432  {
1433  current = nullptr;
1434  }
1435 
1436  // User has pointed on the "Select All" option
1437  if( id == limit + 1 )
1438  {
1439  for( int i = 0; i < aCollector->GetCount(); ++i )
1440  highlight( ( *aCollector )[i], BRIGHTENED );
1441  selectAll = true;
1442  }
1443  else
1444  {
1445  selectAll = false;
1446  }
1447  }
1448  else if( evt->Action() == TA_CHOICE_MENU_CHOICE )
1449  {
1450  if( selectAll )
1451  {
1452  for( int i = 0; i < aCollector->GetCount(); ++i )
1453  unhighlight( ( *aCollector )[i], BRIGHTENED );
1454  }
1455  else if( current )
1456  unhighlight( current, BRIGHTENED );
1457 
1458  OPT<int> id = evt->GetCommandId();
1459 
1460  // User has selected the "Select All" option
1461  if( id == limit + 1 )
1462  {
1463  selectAll = true;
1464  current = nullptr;
1465  }
1466  // User has selected an item, so this one will be returned
1467  else if( id && ( *id > 0 ) && ( *id <= limit ) )
1468  {
1469  selectAll = false;
1470  current = ( *aCollector )[*id - 1];
1471  }
1472  else
1473  {
1474  selectAll = false;
1475  current = nullptr;
1476  }
1477  }
1478  else if( evt->Action() == TA_CHOICE_MENU_CLOSED )
1479  {
1480  break;
1481  }
1482 
1483  getView()->UpdateItems();
1484  m_frame->GetCanvas()->Refresh();
1485  }
1486  } while( expandSelection );
1487 
1488  if( selectAll )
1489  return true;
1490  else if( current )
1491  {
1492  unhighlight( current, BRIGHTENED );
1493 
1494  getView()->UpdateItems();
1495  m_frame->GetCanvas()->Refresh();
1496 
1497  aCollector->Empty();
1498  aCollector->Append( current );
1499  return true;
1500  }
1501 
1502  return false;
1503 }
1504 
1505 
1506 bool EE_SELECTION_TOOL::Selectable( const EDA_ITEM* aItem, bool checkVisibilityOnly ) const
1507 {
1508  // NOTE: in the future this is where Eeschema layer/itemtype visibility will be handled
1509  SYMBOL_EDIT_FRAME* symEditFrame = dynamic_cast< SYMBOL_EDIT_FRAME* >( m_frame );
1510 
1511  // Do not allow selection of anything except fields when the current symbol in the symbol
1512  // editor is a derived symbol.
1513  if( symEditFrame && symEditFrame->GetCurPart() && symEditFrame->GetCurPart()->IsAlias()
1514  && aItem->Type() != LIB_FIELD_T )
1515  return false;
1516 
1517  switch( aItem->Type() )
1518  {
1519  case SCH_PIN_T:
1520  if( !static_cast<const SCH_PIN*>( aItem )->IsVisible() && !m_frame->GetShowAllPins() )
1521  return false;
1522  break;
1523 
1524  case LIB_PART_T: // In symbol_editor we do not want to select the symbol itself.
1525  return false;
1526 
1527  case LIB_FIELD_T: // LIB_FIELD object can always be edited.
1528  break;
1529 
1530  case LIB_ARC_T:
1531  case LIB_CIRCLE_T:
1532  case LIB_TEXT_T:
1533  case LIB_RECTANGLE_T:
1534  case LIB_POLYLINE_T:
1535  case LIB_BEZIER_T:
1536  case LIB_PIN_T:
1537  {
1538  if( symEditFrame )
1539  {
1540  LIB_ITEM* lib_item = (LIB_ITEM*) aItem;
1541 
1542  if( lib_item->GetUnit() && lib_item->GetUnit() != symEditFrame->GetUnit() )
1543  return false;
1544 
1545  if( lib_item->GetConvert() && lib_item->GetConvert() != symEditFrame->GetConvert() )
1546  return false;
1547  }
1548 
1549  break;
1550  }
1551 
1552  case SCH_MARKER_T: // Always selectable
1553  return true;
1554 
1555  default: // Suppress warnings
1556  break;
1557  }
1558 
1559  return true;
1560 }
1561 
1562 
1564 {
1565  if( m_selection.Empty() )
1566  return;
1567 
1568  while( m_selection.GetSize() )
1570 
1571  getView()->Update( &m_selection );
1572 
1573  m_selection.SetIsHover( false );
1575 
1576  // Inform other potentially interested tools
1578 }
1579 
1580 
1582 {
1583  highlight( aItem, SELECTED, &m_selection );
1584 }
1585 
1586 
1588 {
1589  unhighlight( aItem, SELECTED, &m_selection );
1590 }
1591 
1592 
1593 void EE_SELECTION_TOOL::highlight( EDA_ITEM* aItem, int aMode, EE_SELECTION* aGroup )
1594 {
1595  KICAD_T itemType = aItem->Type();
1596 
1597  if( aMode == SELECTED )
1598  aItem->SetSelected();
1599  else if( aMode == BRIGHTENED )
1600  aItem->SetBrightened();
1601 
1602  if( aGroup )
1603  aGroup->Add( aItem );
1604 
1605  // Highlight pins and fields. (All the other component children are currently only
1606  // represented in the LIB_PART and will inherit the settings of the parent component.)
1607  if( SCH_ITEM* sch_item = dynamic_cast<SCH_ITEM*>( aItem ) )
1608  {
1609  sch_item->RunOnChildren(
1610  [&]( SCH_ITEM* aChild )
1611  {
1612  if( aMode == SELECTED )
1613  aChild->SetSelected();
1614  else if( aMode == BRIGHTENED )
1615  aChild->SetSelected();
1616  } );
1617  }
1618 
1619  if( itemType == SCH_PIN_T || itemType == SCH_FIELD_T || itemType == SCH_SHEET_PIN_T )
1620  getView()->Update( aItem->GetParent() );
1621  else
1622  getView()->Update( aItem );
1623 }
1624 
1625 
1626 void EE_SELECTION_TOOL::unhighlight( EDA_ITEM* aItem, int aMode, EE_SELECTION* aGroup )
1627 {
1628  KICAD_T itemType = aItem->Type();
1629 
1630  if( aMode == SELECTED )
1631  aItem->ClearSelected();
1632  else if( aMode == BRIGHTENED )
1633  aItem->ClearBrightened();
1634 
1635  if( aGroup )
1636  aGroup->Remove( aItem );
1637 
1638  // Unhighlight pins and fields. (All the other component children are currently only
1639  // represented in the LIB_PART.)
1640  if( SCH_ITEM* sch_item = dynamic_cast<SCH_ITEM*>( aItem ) )
1641  {
1642  sch_item->RunOnChildren(
1643  [&]( SCH_ITEM* aChild )
1644  {
1645  if( aMode == SELECTED )
1646  aChild->ClearSelected();
1647  else if( aMode == BRIGHTENED )
1648  aChild->ClearBrightened();
1649  } );
1650  }
1651 
1652  if( itemType == SCH_PIN_T || itemType == SCH_FIELD_T || itemType == SCH_SHEET_PIN_T )
1653  getView()->Update( aItem->GetParent() );
1654  else
1655  getView()->Update( aItem );
1656 }
1657 
1658 
1660 {
1661  const unsigned GRIP_MARGIN = 20;
1662  VECTOR2I margin = getView()->ToWorld( VECTOR2I( GRIP_MARGIN, GRIP_MARGIN ), false );
1663 
1664  // Check if the point is located within any of the currently selected items bounding boxes
1665  for( auto item : m_selection )
1666  {
1667  BOX2I itemBox = item->ViewBBox();
1668  itemBox.Inflate( margin.x, margin.y ); // Give some margin for gripping an item
1669 
1670  if( itemBox.Contains( aPoint ) )
1671  return true;
1672  }
1673 
1674  return false;
1675 }
1676 
1677 
1679 {
1681 
1686 
1692 
1694 }
1695 
1696 
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:134
void Empty()
Function Empty sets the list to empty.
Definition: collector.h:113
static TOOL_ACTION editPageNumber
Definition: ee_actions.h:155
void ClearReferencePoint()
Definition: selection.h:267
static TOOL_ACTION pinTable
Definition: ee_actions.h:146
KIGFX::SCH_VIEW * GetView() const override
Function GetView() Returns a pointer to the VIEW instance used in the panel.
static TOOL_ACTION properties
Definition: ee_actions.h:121
void AddStandardSubMenus(TOOL_MENU &aMenu)
Function CreateBasicMenu.
virtual EDA_ITEM * GetItem(const KIID &aId)
Fetch an item by KIID.
void OnIdle(wxIdleEvent &aEvent)
static const TOOL_EVENT SelectedEvent
Definition: actions.h:208
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:94
KIID niluuid(0)
static bool IsDrawingWire(const SELECTION &aSelection)
int SelectAll(const TOOL_EVENT &aEvent)
Select all visible items in sheet
TOOL_EVENT * Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Function Wait()
bool collectHits(EE_COLLECTOR &aCollector, const VECTOR2I &aWhere, const KICAD_T *aFilterList=EE_COLLECTOR::AllItems)
Function CollectHits() Selects one or more items at the location given by parameter aWhere.
static TOOL_ACTION breakBus
Definition: ee_actions.h:135
static SELECTION_CONDITION SingleSymbol
wxPoint GetStartPoint() const
Definition: sch_line.h:94
bool IsSelected() const
Definition: eda_item.h:191
Model changes (required full reload)
Definition: tool_base.h:82
static const TOOL_EVENT UnselectedEvent
Definition: actions.h:209
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
Defines the structure of a menu based on ACTIONs.
Definition: action_menu.h:43
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:456
void SetOrigin(VECTOR2I aOrigin)
Set the origin of the rectange (the fixed corner)
void ClearSelected()
Definition: eda_item.h:199
static SELECTION_CONDITION MoreThan(int aNumber)
Creates a functor that tests if the number of selected items is greater than the value given as param...
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.
EDA_RECT GetBoundingBox() const override
static TOOL_ACTION addItemsToSel
Selects a list of items (specified as the event parameter)
Definition: ee_actions.h:63
VIEW_CONTROLS class definition.
static bool Idle(const SELECTION &aSelection)
Tests if there no items selected or being edited.
static SELECTION_CONDITION OnlyTypes(const KICAD_T aTypes[])
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:357
int GetWidth() const
Definition: eda_rect.h:119
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: eda_item.h:197
static TOOL_ACTION zoomFitScreen
Definition: actions.h:94
#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:141
VECTOR2I BestSnapAnchor(const VECTOR2I &aOrigin, SCH_ITEM *aDraggedItem)
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.
#define IS_ROLLOVER
Rollover active. Used for hyperlink highlighting.
Definition: eda_item.h:128
void UpdateAll()
Runs update handlers for the menu and its submenus.
KICURSOR
Definition: cursors.h:33
static TOOL_ACTION zoomFitObjects
Definition: actions.h:95
static TOOL_ACTION removeItemsFromSel
Definition: ee_actions.h:64
static SELECTION_CONDITION Count(int aNumber)
Creates a functor that tests if the number of selected items is equal to the value given as parameter...
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.
Definition: eda_rect.cpp:57
void Remove(int aIndex)
Function Remove removes the item at aIndex (first position is 0);.
Definition: collector.h:133
bool InvokeTool(TOOL_ID aToolId)
Function InvokeTool() Calls a tool by sending a tool activation event to tool of given ID.
void SetCurrentCursor(KICURSOR cursor)
Function SetCurrentCursor Set the current cursor shape for this panel.
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:201
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:62
static TOOL_ACTION breakWire
Definition: ee_actions.h:134
void SetIsHover(bool aIsHover)
Definition: selection.h:65
virtual void Add(EDA_ITEM *aItem)
Definition: selection.h:75
const KICAD_T movableSymbolItems[]
static TOOL_ACTION leaveSheet
Definition: ee_actions.h:185
void ClearBrightened()
Definition: eda_item.h:200
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:123
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: eda_item.h:295
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:104
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
int SelectNode(const TOOL_EVENT &aEvent)
Select node under cursor
Definition: kiid.h:44
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.h:262
int GetUnit() const
Definition: lib_item.h:296
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
void Transfer(int aIndex)
Moves the item at aIndex (first position is 0) to the backup list.
Definition: collector.h:175
void BrightenItem(EDA_ITEM *aItem)
bool selectPoint(EE_COLLECTOR &aCollector, EDA_ITEM **aItem=nullptr, bool *aSelectionCancelledFlag=nullptr, bool aAdd=false, bool aSubtract=false, bool aExclusiveOr=false)
Function SelectPoint() This is the primary SelectPoint method that will prompt the user with a menu t...
#define BRIGHTENED
item is drawn with a bright contour
Definition: eda_item.h:129
void highlight(EDA_ITEM *aItem, int aHighlightMode, EE_SELECTION *aGroup=nullptr)
Function highlight() Highlights the item visually.
void narrowSelection(EE_COLLECTOR &collector, const VECTOR2I &aWhere, bool aCheckLocked)
Applies rules to narrow the collection down to selectable objects, and then heuristics to try and nar...
void SetFlags(STATUS_FLAGS aMask)
Definition: eda_item.h:220
static TOOL_ACTION addItemToSel
Selects an item (specified as the event parameter).
Definition: ee_actions.h:59
void SetSelected()
Definition: eda_item.h:196
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.
static TOOL_ACTION explicitCrossProbe
Definition: ee_actions.h:198
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:145
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
bool Contains(const Vec &aPoint) const
Function Contains.
Definition: box2.h:151
#define SELECTED
Definition: eda_item.h:113
TOOL_EVENT.
Definition: tool_event.h:171
void SetMaximum()
Definition: box2.h:73
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:136
const BITMAP_OPAQUE net_highlight_schematic_xpm[1]
EDA_ITEM * GetParent() const
Definition: eda_item.h:183
bool GetDragSelects() const
Indicates that a drag should draw a selection rectangle, even when started over an item.
Definition: tools_holder.h:153
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:210
virtual bool IsType(const KICAD_T aScanTypes[]) const
Function IsType Checks whether the item is one of the listed types.
Definition: eda_item.h:250
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:1394
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:85
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
Definition: eda_item.h:576
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:167
static SELECTION_CONDITION SingleMultiUnitSymbol
virtual KIGFX::VIEW_ITEM * GetItem(unsigned int aIdx) const override
Definition: selection.h:104
int GetConvert() const
Definition: lib_item.h:299
const BITMAP_OPAQUE info_xpm[1]
Definition: info.cpp:75
LIB_PART * GetCurPart()
Return the current part being edited or NULL if none selected.
void UnbrightenItem(EDA_ITEM *aItem)
EDA_ITEM * GetNode(VECTOR2I aPosition)
Find (but don't select) node under cursor
int GetHeight() const
Definition: eda_rect.h:120
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:120
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:219
bool IsMirroredX() const
Function IsMirroredX() Returns true if view is flipped across the X axis.
Definition: view.h:232
void SetSubtractive(bool aSubtractive)
virtual unsigned int GetSize() const override
Function GetSize() Returns the number of stored items.
Definition: selection.h:99
std::vector< SCH_SHEET_PIN * > & GetPins()
Definition: sch_sheet.h:364
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
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.
Definition: eda_rect.cpp:35
void unselect(EDA_ITEM *aItem)
Function unselect() Takes necessary action mark an item as unselected.
#define STARTPOINT
When a line is selected, these flags indicate which.
Definition: eda_item.h:111
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:302
virtual bool IsPointClickableAnchor(const wxPoint &aPos) const
Definition: sch_item.h:388
SCH_SHEET & Root() const
Definition: schematic.h:102
static KICAD_T nodeTypes[]
bool HasAdditionalItems()
Test if the collector has heuristic backup items.
Definition: collector.h:157
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
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() This overload of SelectPoint will create an EE_COLLECTOR and collect hits at l...
#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
static TOOL_ACTION assignNetclass
Definition: ee_actions.h:152
virtual wxString GetSelectMenuText(EDA_UNITS aUnits) const
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
Definition: eda_item.cpp:123
std::pair< VIEW_ITEM *, int > LAYER_ITEM_PAIR
Definition: view.h:68
bool HitTestPoints(const wxPoint &pointA, const wxPoint &pointB, double threshold)
Test, if two points are near each other.
Definition: trigo.h:172
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:159
static SELECTION_CONDITION OnlyType(KICAD_T aType)
Creates a functor that tests if the selected items are only of given type.
bool IsAlias() const
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
TOOL_EVENT MakeEvent() const
Returns the event associated with the action (i.e.
Definition: tool_action.h:113
int Size() const
Returns the number of selected parts.
Definition: selection.h:126
Schematic symbol object.
Definition: sch_component.h:79
static bool Empty(const SELECTION &aSelection)
Tests if there are no items selected.
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: eda_item.h:148
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:79
static TOOL_ACTION enterSheet
Definition: ee_actions.h:184
boost::optional< T > OPT
Definition: optional.h:7
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:221
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Sets the item visibility.
Definition: view.cpp:1459
void Combine()
Re-combines the backup list into the main list of the collector.
Definition: collector.h:165
SCH_SHEET_PATH & GetCurrentSheet() const
#define ENDPOINT
ends. (Used to support dragging.)
Definition: eda_item.h:112
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:327
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:832
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:433
virtual const EDA_RECT GetBoundingBox() const
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes.
Definition: eda_item.cpp:89
KIGFX::VIEW_CONTROLS * getViewControls() const
Function getViewControls()
Definition: tool_base.cpp:42
VIEW.
Definition: view.h:63
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.
Definition: eda_item.cpp:221
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Adds a menu entry to run a TOOL_ACTION on selected items.
EE_SELECTION m_selection
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:194
static TOOL_ACTION selectAll
Definition: actions.h:73
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:201
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
Definition: eda_rect.cpp:363
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const
For dynamic VIEWs, informs the associated VIEW that the graphical representation of this item has cha...
Definition: view.cpp:1513
const KICAD_T movableSchematicItems[]
OPT< TOOL_EVENT > OPT_TOOL_EVENT
Definition: tool_event.h:556
KICAD_T Type() const
Function Type()
Definition: eda_item.h:181
int Main(const TOOL_EVENT &aEvent)
Function Main()
The symbol library editor main window.
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:86
wxPoint GetEndPoint() const
Definition: sch_line.h:97