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 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 <ee_actions.h>
27 #include <core/typeinfo.h>
28 #include <sch_item.h>
29 #include <ee_selection_tool.h>
30 #include <sch_base_frame.h>
31 #include <sch_edit_frame.h>
32 #include <lib_edit_frame.h>
33 #include <viewlib_frame.h>
34 #include <sch_component.h>
35 #include <sch_sheet.h>
36 #include <sch_field.h>
37 #include <sch_line.h>
38 #include <view/view.h>
39 #include <view/view_controls.h>
40 #include <view/view_group.h>
42 #include <tool/tool_event.h>
43 #include <tool/tool_manager.h>
45 #include <ee_collectors.h>
46 #include <painter.h>
47 #include <eeschema_id.h>
48 #include <menus_helpers.h>
49 
50 
51 SELECTION_CONDITION EE_CONDITIONS::Empty = [] (const SELECTION& aSelection )
52 {
53  return aSelection.Empty();
54 };
55 
56 
57 SELECTION_CONDITION EE_CONDITIONS::Idle = [] (const SELECTION& aSelection )
58 {
59  return ( !aSelection.Front() || aSelection.Front()->GetEditFlags() == 0 );
60 };
61 
62 
64 {
65  return ( aSelection.Front() && aSelection.Front()->GetEditFlags() == 0 );
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  {
77  return !comp->GetPartRef() || !comp->GetPartRef()->IsPower();
78  }
79  }
80 
81  return false;
82 };
83 
84 
86 {
87  if( aSel.GetSize() == 1 )
88  {
89  SCH_COMPONENT* comp = dynamic_cast<SCH_COMPONENT*>( aSel.Front() );
90 
91  if( comp )
92  {
93  return comp->GetPartRef() && comp->GetPartRef()->HasConversion();
94  }
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  {
109  return comp->GetPartRef() && comp->GetPartRef()->GetUnitCount() >= 2;
110  }
111  }
112 
113  return false;
114 };
115 
116 
117 #define HITTEST_THRESHOLD_PIXELS 5
118 
119 
121  TOOL_INTERACTIVE( "eeschema.InteractiveSelection" ),
122  m_frame( nullptr ),
123  m_additive( false ),
124  m_subtractive( false ),
125  m_exclusive_or( false ),
126  m_multiple( false ),
127  m_skip_heuristics( false ),
128  m_isLibEdit( false ),
129  m_isLibView( false ),
130  m_unit( 0 ),
131  m_convert( 0 )
132 {
133 }
134 
135 
137 {
138  getView()->Remove( &m_selection );
139 }
140 
142 
144 {
145  m_frame = getEditFrame<SCH_BASE_FRAME>();
146 
147  LIB_VIEW_FRAME* libViewFrame = dynamic_cast<LIB_VIEW_FRAME*>( m_frame );
148  LIB_EDIT_FRAME* libEditFrame = dynamic_cast<LIB_EDIT_FRAME*>( m_frame );
149 
150  if( libEditFrame )
151  {
152  m_isLibEdit = true;
153  m_unit = libEditFrame->GetUnit();
154  m_convert = libEditFrame->GetConvert();
155  }
156  else
157  m_isLibView = libViewFrame != nullptr;
158 
159 
160  static KICAD_T wireOrBusTypes[] = { SCH_LINE_LOCATE_WIRE_T, SCH_LINE_LOCATE_BUS_T, EOT };
161 
162  auto wireSelection = E_C::MoreThan( 0 ) && E_C::OnlyType( SCH_LINE_LOCATE_WIRE_T );
163  auto busSelection = E_C::MoreThan( 0 ) && E_C::OnlyType( SCH_LINE_LOCATE_BUS_T );
164  auto wireOrBusSelection = E_C::MoreThan( 0 ) && E_C::OnlyTypes( wireOrBusTypes );
165  auto sheetSelection = E_C::Count( 1 ) && E_C::OnlyType( SCH_SHEET_T );
166  auto schEditCondition = [this] ( const SELECTION& aSel ) {
167  return !m_isLibEdit && !m_isLibView;
168  };
169  auto belowRootSheetCondition = [this] ( const SELECTION& aSel ) {
171  };
172  auto havePartCondition = [ this ] ( const SELECTION& sel ) {
173  return m_isLibEdit && ( (LIB_EDIT_FRAME*) m_frame )->GetCurPart();
174  };
175 
176  auto& menu = m_menu.GetMenu();
177 
178  menu.AddItem( EE_ACTIONS::enterSheet, sheetSelection && EE_CONDITIONS::Idle, 1 );
179  menu.AddItem( EE_ACTIONS::explicitCrossProbe, sheetSelection && EE_CONDITIONS::Idle, 1 );
180  menu.AddItem( EE_ACTIONS::leaveSheet, belowRootSheetCondition, 1 );
181 
182  menu.AddSeparator( 100 );
183  menu.AddItem( EE_ACTIONS::drawWire, schEditCondition && EE_CONDITIONS::Empty, 100 );
184  menu.AddItem( EE_ACTIONS::drawBus, schEditCondition && EE_CONDITIONS::Empty, 100 );
185 
186  menu.AddSeparator( 100 );
188 
189  menu.AddSeparator( 100 );
191 
192  menu.AddSeparator( 200 );
193  menu.AddItem( EE_ACTIONS::selectConnection, wireOrBusSelection && EE_CONDITIONS::Idle, 250 );
194  menu.AddItem( EE_ACTIONS::placeJunction, wireOrBusSelection && EE_CONDITIONS::Idle, 250 );
195  menu.AddItem( EE_ACTIONS::placeLabel, wireOrBusSelection && EE_CONDITIONS::Idle, 250 );
196  menu.AddItem( EE_ACTIONS::placeGlobalLabel, wireOrBusSelection && EE_CONDITIONS::Idle, 250 );
197  menu.AddItem( EE_ACTIONS::placeHierLabel, wireOrBusSelection && EE_CONDITIONS::Idle, 250 );
198  menu.AddItem( EE_ACTIONS::breakWire, wireSelection && EE_CONDITIONS::Idle, 250 );
199  menu.AddItem( EE_ACTIONS::breakBus, busSelection && EE_CONDITIONS::Idle, 250 );
200  menu.AddItem( EE_ACTIONS::placeSheetPin, sheetSelection && EE_CONDITIONS::Idle, 250 );
201  menu.AddItem( EE_ACTIONS::importSheetPin, sheetSelection && EE_CONDITIONS::Idle, 250 );
202 
203  menu.AddSeparator( 400 );
204  menu.AddItem( EE_ACTIONS::symbolProperties, havePartCondition && EE_CONDITIONS::Empty, 400 );
205  menu.AddItem( EE_ACTIONS::pinTable, havePartCondition && EE_CONDITIONS::Empty, 400 );
206 
207  menu.AddSeparator( 1000 );
209 
210  return true;
211 }
212 
213 
215 {
216  m_frame = getEditFrame<SCH_BASE_FRAME>();
217 
218  if( aReason == TOOL_BASE::MODEL_RELOAD )
219  {
220  // Remove pointers to the selected items from containers without changing their
221  // properties (as they are already deleted while a new sheet is loaded)
222  m_selection.Clear();
223  getView()->GetPainter()->GetSettings()->SetHighlight( false );
224 
225  LIB_EDIT_FRAME* libEditFrame = dynamic_cast<LIB_EDIT_FRAME*>( m_frame );
226  LIB_VIEW_FRAME* libViewFrame = dynamic_cast<LIB_VIEW_FRAME*>( m_frame );
227 
228  if( libEditFrame )
229  {
230  m_isLibEdit = true;
231  m_unit = libEditFrame->GetUnit();
232  m_convert = libEditFrame->GetConvert();
233  }
234  else
235  m_isLibView = libViewFrame != nullptr;
236  }
237  else
238  // Restore previous properties of selected items and remove them from containers
239  ClearSelection();
240 
241  // Reinsert the VIEW_GROUP, in case it was removed from the VIEW
242  getView()->Remove( &m_selection );
243  getView()->Add( &m_selection );
244 }
245 
246 
248 {
249  ACTION_MENU* actionMenu = aEvent.Parameter<ACTION_MENU*>();
250  CONDITIONAL_MENU* conditionalMenu = dynamic_cast<CONDITIONAL_MENU*>( actionMenu );
251 
252  if( conditionalMenu )
253  conditionalMenu->Evaluate( m_selection );
254 
255  if( actionMenu )
256  actionMenu->UpdateAll();
257 
258  return 0;
259 }
260 
261 
263 {
264  const KICAD_T movableItems[] =
265  {
266  SCH_MARKER_T,
271  SCH_LINE_T,
272  SCH_BITMAP_T,
273  SCH_TEXT_T,
274  SCH_LABEL_T,
277  SCH_FIELD_T,
280  SCH_SHEET_T,
281  EOT
282  };
283 
284  // Main loop: keep receiving events
285  while( TOOL_EVENT* evt = Wait() )
286  {
287  if( m_frame->ToolStackIsEmpty() )
288  m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
289 
291 
292  if( evt->Modifier( MD_SHIFT ) && evt->Modifier( MD_CTRL ) )
293  m_subtractive = true;
294  else if( evt->Modifier( MD_SHIFT ) )
295  m_additive = true;
296  else if( evt->Modifier( MD_CTRL ) )
297  m_exclusive_or = true;
298 
299  // Is the user requesting that the selection list include all possible
300  // items without removing less likely selection candidates
301  m_skip_heuristics = !!evt->Modifier( MD_ALT );
302 
303  // Single click? Select single object
304  if( evt->IsClick( BUT_LEFT ) )
305  {
306  SelectPoint( evt->Position(), EE_COLLECTOR::AllItems, nullptr, false,
308  }
309 
310  // right click? if there is any object - show the context menu
311  else if( evt->IsClick( BUT_RIGHT ) )
312  {
313  bool selectionCancelled = false;
314 
315  if( m_selection.Empty() ||
316  !m_selection.GetBoundingBox().Contains( wxPoint( evt->Position() ) ) )
317  {
318  ClearSelection();
319  SelectPoint( evt->Position(), EE_COLLECTOR::AllItems, &selectionCancelled );
320  m_selection.SetIsHover( true );
321  }
322 
323  if( !selectionCancelled )
325  }
326 
327  // double click? Display the properties window
328  else if( evt->IsDblClick( BUT_LEFT ) )
329  {
330  if( m_selection.Empty() )
331  SelectPoint( evt->Position());
332 
333  EDA_ITEM* item = m_selection.Front();
334 
335  if( item && item->Type() == SCH_SHEET_T )
337  else
339  }
340 
341  // drag with LMB? Select multiple objects (or at least draw a selection box) or drag them
342  else if( evt->IsDrag( BUT_LEFT ) )
343  {
345  {
346  selectMultiple();
347  }
348  else
349  {
350  // selection is empty? try to start dragging the item under the point where drag
351  // started
352  if( m_selection.Empty() )
353  m_selection = RequestSelection( movableItems );
354 
355  // Check if dragging has started within any of selected items bounding box
356  if( selectionContains( evt->Position() ) )
357  {
358  // Yes -> run the move tool and wait till it finishes
359  m_toolMgr->InvokeTool( "eeschema.InteractiveMove" );
360  }
361  else
362  {
363  // No -> drag a selection box
364  selectMultiple();
365  }
366  }
367  }
368 
369  // context sub-menu selection? Handle unit selection or bus unfolding
370  else if( evt->Category() == TC_COMMAND && evt->Action() == TA_CHOICE_MENU_CHOICE )
371  {
372  if( evt->GetCommandId().get() >= ID_POPUP_SCH_SELECT_UNIT_CMP
373  && evt->GetCommandId().get() <= ID_POPUP_SCH_SELECT_UNIT_CMP_MAX )
374  {
375  SCH_COMPONENT* component = dynamic_cast<SCH_COMPONENT*>( m_selection.Front() );
376  int unit = evt->GetCommandId().get() - ID_POPUP_SCH_SELECT_UNIT_CMP;
377 
378  if( component )
379  static_cast<SCH_EDIT_FRAME*>( m_frame )->SelectUnit( component, unit );
380  }
381  else if( evt->GetCommandId().get() >= ID_POPUP_SCH_UNFOLD_BUS
382  && evt->GetCommandId().get() <= ID_POPUP_SCH_UNFOLD_BUS_END )
383  {
384  wxString* net = new wxString( *evt->Parameter<wxString*>() );
386  }
387 
388  }
389 
390  else if( evt->IsCancelInteractive() )
391  {
392  ClearSelection();
393  }
394 
395  else if( evt->Action() == TA_UNDO_REDO_PRE )
396  {
397  ClearSelection();
398  }
399 
400  else
401  evt->SetPassEvent();
402  }
403 
404  // This tool is supposed to be active forever
405  assert( false );
406 
407  return 0;
408 }
409 
410 
412 {
413  return m_selection;
414 }
415 
416 
417 EDA_ITEM* EE_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, const KICAD_T* aFilterList,
418  bool* aSelectionCancelledFlag, bool aCheckLocked,
419  bool aAdd, bool aSubtract, bool aExclusiveOr )
420 {
421  EDA_ITEM* start;
422  EE_COLLECTOR collector;
423 
424  if( m_isLibEdit )
425  start = static_cast<LIB_EDIT_FRAME*>( m_frame )->GetCurPart();
426  else
427  start = m_frame->GetScreen()->GetDrawItems();
428 
429  // Empty schematics have no draw items
430  if( !start )
431  return nullptr;
432 
433  collector.m_Threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
434  collector.Collect( start, aFilterList, (wxPoint) aWhere, m_unit, m_convert );
435 
436  // Post-process collected items
437  for( int i = collector.GetCount() - 1; i >= 0; --i )
438  {
439  if( !Selectable( collector[ i ] ) )
440  {
441  collector.Remove( i );
442  continue;
443  }
444 
445  if( aCheckLocked && collector[ i ]->IsLocked() )
446  {
447  collector.Remove( i );
448  continue;
449  }
450 
451  // SelectPoint, unlike other selection routines, can select line ends
452  if( collector[ i ]->Type() == SCH_LINE_T )
453  {
454  SCH_LINE* line = (SCH_LINE*) collector[ i ];
455  line->ClearFlags( STARTPOINT | ENDPOINT );
456 
457  if( HitTestPoints( line->GetStartPoint(), (wxPoint) aWhere, collector.m_Threshold ) )
458  line->SetFlags( STARTPOINT );
459  else if (HitTestPoints( line->GetEndPoint(), (wxPoint) aWhere, collector.m_Threshold ) )
460  line->SetFlags( ENDPOINT );
461  else
462  line->SetFlags( STARTPOINT | ENDPOINT );
463  }
464  }
465 
467 
468  // Apply some ugly heuristics to avoid disambiguation menus whenever possible
469  if( collector.GetCount() > 1 && !m_skip_heuristics )
470  {
471  GuessSelectionCandidates( collector, aWhere );
472  }
473 
474  // If still more than one item we're going to have to ask the user.
475  if( collector.GetCount() > 1 )
476  {
477  collector.m_MenuTitle = _( "Clarify Selection" );
478  // Must call selectionMenu via RunAction() to avoid event-loop contention
479  m_toolMgr->RunAction( EE_ACTIONS::selectionMenu, true, &collector );
480 
481  if( collector.m_MenuCancelled )
482  {
483  if( aSelectionCancelledFlag )
484  *aSelectionCancelledFlag = true;
485 
486  return nullptr;
487  }
488  }
489 
490  if( !aAdd && !aSubtract && !aExclusiveOr )
491  ClearSelection();
492 
493  if( collector.GetCount() == 1 )
494  {
495  EDA_ITEM* item = collector[ 0 ];
496 
497  if( aSubtract || ( aExclusiveOr && item->IsSelected() ) )
498  {
499  unselect( item );
501  return nullptr;
502  }
503  else
504  {
505  select( item );
507  return item;
508  }
509  }
510 
511  return nullptr;
512 }
513 
514 
516 {
517  // There are certain parent/child and enclosure combinations that can be handled
518  // automatically.
519 
520  // Prefer exact hits to sloppy ones
521  int exactHits = 0;
522 
523  for( int i = collector.GetCount() - 1; i >= 0; --i )
524  {
525  EDA_ITEM* item = collector[ i ];
526 
527  if( item->HitTest( (wxPoint) aPos, 0 ) )
528  exactHits++;
529  }
530 
531  if( exactHits > 0 && exactHits < collector.GetCount() )
532  {
533  for( int i = collector.GetCount() - 1; i >= 0; --i )
534  {
535  EDA_ITEM* item = collector[ i ];
536 
537  if( !item->HitTest( (wxPoint) aPos, 0 ) )
538  collector.Remove( item );
539  }
540  }
541 
542  // Prefer a non-sheet to a sheet
543  for( int i = 0; collector.GetCount() == 2 && i < 2; ++i )
544  {
545  EDA_ITEM* item = collector[ i ];
546  EDA_ITEM* other = collector[ ( i + 1 ) % 2 ];
547 
548  if( item->Type() != SCH_SHEET_T && other->Type() == SCH_SHEET_T )
549  collector.Remove( other );
550  }
551 
552  // Prefer a symbol to a pin
553  for( int i = 0; collector.GetCount() == 2 && i < 2; ++i )
554  {
555  EDA_ITEM* item = collector[ i ];
556  EDA_ITEM* other = collector[ ( i + 1 ) % 2 ];
557 
558  if( item->Type() == SCH_COMPONENT_T && other->Type() == SCH_PIN_T )
559  collector.Remove( other );
560  }
561 
562  // Prefer a field to a symbol
563  for( int i = 0; collector.GetCount() == 2 && i < 2; ++i )
564  {
565  EDA_ITEM* item = collector[ i ];
566  EDA_ITEM* other = collector[ ( i + 1 ) % 2 ];
567 
568  if( item->Type() == SCH_FIELD_T && other->Type() == SCH_COMPONENT_T )
569  collector.Remove( other );
570  }
571 
572  // No need for multiple wires at a single point; if there's a junction select that;
573  // otherwise any of the wires will do
574  bool junction = false;
575  bool wiresOnly = true;
576 
577  for( EDA_ITEM* item : collector )
578  {
579  if( item->Type() == SCH_JUNCTION_T )
580  junction = true;
581  else if( item->Type() != SCH_LINE_T )
582  wiresOnly = false;
583  }
584 
585  if( wiresOnly )
586  {
587  for( int j = collector.GetCount() - 1; j >= 0; --j )
588  {
589  if( junction && collector[ j ]->Type() != SCH_JUNCTION_T )
590  collector.Remove( j );
591  else if( !junction && j > 0 )
592  collector.Remove( j );
593  }
594  }
595 }
596 
597 
599 {
600  // Filter an existing selection
601  if( !m_selection.Empty() )
602  {
603  for( int i = m_selection.GetSize() - 1; i >= 0; --i )
604  {
605  EDA_ITEM* item = (EDA_ITEM*) m_selection.GetItem( i );
606 
607  if( !item->IsType( aFilterList ) )
608  {
609  unselect( item );
611  }
612  }
613 
614  }
615 
616  // If nothing was selected, or we filtered everything out, do a hover selection
617  if( m_selection.Empty() )
618  {
619  VECTOR2D cursorPos = getViewControls()->GetCursorPosition( true );
620 
621  ClearSelection();
622  SelectPoint( cursorPos, aFilterList );
623  m_selection.SetIsHover( true );
625  }
626 
628 
629  return m_selection;
630 }
631 
632 
634 {
635  VECTOR2I refP( 0, 0 );
636 
637  if( m_selection.Size() > 0 )
638  {
639  if( m_isLibEdit )
640  refP = static_cast<LIB_ITEM*>( m_selection.GetTopLeftItem() )->GetPosition();
641  else
642  refP = static_cast<SCH_ITEM*>( m_selection.GetTopLeftItem() )->GetPosition();
643  }
644 
646 }
647 
648 
650 {
651  bool cancelled = false; // Was the tool cancelled while it was running?
652  m_multiple = true; // Multiple selection mode is active
653  KIGFX::VIEW* view = getView();
654 
656  view->Add( &area );
657 
658  while( TOOL_EVENT* evt = Wait() )
659  {
660  if( evt->IsCancelInteractive() || evt->IsActivate() )
661  {
662  cancelled = true;
663  break;
664  }
665 
666  if( evt->IsDrag( BUT_LEFT ) )
667  {
669  ClearSelection();
670 
671  // Start drawing a selection box
672  area.SetOrigin( evt->DragOrigin() );
673  area.SetEnd( evt->Position() );
674  area.SetAdditive( m_additive );
677 
678  view->SetVisible( &area, true );
679  view->Update( &area );
680  getViewControls()->SetAutoPan( true );
681  }
682 
683  if( evt->IsMouseUp( BUT_LEFT ) )
684  {
685  getViewControls()->SetAutoPan( false );
686 
687  // End drawing the selection box
688  view->SetVisible( &area, false );
689 
690  // Mark items within the selection box as selected
691  std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems;
692  std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> sheetPins;
693 
694  // Filter the view items based on the selection box
695  BOX2I selectionBox = area.ViewBBox();
696  view->Query( selectionBox, selectedItems ); // Get the list of selected items
697 
698  // Sheet pins aren't in the view; add them by hand
699  for( KIGFX::VIEW::LAYER_ITEM_PAIR& pair : selectedItems )
700  {
701  SCH_SHEET* sheet = dynamic_cast<SCH_SHEET*>( pair.first );
702 
703  if( sheet )
704  {
705  int layer = pair.second;
706 
707  for( SCH_SHEET_PIN& pin : sheet->GetPins() )
708  sheetPins.emplace_back( KIGFX::VIEW::LAYER_ITEM_PAIR( &pin, layer ) );
709  }
710  }
711 
712  selectedItems.insert( selectedItems.end(), sheetPins.begin(), sheetPins.end() );
713 
714  int width = area.GetEnd().x - area.GetOrigin().x;
715  int height = area.GetEnd().y - area.GetOrigin().y;
716 
717  /* Selection mode depends on direction of drag-selection:
718  * Left > Right : Select objects that are fully enclosed by selection
719  * Right > Left : Select objects that are crossed by selection
720  */
721  bool windowSelection = width >= 0;
722  bool anyAdded = false;
723  bool anySubtracted = false;
724 
725  if( view->IsMirroredX() )
726  windowSelection = !windowSelection;
727 
728  // Construct an EDA_RECT to determine EDA_ITEM selection
729  EDA_RECT selectionRect( (wxPoint) area.GetOrigin(), wxSize( width, height ) );
730 
731  selectionRect.Normalize();
732 
733  for( KIGFX::VIEW::LAYER_ITEM_PAIR& pair : selectedItems )
734  {
735  EDA_ITEM* item = dynamic_cast<EDA_ITEM*>( pair.first );
736 
737  if( item && Selectable( item ) && item->HitTest( selectionRect, windowSelection ) )
738  {
739  if( m_subtractive || ( m_exclusive_or && item->IsSelected() ) )
740  {
741  unselect( item );
742  anySubtracted = true;
743  }
744  else
745  {
746  select( item );
747  item->SetFlags( STARTPOINT | ENDPOINT );
748  anyAdded = true;
749  }
750  }
751  }
752 
753  m_selection.SetIsHover( false );
754 
755  // Inform other potentially interested tools
756  if( anyAdded )
758 
759  if( anySubtracted )
761 
762  break; // Stop waiting for events
763  }
764  }
765 
766  getViewControls()->SetAutoPan( false );
767 
768  // Stop drawing the selection box
769  view->Remove( &area );
770  m_multiple = false; // Multiple selection mode is inactive
771 
772  if( !cancelled )
774 
775  return cancelled;
776 }
777 
778 
779 static KICAD_T nodeTypes[] =
780 {
785  SCH_LABEL_T,
790  EOT
791 };
792 
793 
795 {
796  if( m_frame->GetScreen()->GetDrawItems() == nullptr ) // Empty schematics
797  return nullptr;
798 
799  EE_COLLECTOR collector;
800 
801  int thresholdMax = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
802 
803  for( int threshold : { 0, thresholdMax/2, thresholdMax } )
804  {
805  collector.m_Threshold = threshold;
806  collector.Collect( m_frame->GetScreen()->GetDrawItems(), nodeTypes, (wxPoint) aPosition );
807 
808  if( collector.GetCount() > 0 )
809  break;
810  }
811 
812  return collector.GetCount() ? collector[ 0 ] : nullptr;
813 }
814 
815 
817 {
818  VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !aEvent.Modifier( MD_ALT ) );
819 
820  SelectPoint( cursorPos, nodeTypes );
821 
822  return 0;
823 }
824 
825 
827 {
828  static KICAD_T wiresAndBusses[] = { SCH_LINE_LOCATE_WIRE_T, SCH_LINE_LOCATE_BUS_T, EOT };
829 
830  RequestSelection( wiresAndBusses );
831 
832  if( m_selection.Empty() )
833  return 0;
834 
835  SCH_LINE* line = (SCH_LINE*) m_selection.Front();
836  EDA_ITEMS items;
837 
839  m_frame->GetScreen()->MarkConnections( line );
840 
841  for( EDA_ITEM* item = m_frame->GetScreen()->GetDrawItems(); item; item = item->Next() )
842  {
843  if( item->HasFlag( CANDIDATE ) )
844  select( item );
845  }
846 
847  if( m_selection.GetSize() > 1 )
849 
850  return 0;
851 }
852 
853 
855 {
856  AddItemToSel( aEvent.Parameter<EDA_ITEM*>() );
857  m_selection.SetIsHover( false );
858  return 0;
859 }
860 
861 
862 void EE_SELECTION_TOOL::AddItemToSel( EDA_ITEM* aItem, bool aQuietMode )
863 {
864  if( aItem )
865  {
866  select( aItem );
867 
868  // Inform other potentially interested tools
869  if( !aQuietMode )
871  }
872 }
873 
874 
876 {
877  AddItemsToSel( aEvent.Parameter<EDA_ITEMS*>(), false );
878  m_selection.SetIsHover( false );
879  return 0;
880 }
881 
882 
883 void EE_SELECTION_TOOL::AddItemsToSel( EDA_ITEMS* aList, bool aQuietMode )
884 {
885  if( aList )
886  {
887  for( EDA_ITEM* item : *aList )
888  select( item );
889 
890  // Inform other potentially interested tools
891  if( !aQuietMode )
893  }
894 }
895 
896 
898 {
899  RemoveItemFromSel( aEvent.Parameter<EDA_ITEM*>() );
900  m_selection.SetIsHover( false );
901  return 0;
902 }
903 
904 
905 void EE_SELECTION_TOOL::RemoveItemFromSel( EDA_ITEM* aItem, bool aQuietMode )
906 {
907  if( aItem )
908  {
909  unselect( aItem );
910 
911  // Inform other potentially interested tools
912  if( !aQuietMode )
914  }
915 }
916 
917 
919 {
920  RemoveItemsFromSel( aEvent.Parameter<EDA_ITEMS*>(), false );
921  m_selection.SetIsHover( false );
922  return 0;
923 }
924 
925 
926 void EE_SELECTION_TOOL::RemoveItemsFromSel( EDA_ITEMS* aList, bool aQuietMode )
927 {
928  if( aList )
929  {
930  for( EDA_ITEM* item : *aList )
931  unselect( item );
932 
933  // Inform other potentially interested tools
934  if( !aQuietMode )
936  }
937 }
938 
939 
941 {
942  highlight( aItem, BRIGHTENED );
943 }
944 
945 
947 {
948  unhighlight( aItem, BRIGHTENED );
949 }
950 
951 
953 {
954  ClearSelection();
955 
956  return 0;
957 }
958 
959 
961 {
962  m_selection.Clear();
963 
964  EDA_ITEM* start = nullptr;
965 
966  if( m_isLibEdit )
967  start = static_cast<LIB_EDIT_FRAME*>( m_frame )->GetCurPart();
968  else
969  start = m_frame->GetScreen()->GetDrawItems();
970 
971  INSPECTOR_FUNC inspector = [&] ( EDA_ITEM* item, void* testData )
972  {
973  // If the field and component are selected, only use the component
974  if( item->IsSelected() && !( item->Type() == SCH_FIELD_T && item->GetParent()
975  && item->GetParent()->IsSelected() ) )
976  {
977  select( item );
978  }
979 
980  return SEARCH_CONTINUE;
981  };
982 
983  EDA_ITEM::IterateForward( start, inspector, nullptr, EE_COLLECTOR::AllItems );
984 
986 
987  // Inform other potentially interested tools
989 }
990 
991 
993 {
994  EE_COLLECTOR* collector = aEvent.Parameter<EE_COLLECTOR*>();
995 
996  if( !doSelectionMenu( collector ) )
997  collector->m_MenuCancelled = true;
998 
999  return 0;
1000 }
1001 
1002 
1004 {
1005  EDA_ITEM* current = nullptr;
1006  ACTION_MENU menu( true );
1007 
1008  int limit = std::min( MAX_SELECT_ITEM_IDS, aCollector->GetCount() );
1009 
1010  for( int i = 0; i < limit; ++i )
1011  {
1012  wxString text;
1013  EDA_ITEM* item = ( *aCollector )[i];
1014  text = item->GetSelectMenuText( m_frame->GetUserUnits() );
1015 
1016  wxString menuText = wxString::Format("&%d. %s", i + 1, text );
1017  menu.Add( menuText, i + 1, item->GetMenuImage() );
1018  }
1019 
1020  if( aCollector->m_MenuTitle.Length() )
1021  menu.SetTitle( aCollector->m_MenuTitle );
1022 
1023  menu.SetIcon( info_xpm );
1024  menu.DisplayTitle( true );
1025  SetContextMenu( &menu, CMENU_NOW );
1026 
1027  while( TOOL_EVENT* evt = Wait() )
1028  {
1029  if( evt->Action() == TA_CHOICE_MENU_UPDATE )
1030  {
1031  if( current )
1032  unhighlight( current, BRIGHTENED );
1033 
1034  int id = *evt->GetCommandId();
1035 
1036  // User has pointed an item, so show it in a different way
1037  if( id > 0 && id <= limit )
1038  {
1039  current = ( *aCollector )[id - 1];
1040  highlight( current, BRIGHTENED );
1041  }
1042  else
1043  {
1044  current = nullptr;
1045  }
1046  }
1047  else if( evt->Action() == TA_CHOICE_MENU_CHOICE )
1048  {
1049  if( current )
1050  unhighlight( current, BRIGHTENED );
1051 
1052  OPT<int> id = evt->GetCommandId();
1053 
1054  // User has selected an item, so this one will be returned
1055  if( id && ( *id > 0 ) )
1056  current = ( *aCollector )[*id - 1];
1057  else
1058  current = nullptr;
1059 
1060  break;
1061  }
1062 
1063  getView()->UpdateItems();
1064  m_frame->GetCanvas()->Refresh();
1065  }
1066 
1067  if( current )
1068  {
1069  unhighlight( current, BRIGHTENED );
1070 
1071  getView()->UpdateItems();
1072  m_frame->GetCanvas()->Refresh();
1073 
1074  aCollector->Empty();
1075  aCollector->Append( current );
1076  return true;
1077  }
1078 
1079  return false;
1080 }
1081 
1082 
1083 bool EE_SELECTION_TOOL::Selectable( const EDA_ITEM* aItem, bool checkVisibilityOnly ) const
1084 {
1085  // NOTE: in the future this is where eeschema layer/itemtype visibility will be handled
1086  LIB_EDIT_FRAME* symbeditFrame = dynamic_cast< LIB_EDIT_FRAME* >( m_frame );
1087 
1088  switch( aItem->Type() )
1089  {
1090  case SCH_PIN_T:
1091  if( !static_cast<const SCH_PIN*>( aItem )->IsVisible() && !m_frame->GetShowAllPins() )
1092  return false;
1093  break;
1094 
1095  case LIB_PART_T: // In libedit we do not want to select the symbol itself.
1096  return false;
1097 
1098  case LIB_FIELD_T:
1099  {
1100  if( symbeditFrame )
1101  {
1102  LIB_PART* currentPart = symbeditFrame->GetCurPart();
1103 
1104  // Nothing in derived symbols is editable at the moment.
1105  if( currentPart && currentPart->IsAlias() )
1106  return false;
1107  }
1108 
1109  break;
1110  }
1111 
1112  case LIB_ARC_T:
1113  case LIB_CIRCLE_T:
1114  case LIB_TEXT_T:
1115  case LIB_RECTANGLE_T:
1116  case LIB_POLYLINE_T:
1117  case LIB_BEZIER_T:
1118  case LIB_PIN_T:
1119  {
1120  if( symbeditFrame )
1121  {
1122  LIB_ITEM* lib_item = (LIB_ITEM*) aItem;
1123 
1124  if( lib_item->GetUnit() && lib_item->GetUnit() != symbeditFrame->GetUnit() )
1125  return false;
1126 
1127  if( lib_item->GetConvert() && lib_item->GetConvert() != symbeditFrame->GetConvert() )
1128  return false;
1129  }
1130 
1131  break;
1132  }
1133 
1134  case SCH_MARKER_T: // Always selectable
1135  return true;
1136 
1137  default: // Suppress warnings
1138  break;
1139  }
1140 
1141  return true;
1142 }
1143 
1144 
1146 {
1147  if( m_selection.Empty() )
1148  return;
1149 
1150  while( m_selection.GetSize() )
1152 
1153  getView()->Update( &m_selection );
1154 
1155  m_selection.SetIsHover( false );
1157 
1158  // Inform other potentially interested tools
1160 }
1161 
1162 
1164 {
1165  highlight( aItem, SELECTED, &m_selection );
1166 }
1167 
1168 
1170 {
1171  unhighlight( aItem, SELECTED, &m_selection );
1172 }
1173 
1174 
1175 void EE_SELECTION_TOOL::highlight( EDA_ITEM* aItem, int aMode, EE_SELECTION* aGroup )
1176 {
1177  KICAD_T itemType = aItem->Type();
1178 
1179  if( aMode == SELECTED )
1180  aItem->SetSelected();
1181  else if( aMode == BRIGHTENED )
1182  aItem->SetBrightened();
1183 
1184  if( aGroup )
1185  aGroup->Add( aItem );
1186 
1187  // Highlight pins and fields. (All the other component children are currently only
1188  // represented in the LIB_PART and will inherit the settings of the parent component.)
1189  if( itemType == SCH_COMPONENT_T )
1190  {
1191  SCH_PINS& pins = static_cast<SCH_COMPONENT*>( aItem )->GetPins();
1192 
1193  for( SCH_PIN& pin : pins )
1194  {
1195  if( aMode == SELECTED )
1196  pin.SetSelected();
1197  else if( aMode == BRIGHTENED )
1198  pin.SetBrightened();
1199  }
1200 
1201  std::vector<SCH_FIELD*> fields;
1202  static_cast<SCH_COMPONENT*>( aItem )->GetFields( fields, false );
1203 
1204  for( SCH_FIELD* field : fields )
1205  {
1206  if( aMode == SELECTED )
1207  field->SetSelected();
1208  else if( aMode == BRIGHTENED )
1209  field->SetBrightened();
1210  }
1211  }
1212  else if( itemType == SCH_SHEET_T )
1213  {
1214  SCH_SHEET_PINS& pins = static_cast<SCH_SHEET*>( aItem )->GetPins();
1215 
1216  for( SCH_SHEET_PIN& pin : pins )
1217  {
1218  if( aMode == SELECTED )
1219  pin.SetSelected();
1220  else if( aMode == BRIGHTENED )
1221  pin.SetBrightened();
1222  }
1223  }
1224 
1225  if( itemType == SCH_PIN_T || itemType == SCH_FIELD_T || itemType == SCH_SHEET_PIN_T )
1226  getView()->Update( aItem->GetParent() );
1227  else
1228  getView()->Update( aItem );
1229 }
1230 
1231 
1232 void EE_SELECTION_TOOL::unhighlight( EDA_ITEM* aItem, int aMode, EE_SELECTION* aGroup )
1233 {
1234  KICAD_T itemType = aItem->Type();
1235 
1236  if( aMode == SELECTED )
1237  aItem->ClearSelected();
1238  else if( aMode == BRIGHTENED )
1239  aItem->ClearBrightened();
1240 
1241  if( aGroup )
1242  aGroup->Remove( aItem );
1243 
1244  // Unhighlight pins and fields. (All the other component children are currently only
1245  // represented in the LIB_PART.)
1246  if( itemType == SCH_COMPONENT_T )
1247  {
1248  SCH_PINS& pins = static_cast<SCH_COMPONENT*>( aItem )->GetPins();
1249 
1250  for( SCH_PIN& pin : pins )
1251  {
1252  if( aMode == SELECTED )
1253  pin.ClearSelected();
1254  else if( aMode == BRIGHTENED )
1255  pin.ClearBrightened();
1256  }
1257 
1258  std::vector<SCH_FIELD*> fields;
1259  static_cast<SCH_COMPONENT*>( aItem )->GetFields( fields, false );
1260 
1261  for( SCH_FIELD* field : fields )
1262  {
1263  if( aMode == SELECTED )
1264  field->ClearSelected();
1265  else if( aMode == BRIGHTENED )
1266  field->ClearBrightened();
1267  }
1268  }
1269  else if( itemType == SCH_SHEET_T )
1270  {
1271  SCH_SHEET_PINS& pins = static_cast<SCH_SHEET*>( aItem )->GetPins();
1272 
1273  for( SCH_SHEET_PIN& pin : pins )
1274  {
1275  if( aMode == SELECTED )
1276  pin.ClearSelected();
1277  else if( aMode == BRIGHTENED )
1278  pin.ClearBrightened();
1279  }
1280  }
1281 
1282  if( itemType == SCH_PIN_T || itemType == SCH_FIELD_T || itemType == SCH_SHEET_PIN_T )
1283  getView()->Update( aItem->GetParent() );
1284  else
1285  getView()->Update( aItem );
1286 }
1287 
1288 
1290 {
1291  const unsigned GRIP_MARGIN = 20;
1292  VECTOR2I margin = getView()->ToWorld( VECTOR2I( GRIP_MARGIN, GRIP_MARGIN ), false );
1293 
1294  // Check if the point is located within any of the currently selected items bounding boxes
1295  for( auto item : m_selection )
1296  {
1297  BOX2I itemBox = item->ViewBBox();
1298  itemBox.Inflate( margin.x, margin.y ); // Give some margin for gripping an item
1299 
1300  if( itemBox.Contains( aPoint ) )
1301  return true;
1302  }
1303 
1304  return false;
1305 }
1306 
1307 
1309 {
1311 
1316 
1322 }
1323 
1324 
void Empty()
Function Empty sets the list to empty.
Definition: collector.h:122
void ClearReferencePoint()
Definition: selection.h:248
static TOOL_ACTION pinTable
Definition: ee_actions.h:150
static TOOL_ACTION properties
Definition: ee_actions.h:122
Class 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.
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:197
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:68
int UpdateMenu(const TOOL_EVENT &aEvent)
virtual void Clear() override
Function Clear() Removes all the stored items from the group.
Definition: selection.h:93
std::function< SEARCH_RESULT(EDA_ITEM *aItem, void *aTestData) > INSPECTOR_FUNC
Typedef INSPECTOR is used to inspect and possibly collect the (search) results of iterating over a li...
Definition: base_struct.h:83
static bool IsDrawingWire(const SELECTION &aSelection)
SCH_SHEET_PINS & GetPins()
Definition: sch_sheet.h:335
#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:138
static SELECTION_CONDITION SingleSymbol
int GetConvert() const
wxPoint GetStartPoint() const
Definition: sch_line.h:99
bool IsSelected() const
Definition: base_struct.h:233
Model changes (required full reload)
Definition: tool_base.h:82
static const TOOL_EVENT UnselectedEvent
Definition: actions.h:198
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...
Class ACTION_MENU.
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:475
SCH_ITEM * Next() const
Definition: sch_item.h:153
std::vector< SCH_PIN > SCH_PINS
A container for several SCH_PIN items.
Definition: sch_component.h:51
void SetOrigin(VECTOR2I aOrigin)
Set the origin of the rectange (the fixed corner)
void ClearSelected()
Definition: base_struct.h:243
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 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:65
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:90
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:219
static TOOL_ACTION placeJunction
Definition: ee_actions.h:85
static TOOL_ACTION selectConnection
If current selection is a wire or bus, expand to entire connection.
Definition: ee_actions.h:55
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:83
void SetBrightened()
Definition: base_struct.h:241
#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:109
void SetExclusiveOr(bool aExclusiveOr)
Class EE_COLLECTOR.
Definition: ee_collectors.h:39
bool Selectable(const EDA_ITEM *aItem, bool checkVisibilityOnly=false) const
Function Selectable() Checks conditions for an item to be selected.
virtual bool IsType(const KICAD_T aScanTypes[])
Function IsType Checks whether the item is one of the listed types.
Definition: base_struct.h:294
int AddItemsToSel(const TOOL_EVENT &aEvent)
void select(EDA_ITEM *aItem)
Function select() Takes necessary action mark an item as selected.
LIB_PART * GetCurPart()
Return the current part being edited or NULL if none selected.
void UpdateAll()
Function UpdateAll() Runs update handlers for the menu and its submenus.
#define CANDIDATE
flag indicating that the structure is connected
Definition: base_struct.h:130
static TOOL_ACTION removeItemsFromSel
Definition: ee_actions.h:66
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:587
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:142
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.
Definition: viewlib_frame.h:42
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:137
void SetIsHover(bool aIsHover)
Definition: selection.h:64
virtual void Add(EDA_ITEM *aItem)
Definition: selection.h:74
static TOOL_ACTION leaveSheet
Definition: ee_actions.h:177
void ClearBrightened()
Definition: base_struct.h:245
static TOOL_ACTION removeItemFromSel
Definition: ee_actions.h:62
void Append(EDA_ITEM *item)
Function Append adds an item to the end of the list.
Definition: collector.h:132
void SetAdditive(bool aAdditive)
bool m_MenuCancelled
Definition: collector.h:71
EE_SELECTION & GetSelection()
Function GetSelection()
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:340
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:113
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
#define SELECTED
Definition: base_struct.h:127
int SelectNode(const TOOL_EVENT &aEvent)
Select node under cursor
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.h:243
int GetUnit() const
Definition: lib_item.h:301
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:265
SCH_SHEET * g_RootSheet
Definition: eeschema.cpp:47
static TOOL_ACTION addItemToSel
Selects an item (specified as the event parameter).
Definition: ee_actions.h:61
SCH_SHEET_PATH * g_CurrentSheet
With the new connectivity algorithm, many more places than before want to know what the current sheet...
void SetSelected()
Definition: base_struct.h:239
void SetHighlight(bool aEnabled, int aNetcode=-1, bool aHighlightItems=false)
Function SetHighlight Turns on/off highlighting - it may be done for the active layer,...
Definition: painter.h:141
static TOOL_ACTION drawWire
Definition: ee_actions.h:81
static TOOL_ACTION placeSheetPin
Definition: ee_actions.h:92
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagates an event to tools that requested events of matching type(s).
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
Definition: base_struct.h:642
static TOOL_ACTION explicitCrossProbe
Definition: ee_actions.h:186
void MarkConnections(SCH_LINE *aSegment)
Add all wires and junctions connected to aSegment which are not connected any component pin to aItemL...
Definition: sch_screen.cpp:306
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:149
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:68
bool Contains(const Vec &aPoint) const
Function Contains.
Definition: box2.h:149
Class 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.
void Collect(EDA_ITEM *aItem, 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.
Define a library symbol object.
#define BRIGHTENED
item is drawn with a bright contour
Definition: base_struct.h:143
EDA_ITEM * GetParent() const
Definition: base_struct.h:220
static SEARCH_RESULT IterateForward(EDA_ITEM *listStart, INSPECTOR inspector, void *testData, const KICAD_T scanTypes[])
Function IterateForward walks through the object tree calling the inspector() on each object type req...
Definition: base_struct.h:418
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:199
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:48
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet.h:75
static TOOL_ACTION importSheetPin
Definition: ee_actions.h:93
static TOOL_ACTION clearSelection
Clears the current selection.
Definition: ee_actions.h:58
std::unique_ptr< LIB_PART > & GetPartRef()
static TOOL_ACTION updateMenu
Definition: actions.h:158
static SELECTION_CONDITION SingleMultiUnitSymbol
virtual KIGFX::VIEW_ITEM * GetItem(unsigned int aIdx) const override
Definition: selection.h:103
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:304
#define _(s)
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:119
static bool IsDrawingBus(const SELECTION &aSelection)
static TOOL_ACTION drawBus
Definition: ee_actions.h:82
wxString m_MenuTitle
Definition: collector.h:70
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:209
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:98
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:88
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 GetSettings 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:300
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:86
int AddItemToSel(const TOOL_EVENT &aEvent)
bool ToolStackIsEmpty()
boost::ptr_vector< SCH_SHEET_PIN > SCH_SHEET_PINS
Definition: sch_sheet.h:203
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.
EDA_UNITS_T GetUserUnits() const
Return the user units currently in use.
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
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:161
static TOOL_ACTION selectionMenu
Runs a selection menu to select from a list of items.
Definition: ee_actions.h:69
size_t i
Definition: json11.cpp:649
#define ENDPOINT
ends. (Used to support dragging.)
Definition: base_struct.h:126
static SELECTION_CONDITION OnlyType(KICAD_T aType)
Function OnlyType 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.
Class EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
static const KICAD_T AllItems[]
Definition: ee_collectors.h:42
int Size() const
Returns the number of selected parts.
Definition: selection.h:125
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:73
virtual wxString GetSelectMenuText(EDA_UNITS_T aUnits) const
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
static TOOL_ACTION selectNode
Select the junction, wire or bus segment under the cursor.
Definition: ee_actions.h:51
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:163
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:79
static TOOL_ACTION enterSheet
Definition: ee_actions.h:176
boost::optional< T > OPT
Definition: optional.h:7
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:266
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Sets the item visibility.
Definition: view.cpp:1486
Class SELECTION_AREA.
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:612
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
Class VIEW.
Definition: view.h:61
EDA_ITEM * SelectPoint(const VECTOR2I &aWhere, const KICAD_T *aFilterList=EE_COLLECTOR::AllItems, bool *aSelectionCancelledFlag=NULL, bool aCheckLocked=false, bool aAdd=false, bool aSubtract=false, bool aExclusiveOr=false)
Function selectPoint() Selects an item pointed by the parameter aWhere.
static TOOL_ACTION placeGlobalLabel
Definition: ee_actions.h:89
static TOOL_ACTION finishBus
Definition: ee_actions.h:99
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:154
void ShowContextMenu(SELECTION &aSelection)
Function ShowContextMenu.
Definition: tool_menu.cpp:59
bool GetDragSelects() const
Indicates that a drag should draw a selection rectangle, even when started over an item.
static TOOL_ACTION finishWire
Definition: ee_actions.h:98
void unhighlight(EDA_ITEM *aItem, int aHighlightMode, EE_SELECTION *aGroup=nullptr)
Function unhighlight() Unhighlights the item visually.
VECTOR2D GetCursorPosition() const
Returns the current cursor position in world coordinates.
EDA_ITEM * Front() const
Definition: selection.h:182
KICAD_T Type() const
Function Type()
Definition: base_struct.h:210
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:114
#define min(a, b)
Definition: auxiliary.h:85
int Main(const TOOL_EVENT &aEvent)
Function Main()
#define STARTPOINT
When a line is selected, these flags indicate which.
Definition: base_struct.h:125
void DisplayTitle(bool aDisplay=true)
Function DisplayTitle() Decides whether a title for a pop up menu should be displayed.
Definition: action_menu.cpp:97
SCH_ITEM * GetDrawItems() const
Definition: sch_screen.h:152
virtual void Remove(EDA_ITEM *aItem)
Definition: selection.h:85
wxPoint GetEndPoint() const
Definition: sch_line.h:102