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