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) 2021 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 <tool/tool_event.h>
31 #include <tool/tool_manager.h>
32 #include <tool/selection.h>
33 #include <tools/pl_point_editor.h>
35 #include <tools/pl_actions.h>
39 #include <collector.h>
40 #include <math/util.h> // for KiROUND
41 
42 #include "pl_editor_frame.h"
43 
48 #define MAX_SELECT_ITEM_IDS 40
49 #define HITTEST_THRESHOLD_PIXELS 3
50 
51 
53  TOOL_INTERACTIVE( "plEditor.InteractiveSelection" ),
54  m_frame( nullptr )
55 {
56 }
57 
58 
60 {
61  m_frame = getEditFrame<PL_EDITOR_FRAME>();
62 
63  auto& menu = m_menu.GetMenu();
64 
65  menu.AddSeparator( 200 );
70 
71  menu.AddSeparator( 1000 );
73 
74  m_disambiguateTimer.SetOwner( this );
75  Connect( wxEVT_TIMER, wxTimerEventHandler( PL_SELECTION_TOOL::onDisambiguationExpire ), nullptr, this );
76 
77  return true;
78 }
79 
80 
82 {
83  if( aReason == MODEL_RELOAD )
84  m_frame = getEditFrame<PL_EDITOR_FRAME>();
85 }
86 
87 
89 {
90  ACTION_MENU* actionMenu = aEvent.Parameter<ACTION_MENU*>();
91  CONDITIONAL_MENU* conditionalMenu = dynamic_cast<CONDITIONAL_MENU*>( actionMenu );
92 
93  if( conditionalMenu )
94  conditionalMenu->Evaluate( m_selection );
95 
96  if( actionMenu )
97  actionMenu->UpdateAll();
98 
99  return 0;
100 }
101 
102 
104 {
105  // Main loop: keep receiving events
106  while( TOOL_EVENT* evt = Wait() )
107  {
108  // on left click, a selection is made, depending on modifiers ALT, SHIFT, CTRL:
109  setModifiersState( evt->Modifier( MD_SHIFT ), evt->Modifier( MD_CTRL ),
110  evt->Modifier( MD_ALT ) );
111 
112  bool modifier_enabled = m_subtractive || m_additive || m_exclusive_or;
113 
114  if( evt->IsMouseDown( BUT_LEFT ) )
115  {
116  // Avoid triggering when running under other tools
118 
119  if( m_frame->ToolStackIsEmpty() && pt_tool && !pt_tool->HasPoint() )
120  {
122  m_disambiguateTimer.StartOnce( 500 );
123  }
124  }
125  // Single click? Select single object
126  else if( evt->IsClick( BUT_LEFT ) )
127  {
128  // If the timer has stopped, then we have already run the disambiguate routine
129  // and we don't want to register an extra click here
130  if( !m_disambiguateTimer.IsRunning() )
131  {
132  evt->SetPassEvent();
133  continue;
134  }
135 
136  m_disambiguateTimer.Stop();
137  SelectPoint( evt->Position() );
138  }
139 
140  // right click? if there is any object - show the context menu
141  else if( evt->IsClick( BUT_RIGHT ) )
142  {
143  m_disambiguateTimer.Stop();
144  bool selectionCancelled = false;
145 
146  if( m_selection.Empty() )
147  {
148  SelectPoint( evt->Position(), &selectionCancelled );
149  m_selection.SetIsHover( true );
150  }
151 
152  if( !selectionCancelled )
154  }
155 
156  // double click? Display the properties window
157  else if( evt->IsDblClick( BUT_LEFT ) )
158  {
159  // No double-click actions currently defined
160  }
161 
162  // drag with LMB? Select multiple objects (or at least draw a selection box) or drag them
163  else if( evt->IsDrag( BUT_LEFT ) )
164  {
165  m_disambiguateTimer.Stop();
166 
167  if( modifier_enabled || m_selection.Empty() )
168  {
169  selectMultiple();
170  }
171  else
172  {
173  // Check if dragging has started within any of selected items bounding box
174  if( selectionContains( evt->Position() ) )
175  {
176  // Yes -> run the move tool and wait till it finishes
177  m_toolMgr->RunAction( "plEditor.InteractiveMove.move", true );
178  }
179  else
180  {
181  // No -> clear the selection list
182  ClearSelection();
183  }
184  }
185  }
186 
187  // Middle double click? Do zoom to fit or zoom to objects
188  else if( evt->IsDblClick( BUT_MIDDLE ) )
189  {
191  }
192 
193  else if( evt->IsCancelInteractive() )
194  {
195  m_disambiguateTimer.Stop();
196  ClearSelection();
197  }
198 
199  else if( evt->Action() == TA_UNDO_REDO_PRE )
200  {
201  ClearSelection();
202  }
203 
204  else
205  evt->SetPassEvent();
206 
207 
208  if( m_frame->ToolStackIsEmpty() )
209  {
210  if( !modifier_enabled
211  && !m_selection.Empty()
213  && evt->HasPosition()
214  && selectionContains( evt->Position() ) )
215  {
217  }
218  else
219  {
220  if( m_additive )
222  else if( m_subtractive )
224  else if( m_exclusive_or )
226  else
228  }
229  }
230  }
231 
232  return 0;
233 }
234 
235 
237 {
238  wxMouseState keyboardState = wxGetMouseState();
239 
240  setModifiersState( keyboardState.ShiftDown(), keyboardState.ControlDown(),
241  keyboardState.AltDown() );
242 
243  m_skip_heuristics = true;
245  m_skip_heuristics = false;
246 
247  return 0;
248 }
249 
250 
251 void PL_SELECTION_TOOL::onDisambiguationExpire( wxTimerEvent& aEvent )
252 {
254 }
255 
256 
258 {
259  return m_selection;
260 }
261 
262 
263 void PL_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, bool* aSelectionCancelledFlag )
264 {
265  int threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
266 
267  // locate items.
268  COLLECTOR collector;
269 
270  for( DS_DATA_ITEM* dataItem : DS_DATA_MODEL::GetTheInstance().GetItems() )
271  {
272  for( DS_DRAW_ITEM_BASE* drawItem : dataItem->GetDrawItems() )
273  {
274  if( drawItem->HitTest( (wxPoint) aWhere, threshold ) )
275  collector.Append( drawItem );
276  }
277  }
278 
280 
281  // Apply some ugly heuristics to avoid disambiguation menus whenever possible
282  if( collector.GetCount() > 1 && !m_skip_heuristics )
283  {
284  guessSelectionCandidates( collector, aWhere );
285  }
286 
287  // If still more than one item we're going to have to ask the user.
288  if( collector.GetCount() > 1 )
289  {
290  doSelectionMenu( &collector );
291 
292  if( collector.m_MenuCancelled )
293  {
294  if( aSelectionCancelledFlag )
295  *aSelectionCancelledFlag = true;
296 
297  return;
298  }
299  }
300 
301  bool anyAdded = false;
302  bool anySubtracted = false;
303 
304 
306  {
307  if( collector.GetCount() == 0 )
308  anySubtracted = true;
309 
310  ClearSelection();
311  }
312 
313  if( collector.GetCount() > 0 )
314  {
315  for( int i = 0; i < collector.GetCount(); ++i )
316  {
317  if( m_subtractive || ( m_exclusive_or && collector[i]->IsSelected() ) )
318  {
319  unselect( collector[i] );
320  anySubtracted = true;
321  }
322  else
323  {
324  select( collector[i] );
325  anyAdded = true;
326  }
327  }
328  }
329 
330  if( anyAdded )
332 
333  if( anySubtracted )
335 }
336 
337 
339 {
340  // There are certain conditions that can be handled automatically.
341 
342  // Prefer an exact hit to a sloppy one
343  for( int i = 0; collector.GetCount() == 2 && i < 2; ++i )
344  {
345  EDA_ITEM* item = collector[ i ];
346  EDA_ITEM* other = collector[ ( i + 1 ) % 2 ];
347 
348  if( item->HitTest( (wxPoint) aPos, 0 ) && !other->HitTest( (wxPoint) aPos, 0 ) )
349  collector.Transfer( other );
350  }
351 }
352 
353 
355 {
356  // If nothing is selected do a hover selection
357  if( m_selection.Empty() )
358  {
359  VECTOR2D cursorPos = getViewControls()->GetCursorPosition( true );
360 
361  ClearSelection();
362  SelectPoint( cursorPos );
363  m_selection.SetIsHover( true );
364  }
365 
366  return m_selection;
367 }
368 
369 
371 {
372  bool cancelled = false; // Was the tool cancelled while it was running?
373  m_multiple = true; // Multiple selection mode is active
374  KIGFX::VIEW* view = getView();
375 
377  view->Add( &area );
378 
379  while( TOOL_EVENT* evt = Wait() )
380  {
381  int width = area.GetEnd().x - area.GetOrigin().x;
382 
383  /* Selection mode depends on direction of drag-selection:
384  * Left > Right : Select objects that are fully enclosed by selection
385  * Right > Left : Select objects that are crossed by selection
386  */
387  bool windowSelection = width >= 0 ? true : false;
388 
390  windowSelection ? KICURSOR::SELECT_WINDOW : KICURSOR::SELECT_LASSO );
391 
392  if( evt->IsCancelInteractive() || evt->IsActivate() )
393  {
394  cancelled = true;
395  break;
396  }
397 
398  if( evt->IsDrag( BUT_LEFT ) )
399  {
401  ClearSelection();
402 
403  // Start drawing a selection box
404  area.SetOrigin( evt->DragOrigin() );
405  area.SetEnd( evt->Position() );
408  area.SetExclusiveOr( false );
409 
410  view->SetVisible( &area, true );
411  view->Update( &area );
412  getViewControls()->SetAutoPan( true );
413  }
414 
415  if( evt->IsMouseUp( BUT_LEFT ) )
416  {
417  getViewControls()->SetAutoPan( false );
418 
419  // End drawing the selection box
420  view->SetVisible( &area, false );
421 
422  int height = area.GetEnd().y - area.GetOrigin().y;
423 
424  bool anyAdded = false;
425  bool anySubtracted = false;
426 
427  // Construct an EDA_RECT to determine EDA_ITEM selection
428  EDA_RECT selectionRect( (wxPoint)area.GetOrigin(), wxSize( width, height ) );
429 
430  selectionRect.Normalize();
431 
432  for( DS_DATA_ITEM* dataItem : DS_DATA_MODEL::GetTheInstance().GetItems() )
433  {
434  for( DS_DRAW_ITEM_BASE* item : dataItem->GetDrawItems() )
435  {
436  if( item->HitTest( selectionRect, windowSelection ) )
437  {
438  if( m_subtractive || ( m_exclusive_or && item->IsSelected() ) )
439  {
440  unselect( item );
441  anySubtracted = true;
442  }
443  else
444  {
445  select( item );
446  anyAdded = true;
447  }
448  }
449  }
450  }
451 
452  // Inform other potentially interested tools
453  if( anyAdded )
455 
456  if( anySubtracted )
458 
459  break; // Stop waiting for events
460  }
461  }
462 
463  getViewControls()->SetAutoPan( false );
464 
465  // Stop drawing the selection box
466  view->Remove( &area );
467  m_multiple = false; // Multiple selection mode is inactive
468 
469  if( !cancelled )
471 
472  return cancelled;
473 }
474 
475 
477 {
478  AddItemToSel( aEvent.Parameter<EDA_ITEM*>() );
479  return 0;
480 }
481 
482 
483 void PL_SELECTION_TOOL::AddItemToSel( EDA_ITEM* aItem, bool aQuietMode )
484 {
485  if( aItem )
486  {
487  select( aItem );
488 
489  // Inform other potentially interested tools
490  if( !aQuietMode )
492  }
493 }
494 
495 
497 {
498  AddItemsToSel( aEvent.Parameter<EDA_ITEMS*>(), false );
499  return 0;
500 }
501 
502 
503 void PL_SELECTION_TOOL::AddItemsToSel( EDA_ITEMS* aList, bool aQuietMode )
504 {
505  if( aList )
506  {
507  for( EDA_ITEM* item : *aList )
508  select( item );
509 
510  // Inform other potentially interested tools
511  if( !aQuietMode )
513  }
514 }
515 
516 
518 {
519  RemoveItemFromSel( aEvent.Parameter<EDA_ITEM*>() );
520  return 0;
521 }
522 
523 
524 void PL_SELECTION_TOOL::RemoveItemFromSel( EDA_ITEM* aItem, bool aQuietMode )
525 {
526  if( aItem )
527  {
528  unselect( aItem );
529 
530  // Inform other potentially interested tools
531  if( !aQuietMode )
533  }
534 }
535 
536 
538 {
539  RemoveItemsFromSel( aEvent.Parameter<EDA_ITEMS*>(), false );
540  return 0;
541 }
542 
543 
544 void PL_SELECTION_TOOL::RemoveItemsFromSel( EDA_ITEMS* aList, bool aQuietMode )
545 {
546  if( aList )
547  {
548  for( EDA_ITEM* item : *aList )
549  unselect( item );
550 
551  // Inform other potentially interested tools
552  if( !aQuietMode )
554  }
555 }
556 
557 
559 {
560  highlight( aItem, BRIGHTENED );
561 }
562 
563 
565 {
566  unhighlight( aItem, BRIGHTENED );
567 }
568 
569 
571 {
572  ClearSelection();
573  return 0;
574 }
575 
576 
578 {
579  m_selection.Clear();
580 
581  for( DS_DATA_ITEM* dataItem : DS_DATA_MODEL::GetTheInstance().GetItems() )
582  {
583  for( DS_DRAW_ITEM_BASE* item : dataItem->GetDrawItems() )
584  {
585  if( item->IsSelected() )
586  select( item );
587  }
588  }
589 }
590 
591 
593 {
594  COLLECTOR* collector = aEvent.Parameter<COLLECTOR*>();
595 
596  if( !doSelectionMenu( collector ) )
597  collector->m_MenuCancelled = true;
598 
599  return 0;
600 }
601 
602 
604 {
605  EDA_ITEM* current = nullptr;
606  ACTION_MENU menu( true );
607 
608  // ID limit is `MAX_SELECT_ITEM_IDS+1` because the last item is "select all"
609  // and the first item has ID of 1.
610  int limit = std::min( MAX_SELECT_ITEM_IDS + 1, aCollector->GetCount() );
611 
612  for( int i = 0; i < limit; ++i )
613  {
614  wxString text;
615  EDA_ITEM* item = ( *aCollector )[i];
617 
618  wxString menuText = wxString::Format( "&%d. %s\t%d", i + 1, text, i + 1 );
619  menu.Add( menuText, i + 1, item->GetMenuImage() );
620  }
621 
622  menu.AppendSeparator();
623  menu.Add( _( "Select &All\tA" ), limit + 1, BITMAPS::INVALID_BITMAP );
624 
625  if( aCollector->m_MenuTitle.Length() )
626  {
627  menu.SetTitle( aCollector->m_MenuTitle );
628  menu.SetIcon( BITMAPS::info );
629  menu.DisplayTitle( true );
630  }
631  else
632  {
633  menu.DisplayTitle( false );
634  }
635 
636  SetContextMenu( &menu, CMENU_NOW );
637 
638  bool selectAll = false;
639 
640  while( TOOL_EVENT* evt = Wait() )
641  {
642  if( evt->Action() == TA_CHOICE_MENU_UPDATE )
643  {
644  if( selectAll )
645  {
646  for( int i = 0; i < aCollector->GetCount(); ++i )
647  unhighlight( ( *aCollector )[i], BRIGHTENED );
648  }
649  else if( current )
650  {
651  unhighlight( current, BRIGHTENED );
652  }
653 
654  int id = *evt->GetCommandId();
655 
656  // User has pointed an item, so show it in a different way
657  if( id > 0 && id <= limit )
658  {
659  current = ( *aCollector )[id - 1];
660  highlight( current, BRIGHTENED );
661  }
662  else
663  {
664  current = nullptr;
665  }
666 
667  if( id == limit + 1 )
668  {
669  for( int i = 0; i < aCollector->GetCount(); ++i )
670  highlight( ( *aCollector )[i], BRIGHTENED );
671 
672  selectAll = true;
673  }
674  else
675  {
676  selectAll = false;
677  }
678  }
679  else if( evt->Action() == TA_CHOICE_MENU_CHOICE )
680  {
681  if( selectAll )
682  {
683  for( int i = 0; i < aCollector->GetCount(); ++i )
684  unhighlight( ( *aCollector )[i], BRIGHTENED );
685  }
686  else if( current )
687  {
688  unhighlight( current, BRIGHTENED );
689  }
690 
691  OPT<int> id = evt->GetCommandId();
692 
693  // User has selected an item, so this one will be returned
694  if( id == limit + 1 )
695  {
696  selectAll = true;
697  current = nullptr;
698  }
699  else if( id && ( *id > 0 ) && ( *id <= limit ) )
700  {
701  selectAll = false;
702  current = ( *aCollector )[*id - 1];
703  }
704  else
705  {
706  selectAll = false;
707  current = nullptr;
708  }
709  }
710  else if( evt->Action() == TA_CHOICE_MENU_CLOSED )
711  {
712  break;
713  }
714 
715  getView()->UpdateItems();
716  m_frame->GetCanvas()->Refresh();
717  }
718 
719  if( selectAll )
720  {
721  return true;
722  }
723  else if( current )
724  {
725  unhighlight( current, BRIGHTENED );
726 
727  getView()->UpdateItems();
728  m_frame->GetCanvas()->Refresh();
729 
730  aCollector->Empty();
731  aCollector->Append( current );
732  return true;
733  }
734 
735  return false;
736 }
737 
738 
740 {
741  if( m_selection.Empty() )
742  return;
743 
744  while( m_selection.GetSize() )
746 
747  getView()->Update( &m_selection );
748 
749  m_selection.SetIsHover( false );
751 
752  // Inform other potentially interested tools
754 }
755 
756 
758 {
759  highlight( aItem, SELECTED, &m_selection );
760 }
761 
762 
764 {
765  unhighlight( aItem, SELECTED, &m_selection );
766 }
767 
768 
769 void PL_SELECTION_TOOL::highlight( EDA_ITEM* aItem, int aMode, PL_SELECTION* aGroup )
770 {
771  if( aMode == SELECTED )
772  aItem->SetSelected();
773  else if( aMode == BRIGHTENED )
774  aItem->SetBrightened();
775 
776  if( aGroup )
777  aGroup->Add( aItem );
778 
779  getView()->Update( aItem );
780 }
781 
782 
783 void PL_SELECTION_TOOL::unhighlight( EDA_ITEM* aItem, int aMode, PL_SELECTION* aGroup )
784 {
785  if( aMode == SELECTED )
786  aItem->ClearSelected();
787  else if( aMode == BRIGHTENED )
788  aItem->ClearBrightened();
789 
790  if( aGroup )
791  aGroup->Remove( aItem );
792 
793  getView()->Update( aItem );
794 }
795 
796 
798 {
799  const unsigned GRIP_MARGIN = 20;
800  VECTOR2I margin = getView()->ToWorld( VECTOR2I( GRIP_MARGIN, GRIP_MARGIN ), false );
801 
802  // Check if the point is located within any of the currently selected items bounding boxes
803  for( auto item : m_selection )
804  {
805  BOX2I itemBox = item->ViewBBox();
806  itemBox.Inflate( margin.x, margin.y ); // Give some margin for gripping an item
807 
808  if( itemBox.Contains( aPoint ) )
809  return true;
810  }
811 
812  return false;
813 }
814 
815 
817 {
819 
822 
828 
830 }
void Empty()
Clear the list.
Definition: collector.h:90
void SetEnd(const VECTOR2I &aEnd)
Set the current end of the rectangle (the corner that moves with the cursor.
void ClearReferencePoint()
Definition: selection.h:197
void AddStandardSubMenus(TOOL_MENU &aMenu)
Construct a "basic" menu for a tool, containing only items that apply to all tools (e....
#define MAX_SELECT_ITEM_IDS
The maximum number of items in the clarify selection context menu.
static const TOOL_EVENT SelectedEvent
Definition: actions.h:200
TOOL_MENU m_menu
The functions below are not yet implemented - their interface may change.
virtual void Clear() override
Remove all the stored items from the group.
Definition: selection.h:83
void RebuildSelection()
Rebuild the selection from the flags in the view items.
int RemoveItemFromSel(const TOOL_EVENT &aEvent)
void SetCurrentCursor(KICURSOR aCursor)
Set the current cursor shape for this panel.
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))
Suspend execution of the tool until an event specified in aEventList arrives.
Model changes (required full reload)
Definition: tool_base.h:80
static const TOOL_EVENT UnselectedEvent
Definition: actions.h:201
Defines the structure of a menu based on ACTIONs.
Definition: action_menu.h:48
VECTOR2D ToWorld(const VECTOR2D &aCoord, bool aAbsolute=true) const
Converts a screen space point/vector to a point/vector in world space coordinates.
Definition: view.cpp:449
virtual void Add(EDA_ITEM *aItem)
Definition: selection.cpp:32
static const TOOL_EVENT DisambiguatePoint
Definition: actions.h:215
void SetIcon(BITMAPS aIcon)
Assign an icon for the entry.
Definition: action_menu.cpp:73
static TOOL_ACTION drawLine
Definition: pl_actions.h:61
void ClearSelected()
Definition: eda_item.h:131
static TOOL_ACTION addItemsToSel
Select a list of items (specified as the event parameter)
Definition: pl_actions.h:50
int UpdateMenu(const TOOL_EVENT &aEvent)
VECTOR2D GetMousePosition() const
static TOOL_ACTION placeImage
Definition: pl_actions.h:59
void BrightenItem(EDA_ITEM *aItem)
CONDITIONAL_MENU & GetMenu()
Definition: tool_menu.cpp:46
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:214
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp:350
void SetBrightened()
Definition: eda_item.h:129
static TOOL_ACTION zoomFitScreen
Definition: actions.h:96
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:143
void SetExclusiveOr(bool aExclusiveOr)
void select(EDA_ITEM *aItem)
Takes necessary action mark an item as selected.
void UpdateAll()
Run update handlers for the menu and its submenus.
static TOOL_ACTION placeText
Definition: pl_actions.h:58
void SetContextMenu(ACTION_MENU *aMenu, CONTEXT_MENU_TRIGGER aTrigger=CMENU_BUTTON)
Assign a context menu and tells when it should be activated.
void SelectPoint(const VECTOR2I &aWhere, bool *aSelectionCancelledFlag=nullptr)
Select an item pointed by the parameter aWhere.
PL_EDITOR_FRAME * m_frame
VECTOR2< int > VECTOR2I
Definition: vector2d.h:622
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Define which state (aStateFunc) to go when a certain event arrives (aConditions).
int AddItemToSel(const TOOL_EVENT &aEvent)
PL_SELECTION & GetSelection()
Return the set of currently selected items.
void SetIsHover(bool aIsHover)
Definition: selection.h:69
void setModifiersState(bool aShiftState, bool aCtrlState, bool aAltState)
Set the configuration of m_additive, m_subtractive, m_exclusive_or, m_skip_heuristics from the state ...
void ClearBrightened()
Definition: eda_item.h:132
void Append(EDA_ITEM *item)
Add an item to the end of the list.
Definition: collector.h:100
void SetAdditive(bool aAdditive)
bool m_MenuCancelled
Definition: collector.h:244
virtual bool HitTest(const wxPoint &aPosition, int aAccuracy=0) const
Test if aPosition is inside or on the boundary of this item.
Definition: eda_item.h:224
Base class to handle basic graphic items.
Definition: ds_draw_item.h:58
static TOOL_ACTION selectionActivate
Activation of the selection tool.
Definition: pl_actions.h:40
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:82
static TOOL_ACTION addItemToSel
Select an item (specified as the event parameter).
Definition: pl_actions.h:46
void SetOrigin(const VECTOR2I &aOrigin)
void Transfer(int aIndex)
Move the item at aIndex (first position is 0) to the backup list.
Definition: collector.h:152
static TOOL_ACTION removeItemsFromSel
Definition: pl_actions.h:51
bool HasPoint()
Indicate the cursor is over an edit point.
static DS_DATA_MODEL & GetTheInstance()
static function: returns the instance of DS_DATA_MODEL used in the application
bool doSelectionMenu(COLLECTOR *aItems)
Allow the selection of a single item from a list via pop-up menu.
bool selectionContains(const VECTOR2I &aPoint) const
Set up handlers for various events.
MOUSE_DRAG_ACTION GetDragAction() const
Indicates whether a drag should draw a selection rectangle or drag selected (or unselected) objects.
Definition: tools_holder.h:135
void SetSelected()
Definition: eda_item.h:128
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagate an event to tools that requested events of matching type(s).
void unselect(EDA_ITEM *aItem)
Take necessary action mark an item as unselected.
int RemoveItemsFromSel(const TOOL_EVENT &aEvent)
T Parameter() const
Return a non-standard parameter assigned to the event.
Definition: tool_event.h:432
bool Contains(const Vec &aPoint) const
Definition: box2.h:134
Generic, UI-independent tool event.
Definition: tool_event.h:152
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)
Shows a popup menu to trim the COLLECTOR passed as aEvent's parameter down to a single item.
static TOOL_ACTION selectionMenu
Run a selection menu to select from a list of items.
Definition: pl_actions.h:54
bool ToolStackIsEmpty()
Definition: tools_holder.h:116
#define _(s)
static const TOOL_EVENT ClearedEvent
Selected item had a property changed (except movement)
Definition: actions.h:202
#define SELECTED
void UpdateItems()
Iterate through the list of items that asked for updating and updates them.
Definition: view.cpp:1402
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
Definition: eda_item.h:506
static TOOL_ACTION drawRectangle
Definition: pl_actions.h:60
wxTimer m_disambiguateTimer
static TOOL_ACTION updateMenu
Definition: actions.h:167
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
virtual void SetAutoPan(bool aEnabled)
Turn on/off auto panning (this feature is used when there is a tool active (eg.
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:98
static TOOL_ACTION clearSelection
Clear the current selection.
Definition: pl_actions.h:43
wxString m_MenuTitle
Definition: collector.h:243
void SetSubtractive(bool aSubtractive)
void AddSeparator(int aOrder=ANY_ORDER)
Add a separator to the menu.
virtual unsigned int GetSize() const override
Return the number of stored items.
Definition: selection.h:88
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
void Normalize()
Ensures that the height ant width are positive.
Definition: eda_rect.cpp:35
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
static TOOL_ACTION removeItemFromSel
Definition: pl_actions.h:47
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:281
PL_SELECTION m_selection
int Main(const TOOL_EVENT &aEvent)
The main loop.
void SetTitle(const wxString &aTitle) override
Set title for the menu.
Definition: action_menu.cpp:87
bool Init() override
Init() is called once upon a registration of the tool.
Drawing sheet structure type definitions.
Definition: ds_data_item.h:95
virtual wxString GetSelectMenuText(EDA_UNITS aUnits) const
Return the text to display to be used in the selection clarification context menu when multiple items...
Definition: eda_item.cpp:109
void UnbrightenItem(EDA_ITEM *aItem)
virtual BITMAPS GetMenuImage() const
Return a pointer to an image to be used in menus.
Definition: eda_item.cpp:274
virtual void Remove(EDA_ITEM *aItem)
Definition: selection.cpp:44
wxMenuItem * Add(const wxString &aLabel, int aId, BITMAPS aIcon)
Add a wxWidgets-style entry to the menu.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
Handle the component boundary box.
Definition: eda_rect.h:42
static bool Empty(const SELECTION &aSelection)
Test if there are no items selected.
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:73
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:99
An abstract class that will find and hold all the objects according to an inspection done by the Insp...
Definition: collector.h:48
RESET_REASON
Determine the reason of reset for a tool.
Definition: tool_base.h:77
void highlight(EDA_ITEM *aItem, int aHighlightMode, PL_SELECTION *aGroup=nullptr)
Highlight the item visually.
boost::optional< T > OPT
Definition: optional.h:7
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Set the item visibility.
Definition: view.cpp:1516
void unhighlight(EDA_ITEM *aItem, int aHighlightMode, PL_SELECTION *aGroup=nullptr)
Unhighlight the item visually.
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
Represent a selection area (currently a rectangle) in a VIEW, drawn corner-to-corner between two poin...
int AddItemsToSel(const TOOL_EVENT &aEvent)
VECTOR2I m_originalCursor
bool selectMultiple()
Handle drawing a selection box that allows one to select many items at the same time.
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:320
int disambiguateCursor(const TOOL_EVENT &aEvent)
Handle disambiguation actions including displaying the menu.
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:42
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:68
#define HITTEST_THRESHOLD_PIXELS
void onDisambiguationExpire(wxTimerEvent &aEvent)
Start the process to show our disambiguation menu once the user has kept the mouse down for the minim...
void ShowContextMenu(SELECTION &aSelection)
Helper function to set and immediately show a CONDITIONAL_MENU in concert with the given SELECTION.
Definition: tool_menu.cpp:59
PL_SELECTION & RequestSelection()
Return either an existing selection (filtered), or the selection at the current cursor if the existin...
EDA_UNITS GetUserUnits() const
Return the user units currently in use.
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
EDA_ITEM * Front() const
Definition: selection.h:145
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition: view.cpp:1570
Tool that displays edit points allowing to modify items by dragging the points.
#define BRIGHTENED
item is drawn with a bright contour
void DisplayTitle(bool aDisplay=true)
Decide whether a title for a pop up menu should be displayed.
Definition: action_menu.cpp:98