KiCad PCB EDA Suite
pl_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 <bitmaps.h>
27 #include <view/view.h>
28 #include <view/view_controls.h>
30 #include <pl_editor_frame.h>
31 #include <tool/tool_event.h>
32 #include <tool/tool_manager.h>
33 #include <tool/selection.h>
34 #include <tools/pl_actions.h>
35 #include <ws_data_model.h>
36 #include <ws_draw_item.h>
37 #include <collector.h>
38 #include "pl_selection_tool.h"
39 #include <math/util.h> // for KiROUND
40 
45 #define MAX_SELECT_ITEM_IDS 40
46 
47 
48 SELECTION_CONDITION PL_CONDITIONS::Idle = [] (const SELECTION& aSelection )
49 {
50  return ( !aSelection.Front() || aSelection.Front()->GetEditFlags() == 0 );
51 };
52 
53 
54 #define HITTEST_THRESHOLD_PIXELS 3
55 
56 
58  TOOL_INTERACTIVE( "plEditor.InteractiveSelection" ),
59  m_frame( nullptr ),
60  m_additive( false ),
61  m_subtractive( false ),
62  m_exclusive_or( false ),
63  m_multiple( false ),
64  m_skip_heuristics( false )
65 {
66 }
67 
68 
70 {
71  m_frame = getEditFrame<PL_EDITOR_FRAME>();
72 
73  auto& menu = m_menu.GetMenu();
74 
75  menu.AddSeparator( 200 );
76  menu.AddItem( PL_ACTIONS::drawLine, PL_CONDITIONS::Idle, 250 );
77  menu.AddItem( PL_ACTIONS::drawRectangle, PL_CONDITIONS::Idle, 250 );
78  menu.AddItem( PL_ACTIONS::placeText, PL_CONDITIONS::Idle, 250 );
79  menu.AddItem( PL_ACTIONS::placeImage, PL_CONDITIONS::Idle, 250 );
81 
82  menu.AddSeparator( 1000 );
84 
85  return true;
86 }
87 
88 
90 {
91  if( aReason == MODEL_RELOAD )
92  m_frame = getEditFrame<PL_EDITOR_FRAME>();
93 }
94 
95 
97 {
98  ACTION_MENU* actionMenu = aEvent.Parameter<ACTION_MENU*>();
99  CONDITIONAL_MENU* conditionalMenu = dynamic_cast<CONDITIONAL_MENU*>( actionMenu );
100 
101  if( conditionalMenu )
102  conditionalMenu->Evaluate( m_selection );
103 
104  if( actionMenu )
105  actionMenu->UpdateAll();
106 
107  return 0;
108 }
109 
110 
112 {
113  // Main loop: keep receiving events
114  while( TOOL_EVENT* evt = Wait() )
115  {
116  if( m_frame->ToolStackIsEmpty() )
117  m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
118 
120 
121  if( evt->Modifier( MD_SHIFT ) && evt->Modifier( MD_CTRL ) )
122  m_subtractive = true;
123  else if( evt->Modifier( MD_SHIFT ) )
124  m_additive = true;
125  else if( evt->Modifier( MD_CTRL ) )
126  m_exclusive_or = true;
127 
128  // Is the user requesting that the selection list include all possible
129  // items without removing less likely selection candidates
130  m_skip_heuristics = !!evt->Modifier( MD_ALT );
131 
132  // Single click? Select single object
133  if( evt->IsClick( BUT_LEFT ) )
134  {
135  SelectPoint( evt->Position());
136  }
137 
138  // right click? if there is any object - show the context menu
139  else if( evt->IsClick( BUT_RIGHT ) )
140  {
141  bool selectionCancelled = false;
142 
143  if( m_selection.Empty() )
144  {
145  SelectPoint( evt->Position(), &selectionCancelled );
146  m_selection.SetIsHover( true );
147  }
148 
149  if( !selectionCancelled )
151  }
152 
153  // double click? Display the properties window
154  else if( evt->IsDblClick( BUT_LEFT ) )
155  {
156  // No double-click actions currently defined
157  }
158 
159  // drag with LMB? Select multiple objects (or at least draw a selection box) or drag them
160  else if( evt->IsDrag( BUT_LEFT ) )
161  {
163  {
164  selectMultiple();
165  }
166  else
167  {
168  // Check if dragging has started within any of selected items bounding box
169  if( selectionContains( evt->Position() ) )
170  {
171  // Yes -> run the move tool and wait till it finishes
172  m_toolMgr->InvokeTool( "plEditor.InteractiveEdit" );
173  }
174  else
175  {
176  // No -> clear the selection list
177  ClearSelection();
178  }
179  }
180  }
181 
182  // Middle double click? Do zoom to fit or zoom to objects
183  else if( evt->IsDblClick( BUT_MIDDLE ) )
184  {
186  }
187 
188  else if( evt->IsCancelInteractive() )
189  {
190  ClearSelection();
191  }
192 
193  else if( evt->Action() == TA_UNDO_REDO_PRE )
194  {
195  ClearSelection();
196  }
197 
198  else
199  evt->SetPassEvent();
200  }
201 
202  return 0;
203 }
204 
205 
207 {
208  return m_selection;
209 }
210 
211 
212 void PL_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, bool* aSelectionCancelledFlag )
213 {
214  int threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
215 
216  // locate items.
217  COLLECTOR collector;
218 
219  for( WS_DATA_ITEM* dataItem : WS_DATA_MODEL::GetTheInstance().GetItems() )
220  {
221  for( WS_DRAW_ITEM_BASE* drawItem : dataItem->GetDrawItems() )
222  {
223  if( drawItem->HitTest( (wxPoint) aWhere, threshold ) )
224  collector.Append( drawItem );
225  }
226  }
227 
229 
230  // Apply some ugly heuristics to avoid disambiguation menus whenever possible
231  if( collector.GetCount() > 1 && !m_skip_heuristics )
232  {
233  guessSelectionCandidates( collector, aWhere );
234  }
235 
236  // If still more than one item we're going to have to ask the user.
237  if( collector.GetCount() > 1 )
238  {
239  collector.m_MenuTitle = _( "Clarify Selection" );
240 
241  // Must call selectionMenu via RunAction() to avoid event-loop contention
242  m_toolMgr->RunAction( PL_ACTIONS::selectionMenu, true, &collector );
243 
244  if( collector.m_MenuCancelled )
245  {
246  if( aSelectionCancelledFlag )
247  *aSelectionCancelledFlag = true;
248 
249  return;
250  }
251  }
252 
254  ClearSelection();
255 
256  bool anyAdded = false;
257  bool anySubtracted = false;
258 
259  if( collector.GetCount() > 0 )
260  {
261  for( int i = 0; i < collector.GetCount(); ++i )
262  {
263  if( m_subtractive || ( m_exclusive_or && collector[i]->IsSelected() ) )
264  {
265  unselect( collector[i] );
266  anySubtracted = true;
267  }
268  else
269  {
270  select( collector[i] );
271  anyAdded = true;
272  }
273  }
274  }
275 
276  if( anyAdded )
278 
279  if( anySubtracted )
281 }
282 
283 
285 {
286  // There are certain conditions that can be handled automatically.
287 
288  // Prefer an exact hit to a sloppy one
289  for( int i = 0; collector.GetCount() == 2 && i < 2; ++i )
290  {
291  EDA_ITEM* item = collector[ i ];
292  EDA_ITEM* other = collector[ ( i + 1 ) % 2 ];
293 
294  if( item->HitTest( (wxPoint) aPos, 0 ) && !other->HitTest( (wxPoint) aPos, 0 ) )
295  collector.Transfer( other );
296  }
297 }
298 
299 
301 {
302  // If nothing is selected do a hover selection
303  if( m_selection.Empty() )
304  {
305  VECTOR2D cursorPos = getViewControls()->GetCursorPosition( true );
306 
307  ClearSelection();
308  SelectPoint( cursorPos );
309  m_selection.SetIsHover( true );
310  }
311 
312  return m_selection;
313 }
314 
315 
317 {
318  bool cancelled = false; // Was the tool cancelled while it was running?
319  m_multiple = true; // Multiple selection mode is active
320  KIGFX::VIEW* view = getView();
321 
323  view->Add( &area );
324 
325  while( TOOL_EVENT* evt = Wait() )
326  {
327  if( evt->IsCancelInteractive() || evt->IsActivate() )
328  {
329  cancelled = true;
330  break;
331  }
332 
333  if( evt->IsDrag( BUT_LEFT ) )
334  {
336  ClearSelection();
337 
338  // Start drawing a selection box
339  area.SetOrigin( evt->DragOrigin() );
340  area.SetEnd( evt->Position() );
341  area.SetAdditive( m_additive );
344 
345  view->SetVisible( &area, true );
346  view->Update( &area );
347  getViewControls()->SetAutoPan( true );
348  }
349 
350  if( evt->IsMouseUp( BUT_LEFT ) )
351  {
352  getViewControls()->SetAutoPan( false );
353 
354  // End drawing the selection box
355  view->SetVisible( &area, false );
356 
357  int width = area.GetEnd().x - area.GetOrigin().x;
358  int height = area.GetEnd().y - area.GetOrigin().y;
359 
360  /* Selection mode depends on direction of drag-selection:
361  * Left > Right : Select objects that are fully enclosed by selection
362  * Right > Left : Select objects that are crossed by selection
363  */
364  bool windowSelection = width >= 0 ? true : false;
365  bool anyAdded = false;
366  bool anySubtracted = false;
367 
368  // Construct an EDA_RECT to determine EDA_ITEM selection
369  EDA_RECT selectionRect( (wxPoint)area.GetOrigin(), wxSize( width, height ) );
370 
371  selectionRect.Normalize();
372 
373  for( WS_DATA_ITEM* dataItem : WS_DATA_MODEL::GetTheInstance().GetItems() )
374  {
375  for( WS_DRAW_ITEM_BASE* item : dataItem->GetDrawItems() )
376  {
377  if( item->HitTest( selectionRect, windowSelection ) )
378  {
379  if( m_subtractive || ( m_exclusive_or && item->IsSelected() ) )
380  {
381  unselect( item );
382  anySubtracted = true;
383  }
384  else
385  {
386  select( item );
387  anyAdded = true;
388  }
389  }
390  }
391  }
392 
393  // Inform other potentially interested tools
394  if( anyAdded )
396 
397  if( anySubtracted )
399 
400  break; // Stop waiting for events
401  }
402  }
403 
404  getViewControls()->SetAutoPan( false );
405 
406  // Stop drawing the selection box
407  view->Remove( &area );
408  m_multiple = false; // Multiple selection mode is inactive
409 
410  if( !cancelled )
412 
413  return cancelled;
414 }
415 
416 
418 {
419  AddItemToSel( aEvent.Parameter<EDA_ITEM*>() );
420  return 0;
421 }
422 
423 
424 void PL_SELECTION_TOOL::AddItemToSel( EDA_ITEM* aItem, bool aQuietMode )
425 {
426  if( aItem )
427  {
428  select( aItem );
429 
430  // Inform other potentially interested tools
431  if( !aQuietMode )
433  }
434 }
435 
436 
438 {
439  AddItemsToSel( aEvent.Parameter<EDA_ITEMS*>(), false );
440  return 0;
441 }
442 
443 
444 void PL_SELECTION_TOOL::AddItemsToSel( EDA_ITEMS* aList, bool aQuietMode )
445 {
446  if( aList )
447  {
448  for( EDA_ITEM* item : *aList )
449  select( item );
450 
451  // Inform other potentially interested tools
452  if( !aQuietMode )
454  }
455 }
456 
457 
459 {
460  RemoveItemFromSel( aEvent.Parameter<EDA_ITEM*>() );
461  return 0;
462 }
463 
464 
465 void PL_SELECTION_TOOL::RemoveItemFromSel( EDA_ITEM* aItem, bool aQuietMode )
466 {
467  if( aItem )
468  {
469  unselect( aItem );
470 
471  // Inform other potentially interested tools
472  if( !aQuietMode )
474  }
475 }
476 
477 
479 {
480  RemoveItemsFromSel( aEvent.Parameter<EDA_ITEMS*>(), false );
481  return 0;
482 }
483 
484 
485 void PL_SELECTION_TOOL::RemoveItemsFromSel( EDA_ITEMS* aList, bool aQuietMode )
486 {
487  if( aList )
488  {
489  for( EDA_ITEM* item : *aList )
490  unselect( item );
491 
492  // Inform other potentially interested tools
493  if( !aQuietMode )
495  }
496 }
497 
498 
500 {
501  highlight( aItem, BRIGHTENED );
502 }
503 
504 
506 {
507  unhighlight( aItem, BRIGHTENED );
508 }
509 
510 
512 {
513  ClearSelection();
514  return 0;
515 }
516 
517 
519 {
520  m_selection.Clear();
521 
522  for( WS_DATA_ITEM* dataItem : WS_DATA_MODEL::GetTheInstance().GetItems() )
523  {
524  for( WS_DRAW_ITEM_BASE* item : dataItem->GetDrawItems() )
525  {
526  if( item->IsSelected() )
527  select( item );
528  }
529  }
530 }
531 
532 
534 {
535  COLLECTOR* collector = aEvent.Parameter<COLLECTOR*>();
536 
537  if( !doSelectionMenu( collector ) )
538  collector->m_MenuCancelled = true;
539 
540  return 0;
541 }
542 
543 
545 {
546  EDA_ITEM* current = nullptr;
547  ACTION_MENU menu( true );
548 
549  // ID limit is `MAX_SELECT_ITEM_IDS+1` because the last item is "select all"
550  // and the first item has ID of 1.
551  int limit = std::min( MAX_SELECT_ITEM_IDS + 1, aCollector->GetCount() );
552 
553  for( int i = 0; i < limit; ++i )
554  {
555  wxString text;
556  EDA_ITEM* item = ( *aCollector )[i];
557  text = item->GetSelectMenuText( m_frame->GetUserUnits() );
558 
559  wxString menuText = wxString::Format( "&%d. %s\t%d", i + 1, text, i + 1 );
560  menu.Add( menuText, i + 1, item->GetMenuImage() );
561  }
562 
563  menu.AppendSeparator();
564  menu.Add( _( "Select &All\tA" ), limit + 1, net_highlight_xpm );
565 
566  if( aCollector->m_MenuTitle.Length() )
567  menu.SetTitle( aCollector->m_MenuTitle );
568 
569  menu.SetIcon( info_xpm );
570  menu.DisplayTitle( true );
571  SetContextMenu( &menu, CMENU_NOW );
572 
573  bool selectAll = false;
574 
575  while( TOOL_EVENT* evt = Wait() )
576  {
577  if( evt->Action() == TA_CHOICE_MENU_UPDATE )
578  {
579  if( selectAll )
580  {
581  for( int i = 0; i < aCollector->GetCount(); ++i )
582  unhighlight( ( *aCollector )[i], BRIGHTENED );
583  }
584  else if( current )
585  {
586  unhighlight( current, BRIGHTENED );
587  }
588 
589  int id = *evt->GetCommandId();
590 
591  // User has pointed an item, so show it in a different way
592  if( id > 0 && id <= limit )
593  {
594  current = ( *aCollector )[id - 1];
595  highlight( current, BRIGHTENED );
596  }
597  else
598  {
599  current = nullptr;
600  }
601 
602  if( id == limit + 1 )
603  {
604  for( int i = 0; i < aCollector->GetCount(); ++i )
605  highlight( ( *aCollector )[i], BRIGHTENED );
606 
607  selectAll = true;
608  }
609  else
610  {
611  selectAll = false;
612  }
613  }
614  else if( evt->Action() == TA_CHOICE_MENU_CHOICE )
615  {
616  if( selectAll )
617  {
618  for( int i = 0; i < aCollector->GetCount(); ++i )
619  unhighlight( ( *aCollector )[i], BRIGHTENED );
620  }
621  else if( current )
622  {
623  unhighlight( current, BRIGHTENED );
624  }
625 
626  OPT<int> id = evt->GetCommandId();
627 
628  // User has selected an item, so this one will be returned
629  if( id == limit + 1 )
630  {
631  selectAll = true;
632  current = nullptr;
633  }
634  else if( id && ( *id > 0 ) && ( *id <= limit ) )
635  {
636  selectAll = false;
637  current = ( *aCollector )[*id - 1];
638  }
639  else
640  {
641  selectAll = false;
642  current = nullptr;
643  }
644  }
645  else if( evt->Action() == TA_CHOICE_MENU_CLOSED )
646  {
647  break;
648  }
649 
650  getView()->UpdateItems();
651  m_frame->GetCanvas()->Refresh();
652  }
653 
654  if( selectAll )
655  {
656  return true;
657  }
658  else if( current )
659  {
660  unhighlight( current, BRIGHTENED );
661 
662  getView()->UpdateItems();
663  m_frame->GetCanvas()->Refresh();
664 
665  aCollector->Empty();
666  aCollector->Append( current );
667  return true;
668  }
669 
670  return false;
671 }
672 
673 
675 {
676  if( m_selection.Empty() )
677  return;
678 
679  while( m_selection.GetSize() )
681 
682  getView()->Update( &m_selection );
683 
684  m_selection.SetIsHover( false );
686 
687  // Inform other potentially interested tools
689 }
690 
691 
693 {
694  highlight( aItem, SELECTED, &m_selection );
695 }
696 
697 
699 {
700  unhighlight( aItem, SELECTED, &m_selection );
701 }
702 
703 
704 void PL_SELECTION_TOOL::highlight( EDA_ITEM* aItem, int aMode, PL_SELECTION* aGroup )
705 {
706  if( aMode == SELECTED )
707  aItem->SetSelected();
708  else if( aMode == BRIGHTENED )
709  aItem->SetBrightened();
710 
711  if( aGroup )
712  aGroup->Add( aItem );
713 
714  getView()->Update( aItem );
715 }
716 
717 
718 void PL_SELECTION_TOOL::unhighlight( EDA_ITEM* aItem, int aMode, PL_SELECTION* aGroup )
719 {
720  if( aMode == SELECTED )
721  aItem->ClearSelected();
722  else if( aMode == BRIGHTENED )
723  aItem->ClearBrightened();
724 
725  if( aGroup )
726  aGroup->Remove( aItem );
727 
728  getView()->Update( aItem );
729 }
730 
731 
733 {
734  const unsigned GRIP_MARGIN = 20;
735  VECTOR2I margin = getView()->ToWorld( VECTOR2I( GRIP_MARGIN, GRIP_MARGIN ), false );
736 
737  // Check if the point is located within any of the currently selected items bounding boxes
738  for( auto item : m_selection )
739  {
740  BOX2I itemBox = item->ViewBBox();
741  itemBox.Inflate( margin.x, margin.y ); // Give some margin for gripping an item
742 
743  if( itemBox.Contains( aPoint ) )
744  return true;
745  }
746 
747  return false;
748 }
749 
750 
752 {
754 
757 
763 }
764 
765 
void Empty()
Function Empty sets the list to empty.
Definition: collector.h:110
void ClearReferencePoint()
Definition: selection.h:250
void AddStandardSubMenus(TOOL_MENU &aMenu)
Function CreateBasicMenu.
wxMenuItem * Add(const wxString &aLabel, int aId, const BITMAP_OPAQUE *aIcon)
Adds a wxWidgets-style entry to the menu.
#define MAX_SELECT_ITEM_IDS
The maximum number of items in the clarify selection context menu.
static const TOOL_EVENT SelectedEvent
Definition: actions.h:206
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
COLLECTOR class definition.
virtual void Clear() override
Function Clear() Removes all the stored items from the group.
Definition: selection.h:95
void RebuildSelection()
Rebuild the selection from the flags in the view items.
int RemoveItemFromSel(const TOOL_EVENT &aEvent)
PL_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
TOOL_EVENT * Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Function Wait()
Work sheet structure type definitions.
Definition: ws_data_item.h:93
Model changes (required full reload)
Definition: tool_base.h:82
static const TOOL_EVENT UnselectedEvent
Definition: actions.h:207
Defines the structure of a menu based on ACTIONs.
Definition: action_menu.h:43
VECTOR2D ToWorld(const VECTOR2D &aCoord, bool aAbsolute=true) const
Function ToWorld() Converts a screen space point/vector to a point/vector in world space coordinates.
Definition: view.cpp:474
void SetOrigin(VECTOR2I aOrigin)
Set the origin of the rectange (the fixed corner)
static TOOL_ACTION drawLine
Definition: pl_actions.h:67
void ClearSelected()
Definition: base_struct.h:211
static TOOL_ACTION addItemsToSel
Selects a list of items (specified as the event parameter)
Definition: pl_actions.h:56
void SetCurrentCursor(wxStockCursor aStockCursorID)
Function SetCurrentCursor Set the current cursor shape for this panel.
VIEW_CONTROLS class definition.
int UpdateMenu(const TOOL_EVENT &aEvent)
static TOOL_ACTION placeImage
Definition: pl_actions.h:65
void BrightenItem(EDA_ITEM *aItem)
CONDITIONAL_MENU & GetMenu()
Function GetMenu.
Definition: tool_menu.cpp:46
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:219
virtual void Remove(VIEW_ITEM *aItem)
Function Remove() Removes a VIEW_ITEM from the view.
Definition: view.cpp:375
void SetBrightened()
Definition: base_struct.h:209
static SELECTION_CONDITION Idle
static TOOL_ACTION zoomFitScreen
Definition: actions.h:94
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:140
void SetExclusiveOr(bool aExclusiveOr)
void select(EDA_ITEM *aItem)
Function select() Takes necessary action mark an item as selected.
void UpdateAll()
Runs update handlers for the menu and its submenus.
static TOOL_ACTION placeText
Definition: pl_actions.h:64
void SetContextMenu(ACTION_MENU *aMenu, CONTEXT_MENU_TRIGGER aTrigger=CMENU_BUTTON)
Function SetContextMenu()
void SelectPoint(const VECTOR2I &aWhere, bool *aSelectionCancelledFlag=nullptr)
Function selectPoint() Selects an item pointed by the parameter aWhere.
const BITMAP_OPAQUE net_highlight_xpm[1]
PL_EDITOR_FRAME * m_frame
VECTOR2< int > VECTOR2I
Definition: vector2d.h:594
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Function Go()
int AddItemToSel(const TOOL_EVENT &aEvent)
bool InvokeTool(TOOL_ID aToolId)
Function InvokeTool() Calls a tool by sending a tool activation event to tool of given ID.
PL_SELECTION & GetSelection()
Function GetSelection()
void SetIsHover(bool aIsHover)
Definition: selection.h:66
virtual void Add(EDA_ITEM *aItem)
Definition: selection.h:76
static WS_DATA_MODEL & GetTheInstance()
static function: returns the instance of WS_DATA_MODEL used in the application
void ClearBrightened()
Definition: base_struct.h:212
void Append(EDA_ITEM *item)
Function Append adds an item to the end of the list.
Definition: collector.h:120
void SetAdditive(bool aAdditive)
bool m_MenuCancelled
Definition: collector.h:70
virtual bool HitTest(const wxPoint &aPosition, int aAccuracy=0) const
Function HitTest tests if aPosition is contained within or on the bounding box of an item.
Definition: base_struct.h:307
static TOOL_ACTION selectionActivate
Activation of the selection tool.
Definition: pl_actions.h:46
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:101
#define SELECTED
Definition: base_struct.h:124
static TOOL_ACTION addItemToSel
Selects an item (specified as the event parameter).
Definition: pl_actions.h:52
void Transfer(int aIndex)
Moves the item at aIndex (first position is 0) to the backup list.
Definition: collector.h:174
static TOOL_ACTION removeItemsFromSel
Definition: pl_actions.h:57
bool doSelectionMenu(COLLECTOR *aItems)
Allows the selection of a single item from a list via pop-up menu.
bool selectionContains(const VECTOR2I &aPoint) const
Function selectionContains()
void SetSelected()
Definition: base_struct.h:208
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagates an event to tools that requested events of matching type(s).
void unselect(EDA_ITEM *aItem)
Function unselect() Takes necessary action mark an item as unselected.
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
Definition: base_struct.h:588
int RemoveItemsFromSel(const TOOL_EVENT &aEvent)
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:435
void SetIcon(const BITMAP_OPAQUE *aIcon)
Assigns an icon for the entry.
Definition: action_menu.cpp:71
bool Contains(const Vec &aPoint) const
Function Contains.
Definition: box2.h:151
TOOL_EVENT.
Definition: tool_event.h:171
void guessSelectionCandidates(COLLECTOR &collector, const VECTOR2I &aWhere)
Apply heuristics to try and determine a single object when multiple are found under the cursor.
int SelectionMenu(const TOOL_EVENT &aEvent)
Function SelectionMenu() Shows a popup menu to trim the COLLECTOR passed as aEvent's parameter down t...
static TOOL_ACTION selectionMenu
Runs a selection menu to select from a list of items.
Definition: pl_actions.h:60
bool ToolStackIsEmpty()
Definition: tools_holder.h:117
#define BRIGHTENED
item is drawn with a bright contour
Definition: base_struct.h:139
static const TOOL_EVENT ClearedEvent
Definition: actions.h:208
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:1412
static TOOL_ACTION drawRectangle
Definition: pl_actions.h:66
static TOOL_ACTION updateMenu
Definition: actions.h:165
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:1531
const BITMAP_OPAQUE info_xpm[1]
Definition: info.cpp:75
KIGFX::VIEW * getView() const
Function getView()
Definition: tool_base.cpp:36
virtual void SetAutoPan(bool aEnabled)
Function SetAutoPan Turns on/off auto panning (this feature is used when there is a tool active (eg.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:121
static TOOL_ACTION clearSelection
Clears the current selection.
Definition: pl_actions.h:49
wxString m_MenuTitle
Definition: collector.h:69
void SetSubtractive(bool aSubtractive)
void AddSeparator(int aOrder=ANY_ORDER)
Adds a separator to the menu.
virtual unsigned int GetSize() const override
Function GetSize() Returns the number of stored items.
Definition: selection.h:100
void Normalize()
Function Normalize ensures that the height ant width are positive.
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
static TOOL_ACTION removeItemFromSel
Definition: pl_actions.h:53
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:302
PL_SELECTION m_selection
int Main(const TOOL_EVENT &aEvent)
Function Main()
void SetTitle(const wxString &aTitle) override
Sets title for the menu.
Definition: action_menu.cpp:89
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
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:201
#define _(s)
Definition: 3d_actions.cpp:33
virtual wxString GetSelectMenuText(EDA_UNITS aUnits) const
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
void UnbrightenItem(EDA_ITEM *aItem)
EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:68
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:159
COLLECTOR is an abstract class that will find and hold all the objects according to an inspection don...
Definition: collector.h:55
static TOOL_ACTION appendImportedWorksheet
Definition: pl_actions.h:68
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:79
void highlight(EDA_ITEM *aItem, int aHighlightMode, PL_SELECTION *aGroup=nullptr)
Function highlight() Highlights the item visually.
boost::optional< T > OPT
Definition: optional.h:7
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Sets the item visibility.
Definition: view.cpp:1477
void unhighlight(EDA_ITEM *aItem, int aHighlightMode, PL_SELECTION *aGroup=nullptr)
Function unhighlight() Unhighlights the item visually.
void setTransitions() override
Sets up handlers for various events.
int AddItemsToSel(const TOOL_EVENT &aEvent)
bool selectMultiple()
Function selectMultiple() Handles drawing a selection box that allows one to select many items at the...
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:345
KIGFX::VIEW_CONTROLS * getViewControls() const
Function getViewControls()
Definition: tool_base.cpp:42
VIEW.
Definition: view.h:61
#define HITTEST_THRESHOLD_PIXELS
virtual BITMAP_DEF GetMenuImage() const
Function GetMenuImage returns a pointer to an image to be used in menus.
void ShowContextMenu(SELECTION &aSelection)
Function ShowContextMenu.
Definition: tool_menu.cpp:59
PL_SELECTION & RequestSelection()
Function RequestSelection()
EDA_UNITS GetUserUnits() const
Return the user units currently in use.
VECTOR2D GetCursorPosition() const
Returns the current cursor position in world coordinates.
EDA_ITEM * Front() const
Definition: selection.h:184
void DisplayTitle(bool aDisplay=true)
Decides whether a title for a pop up menu should be displayed.
virtual void Remove(EDA_ITEM *aItem)
Definition: selection.h:87