KiCad PCB EDA Suite
Loading...
Searching...
No Matches
symbol_editor_move_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-2023 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#include <tool/tool_manager.h>
27#include <ee_actions.h>
28#include <ee_grid_helper.h>
29#include <eda_item.h>
31#include <sch_shape.h>
32#include <sch_commit.h>
33#include <wx/debug.h>
34#include <view/view_controls.h>
37
38
40 EE_TOOL_BASE( "eeschema.SymbolMoveTool" ),
41 m_moveInProgress( false )
42{
43}
44
45
47{
49
50 //
51 // Add move actions to the selection tool menu
52 //
54
55 auto canMove =
56 [&]( const SELECTION& sel )
57 {
59 wxCHECK( editor, false );
60
61 if( !editor->IsSymbolEditable() )
62 return false;
63
64 if( editor->IsSymbolAlias() )
65 {
66 for( EDA_ITEM* item : sel )
67 {
68 if( item->Type() != SCH_FIELD_T )
69 return false;
70 }
71 }
72
73 return true;
74 };
75
76 selToolMenu.AddItem( EE_ACTIONS::move, canMove && EE_CONDITIONS::IdleSelection, 150 );
77 selToolMenu.AddItem( EE_ACTIONS::alignToGrid, canMove && EE_CONDITIONS::IdleSelection, 150 );
78
79 return true;
80}
81
82
84{
85 EE_TOOL_BASE::Reset( aReason );
86
87 if( aReason == MODEL_RELOAD )
88 m_moveInProgress = false;
89}
90
91
93{
94 if( SCH_COMMIT* commit = dynamic_cast<SCH_COMMIT*>( aEvent.Commit() ) )
95 {
96 wxCHECK( aEvent.SynchronousState(), 0 );
97 aEvent.SynchronousState()->store( STS_RUNNING );
98
99 if( doMoveSelection( aEvent, commit ) )
100 aEvent.SynchronousState()->store( STS_FINISHED );
101 else
102 aEvent.SynchronousState()->store( STS_CANCELLED );
103 }
104 else
105 {
106 SCH_COMMIT localCommit( m_toolMgr );
107
108 if( doMoveSelection( aEvent, &localCommit ) )
109 localCommit.Push( _( "Move" ) );
110 else
111 localCommit.Revert();
112 }
113
114 return 0;
115}
116
117
119{
122
123 m_anchorPos = { 0, 0 };
124
125 // Be sure that there is at least one item that we can move. If there's no selection try
126 // looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection).
127 EE_SELECTION& selection = m_frame->IsSymbolAlias()
130 bool unselect = selection.IsHover();
131
132 if( !m_frame->IsSymbolEditable() || selection.Empty() )
133 return false;
134
135 if( m_moveInProgress )
136 {
137 // The tool hotkey is interpreted as a click when already moving
139 return true;
140 }
141
142 m_frame->PushTool( aEvent );
143
144 Activate();
145 // Must be done after Activate() so that it gets set into the correct context
146 controls->ShowCursor( true );
147 controls->SetAutoPan( true );
148
149 bool restore_state = false;
150 TOOL_EVENT copy = aEvent;
151 TOOL_EVENT* evt = &copy;
152 VECTOR2I prevPos;
153 VECTOR2I moveOffset;
154
155 if( !selection.Front()->IsNew() )
156 aCommit->Modify( m_frame->GetCurSymbol(), m_frame->GetScreen() );
157
158 m_cursor = controls->GetCursorPosition( !aEvent.DisableGridSnapping() );
159
160 // Main loop: keep receiving events
161 do
162 {
163 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::MOVING );
164 grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
165 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
166
167 if( evt->IsAction( &EE_ACTIONS::move )
168 || evt->IsMotion()
169 || evt->IsDrag( BUT_LEFT )
171 {
172 GRID_HELPER_GRIDS snapLayer = grid.GetSelectionGrid( selection );
173
174 if( !m_moveInProgress ) // Prepare to start moving/dragging
175 {
176 SCH_ITEM* lib_item = static_cast<SCH_ITEM*>( selection.Front() );
177
178 // Pick up any synchronized pins
179 //
180 // Careful when pasting. The pasted pin will be at the same location as it
181 // was copied from, leading us to believe it's a synchronized pin. It's not.
182 if( m_frame->SynchronizePins() && !( lib_item->GetEditFlags() & IS_PASTED ) )
183 {
184 std::set<SCH_PIN*> sync_pins;
185
186 for( EDA_ITEM* sel_item : selection )
187 {
188 lib_item = static_cast<SCH_ITEM*>( sel_item );
189
190 if( lib_item->Type() == SCH_PIN_T )
191 {
192 SCH_PIN* cur_pin = static_cast<SCH_PIN*>( lib_item );
193 LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
194 std::vector<bool> got_unit( symbol->GetUnitCount() + 1 );
195
196 got_unit[cur_pin->GetUnit()] = true;
197
198 for( SCH_PIN* pin : symbol->GetAllLibPins() )
199 {
200 if( !got_unit[pin->GetUnit()]
201 && pin->GetPosition() == cur_pin->GetPosition()
202 && pin->GetOrientation() == cur_pin->GetOrientation()
203 && pin->GetBodyStyle() == cur_pin->GetBodyStyle()
204 && pin->GetType() == cur_pin->GetType()
205 && pin->GetName() == cur_pin->GetName() )
206 {
207 if( sync_pins.insert( pin ).second )
208 got_unit[pin->GetUnit()] = true;
209 }
210 }
211 }
212 }
213
214 for( SCH_PIN* pin : sync_pins )
215 m_selectionTool->AddItemToSel( pin, true /*quiet mode*/ );
216 }
217
218 // Apply any initial offset in case we're coming from a previous command.
219 //
220 for( EDA_ITEM* item : selection )
221 moveItem( item, moveOffset );
222
223 // Set up the starting position and move/drag offset
224 //
225 m_cursor = controls->GetCursorPosition( !evt->DisableGridSnapping() );
226
227 if( lib_item->IsNew() )
228 {
229 m_anchorPos = selection.GetReferencePoint();
231
232 // Drag items to the current cursor position
233 for( EDA_ITEM* item : selection )
234 {
235 moveItem( item, delta );
236 updateItem( item, false );
237 }
238
240 }
241 else if( m_frame->GetMoveWarpsCursor() )
242 {
243 // User wants to warp the mouse
244 m_cursor = grid.BestDragOrigin( m_cursor, snapLayer, selection );
245 selection.SetReferencePoint( m_cursor );
247 }
248 else
249 {
250 m_cursor = controls->GetCursorPosition( !evt->DisableGridSnapping() );
252 }
253
254 controls->SetCursorPosition( m_cursor, false );
255
256 prevPos = m_cursor;
257 controls->SetAutoPan( true );
258 m_moveInProgress = true;
259 }
260
261 //------------------------------------------------------------------------
262 // Follow the mouse
263 //
264 m_cursor = grid.BestSnapAnchor( controls->GetCursorPosition( false ), snapLayer,
265 selection );
266 VECTOR2I delta( m_cursor - prevPos );
268
269 moveOffset += delta;
270 prevPos = m_cursor;
271
272 for( EDA_ITEM* item : selection )
273 {
274 moveItem( item, delta );
275 updateItem( item, false );
276 }
277
279 }
280 //------------------------------------------------------------------------
281 // Handle cancel
282 //
283 else if( evt->IsCancelInteractive() || evt->IsActivate() )
284 {
285 if( m_moveInProgress )
286 {
287 evt->SetPassEvent( false );
288 restore_state = true;
289 }
290
291 break;
292 }
293 //------------------------------------------------------------------------
294 // Handle TOOL_ACTION special cases
295 //
296 else if( evt->Action() == TA_UNDO_REDO_PRE )
297 {
298 unselect = true;
299 break;
300 }
301 else if( evt->IsAction( &ACTIONS::doDelete ) )
302 {
303 // Exit on a remove operation; there is no further processing for removed items.
304 break;
305 }
306 else if( evt->IsAction( &ACTIONS::duplicate ) )
307 {
308 wxBell();
309 }
310 //------------------------------------------------------------------------
311 // Handle context menu
312 //
313 else if( evt->IsClick( BUT_RIGHT ) )
314 {
315 m_menu->ShowContextMenu( m_selectionTool->GetSelection() );
316 }
317 //------------------------------------------------------------------------
318 // Handle drop
319 //
320 else if( evt->IsMouseUp( BUT_LEFT )
321 || evt->IsClick( BUT_LEFT )
322 || evt->IsDblClick( BUT_LEFT ) )
323 {
324 if( selection.GetSize() == 1 && selection.Front()->Type() == SCH_PIN_T )
325 {
327
328 try
329 {
330 SCH_PIN* curr_pin = static_cast<SCH_PIN*>( selection.Front() );
331
332 if( pinTool->PlacePin( curr_pin ) )
333 {
334 // PlacePin() clears the current selection, which we don't want. Not only
335 // is it a poor user experience, but it also prevents us from doing the
336 // proper cleanup at the end of this routine (ie: clearing the edit flags).
337 m_selectionTool->AddItemToSel( curr_pin, true /*quiet mode*/ );
338 }
339 else
340 {
341 restore_state = true;
342 }
343 }
344 catch( const boost::bad_pointer& e )
345 {
346 restore_state = true;
347 wxFAIL_MSG( wxString::Format( wxT( "Boost pointer exception occurred: %s" ),
348 e.what() ) );
349 }
350 }
351
352 break; // Finish
353 }
354 else
355 {
356 evt->SetPassEvent();
357 }
358
359 } while( ( evt = Wait() ) ); // Assignment intentional; not equality test
360
361 controls->ForceCursorPosition( false );
362 controls->ShowCursor( false );
363 controls->SetAutoPan( false );
364
365 m_anchorPos = { 0, 0 };
366
367 for( EDA_ITEM* item : selection )
368 item->ClearEditFlags();
369
370 if( unselect )
372
373 m_moveInProgress = false;
374 m_frame->PopTool( aEvent );
375
376 return !restore_state;
377}
378
379
381{
384 SCH_COMMIT commit( m_toolMgr );
385
386 auto doMoveItem =
387 [&]( EDA_ITEM* item, const VECTOR2I& delta )
388 {
389 commit.Modify( item, m_frame->GetScreen() );
390 static_cast<SCH_ITEM*>( item )->Move( delta );
391 updateItem( item, true );
392 };
393
394 for( EDA_ITEM* item : selection )
395 {
396 if( SCH_SHAPE* shape = dynamic_cast<SCH_SHAPE*>( item ) )
397 {
398 VECTOR2I newStart = grid.AlignGrid( shape->GetStart(), grid.GetItemGrid( shape ) );
399 VECTOR2I newEnd = grid.AlignGrid( shape->GetEnd(), grid.GetItemGrid( shape ) );
400
401 switch( shape->GetShape() )
402 {
403 case SHAPE_T::SEGMENT:
404 case SHAPE_T::RECTANGLE:
405 case SHAPE_T::CIRCLE:
406 case SHAPE_T::ARC:
407 if( newStart == newEnd ||
408 shape->GetShape() == SHAPE_T::CIRCLE || shape->GetShape() == SHAPE_T::ARC )
409 {
410 // For arc and circle, never modify the shape. just snap its position
411 // For others, don't collapse shape; just snap its position
412 if( newStart != shape->GetStart() )
413 doMoveItem( shape, newStart - shape->GetStart() );
414 }
415 else if( newStart != shape->GetStart() || newEnd != shape->GetEnd() )
416 {
417 // Snap both ends
418 commit.Modify( shape, m_frame->GetScreen() );
419
420 shape->SetStart( newStart );
421 shape->SetEnd( newEnd );
422
423 updateItem( item, true );
424 }
425
426 break;
427
428 case SHAPE_T::POLY:
429 if( shape->GetPointCount() > 0 )
430 {
431 std::vector<VECTOR2I> newPts;
432
433 for( const VECTOR2I& pt : shape->GetPolyShape().Outline( 0 ).CPoints() )
434 newPts.push_back( grid.AlignGrid( pt, grid.GetItemGrid( shape ) ) );
435
436 bool collapsed = false;
437
438 for( int ii = 0; ii < (int) newPts.size() - 1; ++ii )
439 {
440 if( newPts[ii] == newPts[ii + 1] )
441 collapsed = true;
442 }
443
444 if( collapsed )
445 {
446 // Don't collapse shape; just snap its position
447 if( newStart != shape->GetStart() )
448 doMoveItem( shape, newStart - shape->GetStart() );
449 }
450 else
451 {
452 commit.Modify( shape, m_frame->GetScreen() );
453
454 for( int ii = 0; ii < (int) newPts.size(); ++ii )
455 shape->GetPolyShape().Outline( 0 ).SetPoint( ii, newPts[ii] );
456
457 updateItem( item, true );
458 }
459 }
460
461 break;
462
463 case SHAPE_T::BEZIER:
464 // Snapping bezier control points is unlikely to be useful. Just snap its
465 // position.
466 if( newStart != shape->GetStart() )
467 doMoveItem( shape, newStart - shape->GetStart() );
468
469 break;
470
471 case SHAPE_T::UNDEFINED:
472 wxASSERT_MSG( false, wxT( "Undefined shape in AlignElements" ) );
473 break;
474 }
475 }
476 else
477 {
478 VECTOR2I newPos = grid.AlignGrid( item->GetPosition(), grid.GetItemGrid( item ) );
479 VECTOR2I delta = newPos - item->GetPosition();
480
481 if( delta != VECTOR2I( 0, 0 ) )
482 doMoveItem( item, delta );
483
484 if( SCH_PIN* pin = dynamic_cast<SCH_PIN*>( item ) )
485 {
486 int length = pin->GetLength();
487 int pinGrid;
488
489 if( pin->GetOrientation() == PIN_ORIENTATION::PIN_LEFT
490 || pin->GetOrientation() == PIN_ORIENTATION::PIN_RIGHT )
491 {
492 pinGrid = KiROUND( grid.GetGridSize( grid.GetItemGrid( item ) ).x );
493 }
494 else
495 {
496 pinGrid = KiROUND( grid.GetGridSize( grid.GetItemGrid( item ) ).y );
497 }
498
499 int newLength = KiROUND( (double) length / pinGrid ) * pinGrid;
500
501 if( newLength > 0 )
502 pin->SetLength( newLength );
503 }
504 }
505 }
506
508
509 commit.Push( _( "Align" ) );
510 return 0;
511}
512
513
515{
516 static_cast<SCH_ITEM*>( aItem )->Move( aDelta );
517 aItem->SetFlags( IS_MOVING );
518}
519
520
522{
525}
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition: box2.h:990
static TOOL_ACTION duplicate
Definition: actions.h:77
static TOOL_ACTION doDelete
Definition: actions.h:78
static TOOL_ACTION cursorClick
Definition: actions.h:169
static TOOL_ACTION refreshPreview
Definition: actions.h:149
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Create an undo entry for an item that has been already modified.
Definition: commit.h:105
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Add a menu entry to run a TOOL_ACTION on selected items.
void SetCurrentCursor(KICURSOR aCursor)
Set the current cursor shape for this panel.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:89
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:243
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:133
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:127
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:101
bool IsNew() const
Definition: eda_item.h:107
static TOOL_ACTION alignToGrid
Definition: ee_actions.h:126
static TOOL_ACTION move
Definition: ee_actions.h:127
static TOOL_ACTION clearSelection
Clears the current selection.
Definition: ee_actions.h:56
EE_SELECTION & RequestSelection(const std::vector< KICAD_T > &aScanTypes={ SCH_LOCATE_ANY_T }, bool aPromoteCellSelections=false)
Return either an existing selection (filtered), or the selection at the current cursor position if th...
EE_SELECTION & GetSelection()
A foundation class for a tool operating on a schematic or symbol.
Definition: ee_tool_base.h:48
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
Definition: ee_tool_base.h:84
void updateItem(EDA_ITEM *aItem, bool aUpdateRTree) const
Similar to getView()->Update(), but handles items that are redrawn by their parents and updating the ...
Definition: ee_tool_base.h:109
EE_SELECTION_TOOL * m_selectionTool
Definition: ee_tool_base.h:200
bool Init() override
Init() is called once upon a registration of the tool.
Definition: ee_tool_base.h:64
static const TOOL_EVENT SelectedItemsMoved
Used to inform tools that the selection should temporarily be non-editable.
Definition: actions.h:302
An interface for classes handling user events controlling the view behavior such as zooming,...
virtual void ForceCursorPosition(bool aEnabled, const VECTOR2D &aPosition=VECTOR2D(0, 0))
Place the cursor immediately at a given point.
virtual void ShowCursor(bool aEnabled)
Enable or disables display of cursor.
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
virtual void SetCursorPosition(const VECTOR2D &aPosition, bool aWarpView=true, bool aTriggeredByArrows=false, long aArrowCommand=0)=0
Move cursor to the requested position expressed in world coordinates.
virtual void SetAutoPan(bool aEnabled)
Turn on/off auto panning (this feature is used when there is a tool active (eg.
Define a library symbol object.
Definition: lib_symbol.h:78
std::vector< SCH_PIN * > GetAllLibPins() const
Return a list of pin pointers for all units / converts.
Definition: lib_symbol.cpp:854
int GetUnitCount() const override
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Revert the commit by restoring the modified items state.
Definition: sch_commit.cpp:432
virtual void Revert() override
Definition: sch_commit.cpp:510
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:166
int GetBodyStyle() const
Definition: sch_item.h:232
int GetUnit() const
Definition: sch_item.h:229
const wxString & GetName() const
Definition: sch_pin.cpp:381
PIN_ORIENTATION GetOrientation() const
Definition: sch_pin.cpp:260
VECTOR2I GetPosition() const override
Definition: sch_pin.cpp:252
ELECTRICAL_PINTYPE GetType() const
Definition: sch_pin.cpp:309
static bool IdleSelection(const SELECTION &aSelection)
Test if all selected items are not being edited.
int AddItemToSel(const TOOL_EVENT &aEvent)
bool IsHover() const
Definition: selection.h:84
virtual unsigned int GetSize() const override
Return the number of stored items.
Definition: selection.h:100
EDA_ITEM * Front() const
Definition: selection.h:172
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:110
bool doMoveSelection(const TOOL_EVENT &aEvent, SCH_COMMIT *aCommit)
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
void moveItem(EDA_ITEM *aItem, const VECTOR2I &aDelta)
Set up handlers for various events.
bool Init() override
Init() is called once upon a registration of the tool.
int Main(const TOOL_EVENT &aEvent)
Run an interactive move of the selected items, or the item under the cursor.
int AlignElements(const TOOL_EVENT &aEvent)
Align selected elements to the grid.
bool m_moveInProgress
Last cursor position (needed for getModificationPoint() to avoid changes of edit reference point).
The symbol library editor main window.
bool IsSymbolAlias() const
Return true if aLibId is an alias for the editor screen symbol.
bool IsSymbolEditable() const
Test if a symbol is loaded and can be edited.
LIB_SYMBOL * GetCurSymbol() const
Return the current symbol being edited or NULL if none selected.
virtual void PopTool(const TOOL_EVENT &aEvent)
Pops a tool from the stack.
bool GetMoveWarpsCursor() const
Indicate that a move operation should warp the mouse pointer to the origin of the move object.
Definition: tools_holder.h:150
virtual void PushTool(const TOOL_EVENT &aEvent)
NB: the definition of "tool" is different at the user level.
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:42
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:218
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
RESET_REASON
Determine the reason of reset for a tool.
Definition: tool_base.h:78
@ MODEL_RELOAD
Model changes (the sheet for a schematic)
Definition: tool_base.h:80
Generic, UI-independent tool event.
Definition: tool_event.h:167
bool DisableGridSnapping() const
Definition: tool_event.h:363
bool IsCancelInteractive() const
Indicate the event should restart/end an ongoing interactive tool's event loop (eg esc key,...
Definition: tool_event.cpp:221
TOOL_ACTIONS Action() const
These give a tool a method of informing the TOOL_MANAGER that a particular event should be passed on ...
Definition: tool_event.h:246
bool IsActivate() const
Definition: tool_event.h:337
COMMIT * Commit() const
Returns information about difference between current mouse cursor position and the place where draggi...
Definition: tool_event.h:275
bool IsClick(int aButtonMask=BUT_ANY) const
Definition: tool_event.cpp:209
bool IsDrag(int aButtonMask=BUT_ANY) const
Definition: tool_event.h:307
int Modifier(int aMask=MD_MODIFIER_MASK) const
Definition: tool_event.h:358
bool IsAction(const TOOL_ACTION *aAction) const
Test if the event contains an action issued upon activation of the given TOOL_ACTION.
Definition: tool_event.cpp:82
bool IsDblClick(int aButtonMask=BUT_ANY) const
Definition: tool_event.cpp:215
std::atomic< SYNCRONOUS_TOOL_STATE > * SynchronousState() const
Definition: tool_event.h:272
void SetPassEvent(bool aPass=true)
Returns if it this event has a valid position (true for mouse events and context-menu or hotkey-based...
Definition: tool_event.h:252
bool IsMouseUp(int aButtonMask=BUT_ANY) const
Definition: tool_event.h:317
bool IsMotion() const
Definition: tool_event.h:322
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).
TOOL_MENU & GetToolMenu()
std::unique_ptr< TOOL_MENU > m_menu
The functions below are not yet implemented - their interface may change.
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.
void Activate()
Run the tool.
void PostEvent(const TOOL_EVENT &aEvent)
Put an event to the event queue to be processed at the end of event processing cycle.
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:150
CONDITIONAL_MENU & GetMenu()
Definition: tool_menu.cpp:44
#define _(s)
#define IS_PASTED
Modifier on IS_NEW which indicates it came from clipboard.
#define IS_MOVING
Item being moved.
GRID_HELPER_GRIDS
Definition: grid_helper.h:42
constexpr int delta
@ TA_UNDO_REDO_PRE
Definition: tool_event.h:105
@ MD_SHIFT
Definition: tool_event.h:142
@ STS_CANCELLED
Definition: tool_event.h:160
@ STS_FINISHED
Definition: tool_event.h:159
@ STS_RUNNING
Definition: tool_event.h:158
@ BUT_LEFT
Definition: tool_event.h:131
@ BUT_RIGHT
Definition: tool_event.h:132
@ SCH_FIELD_T
Definition: typeinfo.h:150
@ SCH_PIN_T
Definition: typeinfo.h:153
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:691