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  m_skip_heuristics = true;
240  m_skip_heuristics = false;
241 
242  return 0;
243 }
244 
245 
246 void PL_SELECTION_TOOL::onDisambiguationExpire( wxTimerEvent& aEvent )
247 {
249 }
250 
251 
253 {
254  return m_selection;
255 }
256 
257 
258 void PL_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, bool* aSelectionCancelledFlag )
259 {
260  int threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
261 
262  // locate items.
263  COLLECTOR collector;
264 
265  for( DS_DATA_ITEM* dataItem : DS_DATA_MODEL::GetTheInstance().GetItems() )
266  {
267  for( DS_DRAW_ITEM_BASE* drawItem : dataItem->GetDrawItems() )
268  {
269  if( drawItem->HitTest( (wxPoint) aWhere, threshold ) )
270  collector.Append( drawItem );
271  }
272  }
273 
275 
276  // Apply some ugly heuristics to avoid disambiguation menus whenever possible
277  if( collector.GetCount() > 1 && !m_skip_heuristics )
278  {
279  guessSelectionCandidates( collector, aWhere );
280  }
281 
282  // If still more than one item we're going to have to ask the user.
283  if( collector.GetCount() > 1 )
284  {
285  doSelectionMenu( &collector );
286 
287  if( collector.m_MenuCancelled )
288  {
289  if( aSelectionCancelledFlag )
290  *aSelectionCancelledFlag = true;
291 
292  return;
293  }
294  }
295 
296  bool anyAdded = false;
297  bool anySubtracted = false;
298 
299 
301  {
302  if( collector.GetCount() == 0 )
303  anySubtracted = true;
304 
305  ClearSelection();
306  }
307 
308  if( collector.GetCount() > 0 )
309  {
310  for( int i = 0; i < collector.GetCount(); ++i )
311  {
312  if( m_subtractive || ( m_exclusive_or && collector[i]->IsSelected() ) )
313  {
314  unselect( collector[i] );
315  anySubtracted = true;
316  }
317  else
318  {
319  select( collector[i] );
320  anyAdded = true;
321  }
322  }
323  }
324 
325  if( anyAdded )
327 
328  if( anySubtracted )
330 }
331 
332 
334 {
335  // There are certain conditions that can be handled automatically.
336 
337  // Prefer an exact hit to a sloppy one
338  for( int i = 0; collector.GetCount() == 2 && i < 2; ++i )
339  {
340  EDA_ITEM* item = collector[ i ];
341  EDA_ITEM* other = collector[ ( i + 1 ) % 2 ];
342 
343  if( item->HitTest( (wxPoint) aPos, 0 ) && !other->HitTest( (wxPoint) aPos, 0 ) )
344  collector.Transfer( other );
345  }
346 }
347 
348 
350 {
351  // If nothing is selected do a hover selection
352  if( m_selection.Empty() )
353  {
354  VECTOR2D cursorPos = getViewControls()->GetCursorPosition( true );
355 
356  ClearSelection();
357  SelectPoint( cursorPos );
358  m_selection.SetIsHover( true );
359  }
360 
361  return m_selection;
362 }
363 
364 
366 {
367  bool cancelled = false; // Was the tool cancelled while it was running?
368  m_multiple = true; // Multiple selection mode is active
369  KIGFX::VIEW* view = getView();
370 
372  view->Add( &area );
373 
374  while( TOOL_EVENT* evt = Wait() )
375  {
376  int width = area.GetEnd().x - area.GetOrigin().x;
377 
378  /* Selection mode depends on direction of drag-selection:
379  * Left > Right : Select objects that are fully enclosed by selection
380  * Right > Left : Select objects that are crossed by selection
381  */
382  bool windowSelection = width >= 0 ? true : false;
383 
385  windowSelection ? KICURSOR::SELECT_WINDOW : KICURSOR::SELECT_LASSO );
386 
387  if( evt->IsCancelInteractive() || evt->IsActivate() )
388  {
389  cancelled = true;
390  break;
391  }
392 
393  if( evt->IsDrag( BUT_LEFT ) )
394  {
396  ClearSelection();
397 
398  // Start drawing a selection box
399  area.SetOrigin( evt->DragOrigin() );
400  area.SetEnd( evt->Position() );
403  area.SetExclusiveOr( false );
404 
405  view->SetVisible( &area, true );
406  view->Update( &area );
407  getViewControls()->SetAutoPan( true );
408  }
409 
410  if( evt->IsMouseUp( BUT_LEFT ) )
411  {
412  getViewControls()->SetAutoPan( false );
413 
414  // End drawing the selection box
415  view->SetVisible( &area, false );
416 
417  int height = area.GetEnd().y - area.GetOrigin().y;
418 
419  bool anyAdded = false;
420  bool anySubtracted = false;
421 
422  // Construct an EDA_RECT to determine EDA_ITEM selection
423  EDA_RECT selectionRect( (wxPoint)area.GetOrigin(), wxSize( width, height ) );
424 
425  selectionRect.Normalize();
426 
427  for( DS_DATA_ITEM* dataItem : DS_DATA_MODEL::GetTheInstance().GetItems() )
428  {
429  for( DS_DRAW_ITEM_BASE* item : dataItem->GetDrawItems() )
430  {
431  if( item->HitTest( selectionRect, windowSelection ) )
432  {
433  if( m_subtractive || ( m_exclusive_or && item->IsSelected() ) )
434  {
435  unselect( item );
436  anySubtracted = true;
437  }
438  else
439  {
440  select( item );
441  anyAdded = true;
442  }
443  }
444  }
445  }
446 
447  // Inform other potentially interested tools
448  if( anyAdded )
450 
451  if( anySubtracted )
453 
454  break; // Stop waiting for events
455  }
456  }
457 
458  getViewControls()->SetAutoPan( false );
459 
460  // Stop drawing the selection box
461  view->Remove( &area );
462  m_multiple = false; // Multiple selection mode is inactive
463 
464  if( !cancelled )
466 
467  return cancelled;
468 }
469 
470 
472 {
473  AddItemToSel( aEvent.Parameter<EDA_ITEM*>() );
474  return 0;
475 }
476 
477 
478 void PL_SELECTION_TOOL::AddItemToSel( EDA_ITEM* aItem, bool aQuietMode )
479 {
480  if( aItem )
481  {
482  select( aItem );
483 
484  // Inform other potentially interested tools
485  if( !aQuietMode )
487  }
488 }
489 
490 
492 {
493  AddItemsToSel( aEvent.Parameter<EDA_ITEMS*>(), false );
494  return 0;
495 }
496 
497 
498 void PL_SELECTION_TOOL::AddItemsToSel( EDA_ITEMS* aList, bool aQuietMode )
499 {
500  if( aList )
501  {
502  for( EDA_ITEM* item : *aList )
503  select( item );
504 
505  // Inform other potentially interested tools
506  if( !aQuietMode )
508  }
509 }
510 
511 
513 {
514  RemoveItemFromSel( aEvent.Parameter<EDA_ITEM*>() );
515  return 0;
516 }
517 
518 
519 void PL_SELECTION_TOOL::RemoveItemFromSel( EDA_ITEM* aItem, bool aQuietMode )
520 {
521  if( aItem )
522  {
523  unselect( aItem );
524 
525  // Inform other potentially interested tools
526  if( !aQuietMode )
528  }
529 }
530 
531 
533 {
534  RemoveItemsFromSel( aEvent.Parameter<EDA_ITEMS*>(), false );
535  return 0;
536 }
537 
538 
539 void PL_SELECTION_TOOL::RemoveItemsFromSel( EDA_ITEMS* aList, bool aQuietMode )
540 {
541  if( aList )
542  {
543  for( EDA_ITEM* item : *aList )
544  unselect( item );
545 
546  // Inform other potentially interested tools
547  if( !aQuietMode )
549  }
550 }
551 
552 
554 {
555  highlight( aItem, BRIGHTENED );
556 }
557 
558 
560 {
561  unhighlight( aItem, BRIGHTENED );
562 }
563 
564 
566 {
567  ClearSelection();
568  return 0;
569 }
570 
571 
573 {
574  m_selection.Clear();
575 
576  for( DS_DATA_ITEM* dataItem : DS_DATA_MODEL::GetTheInstance().GetItems() )
577  {
578  for( DS_DRAW_ITEM_BASE* item : dataItem->GetDrawItems() )
579  {
580  if( item->IsSelected() )
581  select( item );
582  }
583  }
584 }
585 
586 
588 {
589  COLLECTOR* collector = aEvent.Parameter<COLLECTOR*>();
590 
591  if( !doSelectionMenu( collector ) )
592  collector->m_MenuCancelled = true;
593 
594  return 0;
595 }
596 
597 
599 {
600  EDA_ITEM* current = nullptr;
601  ACTION_MENU menu( true );
602 
603  // ID limit is `MAX_SELECT_ITEM_IDS+1` because the last item is "select all"
604  // and the first item has ID of 1.
605  int limit = std::min( MAX_SELECT_ITEM_IDS + 1, aCollector->GetCount() );
606 
607  for( int i = 0; i < limit; ++i )
608  {
609  wxString text;
610  EDA_ITEM* item = ( *aCollector )[i];
612 
613  wxString menuText = wxString::Format( "&%d. %s\t%d", i + 1, text, i + 1 );
614  menu.Add( menuText, i + 1, item->GetMenuImage() );
615  }
616 
617  menu.AppendSeparator();
618  menu.Add( _( "Select &All\tA" ), limit + 1, BITMAPS::INVALID_BITMAP );
619 
620  if( aCollector->m_MenuTitle.Length() )
621  {
622  menu.SetTitle( aCollector->m_MenuTitle );
623  menu.SetIcon( BITMAPS::info );
624  menu.DisplayTitle( true );
625  }
626  else
627  {
628  menu.DisplayTitle( false );
629  }
630 
631  SetContextMenu( &menu, CMENU_NOW );
632 
633  bool selectAll = false;
634 
635  while( TOOL_EVENT* evt = Wait() )
636  {
637  if( evt->Action() == TA_CHOICE_MENU_UPDATE )
638  {
639  if( selectAll )
640  {
641  for( int i = 0; i < aCollector->GetCount(); ++i )
642  unhighlight( ( *aCollector )[i], BRIGHTENED );
643  }
644  else if( current )
645  {
646  unhighlight( current, BRIGHTENED );
647  }
648 
649  int id = *evt->GetCommandId();
650 
651  // User has pointed an item, so show it in a different way
652  if( id > 0 && id <= limit )
653  {
654  current = ( *aCollector )[id - 1];
655  highlight( current, BRIGHTENED );
656  }
657  else
658  {
659  current = nullptr;
660  }
661 
662  if( id == limit + 1 )
663  {
664  for( int i = 0; i < aCollector->GetCount(); ++i )
665  highlight( ( *aCollector )[i], BRIGHTENED );
666 
667  selectAll = true;
668  }
669  else
670  {
671  selectAll = false;
672  }
673  }
674  else if( evt->Action() == TA_CHOICE_MENU_CHOICE )
675  {
676  if( selectAll )
677  {
678  for( int i = 0; i < aCollector->GetCount(); ++i )
679  unhighlight( ( *aCollector )[i], BRIGHTENED );
680  }
681  else if( current )
682  {
683  unhighlight( current, BRIGHTENED );
684  }
685 
686  OPT<int> id = evt->GetCommandId();
687 
688  // User has selected an item, so this one will be returned
689  if( id == limit + 1 )
690  {
691  selectAll = true;
692  current = nullptr;
693  }
694  else if( id && ( *id > 0 ) && ( *id <= limit ) )
695  {
696  selectAll = false;
697  current = ( *aCollector )[*id - 1];
698  }
699  else
700  {
701  selectAll = false;
702  current = nullptr;
703  }
704  }
705  else if( evt->Action() == TA_CHOICE_MENU_CLOSED )
706  {
707  break;
708  }
709 
710  getView()->UpdateItems();
711  m_frame->GetCanvas()->Refresh();
712  }
713 
714  if( selectAll )
715  {
716  return true;
717  }
718  else if( current )
719  {
720  unhighlight( current, BRIGHTENED );
721 
722  getView()->UpdateItems();
723  m_frame->GetCanvas()->Refresh();
724 
725  aCollector->Empty();
726  aCollector->Append( current );
727  return true;
728  }
729 
730  return false;
731 }
732 
733 
735 {
736  if( m_selection.Empty() )
737  return;
738 
739  while( m_selection.GetSize() )
741 
742  getView()->Update( &m_selection );
743 
744  m_selection.SetIsHover( false );
746 
747  // Inform other potentially interested tools
749 }
750 
751 
753 {
754  highlight( aItem, SELECTED, &m_selection );
755 }
756 
757 
759 {
760  unhighlight( aItem, SELECTED, &m_selection );
761 }
762 
763 
764 void PL_SELECTION_TOOL::highlight( EDA_ITEM* aItem, int aMode, PL_SELECTION* aGroup )
765 {
766  if( aMode == SELECTED )
767  aItem->SetSelected();
768  else if( aMode == BRIGHTENED )
769  aItem->SetBrightened();
770 
771  if( aGroup )
772  aGroup->Add( aItem );
773 
774  getView()->Update( aItem );
775 }
776 
777 
778 void PL_SELECTION_TOOL::unhighlight( EDA_ITEM* aItem, int aMode, PL_SELECTION* aGroup )
779 {
780  if( aMode == SELECTED )
781  aItem->ClearSelected();
782  else if( aMode == BRIGHTENED )
783  aItem->ClearBrightened();
784 
785  if( aGroup )
786  aGroup->Remove( aItem );
787 
788  getView()->Update( aItem );
789 }
790 
791 
793 {
794  const unsigned GRIP_MARGIN = 20;
795  VECTOR2I margin = getView()->ToWorld( VECTOR2I( GRIP_MARGIN, GRIP_MARGIN ), false );
796 
797  // Check if the point is located within any of the currently selected items bounding boxes
798  for( auto item : m_selection )
799  {
800  BOX2I itemBox = item->ViewBBox();
801  itemBox.Inflate( margin.x, margin.y ); // Give some margin for gripping an item
802 
803  if( itemBox.Contains( aPoint ) )
804  return true;
805  }
806 
807  return false;
808 }
809 
810 
812 {
814 
817 
823 
825 }
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:192
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:199
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:200
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:447
virtual void Add(EDA_ITEM *aItem)
Definition: selection.cpp:32
static const TOOL_EVENT DisambiguatePoint
Definition: actions.h:214
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:132
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:348
void SetBrightened()
Definition: eda_item.h:130
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:623
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:133
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 contained within or on the bounding box of an item.
Definition: eda_item.h:225
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:129
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:201
#define SELECTED
void UpdateItems()
Iterate through the list of items that asked for updating and updates them.
Definition: view.cpp:1406
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
Definition: eda_item.h:507
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:211
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:100
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:1458
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:318
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:1512
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