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>
36 #include <collector.h>
37 #include <math/util.h> // for KiROUND
38 
39 #include "pl_editor_frame.h"
40 #include "pl_selection_tool.h"
41 #include "tools/pl_actions.h"
42 
47 #define MAX_SELECT_ITEM_IDS 40
48 #define HITTEST_THRESHOLD_PIXELS 3
49 
50 
52  TOOL_INTERACTIVE( "plEditor.InteractiveSelection" ),
53  m_frame( nullptr ),
54  m_additive( false ),
55  m_subtractive( false ),
56  m_exclusive_or( false ),
57  m_multiple( false ),
58  m_skip_heuristics( false )
59 {
60 }
61 
62 
64 {
65  m_frame = getEditFrame<PL_EDITOR_FRAME>();
66 
67  auto& menu = m_menu.GetMenu();
68 
69  menu.AddSeparator( 200 );
74 
75  menu.AddSeparator( 1000 );
77 
78  return true;
79 }
80 
81 
83 {
84  if( aReason == MODEL_RELOAD )
85  m_frame = getEditFrame<PL_EDITOR_FRAME>();
86 }
87 
88 
90 {
91  ACTION_MENU* actionMenu = aEvent.Parameter<ACTION_MENU*>();
92  CONDITIONAL_MENU* conditionalMenu = dynamic_cast<CONDITIONAL_MENU*>( actionMenu );
93 
94  if( conditionalMenu )
95  conditionalMenu->Evaluate( m_selection );
96 
97  if( actionMenu )
98  actionMenu->UpdateAll();
99 
100  return 0;
101 }
102 
103 
105 {
106  // Main loop: keep receiving events
107  while( TOOL_EVENT* evt = Wait() )
108  {
109  // on left click, a selection is made, depending on modifiers ALT, SHIFT, CTRL:
110  // Due to the fact ALT key modifier cannot be useed freely on Winows and Linux,
111  // actions are different on OSX and others OS
112  // Especially, ALT key cannot be used to force showing the full selection choice
113  // context menu (the menu is immediately closed on Windows )
114  //
115  // No modifier = select items and deselect previous selection
116  // ALT (on OSX) = skip heuristic and show full selection choice
117  // ALT (on others) = exclusive OR of selected items (inverse selection)
118  //
119  // CTRL/CMD (on OSX) = exclusive OR of selected items (inverse selection)
120  // CTRL (on others) = skip heuristic and show full selection choice
121  //
122  // SHIFT = add selected items to the current selection
123  //
124  // CTRL/CMD+SHIFT (on OSX) = remove selected items to the current selection
125  // CTRL+SHIFT (on others) = unused (can be used for a new action)
126  //
127  // CTRL/CMT+ALT (on OSX) = unused (can be used for a new action)
128  // CTRL+ALT (on others) = do nothing (same as no modifier)
129  //
130  // SHIFT+ALT (on OSX) = do nothing (same as no modifier)
131  // SHIFT+ALT (on others) = remove selected items to the current selection
132 
133 #ifdef __WXOSX_MAC__
134  m_subtractive = evt->Modifier( MD_CTRL ) &&
135  evt->Modifier( MD_SHIFT ) &&
136  !evt->Modifier( MD_ALT );
137 
138  m_additive = evt->Modifier( MD_SHIFT ) &&
139  !evt->Modifier( MD_CTRL ) &&
140  !evt->Modifier( MD_ALT );
141 
142  m_exclusive_or = evt->Modifier( MD_CTRL ) &&
143  !evt->Modifier( MD_SHIFT ) &&
144  !evt->Modifier( MD_ALT );
145 
146  m_skip_heuristics = evt->Modifier( MD_ALT ) &&
147  !evt->Modifier( MD_SHIFT ) &&
148  !evt->Modifier( MD_CTRL );
149 
150 #else
151  m_subtractive = evt->Modifier( MD_SHIFT )
152  && !evt->Modifier( MD_CTRL )
153  && evt->Modifier( MD_ALT );
154 
155  m_additive = evt->Modifier( MD_SHIFT )
156  && !evt->Modifier( MD_CTRL )
157  && !evt->Modifier( MD_ALT );
158 
159  m_exclusive_or = !evt->Modifier( MD_SHIFT )
160  && !evt->Modifier( MD_CTRL )
161  && evt->Modifier( MD_ALT );
162 
163  // Is the user requesting that the selection list include all possible
164  // items without removing less likely selection candidates
165  // Cannot use the Alt key on windows or the disambiguation context menu is immediately
166  // dismissed rendering it useless.
167  m_skip_heuristics = evt->Modifier( MD_CTRL )
168  && !evt->Modifier( MD_SHIFT )
169  && !evt->Modifier( MD_ALT );
170 #endif
171 
172  bool modifier_enabled = m_subtractive || m_additive || m_exclusive_or;
173 
174  // Single click? Select single object
175  if( evt->IsClick( BUT_LEFT ) )
176  {
177  SelectPoint( evt->Position() );
178  }
179 
180  // right click? if there is any object - show the context menu
181  else if( evt->IsClick( BUT_RIGHT ) )
182  {
183  bool selectionCancelled = false;
184 
185  if( m_selection.Empty() )
186  {
187  SelectPoint( evt->Position(), &selectionCancelled );
188  m_selection.SetIsHover( true );
189  }
190 
191  if( !selectionCancelled )
193  }
194 
195  // double click? Display the properties window
196  else if( evt->IsDblClick( BUT_LEFT ) )
197  {
198  // No double-click actions currently defined
199  }
200 
201  // drag with LMB? Select multiple objects (or at least draw a selection box) or drag them
202  else if( evt->IsDrag( BUT_LEFT ) )
203  {
204  if( modifier_enabled || m_selection.Empty() )
205  {
206  selectMultiple();
207  }
208  else
209  {
210  // Check if dragging has started within any of selected items bounding box
211  if( selectionContains( evt->Position() ) )
212  {
213  // Yes -> run the move tool and wait till it finishes
214  m_toolMgr->RunAction( "plEditor.InteractiveMove.move", true );
215  }
216  else
217  {
218  // No -> clear the selection list
219  ClearSelection();
220  }
221  }
222  }
223 
224  // Middle double click? Do zoom to fit or zoom to objects
225  else if( evt->IsDblClick( BUT_MIDDLE ) )
226  {
228  }
229 
230  else if( evt->IsCancelInteractive() )
231  {
232  ClearSelection();
233  }
234 
235  else if( evt->Action() == TA_UNDO_REDO_PRE )
236  {
237  ClearSelection();
238  }
239 
240  else
241  evt->SetPassEvent();
242 
243 
244  if( m_frame->ToolStackIsEmpty() )
245  {
246  if( !modifier_enabled
247  && !m_selection.Empty()
249  && evt->HasPosition()
250  && selectionContains( evt->Position() ) )
251  {
253  }
254  else
255  {
256  if( m_additive )
258  else if( m_subtractive )
260  else if( m_exclusive_or )
262  else
264  }
265  }
266  }
267 
268  return 0;
269 }
270 
271 
273 {
274  return m_selection;
275 }
276 
277 
278 void PL_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, bool* aSelectionCancelledFlag )
279 {
280  int threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
281 
282  // locate items.
283  COLLECTOR collector;
284 
285  for( DS_DATA_ITEM* dataItem : DS_DATA_MODEL::GetTheInstance().GetItems() )
286  {
287  for( DS_DRAW_ITEM_BASE* drawItem : dataItem->GetDrawItems() )
288  {
289  if( drawItem->HitTest( (wxPoint) aWhere, threshold ) )
290  collector.Append( drawItem );
291  }
292  }
293 
295 
296  // Apply some ugly heuristics to avoid disambiguation menus whenever possible
297  if( collector.GetCount() > 1 && !m_skip_heuristics )
298  {
299  guessSelectionCandidates( collector, aWhere );
300  }
301 
302  // If still more than one item we're going to have to ask the user.
303  if( collector.GetCount() > 1 )
304  {
305  // Must call selectionMenu via RunAction() to avoid event-loop contention
306  m_toolMgr->RunAction( PL_ACTIONS::selectionMenu, true, &collector );
307 
308  if( collector.m_MenuCancelled )
309  {
310  if( aSelectionCancelledFlag )
311  *aSelectionCancelledFlag = true;
312 
313  return;
314  }
315  }
316 
318  ClearSelection();
319 
320  bool anyAdded = false;
321  bool anySubtracted = false;
322 
323  if( collector.GetCount() > 0 )
324  {
325  for( int i = 0; i < collector.GetCount(); ++i )
326  {
327  if( m_subtractive || ( m_exclusive_or && collector[i]->IsSelected() ) )
328  {
329  unselect( collector[i] );
330  anySubtracted = true;
331  }
332  else
333  {
334  select( collector[i] );
335  anyAdded = true;
336  }
337  }
338  }
339 
340  if( anyAdded )
342 
343  if( anySubtracted )
345 }
346 
347 
349 {
350  // There are certain conditions that can be handled automatically.
351 
352  // Prefer an exact hit to a sloppy one
353  for( int i = 0; collector.GetCount() == 2 && i < 2; ++i )
354  {
355  EDA_ITEM* item = collector[ i ];
356  EDA_ITEM* other = collector[ ( i + 1 ) % 2 ];
357 
358  if( item->HitTest( (wxPoint) aPos, 0 ) && !other->HitTest( (wxPoint) aPos, 0 ) )
359  collector.Transfer( other );
360  }
361 }
362 
363 
365 {
366  // If nothing is selected do a hover selection
367  if( m_selection.Empty() )
368  {
369  VECTOR2D cursorPos = getViewControls()->GetCursorPosition( true );
370 
371  ClearSelection();
372  SelectPoint( cursorPos );
373  m_selection.SetIsHover( true );
374  }
375 
376  return m_selection;
377 }
378 
379 
381 {
382  bool cancelled = false; // Was the tool cancelled while it was running?
383  m_multiple = true; // Multiple selection mode is active
384  KIGFX::VIEW* view = getView();
385 
387  view->Add( &area );
388 
389  while( TOOL_EVENT* evt = Wait() )
390  {
391  int width = area.GetEnd().x - area.GetOrigin().x;
392 
393  /* Selection mode depends on direction of drag-selection:
394  * Left > Right : Select objects that are fully enclosed by selection
395  * Right > Left : Select objects that are crossed by selection
396  */
397  bool windowSelection = width >= 0 ? true : false;
398 
400  windowSelection ? KICURSOR::SELECT_WINDOW : KICURSOR::SELECT_LASSO );
401 
402  if( evt->IsCancelInteractive() || evt->IsActivate() )
403  {
404  cancelled = true;
405  break;
406  }
407 
408  if( evt->IsDrag( BUT_LEFT ) )
409  {
411  ClearSelection();
412 
413  // Start drawing a selection box
414  area.SetOrigin( evt->DragOrigin() );
415  area.SetEnd( evt->Position() );
416  area.SetAdditive( m_additive );
419 
420  view->SetVisible( &area, true );
421  view->Update( &area );
422  getViewControls()->SetAutoPan( true );
423  }
424 
425  if( evt->IsMouseUp( BUT_LEFT ) )
426  {
427  getViewControls()->SetAutoPan( false );
428 
429  // End drawing the selection box
430  view->SetVisible( &area, false );
431 
432  int height = area.GetEnd().y - area.GetOrigin().y;
433 
434  bool anyAdded = false;
435  bool anySubtracted = false;
436 
437  // Construct an EDA_RECT to determine EDA_ITEM selection
438  EDA_RECT selectionRect( (wxPoint)area.GetOrigin(), wxSize( width, height ) );
439 
440  selectionRect.Normalize();
441 
442  for( DS_DATA_ITEM* dataItem : DS_DATA_MODEL::GetTheInstance().GetItems() )
443  {
444  for( DS_DRAW_ITEM_BASE* item : dataItem->GetDrawItems() )
445  {
446  if( item->HitTest( selectionRect, windowSelection ) )
447  {
448  if( m_subtractive || ( m_exclusive_or && item->IsSelected() ) )
449  {
450  unselect( item );
451  anySubtracted = true;
452  }
453  else
454  {
455  select( item );
456  anyAdded = true;
457  }
458  }
459  }
460  }
461 
462  // Inform other potentially interested tools
463  if( anyAdded )
465 
466  if( anySubtracted )
468 
469  break; // Stop waiting for events
470  }
471  }
472 
473  getViewControls()->SetAutoPan( false );
474 
475  // Stop drawing the selection box
476  view->Remove( &area );
477  m_multiple = false; // Multiple selection mode is inactive
478 
479  if( !cancelled )
481 
482  return cancelled;
483 }
484 
485 
487 {
488  AddItemToSel( aEvent.Parameter<EDA_ITEM*>() );
489  return 0;
490 }
491 
492 
493 void PL_SELECTION_TOOL::AddItemToSel( EDA_ITEM* aItem, bool aQuietMode )
494 {
495  if( aItem )
496  {
497  select( aItem );
498 
499  // Inform other potentially interested tools
500  if( !aQuietMode )
502  }
503 }
504 
505 
507 {
508  AddItemsToSel( aEvent.Parameter<EDA_ITEMS*>(), false );
509  return 0;
510 }
511 
512 
513 void PL_SELECTION_TOOL::AddItemsToSel( EDA_ITEMS* aList, bool aQuietMode )
514 {
515  if( aList )
516  {
517  for( EDA_ITEM* item : *aList )
518  select( item );
519 
520  // Inform other potentially interested tools
521  if( !aQuietMode )
523  }
524 }
525 
526 
528 {
529  RemoveItemFromSel( aEvent.Parameter<EDA_ITEM*>() );
530  return 0;
531 }
532 
533 
534 void PL_SELECTION_TOOL::RemoveItemFromSel( EDA_ITEM* aItem, bool aQuietMode )
535 {
536  if( aItem )
537  {
538  unselect( aItem );
539 
540  // Inform other potentially interested tools
541  if( !aQuietMode )
543  }
544 }
545 
546 
548 {
549  RemoveItemsFromSel( aEvent.Parameter<EDA_ITEMS*>(), false );
550  return 0;
551 }
552 
553 
554 void PL_SELECTION_TOOL::RemoveItemsFromSel( EDA_ITEMS* aList, bool aQuietMode )
555 {
556  if( aList )
557  {
558  for( EDA_ITEM* item : *aList )
559  unselect( item );
560 
561  // Inform other potentially interested tools
562  if( !aQuietMode )
564  }
565 }
566 
567 
569 {
570  highlight( aItem, BRIGHTENED );
571 }
572 
573 
575 {
576  unhighlight( aItem, BRIGHTENED );
577 }
578 
579 
581 {
582  ClearSelection();
583  return 0;
584 }
585 
586 
588 {
589  m_selection.Clear();
590 
591  for( DS_DATA_ITEM* dataItem : DS_DATA_MODEL::GetTheInstance().GetItems() )
592  {
593  for( DS_DRAW_ITEM_BASE* item : dataItem->GetDrawItems() )
594  {
595  if( item->IsSelected() )
596  select( item );
597  }
598  }
599 }
600 
601 
603 {
604  COLLECTOR* collector = aEvent.Parameter<COLLECTOR*>();
605 
606  if( !doSelectionMenu( collector ) )
607  collector->m_MenuCancelled = true;
608 
609  return 0;
610 }
611 
612 
614 {
615  EDA_ITEM* current = nullptr;
616  ACTION_MENU menu( true );
617 
618  // ID limit is `MAX_SELECT_ITEM_IDS+1` because the last item is "select all"
619  // and the first item has ID of 1.
620  int limit = std::min( MAX_SELECT_ITEM_IDS + 1, aCollector->GetCount() );
621 
622  for( int i = 0; i < limit; ++i )
623  {
624  wxString text;
625  EDA_ITEM* item = ( *aCollector )[i];
627 
628  wxString menuText = wxString::Format( "&%d. %s\t%d", i + 1, text, i + 1 );
629  menu.Add( menuText, i + 1, item->GetMenuImage() );
630  }
631 
632  menu.AppendSeparator();
633  menu.Add( _( "Select &All\tA" ), limit + 1, BITMAPS::INVALID_BITMAP );
634 
635  if( aCollector->m_MenuTitle.Length() )
636  {
637  menu.SetTitle( aCollector->m_MenuTitle );
638  menu.SetIcon( BITMAPS::info );
639  menu.DisplayTitle( true );
640  }
641  else
642  {
643  menu.DisplayTitle( false );
644  }
645 
646  SetContextMenu( &menu, CMENU_NOW );
647 
648  bool selectAll = false;
649 
650  while( TOOL_EVENT* evt = Wait() )
651  {
652  if( evt->Action() == TA_CHOICE_MENU_UPDATE )
653  {
654  if( selectAll )
655  {
656  for( int i = 0; i < aCollector->GetCount(); ++i )
657  unhighlight( ( *aCollector )[i], BRIGHTENED );
658  }
659  else if( current )
660  {
661  unhighlight( current, BRIGHTENED );
662  }
663 
664  int id = *evt->GetCommandId();
665 
666  // User has pointed an item, so show it in a different way
667  if( id > 0 && id <= limit )
668  {
669  current = ( *aCollector )[id - 1];
670  highlight( current, BRIGHTENED );
671  }
672  else
673  {
674  current = nullptr;
675  }
676 
677  if( id == limit + 1 )
678  {
679  for( int i = 0; i < aCollector->GetCount(); ++i )
680  highlight( ( *aCollector )[i], BRIGHTENED );
681 
682  selectAll = true;
683  }
684  else
685  {
686  selectAll = false;
687  }
688  }
689  else if( evt->Action() == TA_CHOICE_MENU_CHOICE )
690  {
691  if( selectAll )
692  {
693  for( int i = 0; i < aCollector->GetCount(); ++i )
694  unhighlight( ( *aCollector )[i], BRIGHTENED );
695  }
696  else if( current )
697  {
698  unhighlight( current, BRIGHTENED );
699  }
700 
701  OPT<int> id = evt->GetCommandId();
702 
703  // User has selected an item, so this one will be returned
704  if( id == limit + 1 )
705  {
706  selectAll = true;
707  current = nullptr;
708  }
709  else if( id && ( *id > 0 ) && ( *id <= limit ) )
710  {
711  selectAll = false;
712  current = ( *aCollector )[*id - 1];
713  }
714  else
715  {
716  selectAll = false;
717  current = nullptr;
718  }
719  }
720  else if( evt->Action() == TA_CHOICE_MENU_CLOSED )
721  {
722  break;
723  }
724 
725  getView()->UpdateItems();
726  m_frame->GetCanvas()->Refresh();
727  }
728 
729  if( selectAll )
730  {
731  return true;
732  }
733  else if( current )
734  {
735  unhighlight( current, BRIGHTENED );
736 
737  getView()->UpdateItems();
738  m_frame->GetCanvas()->Refresh();
739 
740  aCollector->Empty();
741  aCollector->Append( current );
742  return true;
743  }
744 
745  return false;
746 }
747 
748 
750 {
751  if( m_selection.Empty() )
752  return;
753 
754  while( m_selection.GetSize() )
756 
757  getView()->Update( &m_selection );
758 
759  m_selection.SetIsHover( false );
761 
762  // Inform other potentially interested tools
764 }
765 
766 
768 {
769  highlight( aItem, SELECTED, &m_selection );
770 }
771 
772 
774 {
775  unhighlight( aItem, SELECTED, &m_selection );
776 }
777 
778 
779 void PL_SELECTION_TOOL::highlight( EDA_ITEM* aItem, int aMode, PL_SELECTION* aGroup )
780 {
781  if( aMode == SELECTED )
782  aItem->SetSelected();
783  else if( aMode == BRIGHTENED )
784  aItem->SetBrightened();
785 
786  if( aGroup )
787  aGroup->Add( aItem );
788 
789  getView()->Update( aItem );
790 }
791 
792 
793 void PL_SELECTION_TOOL::unhighlight( EDA_ITEM* aItem, int aMode, PL_SELECTION* aGroup )
794 {
795  if( aMode == SELECTED )
796  aItem->ClearSelected();
797  else if( aMode == BRIGHTENED )
798  aItem->ClearBrightened();
799 
800  if( aGroup )
801  aGroup->Remove( aItem );
802 
803  getView()->Update( aItem );
804 }
805 
806 
808 {
809  const unsigned GRIP_MARGIN = 20;
810  VECTOR2I margin = getView()->ToWorld( VECTOR2I( GRIP_MARGIN, GRIP_MARGIN ), false );
811 
812  // Check if the point is located within any of the currently selected items bounding boxes
813  for( auto item : m_selection )
814  {
815  BOX2I itemBox = item->ViewBBox();
816  itemBox.Inflate( margin.x, margin.y ); // Give some margin for gripping an item
817 
818  if( itemBox.Contains( aPoint ) )
819  return true;
820  }
821 
822  return false;
823 }
824 
825 
827 {
829 
832 
838 }
void Empty()
Clear the list.
Definition: collector.h:95
void ClearReferencePoint()
Definition: selection.h:269
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:201
void SetEnd(VECTOR2I aEnd)
Set the current end of the rectangle (the corner that moves with the cursor.
TOOL_MENU m_menu
The functions below are not yet implemented - their interface may change.
COLLECTOR class definition.
virtual void Clear() override
Remove all the stored items from the group.
Definition: selection.h:96
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:81
static const TOOL_EVENT UnselectedEvent
Definition: actions.h:202
Defines the structure of a menu based on ACTIONs.
Definition: action_menu.h:47
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:451
void SetIcon(BITMAPS aIcon)
Assign an icon for the entry.
Definition: action_menu.cpp:72
void SetOrigin(VECTOR2I aOrigin)
static TOOL_ACTION drawLine
Definition: pl_actions.h:65
void ClearSelected()
Definition: eda_item.h:182
static TOOL_ACTION addItemsToSel
Select a list of items (specified as the event parameter)
Definition: pl_actions.h:54
int UpdateMenu(const TOOL_EVENT &aEvent)
static TOOL_ACTION placeImage
Definition: pl_actions.h:63
void BrightenItem(EDA_ITEM *aItem)
CONDITIONAL_MENU & GetMenu()
Definition: tool_menu.cpp:46
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp:352
void SetBrightened()
Definition: eda_item.h:180
static TOOL_ACTION zoomFitScreen
Definition: actions.h:99
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:141
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:62
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:67
virtual void Add(EDA_ITEM *aItem)
Definition: selection.h:77
void ClearBrightened()
Definition: eda_item.h:183
void Append(EDA_ITEM *item)
Add an item to the end of the list.
Definition: collector.h:105
void SetAdditive(bool aAdditive)
bool m_MenuCancelled
Definition: collector.h:251
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:275
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:44
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:87
static TOOL_ACTION addItemToSel
Select an item (specified as the event parameter).
Definition: pl_actions.h:50
void Transfer(int aIndex)
Move the item at aIndex (first position is 0) to the backup list.
Definition: collector.h:159
static TOOL_ACTION removeItemsFromSel
Definition: pl_actions.h:55
#define BRIGHTENED
item is drawn with a bright contour
Definition: eda_item.h:131
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:134
void SetSelected()
Definition: eda_item.h:179
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:448
bool Contains(const Vec &aPoint) const
Function Contains.
Definition: box2.h:151
#define SELECTED
Definition: eda_item.h:114
Generic, UI-independent tool event.
Definition: tool_event.h:173
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:58
bool ToolStackIsEmpty()
Definition: tools_holder.h:117
static const TOOL_EVENT ClearedEvent
Selected item had a property changed (except movement)
Definition: actions.h:203
void UpdateItems()
Iterate through the list of items that asked for updating and updates them.
Definition: view.cpp:1397
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
Definition: eda_item.h:557
static TOOL_ACTION drawRectangle
Definition: pl_actions.h:64
static TOOL_ACTION updateMenu
Definition: actions.h:170
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.
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:122
static TOOL_ACTION clearSelection
Clear the current selection.
Definition: pl_actions.h:47
wxString m_MenuTitle
Definition: collector.h:250
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:101
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:51
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)
The main loop.
void SetTitle(const wxString &aTitle) override
Set title for the menu.
Definition: action_menu.cpp:90
bool Init() override
Init() is called once upon a registration of the tool.
Drawing sheet structure type definitions.
Definition: ds_data_item.h:95
#define _(s)
Definition: 3d_actions.cpp:33
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:107
void UnbrightenItem(EDA_ITEM *aItem)
virtual BITMAPS GetMenuImage() const
Return a pointer to an image to be used in menus.
Definition: eda_item.cpp:206
wxMenuItem * Add(const wxString &aLabel, int aId, BITMAPS aIcon)
Add a wxWidgets-style entry to the menu.
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:68
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:150
An abstract class that will find and hold all the objects according to an inspection done by the Insp...
Definition: collector.h:53
RESET_REASON
Determine the reason of reset for a tool.
Definition: tool_base.h:78
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:1449
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)
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:322
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:67
#define HITTEST_THRESHOLD_PIXELS
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:203
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:1503
void DisplayTitle(bool aDisplay=true)
Decide whether a title for a pop up menu should be displayed.
virtual void Remove(EDA_ITEM *aItem)
Definition: selection.h:88