KiCad PCB EDA Suite
EDIT_TOOL Class Reference

The interactive edit tool. More...

#include <edit_tool.h>

Inheritance diagram for EDIT_TOOL:
PCB_TOOL_BASE TOOL_INTERACTIVE TOOL_BASE

Public Types

enum  RESET_REASON { RUN , MODEL_RELOAD , GAL_SWITCH }
 Determine the reason of reset for a tool. More...
 

Public Member Functions

 EDIT_TOOL ()
 
void Reset (RESET_REASON aReason) override
 Bring the tool to a known, initial state. More...
 
bool Init () override
 Init() is called once upon a registration of the tool. More...
 
int GetAndPlace (const TOOL_EVENT &aEvent)
 
int Move (const TOOL_EVENT &aEvent)
 Main loop in which events are handled. More...
 
int MoveIndividually (const TOOL_EVENT &aEvent)
 Move a selection of items one-at-a-time. More...
 
int Drag (const TOOL_EVENT &aEvent)
 Invoke the PNS router to drag tracks or do an offline resizing of an arc track if a single arc track is selected. More...
 
int DragArcTrack (const TOOL_EVENT &aTrack)
 Drag-resize an arc (and change end points of connected straight segments). More...
 
int Properties (const TOOL_EVENT &aEvent)
 Display properties window for the selected object. More...
 
int Rotate (const TOOL_EVENT &aEvent)
 Rotate currently selected items. More...
 
int Flip (const TOOL_EVENT &aEvent)
 Rotate currently selected items. More...
 
int Mirror (const TOOL_EVENT &aEvent)
 Mirror the current selection. More...
 
int Swap (const TOOL_EVENT &aEvent)
 Swap currently selected items' positions. More...
 
int ChangeTrackWidth (const TOOL_EVENT &aEvent)
 
int FilletTracks (const TOOL_EVENT &aEvent)
 Fillet (i.e. More...
 
int Remove (const TOOL_EVENT &aEvent)
 Delete currently selected items. More...
 
int Duplicate (const TOOL_EVENT &aEvent)
 Duplicate the current selection and starts a move action. More...
 
int MoveExact (const TOOL_EVENT &aEvent)
 Invoke a dialog box to allow moving of the item by an exact amount. More...
 
int MoveWithReference (const TOOL_EVENT &aEvent)
 Move an item but with a reference point selected first. More...
 
int CreateArray (const TOOL_EVENT &aEvent)
 Create an array of the selected items, invoking the array editor dialog to set the options. More...
 
BOARD_COMMITGetCurrentCommit () const
 
void SetIsFootprintEditor (bool aEnabled)
 Function SetIsFootprintEditor() More...
 
bool IsFootprintEditor () const
 
void SetIsBoardEditor (bool aEnabled)
 
bool IsBoardEditor () const
 
virtual bool Is45Limited () const
 Should the tool use its 45° mode option? More...
 
void Activate ()
 Run the tool. More...
 
TOOL_MENUGetToolMenu ()
 
void SetContextMenu (ACTION_MENU *aMenu, CONTEXT_MENU_TRIGGER aTrigger=CMENU_BUTTON)
 Assign a context menu and tells when it should be activated. More...
 
void RunMainStack (std::function< void()> aFunc)
 Call a function using the main stack. More...
 
template<class T >
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). More...
 
TOOL_EVENTWait (const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
 Suspend execution of the tool until an event specified in aEventList arrives. More...
 
TOOL_TYPE GetType () const
 Return the type of the tool. More...
 
TOOL_ID GetId () const
 Return the unique identifier of the tool. More...
 
const std::string & GetName () const
 Return the name of the tool. More...
 
TOOL_MANAGERGetManager () const
 Return the instance of TOOL_MANAGER that takes care of the tool. More...
 
bool IsToolActive () const
 

Static Public Member Functions

static void FootprintFilter (const VECTOR2I &, GENERAL_COLLECTOR &aCollector, PCB_SELECTION_TOOL *sTool)
 A selection filter which prunes the selection to contain only items of type #PCB_MODULE_T. More...
 
static void PadFilter (const VECTOR2I &, GENERAL_COLLECTOR &aCollector, PCB_SELECTION_TOOL *sTool)
 A selection filter which prunes the selection to contain only items of type PCB_PAD_T. More...
 

Protected Types

enum  INTERACTIVE_PLACEMENT_OPTIONS { IPO_ROTATE = 0x01 , IPO_FLIP = 0x02 , IPO_SINGLE_CLICK = 0x04 , IPO_REPEAT = 0x08 }
 Options for placing items interactively. More...
 

Protected Member Functions

void doInteractiveItemPlacement (const TOOL_EVENT &aTool, INTERACTIVE_PLACER_BASE *aPlacer, const wxString &aCommitMessage, int aOptions=IPO_ROTATE|IPO_FLIP|IPO_REPEAT)
 Helper function for performing a common interactive idiom: wait for a left click, place an item there (perhaps with a dialog or other user interaction), then have it move with the mouse and respond to rotate/flip, etc. More...
 
KIGFX::PCB_VIEWview () const
 
KIGFX::VIEW_CONTROLScontrols () const
 
PCB_BASE_EDIT_FRAMEframe () const
 
BOARDboard () const
 
FOOTPRINTfootprint () const
 
PCBNEW_SETTINGS::DISPLAY_OPTIONSdisplayOptions () const
 
PCB_DRAW_PANEL_GALcanvas () const
 
const PCB_SELECTIONselection () const
 
PCB_SELECTIONselection ()
 
void attachManager (TOOL_MANAGER *aManager)
 Set the TOOL_MANAGER the tool will belong to. More...
 
KIGFX::VIEWgetView () const
 Returns the instance of #VIEW object used in the application. More...
 
KIGFX::VIEW_CONTROLSgetViewControls () const
 Return the instance of VIEW_CONTROLS object used in the application. More...
 
template<typename T >
T * getEditFrame () const
 Return the application window object, casted to requested user type. More...
 
template<typename T >
T * getModel () const
 Return the model object if it matches the requested type. More...
 

Protected Attributes

bool m_isFootprintEditor
 
bool m_isBoardEditor
 
TOOL_MENU m_menu
 The functions below are not yet implemented - their interface may change. More...
 
TOOL_TYPE m_type
 Unique identifier for the tool, assigned by a TOOL_MANAGER instance. More...
 
TOOL_ID m_toolId
 Name of the tool. More...
 
std::string m_toolName
 
TOOL_MANAGERm_toolMgr
 

Private Member Functions

void setTransitions () override
 < Set up handlers for various events. More...
 
int copyToClipboard (const TOOL_EVENT &aEvent)
 Send the current selection to the clipboard by formatting it as a fake pcb see #AppendBoardFromClipboard for importing. More...
 
int cutToClipboard (const TOOL_EVENT &aEvent)
 Cut the current selection to the clipboard by formatting it as a fake pcb see #AppendBoardFromClipboard for importing. More...
 
bool updateModificationPoint (PCB_SELECTION &aSelection)
 
bool invokeInlineRouter (int aDragMode)
 
bool isRouterActive () const
 
int doMoveSelection (const TOOL_EVENT &aEvent, bool aPickReference=false)
 
VECTOR2I getSafeMovement (const VECTOR2I &aMovement, const BOX2I &aSourceBBox, const VECTOR2D &aBBoxOffset)
 
bool pickReferencePoint (const wxString &aTooltip, const wxString &aSuccessMessage, const wxString &aCanceledMessage, VECTOR2I &aReferencePoint)
 
void resetTransitions ()
 Clear the current transition map and restores the default one created by setTransitions(). More...
 
void goInternal (TOOL_STATE_FUNC &aState, const TOOL_EVENT_LIST &aConditions)
 
EDA_ITEMgetModelInt () const
 
TOOLS_HOLDERgetToolHolderInt () const
 

Private Attributes

PCB_SELECTION_TOOLm_selectionTool
 
std::unique_ptr< BOARD_COMMITm_commit
 
bool m_dragging
 
VECTOR2I m_cursor
 
std::unique_ptr< STATUS_TEXT_POPUPm_statusPopup
 

Static Private Attributes

static const unsigned int COORDS_PADDING = pcbIUScale.mmToIU( 20 )
 

Detailed Description

The interactive edit tool.

Allows one to move, rotate, flip and change properties of items selected using the pcbnew.InteractiveSelection tool.

Definition at line 64 of file edit_tool.h.

Member Enumeration Documentation

◆ INTERACTIVE_PLACEMENT_OPTIONS

Options for placing items interactively.

Enumerator
IPO_ROTATE 

Handle the rotate action in the loop by calling the item's rotate method.

IPO_FLIP 

Handle flip action in the loop by calling the item's flip method.

IPO_SINGLE_CLICK 

Create an item immediately on placement starting, otherwise show the pencil cursor until the item is created.

IPO_REPEAT 

Allow repeat placement of the item.

Definition at line 121 of file pcb_tool_base.h.

121 {
123 IPO_ROTATE = 0x01,
124
126 IPO_FLIP = 0x02,
127
130 IPO_SINGLE_CLICK = 0x04,
131
133 IPO_REPEAT = 0x08
134 };
@ IPO_FLIP
Handle flip action in the loop by calling the item's flip method.
@ IPO_ROTATE
Handle the rotate action in the loop by calling the item's rotate method.
@ IPO_SINGLE_CLICK
Create an item immediately on placement starting, otherwise show the pencil cursor until the item is ...
@ IPO_REPEAT
Allow repeat placement of the item.

◆ RESET_REASON

enum TOOL_BASE::RESET_REASON
inherited

Determine the reason of reset for a tool.

Enumerator
RUN 

Tool is invoked after being inactive.

MODEL_RELOAD 

Model changes (required full reload)

GAL_SWITCH 

Rendering engine changes.

Definition at line 77 of file tool_base.h.

78 {
79 RUN,
82 };
@ MODEL_RELOAD
Model changes (required full reload)
Definition: tool_base.h:80
@ GAL_SWITCH
Rendering engine changes.
Definition: tool_base.h:81
@ RUN
Tool is invoked after being inactive.
Definition: tool_base.h:79

Constructor & Destructor Documentation

◆ EDIT_TOOL()

EDIT_TOOL::EDIT_TOOL ( )

Definition at line 71 of file edit_tool.cpp.

71 :
72 PCB_TOOL_BASE( "pcbnew.InteractiveEdit" ),
73 m_selectionTool( nullptr ),
74 m_dragging( false )
75{
76}
bool m_dragging
Definition: edit_tool.h:204
PCB_SELECTION_TOOL * m_selectionTool
Definition: edit_tool.h:202
PCB_TOOL_BASE(TOOL_ID aId, const std::string &aName)
Constructor.
Definition: pcb_tool_base.h:77

Member Function Documentation

◆ Activate()

void TOOL_INTERACTIVE::Activate ( )
inherited

Run the tool.

After activation, the tool starts receiving events until it is finished.

Definition at line 51 of file tool_interactive.cpp.

52{
54}
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:214
TOOL_ID m_toolId
Name of the tool.
Definition: tool_base.h:209
bool InvokeTool(TOOL_ID aToolId)
Call a tool by sending a tool activation event to tool of given ID.

References TOOL_MANAGER::InvokeTool(), TOOL_BASE::m_toolId, and TOOL_BASE::m_toolMgr.

Referenced by AUTOPLACE_TOOL::autoplace(), copyToClipboard(), SCH_EDIT_TOOL::DeleteItemCursor(), SYMBOL_EDITOR_EDIT_TOOL::DeleteItemCursor(), PL_EDIT_TOOL::DeleteItemCursor(), PCB_CONTROL::DeleteItemCursor(), SCH_LINE_WIRE_BUS_TOOL::doDrawSegments(), PCB_TOOL_BASE::doInteractiveItemPlacement(), doMoveSelection(), DragArcTrack(), DRAWING_TOOL::DrawArc(), DRAWING_TOOL::DrawCircle(), DRAWING_TOOL::DrawDimension(), DRAWING_TOOL::DrawLine(), MICROWAVE_TOOL::drawMicrowaveInductor(), DRAWING_TOOL::DrawRectangle(), SCH_DRAWING_TOOLS::DrawShape(), SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape(), PL_DRAWING_TOOLS::DrawShape(), SCH_DRAWING_TOOLS::DrawSheet(), DRAWING_TOOL::DrawZone(), BOARD_EDITOR_CONTROL::DrillOrigin(), PAD_TOOL::EnumeratePads(), PCB_CONTROL::GridSetOrigin(), SCH_EDITOR_CONTROL::HighlightNetCursor(), ROUTER_TOOL::InlineBreakTrack(), ROUTER_TOOL::InlineDrag(), DRAWING_TOOL::InteractivePlaceWithPreview(), BOARD_INSPECTION_TOOL::LocalRatsnestTool(), EE_POINT_EDITOR::Main(), SCH_MOVE_TOOL::Main(), SYMBOL_EDITOR_MOVE_TOOL::Main(), PICKER_TOOL::Main(), PL_EDIT_TOOL::Main(), PL_POINT_EDITOR::Main(), PCB_PICKER_TOOL::Main(), LENGTH_TUNER_TOOL::MainLoop(), ROUTER_TOOL::MainLoop(), GERBVIEW_INSPECTION_TOOL::MeasureTool(), PCB_VIEWER_TOOLS::MeasureTool(), PCB_POINT_EDITOR::OnSelectionChange(), GROUP_TOOL::PickNewMember(), SYMBOL_EDITOR_DRAWING_TOOLS::PlaceAnchor(), BOARD_EDITOR_CONTROL::PlaceFootprint(), SCH_DRAWING_TOOLS::PlaceImage(), DRAWING_TOOL::PlaceImage(), DRAWING_TOOL::PlaceImportedGraphics(), PL_DRAWING_TOOLS::PlaceItem(), SCH_DRAWING_TOOLS::PlaceSymbol(), DRAWING_TOOL::PlaceText(), Remove(), ROUTER_TOOL::RouteSelected(), POSITION_RELATIVE_TOOL::SelectPositionRelativeItem(), DRAWING_TOOL::SetAnchor(), DRC_TOOL::ShowDRCDialog(), SCH_DRAWING_TOOLS::SingleClickPlace(), SCH_DRAWING_TOOLS::TwoClickPlace(), SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace(), and SCH_LINE_WIRE_BUS_TOOL::UnfoldBus().

◆ attachManager()

void TOOL_BASE::attachManager ( TOOL_MANAGER aManager)
protectedinherited

Set the TOOL_MANAGER the tool will belong to.

Called by TOOL_MANAGER::RegisterTool()

Definition at line 60 of file tool_base.cpp.

61{
62 m_toolMgr = aManager;
63}

References TOOL_BASE::m_toolMgr.

Referenced by TOOL_MANAGER::RegisterTool().

◆ board()

BOARD * PCB_TOOL_BASE::board ( ) const
inlineprotectedinherited

Definition at line 170 of file pcb_tool_base.h.

170{ return getModel<BOARD>(); }

Referenced by PCB_CONTROL::AppendBoard(), BOARD_EDITOR_CONTROL::AssignNetclass(), AUTOPLACE_TOOL::autoplace(), BOARD_INSPECTION_TOOL::calculateSelectionRatsnest(), ChangeTrackWidth(), ZONE_FILLER_TOOL::CheckAllZones(), BOARD_INSPECTION_TOOL::ClearHighlight(), copyToClipboard(), FOOTPRINT_EDITOR_CONTROL::CreateFootprint(), MICROWAVE_TOOL::createInductorBetween(), ROUTER_TOOL::CustomTrackWidthDialog(), PCB_CONTROL::DeleteItemCursor(), PCB_TOOL_BASE::doInteractiveItemPlacement(), doMoveSelection(), DragArcTrack(), DRAWING_TOOL::drawArc(), DRAWING_TOOL::DrawDimension(), DRAWING_TOOL::drawShape(), PAD_TOOL::EnumeratePads(), PAD_TOOL::explodePad(), BOARD_EDITOR_CONTROL::ExportNetlist(), ZONE_FILLER_TOOL::FillAllZones(), FilletTracks(), PCB_TOOL_BASE::footprint(), GROUP_TOOL::Group(), ROUTER_TOOL::handleLayerSwitch(), BOARD_INSPECTION_TOOL::highlightNet(), ROUTER_TOOL::InlineDrag(), DRAWING_TOOL::InteractivePlaceWithPreview(), PCB_CONTROL::LayerNext(), PCB_CONTROL::LayerPrev(), BOARD_INSPECTION_TOOL::LocalRatsnestTool(), MoveExact(), FOOTPRINT_EDITOR_CONTROL::NewFootprint(), PCB_CONTROL::Paste(), PCB_CONTROL::placeBoardItems(), BOARD_EDITOR_CONTROL::PlaceFootprint(), PAD_TOOL::PlacePad(), DRAWING_TOOL::PlaceText(), PCB_CONTROL::pruneItemLayers(), PAD_TOOL::RecombinePad(), BOARD_EDITOR_CONTROL::RepairBoard(), FOOTPRINT_EDITOR_CONTROL::RepairFootprint(), PNS::TOOL_BASE::Reset(), PCB_CONTROL::Reset(), PCB_CONTROL::TrackDisplayMode(), PCB_CONTROL::unfilledZoneCheck(), GROUP_TOOL::Ungroup(), ROUTER_TOOL::UpdateMessagePanel(), PCB_CONTROL::ViaDisplayMode(), PCB_CONTROL::ZoneDisplayMode(), ZONE_FILLER_TOOL::ZoneFill(), ZONE_FILLER_TOOL::ZoneFillDirty(), BOARD_EDITOR_CONTROL::ZoneMerge(), and ZONE_FILLER_TOOL::ZoneUnfillAll().

◆ canvas()

◆ ChangeTrackWidth()

int EDIT_TOOL::ChangeTrackWidth ( const TOOL_EVENT aEvent)

Definition at line 741 of file edit_tool.cpp.

742{
744 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
745 {
746 // Iterate from the back so we don't have to worry about removals.
747 for( int i = aCollector.GetCount() - 1; i >= 0; --i )
748 {
749 BOARD_ITEM* item = aCollector[ i ];
750
751 if( !dynamic_cast<PCB_TRACK*>( item ) )
752 aCollector.Remove( item );
753 }
754 },
755 true /* prompt user regarding locked items */ );
756
757 for( EDA_ITEM* item : selection )
758 {
759 if( item->Type() == PCB_VIA_T )
760 {
761 PCB_VIA* via = static_cast<PCB_VIA*>( item );
762
763 m_commit->Modify( via );
764
765 int new_width;
766 int new_drill;
767
768 if( via->GetViaType() == VIATYPE::MICROVIA )
769 {
770 NETCLASS* netClass = via->GetEffectiveNetClass();
771
772 new_width = netClass->GetuViaDiameter();
773 new_drill = netClass->GetuViaDrill();
774 }
775 else
776 {
777 new_width = board()->GetDesignSettings().GetCurrentViaSize();
778 new_drill = board()->GetDesignSettings().GetCurrentViaDrill();
779 }
780
781 via->SetDrill( new_drill );
782 via->SetWidth( new_width );
783 }
784 else if( item->Type() == PCB_TRACE_T || item->Type() == PCB_ARC_T )
785 {
786 PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( item );
787
788 wxCHECK( track, 0 );
789
790 m_commit->Modify( track );
791
792 int new_width = board()->GetDesignSettings().GetCurrentTrackWidth();
793 track->SetWidth( new_width );
794 }
795 }
796
797 m_commit->Push( _( "Edit track width/via size" ) );
798
799 if( selection.IsHover() )
800 {
802
803 // Notify other tools of the changes -- This updates the visual ratsnest
805 }
806
807 return 0;
808}
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:602
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:81
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:99
std::unique_ptr< BOARD_COMMIT > m_commit
Definition: edit_tool.h:203
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:210
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:204
A collection of nets and the parameters used to route or test these nets.
Definition: netclass.h:47
int GetuViaDrill() const
Definition: netclass.h:92
int GetuViaDiameter() const
Definition: netclass.h:88
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:59
The selection tool: currently supports:
PCB_SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter, bool aConfirmLockedItems=false)
Return the current selection, filtered according to aClientFilter.
BOARD * board() const
const PCB_SELECTION & selection() const
void SetWidth(int aWidth)
Definition: pcb_track.h:104
bool IsHover() const
Definition: selection.h:81
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagate an event to tools that requested events of matching type(s).
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:142
#define _(s)
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:102
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:103
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:101

References _, PCB_TOOL_BASE::board(), COLLECTOR::GetCount(), BOARD_DESIGN_SETTINGS::GetCurrentTrackWidth(), BOARD_DESIGN_SETTINGS::GetCurrentViaDrill(), BOARD_DESIGN_SETTINGS::GetCurrentViaSize(), BOARD::GetDesignSettings(), NETCLASS::GetuViaDiameter(), NETCLASS::GetuViaDrill(), SELECTION::IsHover(), m_commit, m_selectionTool, TOOL_BASE::m_toolMgr, MICROVIA, PCB_ARC_T, PCB_TRACE_T, PCB_VIA_T, TOOL_MANAGER::ProcessEvent(), PCB_SELECTION_TOOL::RequestSelection(), TOOL_MANAGER::RunAction(), EVENTS::SelectedItemsModified, PCB_TOOL_BASE::selection(), PCB_ACTIONS::selectionClear, PCB_TRACK::SetWidth(), and via.

Referenced by setTransitions().

◆ controls()

◆ copyToClipboard()

int EDIT_TOOL::copyToClipboard ( const TOOL_EVENT aEvent)
private

Send the current selection to the clipboard by formatting it as a fake pcb see #AppendBoardFromClipboard for importing.

Definition at line 2157 of file edit_tool.cpp.

2158{
2159 CLIPBOARD_IO io;
2161 getEditFrame<PCB_BASE_EDIT_FRAME>()->GetMagneticItemsSettings() );
2162 TOOL_EVENT selectReferencePoint( aEvent.Category(), aEvent.Action(),
2163 "pcbnew.InteractiveEdit.selectReferencePoint",
2165
2166 frame()->PushTool( selectReferencePoint );
2167 Activate();
2168
2170 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
2171 {
2172 for( int i = aCollector.GetCount() - 1; i >= 0; --i )
2173 {
2174 BOARD_ITEM* item = aCollector[i];
2175
2176 // We can't copy both a footprint and its text in the same operation, so if
2177 // both are selected, remove the text
2178 if( item->Type() == PCB_FP_TEXT_T && aCollector.HasItem( item->GetParent() ) )
2179 aCollector.Remove( item );
2180 }
2181 },
2182
2183 // Prompt user regarding locked items.
2184 aEvent.IsAction( &ACTIONS::cut ) && !m_isFootprintEditor );
2185
2186 if( !selection.Empty() )
2187 {
2188 std::vector<BOARD_ITEM*> items;
2189
2190 for( EDA_ITEM* item : selection )
2191 items.push_back( static_cast<BOARD_ITEM*>( item ) );
2192
2193 VECTOR2I refPoint;
2194
2196 {
2197 if( !pickReferencePoint( _( "Select reference point for the copy..." ),
2198 _( "Selection copied" ),
2199 _( "Copy canceled" ),
2200 refPoint ) )
2201 {
2202 frame()->PopTool( selectReferencePoint );
2203 return 0;
2204 }
2205 }
2206 else
2207 {
2208 refPoint = grid.BestDragOrigin( getViewControls()->GetCursorPosition(), items );
2209 }
2210
2211 selection.SetReferencePoint( refPoint );
2212
2213 io.SetBoard( board() );
2215 frame()->SetStatusText( _( "Selection copied" ) );
2216 }
2217
2218 frame()->PopTool( selectReferencePoint );
2219
2220 return 0;
2221}
static TOOL_ACTION cut
Definition: actions.h:67
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:52
void SaveSelection(const PCB_SELECTION &selected, bool isFootprintEditor)
void SetBoard(BOARD *aBoard)
bool pickReferencePoint(const wxString &aTooltip, const wxString &aSuccessMessage, const wxString &aCanceledMessage, VECTOR2I &aReferencePoint)
Definition: edit_tool.cpp:2074
static TOOL_ACTION copyWithReference
copy command with manual reference point selection
Definition: pcb_actions.h:119
bool m_isFootprintEditor
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.h:252
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:107
virtual void PopTool(const TOOL_EVENT &aEvent)
Pops a tool from the stack.
virtual void PushTool(const TOOL_EVENT &aEvent)
NB: the definition of "tool" is different at the user level.
Generic, UI-independent tool event.
Definition: tool_event.h:156
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:233
TOOL_EVENT_CATEGORY Category() const
Returns more specific information about the type of an event.
Definition: tool_event.h:230
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:88
void Activate()
Run the tool.
@ AS_GLOBAL
Global action (toolbar/main menu event, global shortcut)
Definition: tool_action.h:45

References _, TOOL_EVENT::Action(), TOOL_INTERACTIVE::Activate(), AS_GLOBAL, PCB_TOOL_BASE::board(), TOOL_EVENT::Category(), PCB_ACTIONS::copyWithReference, ACTIONS::cut, SELECTION::Empty(), PCB_TOOL_BASE::frame(), COLLECTOR::GetCount(), TOOL_BASE::getViewControls(), grid, TOOL_EVENT::IsAction(), PCB_TOOL_BASE::m_isFootprintEditor, m_selectionTool, TOOL_BASE::m_toolMgr, pickReferencePoint(), TOOLS_HOLDER::PopTool(), TOOLS_HOLDER::PushTool(), PCB_SELECTION_TOOL::RequestSelection(), CLIPBOARD_IO::SaveSelection(), PCB_TOOL_BASE::selection(), CLIPBOARD_IO::SetBoard(), and SELECTION::SetReferencePoint().

Referenced by cutToClipboard(), and setTransitions().

◆ CreateArray()

int EDIT_TOOL::CreateArray ( const TOOL_EVENT aEvent)

Create an array of the selected items, invoking the array editor dialog to set the options.

Definition at line 1993 of file edit_tool.cpp.

1994{
1995 if( isRouterActive() )
1996 {
1997 wxBell();
1998 return 0;
1999 }
2000
2001 // Be sure that there is at least one item that we can modify
2003 []( const VECTOR2I&, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
2004 {
2005 sTool->FilterCollectorForMarkers( aCollector );
2006 sTool->FilterCollectorForHierarchy( aCollector, true );
2007 } );
2008
2009 if( selection.Empty() )
2010 return 0;
2011
2012 // we have a selection to work on now, so start the tool process
2013 PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
2014 ARRAY_CREATOR array_creator( *editFrame, m_isFootprintEditor, selection, m_toolMgr );
2015 array_creator.Invoke();
2016
2017 return 0;
2018}
bool isRouterActive() const
Definition: edit_tool.cpp:294
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
void FilterCollectorForMarkers(GENERAL_COLLECTOR &aCollector) const
Drop any PCB_MARKERs from the collector.
void FilterCollectorForHierarchy(GENERAL_COLLECTOR &aCollector, bool aMultiselect) const
In general we don't want to select both a parent and any of it's children.

References SELECTION::Empty(), PCB_SELECTION_TOOL::FilterCollectorForHierarchy(), PCB_SELECTION_TOOL::FilterCollectorForMarkers(), ARRAY_CREATOR::Invoke(), isRouterActive(), PCB_TOOL_BASE::m_isFootprintEditor, m_selectionTool, TOOL_BASE::m_toolMgr, PCB_SELECTION_TOOL::RequestSelection(), and PCB_TOOL_BASE::selection().

Referenced by setTransitions().

◆ cutToClipboard()

int EDIT_TOOL::cutToClipboard ( const TOOL_EVENT aEvent)
private

Cut the current selection to the clipboard by formatting it as a fake pcb see #AppendBoardFromClipboard for importing.

Return the right modification point (e.g. for rotation), depending on the number of selected items.

Definition at line 2224 of file edit_tool.cpp.

2225{
2226 if( !copyToClipboard( aEvent ) )
2227 {
2228 // N.B. Setting the CUT flag prevents lock filtering as we only want to delete the items
2229 // that were copied to the clipboard, no more, no fewer. Filtering for locked item, if
2230 // any will be done in the copyToClipboard() routine
2231 TOOL_EVENT evt = aEvent;
2233 Remove( evt );
2234 }
2235
2236 return 0;
2237}
int copyToClipboard(const TOOL_EVENT &aEvent)
Send the current selection to the clipboard by formatting it as a fake pcb see #AppendBoardFromClipbo...
Definition: edit_tool.cpp:2157
int Remove(const TOOL_EVENT &aEvent)
Delete currently selected items.
Definition: edit_tool.cpp:1494
void SetParameter(T aParam)
Set a non-standard parameter assigned to the event.
Definition: tool_event.h:460

References copyToClipboard(), ACTIONS::CUT, Remove(), and TOOL_EVENT::SetParameter().

Referenced by setTransitions().

◆ displayOptions()

◆ doInteractiveItemPlacement()

void PCB_TOOL_BASE::doInteractiveItemPlacement ( const TOOL_EVENT aTool,
INTERACTIVE_PLACER_BASE aPlacer,
const wxString &  aCommitMessage,
int  aOptions = IPO_ROTATE | IPO_FLIP | IPO_REPEAT 
)
protectedinherited

Helper function for performing a common interactive idiom: wait for a left click, place an item there (perhaps with a dialog or other user interaction), then have it move with the mouse and respond to rotate/flip, etc.

More complex interactive processes are not supported here, you should implement a customised event loop for those.

Parameters
aItemCreatorthe callable that will attempt to create the item
aCommitMessagethe message used on a successful commit

Definition at line 39 of file pcb_tool_base.cpp.

42{
43 using namespace std::placeholders;
44 std::unique_ptr<BOARD_ITEM> newItem;
45
46 frame()->PushTool( aTool );
47
48 BOARD_COMMIT commit( frame() );
49
51
52 Activate();
53 // Must be done after Activate() so that it gets set into the correct context
54 controls()->ShowCursor( true );
55 controls()->ForceCursorPosition( false );
56 // do not capture or auto-pan until we start placing an item
57
58 PCB_GRID_HELPER grid( m_toolMgr, frame()->GetMagneticItemsSettings() );
59
60 // Add a VIEW_GROUP that serves as a preview for the new item
61 PCB_SELECTION preview;
62 view()->Add( &preview );
63
64 aPlacer->m_board = board();
65 aPlacer->m_frame = frame();
66 aPlacer->m_modifiers = 0;
67
68 auto makeNewItem =
69 [&]( VECTOR2I aPosition )
70 {
71 if( frame()->GetModel() )
72 newItem = aPlacer->CreateItem();
73
74 if( newItem )
75 {
76 newItem->SetPosition( aPosition );
77 preview.Add( newItem.get() );
78
79 if( newItem->Type() == PCB_FOOTPRINT_T )
80 {
81 FOOTPRINT* fp = dyn_cast<FOOTPRINT*>( newItem.get() );
82
83 // footprints have more drawable parts
84 fp->RunOnChildren( std::bind( &KIGFX::VIEW_GROUP::Add, &preview, _1 ) );
85 }
86 }
87 };
88
89 if( aOptions & IPO_SINGLE_CLICK )
90 makeNewItem( controls()->GetCursorPosition() );
91
92 auto setCursor =
93 [&]()
94 {
95 if( !newItem )
97 else
99 };
100
101 // Set initial cursor
102 setCursor();
103
104 // Main loop: keep receiving events
105 while( TOOL_EVENT* evt = Wait() )
106 {
107 setCursor();
108
109 grid.SetSnap( false ); // Interactive placement tools need to set their own item snaps
110 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
111 VECTOR2I cursorPos = grid.BestSnapAnchor( controls()->GetMousePosition(), nullptr );
112
113 aPlacer->m_modifiers = evt->Modifier();
114
115 auto cleanup =
116 [&] ()
117 {
118 newItem = nullptr;
119 preview.Clear();
120 view()->Update( &preview );
121 controls()->SetAutoPan( false );
122 controls()->CaptureCursor( false );
123 controls()->ShowCursor( true );
124 controls()->ForceCursorPosition( false );
125 };
126
127 if( evt->IsCancelInteractive() )
128 {
129 if( aOptions & IPO_SINGLE_CLICK )
130 {
131 cleanup();
132 frame()->PopTool( aTool );
133 break;
134 }
135 else if( newItem )
136 {
137 cleanup();
138 }
139 else
140 {
141 frame()->PopTool( aTool );
142 break;
143 }
144 }
145 else if( evt->IsActivate() )
146 {
147 if( newItem )
148 cleanup();
149
150 if( evt->IsPointEditor() )
151 {
152 // don't exit (the point editor runs in the background)
153 }
154 else if( evt->IsMoveTool() )
155 {
156 // leave ourselves on the stack so we come back after the move
157 break;
158 }
159 else
160 {
161 frame()->PopTool( aTool );
162 break;
163 }
164 }
165 else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) )
166 {
167 if( !newItem )
168 {
169 // create the item if possible
170 makeNewItem( cursorPos );
171
172 // no item created, so wait for another click
173 if( !newItem )
174 continue;
175
176 controls()->CaptureCursor( true );
177 controls()->SetAutoPan( true );
178 }
179 else
180 {
181 auto oldFlags = newItem->GetFlags();
182 newItem->ClearFlags();
183
184 if( !aPlacer->PlaceItem( newItem.get(), commit ) )
185 {
186 newItem->SetFlags( oldFlags );
187 continue;
188 }
189
190 preview.Clear();
191 newItem.release();
192 commit.Push( aCommitMessage );
193
194 controls()->CaptureCursor( false );
195 controls()->SetAutoPan( false );
196 controls()->ShowCursor( true );
197
198 if( !( aOptions & IPO_REPEAT ) )
199 break;
200
201 if( aOptions & IPO_SINGLE_CLICK )
202 makeNewItem( controls()->GetCursorPosition() );
203
204 setCursor();
205 }
206 }
207 else if( evt->IsClick( BUT_RIGHT ) )
208 {
210 }
211 else if( evt->IsAction( &PCB_ACTIONS::trackViaSizeChanged ) )
212 {
214 }
215 else if( newItem && evt->Category() == TC_COMMAND )
216 {
217 /*
218 * Handle any events that can affect the item as we move it around
219 */
220 if( TOOL_EVT_UTILS::IsRotateToolEvt( *evt ) && ( aOptions & IPO_ROTATE ) )
221 {
222 EDA_ANGLE rotationAngle = TOOL_EVT_UTILS::GetEventRotationAngle( *frame(), *evt );
223 newItem->Rotate( newItem->GetPosition(), rotationAngle );
224 view()->Update( &preview );
225 }
226 else if( evt->IsAction( &PCB_ACTIONS::flip ) && ( aOptions & IPO_FLIP ) )
227 {
228 newItem->Flip( newItem->GetPosition(), frame()->GetPcbNewSettings()->m_FlipLeftRight );
229 view()->Update( &preview );
230 }
231 else if( evt->IsAction( &PCB_ACTIONS::properties ) )
232 {
233 frame()->OnEditItemRequest( newItem.get() );
234
235 // Notify other tools of the changes
237 }
238 else if( evt->IsAction( &ACTIONS::refreshPreview ) )
239 {
240 preview.Clear();
241 newItem.release();
242
243 makeNewItem( cursorPos );
244 aPlacer->SnapItem( newItem.get() );
245 view()->Update( &preview );
246 }
247 else
248 {
249 evt->SetPassEvent();
250 }
251 }
252 else if( newItem && evt->IsMotion() )
253 {
254 // track the cursor
255 newItem->SetPosition( cursorPos );
256 aPlacer->SnapItem( newItem.get() );
257
258 // Show a preview of the item
259 view()->Update( &preview );
260 }
261 else
262 {
263 evt->SetPassEvent();
264 }
265 }
266
267 view()->Remove( &preview );
269 controls()->SetAutoPan( false );
270 controls()->CaptureCursor( false );
271 controls()->ForceCursorPosition( false );
272}
static TOOL_ACTION refreshPreview
Definition: actions.h:109
void SetCurrentCursor(KICURSOR aCursor)
Set the current cursor shape for this panel.
void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction) const
Invoke a function on all BOARD_ITEMs that belong to the footprint (pads, drawings,...
Definition: footprint.cpp:1356
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const override
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition: pcb_view.cpp:92
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1) override
Add a VIEW_ITEM to the view.
Definition: pcb_view.cpp:58
virtual void Remove(VIEW_ITEM *aItem) override
Remove a VIEW_ITEM from the view.
Definition: pcb_view.cpp:75
virtual void CaptureCursor(bool aEnabled)
Force the cursor to stay within the drawing panel area.
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.
virtual void SetAutoPan(bool aEnabled)
Turn on/off auto panning (this feature is used when there is a tool active (eg.
virtual void Add(VIEW_ITEM *aItem)
Add an item to the group.
Definition: view_group.cpp:57
static TOOL_ACTION trackViaSizeChanged
Definition: pcb_actions.h:327
static TOOL_ACTION properties
Activation of the edit tool.
Definition: pcb_actions.h:142
static TOOL_ACTION flip
Flipping of selected objects.
Definition: pcb_actions.h:126
virtual void OnEditItemRequest(BOARD_ITEM *aItem)=0
Install the corresponding dialog editor for the given item.
virtual BOARD_ITEM_CONTAINER * GetModel() const =0
KIGFX::PCB_VIEW * view() const
KIGFX::VIEW_CONTROLS * controls() const
virtual void Add(EDA_ITEM *aItem)
Definition: selection.cpp:32
virtual void Clear() override
Remove all the stored items from the group.
Definition: selection.h:90
TOOL_MANAGER * GetManager() const
Return the instance of TOOL_MANAGER that takes care of the tool.
Definition: tool_base.h:143
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
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 ShowContextMenu(SELECTION &aSelection)
Helper function to set and immediately show a CONDITIONAL_MENU in concert with the given SELECTION.
Definition: tool_menu.cpp:57
EDA_ANGLE GetEventRotationAngle(const PCB_BASE_EDIT_FRAME &aFrame, const TOOL_EVENT &aEvent)
Function getEventRotationAngle()
bool IsRotateToolEvt(const TOOL_EVENT &aEvt)
Function isRotateToolEvt()
virtual void SnapItem(BOARD_ITEM *aItem)
PCB_BASE_EDIT_FRAME * m_frame
Definition: pcb_tool_base.h:64
virtual std::unique_ptr< BOARD_ITEM > CreateItem()=0
virtual bool PlaceItem(BOARD_ITEM *aItem, BOARD_COMMIT &aCommit)
@ TC_COMMAND
Definition: tool_event.h:52
@ BUT_LEFT
Definition: tool_event.h:127
@ BUT_RIGHT
Definition: tool_event.h:128
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition: typeinfo.h:86

References TOOL_INTERACTIVE::Activate(), SELECTION::Add(), KIGFX::VIEW_GROUP::Add(), KIGFX::PCB_VIEW::Add(), ARROW, PCB_TOOL_BASE::board(), BUT_LEFT, BUT_RIGHT, KIGFX::VIEW_CONTROLS::CaptureCursor(), SELECTION::Clear(), PCB_TOOL_BASE::controls(), INTERACTIVE_PLACER_BASE::CreateItem(), PCB_ACTIONS::flip, KIGFX::VIEW_CONTROLS::ForceCursorPosition(), PCB_TOOL_BASE::frame(), PCB_BASE_FRAME::GetCanvas(), TOOL_EVT_UTILS::GetEventRotationAngle(), TOOL_BASE::GetManager(), PCB_BASE_FRAME::GetModel(), TOOL_BASE::getView(), grid, PCB_TOOL_BASE::IPO_FLIP, PCB_TOOL_BASE::IPO_REPEAT, PCB_TOOL_BASE::IPO_ROTATE, PCB_TOOL_BASE::IPO_SINGLE_CLICK, TOOL_EVT_UTILS::IsRotateToolEvt(), INTERACTIVE_PLACER_BASE::m_board, INTERACTIVE_PLACER_BASE::m_frame, TOOL_INTERACTIVE::m_menu, INTERACTIVE_PLACER_BASE::m_modifiers, TOOL_BASE::m_toolMgr, PCB_BASE_EDIT_FRAME::OnEditItemRequest(), PCB_FOOTPRINT_T, PENCIL, PLACE, INTERACTIVE_PLACER_BASE::PlaceItem(), TOOLS_HOLDER::PopTool(), TOOL_MANAGER::ProcessEvent(), PCB_ACTIONS::properties, BOARD_COMMIT::Push(), TOOLS_HOLDER::PushTool(), ACTIONS::refreshPreview, KIGFX::PCB_VIEW::Remove(), TOOL_MANAGER::RunAction(), FOOTPRINT::RunOnChildren(), EVENTS::SelectedItemsModified, PCB_TOOL_BASE::selection(), PCB_ACTIONS::selectionClear, KIGFX::VIEW_CONTROLS::SetAutoPan(), EDA_DRAW_PANEL_GAL::SetCurrentCursor(), TOOL_MENU::ShowContextMenu(), KIGFX::VIEW_CONTROLS::ShowCursor(), INTERACTIVE_PLACER_BASE::SnapItem(), TC_COMMAND, PCB_ACTIONS::trackViaSizeChanged, KIGFX::PCB_VIEW::Update(), PCB_TOOL_BASE::view(), and TOOL_INTERACTIVE::Wait().

Referenced by MICROWAVE_TOOL::addMicrowaveFootprint(), DRAWING_TOOL::DrawVia(), and PAD_TOOL::PlacePad().

◆ doMoveSelection()

int EDIT_TOOL::doMoveSelection ( const TOOL_EVENT aEvent,
bool  aPickReference = false 
)
private

Definition at line 470 of file edit_tool_move_fct.cpp.

471{
472 PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
473 BOARD* board = editFrame->GetBoard();
475 VECTOR2I originalCursorPos = controls->GetCursorPosition();
476
477 // Be sure that there is at least one item that we can modify. If nothing was selected before,
478 // try looking for the stuff under mouse cursor (i.e. KiCad old-style hover selection)
480 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
481 {
482 sTool->FilterCollectorForMarkers( aCollector );
483 sTool->FilterCollectorForHierarchy( aCollector, true );
484 },
485 // Prompt user regarding locked items if in board editor and in free-pad-mode (if
486 // we're not in free-pad mode we delay this until the second RequestSelection()).
487 editFrame->GetPcbNewSettings()->m_AllowFreePads && !m_isFootprintEditor );
488
489 if( m_dragging || selection.Empty() )
490 return 0;
491
492 LSET item_layers = selection.GetSelectionLayers();
493 bool is_hover = selection.IsHover(); // N.B. This must be saved before the second call
494 // to RequestSelection() below
495 VECTOR2I pickedReferencePoint;
496
497 // Now filter out pads if not in free pads mode. We cannot do this in the first
498 // RequestSelection() as we need the item_layers when a pad is the selection front.
500 {
502 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
503 {
504 sTool->FilterCollectorForMarkers( aCollector );
505 sTool->FilterCollectorForHierarchy( aCollector, true );
506 sTool->FilterCollectorForFreePads( aCollector );
507 },
508 true /* prompt user regarding locked items */ );
509 }
510
511 if( selection.Empty() )
512 return 0;
513
514 editFrame->PushTool( aEvent );
515
516 Activate();
517 // Must be done after Activate() so that it gets set into the correct context
518 controls->ShowCursor( true );
519 controls->SetAutoPan( true );
521
522 if( aPickReference && !pickReferencePoint( _( "Select reference point for move..." ), "", "",
523 pickedReferencePoint ) )
524 {
525 if( is_hover )
527
528 editFrame->PopTool( aEvent );
529 return 0;
530 }
531
532 auto displayConstraintsMessage =
533 [editFrame]( bool constrained )
534 {
535 editFrame->DisplayConstraintsMsg( constrained ? _( "Constrain to H, V, 45" )
536 : wxT( "" ) );
537 };
538
539 std::vector<BOARD_ITEM*> sel_items; // All the items operated on by the move below
540 std::vector<BOARD_ITEM*> orig_items; // All the original items in the selection
541 std::vector<FOOTPRINT*> lastFpInConflict; // last footprints with courtyard overlapping
542
543 for( EDA_ITEM* item : selection )
544 {
545 BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item );
546 FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( item );
547
548 if( boardItem )
549 {
550 if( !is_hover )
551 orig_items.push_back( boardItem );
552
553 sel_items.push_back( boardItem );
554 }
555
556 if( footprint )
557 {
558 for( PAD* pad : footprint->Pads() )
559 sel_items.push_back( pad );
560
561 // Clear this flag here; it will be set by the netlist updater if the footprint is new
562 // so that it was skipped in the initial connectivity update in OnNetlistChanged
563 footprint->SetAttributes( footprint->GetAttributes() & ~FP_JUST_ADDED );
564 }
565 }
566
567 bool restore_state = false;
568 VECTOR2I originalPos;
569 VECTOR2I totalMovement;
570 VECTOR2D bboxMovement;
571 BOX2I originalBBox;
572 bool updateBBox = true;
574 TOOL_EVENT copy = aEvent;
575 TOOL_EVENT* evt = &copy;
576 VECTOR2I prevPos;
577
578 bool hv45Mode = false;
579 bool eatFirstMouseUp = true;
580 bool hasRedrawn3D = false;
581 bool allowRedraw3D = editFrame->GetPcbNewSettings()->m_Display.m_Live3DRefresh;
582 // Courtyard conflicts will be tested only if the LAYER_CONFLICTS_SHADOW gal layer is visible
583 bool showCourtyardConflicts = !m_isFootprintEditor
585
586 displayConstraintsMessage( hv45Mode );
587
588 // Used to test courtyard overlaps
590
591 if( showCourtyardConflicts )
592 {
593 drc_on_move.Init( board );
594 drc_on_move.SetDRCEngine( m_toolMgr->GetTool<DRC_TOOL>()->GetDRCEngine().get() );
595 }
596
597 // Prime the pump
599
600 // Main loop: keep receiving events
601 do
602 {
603 VECTOR2I movement;
605 grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
606 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
607
608 if( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) )
609 eatFirstMouseUp = false;
610
611 if( evt->IsAction( &PCB_ACTIONS::move ) || evt->IsMotion() || evt->IsDrag( BUT_LEFT )
615 {
616 if( m_dragging && evt->Category() == TC_MOUSE )
617 {
618 bool redraw3D = false;
619
620 VECTOR2I mousePos( controls->GetMousePosition() );
621
622 m_cursor = grid.BestSnapAnchor( mousePos, item_layers, sel_items );
623
625 {
627
628 // The arrow keys are by definition SINGLE AXIS. Do not allow the other
629 // axis to be snapped to the grid.
630 if( action == ACTIONS::CURSOR_LEFT || action == ACTIONS::CURSOR_RIGHT )
631 m_cursor.y = prevPos.y;
632 else if( action == ACTIONS::CURSOR_UP || action == ACTIONS::CURSOR_DOWN )
633 m_cursor.x = prevPos.x;
634 }
635
637 originalPos = m_cursor;
638
639 if( hv45Mode )
640 {
641 VECTOR2I moveVector = m_cursor - originalPos;
642 m_cursor = originalPos + GetVectorSnapped45( moveVector );
643 }
644
645 if( updateBBox )
646 {
647 originalBBox = BOX2I();
648 bboxMovement = VECTOR2D();
649
650 for( EDA_ITEM* item : sel_items )
651 {
652 BOX2I viewBBOX = item->ViewBBox();
653
654 if( originalBBox.GetWidth() == 0 && originalBBox.GetHeight() == 0 )
655 originalBBox = viewBBOX;
656 else
657 originalBBox.Merge( viewBBOX );
658 }
659
660 updateBBox = false;
661 }
662
663 // Constrain selection bounding box to coordinates limits
664 movement = getSafeMovement( m_cursor - prevPos, originalBBox, bboxMovement );
665
666 // Apply constrained movement
667 m_cursor = prevPos + movement;
668
671
672 prevPos = m_cursor;
673 totalMovement += movement;
674 bboxMovement += movement;
675
676 // Drag items to the current cursor position
677 for( EDA_ITEM* item : sel_items )
678 {
679 // Don't double move footprint pads, fields, etc.
680 //
681 // For PCB_GROUP_T, we make sure the selection includes only the top level
682 // group and not its descendants.
683 if( !item->GetParent() || !item->GetParent()->IsSelected() )
684 static_cast<BOARD_ITEM*>( item )->Move( movement );
685
686 if( !redraw3D && item->Type() == PCB_FOOTPRINT_T )
687 redraw3D = true;
688 }
689
690 if( redraw3D && allowRedraw3D )
691 {
692 editFrame->Update3DView( false, true );
693 hasRedrawn3D = true;
694 }
695
696 if( showCourtyardConflicts && drc_on_move.m_FpInMove.size() )
697 {
698 drc_on_move.Run();
699
700 bool need_redraw = false; // will be set to true if a COURTYARD_CONFLICT
701 // has changed
702
703 // Ensure the "old" conflicts are cleared
704 for( FOOTPRINT* fp: lastFpInConflict )
705 {
706 fp->ClearFlags( COURTYARD_CONFLICT );
707 m_toolMgr->GetView()->Update( fp );
708 need_redraw = true;
709 }
710
711 lastFpInConflict.clear();
712
713 for( FOOTPRINT* fp: drc_on_move.m_FpInConflict )
714 {
715 if( !fp->HasFlag( COURTYARD_CONFLICT ) )
716 {
718 m_toolMgr->GetView()->Update( fp );
719 need_redraw = true;
720 }
721
722 lastFpInConflict.push_back( fp );
723 }
724
725 if( need_redraw )
727 }
728
730 }
731 else if( !m_dragging && !evt->IsAction( &ACTIONS::refreshPreview ) )
732 {
733 // Prepare to start dragging
734 if( !( evt->IsAction( &PCB_ACTIONS::move )
738 {
740 break;
741 }
742
743 editFrame->HideSolderMask();
744
745 m_dragging = true;
746
747 // When editing footprints, all items have the same parent
748 if( IsFootprintEditor() )
749 {
750 m_commit->Modify( selection.Front() );
751 }
752 else
753 {
754 // Save items, so changes can be undone
755 for( EDA_ITEM* item : selection )
756 {
757 // Don't double move footprint pads, fields, etc.
758 //
759 // For PCB_GROUP_T, the parent is the board.
760 if( item->GetParent() && item->GetParent()->IsSelected() )
761 continue;
762
763 m_commit->Modify( item );
764
765 // If moving a group, record position of all the descendants for undo
766 if( item->Type() == PCB_GROUP_T )
767 {
768 PCB_GROUP* group = static_cast<PCB_GROUP*>( item );
769 group->RunOnDescendants( [&]( BOARD_ITEM* bItem )
770 {
771 m_commit->Modify( bItem );
772 });
773 }
774 }
775 }
776
777 editFrame->UndoRedoBlock( true );
779
781 {
782 // start moving with the reference point attached to the cursor
783 grid.SetAuxAxes( false );
784
785 if( hv45Mode )
786 {
787 VECTOR2I moveVector = m_cursor - originalPos;
788 m_cursor = originalPos + GetVectorSnapped45( moveVector );
789 }
790
791 movement = m_cursor - selection.GetReferencePoint();
792
793 // Drag items to the current cursor position
794 for( EDA_ITEM* item : selection )
795 {
796 // Don't double move footprint pads, fields, etc.
797 if( item->GetParent() && item->GetParent()->IsSelected() )
798 continue;
799
800 static_cast<BOARD_ITEM*>( item )->Move( movement );
801 }
802
804 }
805 else
806 {
807 std::vector<BOARD_ITEM*> items;
808
809 for( EDA_ITEM* item : selection )
810 {
811 items.push_back( static_cast<BOARD_ITEM*>( item ) );
812
813 if( item->Type() == PCB_FOOTPRINT_T )
814 drc_on_move.m_FpInMove.push_back( static_cast<FOOTPRINT*>( item ) );
815 }
816
817 m_cursor = grid.BestDragOrigin( originalCursorPos, items );
818
819 // Set the current cursor position to the first dragged item origin, so the
820 // movement vector could be computed later
821 if( aPickReference )
822 {
823 selection.SetReferencePoint( pickedReferencePoint );
824 controls->ForceCursorPosition( true, pickedReferencePoint );
825 m_cursor = pickedReferencePoint;
826 }
827 else
828 {
829 // Check if user wants to warp the mouse to origin of moved object
830 if( !editFrame->GetMoveWarpsCursor() )
831 m_cursor = originalCursorPos; // No, so use original mouse pos instead
832
834 grid.SetAuxAxes( true, m_cursor );
835 }
836
837 originalPos = m_cursor;
838 }
839
840 // Update variables for bounding box collision calculations
841 updateBBox = true;
842
844
845 prevPos = m_cursor;
846 controls->SetAutoPan( true );
848 }
849
851 }
852 else if( evt->IsCancelInteractive() || evt->IsActivate() )
853 {
854 if( m_dragging && evt->IsCancelInteractive() )
855 evt->SetPassEvent( false );
856
857 restore_state = true; // Canceling the tool means that items have to be restored
858 break; // Finish
859 }
860 else if( evt->IsAction( &ACTIONS::undo ) )
861 {
862 restore_state = true; // Perform undo locally
863 break; // Finish
864 }
865 else if( evt->IsAction( &ACTIONS::doDelete ) || evt->IsAction( &ACTIONS::cut ) )
866 {
867 // Dispatch TOOL_ACTIONs
868 evt->SetPassEvent();
869 break; // finish -- there is no further processing for removed items
870 }
871 else if( evt->IsAction( &ACTIONS::duplicate ) )
872 {
873 evt->SetPassEvent();
874 break; // finish -- Duplicate tool will start a new Move with the dup'ed items
875 }
876 else if( evt->IsAction( &PCB_ACTIONS::rotateCw )
878 || evt->IsAction( &PCB_ACTIONS::flip )
880 || evt->IsAction( &PCB_ACTIONS::mirrorV ) )
881 {
882 updateBBox = true;
883 eatFirstMouseUp = false;
884 evt->SetPassEvent();
885 }
886 else if( evt->IsAction( &PCB_ACTIONS::moveExact ) )
887 {
888 // Reset positions so the Move Exactly is from the start.
889 for( EDA_ITEM* item : selection )
890 {
891 BOARD_ITEM* i = static_cast<BOARD_ITEM*>( item );
892 i->Move( -totalMovement );
893 }
894
895 break; // finish -- we moved exactly, so we are finished
896 }
897 else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
898 {
899 // Eat mouse-up/-click events that leaked through from the lock dialog
900 if( eatFirstMouseUp && evt->Parameter<intptr_t>() != ACTIONS::CURSOR_CLICK )
901 {
902 eatFirstMouseUp = false;
903 continue;
904 }
905
906 break; // finish
907 }
908 else if( evt->IsAction( &PCB_ACTIONS::toggleHV45Mode ) )
909 {
910 hv45Mode = !hv45Mode;
911 displayConstraintsMessage( hv45Mode );
912 evt->SetPassEvent( false );
913 }
914 else
915 {
916 evt->SetPassEvent();
917 }
918
919 } while( ( evt = Wait() ) ); // Assignment (instead of equality test) is intentional
920
921 // Clear temporary COURTYARD_CONFLICT flag and ensure the conflict shadow is cleared
922 for( FOOTPRINT* fp: lastFpInConflict )
923 {
924 m_toolMgr->GetView()->Update( fp );
926 }
927
929 controls->ShowCursor( false );
930 controls->SetAutoPan( false );
931
932 m_dragging = false;
933 editFrame->UndoRedoBlock( false );
934
935 m_toolMgr->GetTool<DRAWING_TOOL>()->UpdateStatusBar();
936
937 if( hasRedrawn3D && restore_state )
938 editFrame->Update3DView( false, true );
939
940 // Discard reference point when selection is "dropped" onto the board
942
943 // TODO: there's an encapsulation leak here: this commit often has more than just the move
944 // in it; for instance it might have a paste, append board, etc. as well.
945 if( restore_state )
946 m_commit->Revert();
947 else
948 m_commit->Push( _( "Drag" ) );
949
950 // Remove the dynamic ratsnest from the screen
952
953 // Unselect all items to clear selection flags and then re-select the originally selected
954 // items.
956 m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &orig_items );
957
958 editFrame->PopTool( aEvent );
960
961 return restore_state ? -1 : 0;
962}
BOX2< VECTOR2I > BOX2I
Definition: box2.h:847
@ CURSOR_RIGHT
Definition: actions.h:189
@ CURSOR_LEFT
Definition: actions.h:189
@ CURSOR_CLICK
Definition: actions.h:190
@ CURSOR_UP
Definition: actions.h:189
@ CURSOR_DOWN
Definition: actions.h:189
static TOOL_ACTION undo
Definition: actions.h:65
static TOOL_ACTION duplicate
Definition: actions.h:72
static TOOL_ACTION doDelete
Definition: actions.h:73
virtual void Move(const VECTOR2I &aMoveVector)
Move this object.
Definition: board_item.h:255
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:265
bool IsElementVisible(GAL_LAYER_ID aLayer) const
Test whether a given element category is visible.
Definition: board.cpp:551
coord_type GetHeight() const
Definition: box2.h:188
coord_type GetWidth() const
Definition: box2.h:187
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:588
Tool responsible for drawing graphical elements like lines, arcs, circles, etc.
Definition: drawing_tool.h:51
virtual bool Run() override
Run this provider against the given PCB with configured options (if any).
void SetDRCEngine(DRC_ENGINE *engine)
std::shared_ptr< DRC_ENGINE > GetDRCEngine()
Definition: drc_tool.h:78
void DisplayConstraintsMsg(const wxString &msg)
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:156
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:157
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
Definition: eda_item.h:159
int Move(const TOOL_EVENT &aEvent)
Main loop in which events are handled.
VECTOR2I getSafeMovement(const VECTOR2I &aMovement, const BOX2I &aSourceBBox, const VECTOR2D &aBBoxOffset)
VECTOR2I m_cursor
Definition: edit_tool.h:205
bool invokeInlineRouter(int aDragMode)
Definition: edit_tool.cpp:264
static const TOOL_EVENT SelectedItemsMoved
Used to inform tools that the selection should temporarily be non-editable.
Definition: actions.h:213
void SetAttributes(int aAttributes)
Definition: footprint.h:246
int GetAttributes() const
Definition: footprint.h:245
PADS & Pads()
Definition: footprint.h:174
An interface for classes handling user events controlling the view behavior such as zooming,...
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
virtual VECTOR2D GetMousePosition(bool aWorldCoordinates=true) const =0
Return the current mouse pointer position.
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.
const VC_SETTINGS & GetSettings() const
Apply VIEW_CONTROLS settings from an object.
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:1574
void MarkTargetDirty(int aTarget)
Set or clear target 'dirty' flag.
Definition: view.h:617
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:530
Definition: pad.h:58
TRACK_DRAG_ACTION m_TrackDragAction
static TOOL_ACTION toggleHV45Mode
Definition: pcb_actions.h:455
static TOOL_ACTION mirrorH
Mirroring of selected items.
Definition: pcb_actions.h:129
static TOOL_ACTION hideLocalRatsnest
Definition: pcb_actions.h:496
static TOOL_ACTION moveWithReference
move with a reference point
Definition: pcb_actions.h:116
static TOOL_ACTION moveExact
Activation of the exact move tool.
Definition: pcb_actions.h:145
static TOOL_ACTION updateLocalRatsnest
Definition: pcb_actions.h:497
static TOOL_ACTION moveIndividually
move items one-by-one
Definition: pcb_actions.h:113
static TOOL_ACTION move
move or drag an item
Definition: pcb_actions.h:110
static TOOL_ACTION mirrorV
Definition: pcb_actions.h:130
static TOOL_ACTION selectItems
Select a list of items (specified as the event parameter)
Definition: pcb_actions.h:66
static TOOL_ACTION rotateCw
Rotation of selected objects.
Definition: pcb_actions.h:122
static TOOL_ACTION rotateCcw
Definition: pcb_actions.h:123
Common, abstract interface for edit frames.
void UndoRedoBlock(bool aBlock=true)
Enable/disable undo and redo operations.
virtual MAGNETIC_SETTINGS * GetMagneticItemsSettings()
BOARD * GetBoard() const
virtual void Update3DView(bool aMarkDirty, bool aRefresh, const wxString *aTitle=nullptr)
Update the 3D view, if the viewer is opened by this frame.
A set of BOARD_ITEMs (i.e., without duplicates).
Definition: pcb_group.h:51
void FilterCollectorForFreePads(GENERAL_COLLECTOR &aCollector) const
Check the "allow free pads" setting and if disabled, replace any pads in the collector with their par...
const LSET GetSelectionLayers()
bool IsFootprintEditor() const
FOOTPRINT * footprint() const
VECTOR2I GetReferencePoint() const
Definition: selection.h:244
EDA_ITEM * Front() const
Definition: selection.h:200
void ClearReferencePoint()
Definition: selection.h:257
bool HasReferencePoint() const
Definition: selection.h:239
bool GetMoveWarpsCursor() const
Indicate that a move operation should warp the mouse pointer to the origin of the move object.
Definition: tools_holder.h:153
bool DisableGridSnapping() const
Definition: tool_event.h:344
bool IsCancelInteractive() const
Indicate the event should restart/end an ongoing interactive tool's event loop (eg esc key,...
Definition: tool_event.cpp:212
T Parameter() const
Return a non-standard parameter assigned to the event.
Definition: tool_event.h:442
bool IsActivate() const
Definition: tool_event.h:318
bool IsClick(int aButtonMask=BUT_ANY) const
Definition: tool_event.cpp:200
bool IsDrag(int aButtonMask=BUT_ANY) const
Definition: tool_event.h:288
int Modifier(int aMask=MD_MODIFIER_MASK) const
Definition: tool_event.h:339
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:239
bool IsMouseUp(int aButtonMask=BUT_ANY) const
Definition: tool_event.h:298
bool IsMotion() const
Definition: tool_event.h:303
void PostEvent(const TOOL_EVENT &aEvent)
Put an event to the event queue to be processed at the end of event processing cycle.
KIGFX::VIEW * GetView() const
Definition: tool_manager.h:285
#define COURTYARD_CONFLICT
temporary set when moving footprints having courtyard overlapping
VECTOR2< T > GetVectorSnapped45(const VECTOR2< T > &aVec, bool only45=false)
Snap a vector onto the nearest 0, 45 or 90 degree line.
@ LAYER_CONFLICTS_SHADOW
shadow layer for items flagged conficting
Definition: layer_ids.h:241
@ TARGET_OVERLAY
Items that may change while the view stays the same (noncached)
Definition: definitions.h:50
@ DM_ANY
Definition: pns_router.h:77
bool m_lastKeyboardCursorPositionValid
ACTIONS::CURSOR_UP, ACTIONS::CURSOR_DOWN, etc.
long m_lastKeyboardCursorCommand
Position of the above event.
@ TC_MOUSE
Definition: tool_event.h:50
@ MD_SHIFT
Definition: tool_event.h:138
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
Definition: typeinfo.h:115
VECTOR2< double > VECTOR2D
Definition: vector2d.h:617
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618

References _, TOOL_INTERACTIVE::Activate(), ARROW, PCB_TOOL_BASE::board(), BUT_LEFT, TOOL_EVENT::Category(), SELECTION::ClearReferencePoint(), PCB_TOOL_BASE::controls(), copy, COURTYARD_CONFLICT, ACTIONS::CURSOR_CLICK, ACTIONS::CURSOR_DOWN, ACTIONS::CURSOR_LEFT, ACTIONS::CURSOR_RIGHT, ACTIONS::CURSOR_UP, ACTIONS::cut, TOOL_EVENT::DisableGridSnapping(), EDA_DRAW_FRAME::DisplayConstraintsMsg(), PNS::DM_ANY, ACTIONS::doDelete, ACTIONS::duplicate, SELECTION::Empty(), PCB_SELECTION_TOOL::FilterCollectorForFreePads(), PCB_SELECTION_TOOL::FilterCollectorForHierarchy(), PCB_SELECTION_TOOL::FilterCollectorForMarkers(), PCB_ACTIONS::flip, PCB_TOOL_BASE::footprint(), KIGFX::VIEW_CONTROLS::ForceCursorPosition(), SELECTION::Front(), FOOTPRINT::GetAttributes(), PCB_BASE_FRAME::GetBoard(), PCB_BASE_FRAME::GetCanvas(), KIGFX::VIEW_CONTROLS::GetCursorPosition(), DRC_TOOL::GetDRCEngine(), BOX2< Vec >::GetHeight(), PCB_BASE_FRAME::GetMagneticItemsSettings(), KIGFX::VIEW_CONTROLS::GetMousePosition(), TOOLS_HOLDER::GetMoveWarpsCursor(), PCB_BASE_FRAME::GetPcbNewSettings(), SELECTION::GetReferencePoint(), getSafeMovement(), PCB_SELECTION::GetSelectionLayers(), KIGFX::VIEW_CONTROLS::GetSettings(), TOOL_MANAGER::GetTool(), GetVectorSnapped45(), TOOL_BASE::getView(), TOOL_MANAGER::GetView(), TOOL_BASE::getViewControls(), BOX2< Vec >::GetWidth(), grid, group, EDA_ITEM::HasFlag(), SELECTION::HasReferencePoint(), PCB_ACTIONS::hideLocalRatsnest, PCB_BASE_FRAME::HideSolderMask(), DRC_TEST_PROVIDER_COURTYARD_CLEARANCE_ON_MOVE::Init(), invokeInlineRouter(), TOOL_EVENT::IsAction(), TOOL_EVENT::IsActivate(), TOOL_EVENT::IsCancelInteractive(), TOOL_EVENT::IsClick(), TOOL_EVENT::IsDrag(), BOARD::IsElementVisible(), PCB_TOOL_BASE::IsFootprintEditor(), SELECTION::IsHover(), TOOL_EVENT::IsMotion(), TOOL_EVENT::IsMouseUp(), LAYER_CONFLICTS_SHADOW, PCBNEW_SETTINGS::m_AllowFreePads, m_commit, m_cursor, PCBNEW_SETTINGS::m_Display, m_dragging, DRC_TEST_PROVIDER_COURTYARD_CLEARANCE_ON_MOVE::m_FpInConflict, DRC_TEST_PROVIDER_COURTYARD_CLEARANCE_ON_MOVE::m_FpInMove, PCB_TOOL_BASE::m_isFootprintEditor, KIGFX::VC_SETTINGS::m_lastKeyboardCursorCommand, KIGFX::VC_SETTINGS::m_lastKeyboardCursorPositionValid, PCBNEW_SETTINGS::DISPLAY_OPTIONS::m_Live3DRefresh, m_selectionTool, TOOL_BASE::m_toolMgr, PCBNEW_SETTINGS::m_TrackDragAction, KIGFX::VIEW::MarkTargetDirty(), MD_SHIFT, BOX2< Vec >::Merge(), PCB_ACTIONS::mirrorH, PCB_ACTIONS::mirrorV, TOOL_EVENT::Modifier(), MOVE, Move(), BOARD_ITEM::Move(), PCB_ACTIONS::move, PCB_ACTIONS::moveExact, PCB_ACTIONS::moveIndividually, PCB_ACTIONS::moveWithReference, MOVING, pad, FOOTPRINT::Pads(), TOOL_EVENT::Parameter(), PCB_FOOTPRINT_T, PCB_GROUP_T, pickReferencePoint(), TOOLS_HOLDER::PopTool(), TOOL_MANAGER::PostEvent(), TOOLS_HOLDER::PushTool(), ACTIONS::refreshPreview, PCB_SELECTION_TOOL::RequestSelection(), PCB_ACTIONS::rotateCcw, PCB_ACTIONS::rotateCw, DRC_TEST_PROVIDER_COURTYARD_CLEARANCE_ON_MOVE::Run(), TOOL_MANAGER::RunAction(), EVENTS::SelectedItemsModified, EVENTS::SelectedItemsMoved, PCB_TOOL_BASE::selection(), PCB_ACTIONS::selectionClear, PCB_ACTIONS::selectItems, FOOTPRINT::SetAttributes(), KIGFX::VIEW_CONTROLS::SetAutoPan(), EDA_DRAW_PANEL_GAL::SetCurrentCursor(), KIGFX::VIEW_CONTROLS::SetCursorPosition(), DRC_TEST_PROVIDER::SetDRCEngine(), EDA_ITEM::SetFlags(), TOOL_EVENT::SetPassEvent(), SELECTION::SetReferencePoint(), KIGFX::VIEW_CONTROLS::ShowCursor(), KIGFX::TARGET_OVERLAY, TC_MOUSE, PCB_ACTIONS::toggleHV45Mode, ACTIONS::undo, PCB_BASE_EDIT_FRAME::UndoRedoBlock(), KIGFX::VIEW::Update(), PCB_BASE_FRAME::Update3DView(), PCB_ACTIONS::updateLocalRatsnest, TOOL_INTERACTIVE::Wait(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by Move(), MoveIndividually(), and MoveWithReference().

◆ Drag()

int EDIT_TOOL::Drag ( const TOOL_EVENT aEvent)

Invoke the PNS router to drag tracks or do an offline resizing of an arc track if a single arc track is selected.

Definition at line 302 of file edit_tool.cpp.

303{
304 if( !m_toolMgr->GetTool<ROUTER_TOOL>() )
305 return false; // don't drag when no router tool (i.e. fp editor)
306
308 return false; // don't drag when router is already active
309
310 int mode = PNS::DM_ANY;
311
312 if( aEvent.IsAction( &PCB_ACTIONS::dragFreeAngle ) )
313 mode |= PNS::DM_FREE_ANGLE;
314
316 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
317 {
318 sTool->FilterCollectorForFreePads( aCollector );
319 sTool->FilterCollectorForHierarchy( aCollector, true );
320
321 if( aCollector.GetCount() > 1 )
322 sTool->GuessSelectionCandidates( aCollector, aPt );
323
324 /*
325 * If we have a knee between two segments, or a via attached to two segments,
326 * then drop the selection to a single item.
327 */
328
329 std::vector<PCB_TRACK*> tracks;
330 std::vector<PCB_TRACK*> vias;
331
332 for( EDA_ITEM* item : aCollector )
333 {
334 if( PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( item ) )
335 {
336 if( track->Type() == PCB_VIA_T )
337 vias.push_back( track );
338 else
339 tracks.push_back( track );
340 }
341 }
342
343 auto connected = []( PCB_TRACK* track, const VECTOR2I& pt )
344 {
345 return track->GetStart() == pt || track->GetEnd() == pt;
346 };
347
348 if( tracks.size() == 2 && vias.size() == 0 )
349 {
350 if( connected( tracks[0], tracks[1]->GetStart() )
351 || connected( tracks[0], tracks[1]->GetEnd() ) )
352 {
353 aCollector.Remove( tracks[1] );
354 }
355 }
356 else if( tracks.size() == 2 && vias.size() == 1 )
357 {
358 if( connected( tracks[0], vias[0]->GetPosition() )
359 && connected( tracks[1], vias[0]->GetPosition() ) )
360 {
361 aCollector.Remove( tracks[0] );
362 aCollector.Remove( tracks[1] );
363 }
364 }
365 },
366 true /* prompt user regarding locked items */ );
367
368 if( selection.Empty() )
369 return 0;
370
371 if( selection.Size() == 1 && selection.Front()->Type() == PCB_ARC_T )
372 {
373 // TODO: This really should be done in PNS to ensure DRC is maintained, but for now
374 // it allows interactive editing of an arc track
375 return DragArcTrack( aEvent );
376 }
377 else
378 {
379 invokeInlineRouter( mode );
380 }
381
382 return 0;
383}
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
Definition: collector.h:109
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:111
int DragArcTrack(const TOOL_EVENT &aTrack)
Drag-resize an arc (and change end points of connected straight segments).
Definition: edit_tool.cpp:386
static TOOL_ACTION dragFreeAngle
Definition: pcb_actions.h:160
void GuessSelectionCandidates(GENERAL_COLLECTOR &aCollector, const VECTOR2I &aWhere) const
Try to guess best selection candidates in case multiple items are clicked, by doing some brain-dead h...
const VECTOR2I & GetStart() const
Definition: pcb_track.h:111
const VECTOR2I & GetEnd() const
Definition: pcb_track.h:108
int Size() const
Returns the number of selected parts.
Definition: selection.h:113
bool IsToolActive() const
Definition: tool_base.cpp:31
@ DM_FREE_ANGLE
Definition: pns_router.h:75

References PNS::DM_ANY, PNS::DM_FREE_ANGLE, PCB_ACTIONS::dragFreeAngle, PCB_SELECTION_TOOL::FilterCollectorForFreePads(), PCB_SELECTION_TOOL::FilterCollectorForHierarchy(), COLLECTOR::GetCount(), PCB_TRACK::GetEnd(), PCB_TRACK::GetStart(), TOOL_MANAGER::GetTool(), PCB_SELECTION_TOOL::GuessSelectionCandidates(), TOOL_EVENT::IsAction(), TOOL_BASE::IsToolActive(), m_selectionTool, TOOL_BASE::m_toolMgr, COLLECTOR::Remove(), PCB_SELECTION_TOOL::RequestSelection(), and PCB_TOOL_BASE::selection().

Referenced by setTransitions().

◆ DragArcTrack()

int EDIT_TOOL::DragArcTrack ( const TOOL_EVENT aTrack)

Drag-resize an arc (and change end points of connected straight segments).

Definition at line 386 of file edit_tool.cpp.

387{
389
390 if( selection.Size() != 1 || selection.Front()->Type() != PCB_ARC_T )
391 return 0;
392
393 PCB_ARC* theArc = static_cast<PCB_ARC*>( selection.Front() );
394 EDA_ANGLE maxTangentDeviation( ADVANCED_CFG::GetCfg().m_MaxTangentAngleDeviation, DEGREES_T );
395
396 if( theArc->GetAngle() + maxTangentDeviation >= ANGLE_180 )
397 {
398 wxString msg = wxString::Format( _( "Unable to resize arc tracks of %s or greater." ),
399 EDA_UNIT_UTILS::UI::MessageTextFromValue( ANGLE_180 - maxTangentDeviation ) );
400 frame()->ShowInfoBarError( msg );
401
402 return 0; // don't bother with > 180 degree arcs
403 }
404
406
407 Activate();
408 // Must be done after Activate() so that it gets set into the correct context
409 controls->ShowCursor( true );
410 controls->SetAutoPan( true );
411
412 bool restore_state = false;
413 VECTOR2I arcCenter = theArc->GetCenter();
414 SEG tanStart = SEG( arcCenter, theArc->GetStart() ).PerpendicularSeg( theArc->GetStart() );
415 SEG tanEnd = SEG( arcCenter, theArc->GetEnd() ).PerpendicularSeg( theArc->GetEnd() );
416
417 //Ensure the tangent segments are in the correct orientation
418 OPT_VECTOR2I tanIntersect = tanStart.IntersectLines( tanEnd );
419
420 if( !tanIntersect )
421 return 0;
422
423 tanStart.A = *tanIntersect;
424 tanStart.B = theArc->GetStart();
425 tanEnd.A = *tanIntersect;
426 tanEnd.B = theArc->GetEnd();
427
428 auto getUniqueTrackAtAnchorCollinear =
429 [&]( const VECTOR2I& aAnchor, const SEG& aCollinearSeg ) -> PCB_TRACK*
430 {
431 std::shared_ptr<CONNECTIVITY_DATA> conn = board()->GetConnectivity();
432
433 // Allow items at a distance within the width of the arc track
434 int allowedDeviation = theArc->GetWidth();
435
436 std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
437
438 for( int i = 0; i < 3; i++ )
439 {
440 itemsOnAnchor = conn->GetConnectedItemsAtAnchor( theArc, aAnchor,
443 allowedDeviation );
444 allowedDeviation /= 2;
445
446 if( itemsOnAnchor.size() == 1 )
447 break;
448 }
449
450 PCB_TRACK* retval = nullptr;
451
452 if( itemsOnAnchor.size() == 1 && itemsOnAnchor.front()->Type() == PCB_TRACE_T )
453 {
454 retval = static_cast<PCB_TRACK*>( itemsOnAnchor.front() );
455 SEG trackSeg( retval->GetStart(), retval->GetEnd() );
456
457 // Allow deviations in colinearity as defined in ADVANCED_CFG
458 if( trackSeg.Angle( aCollinearSeg ) > maxTangentDeviation )
459 retval = nullptr;
460 }
461
462 if( !retval )
463 {
464 retval = new PCB_TRACK( theArc->GetParent() );
465 retval->SetStart( aAnchor );
466 retval->SetEnd( aAnchor );
467 retval->SetNet( theArc->GetNet() );
468 retval->SetLayer( theArc->GetLayer() );
469 retval->SetWidth( theArc->GetWidth() );
470 retval->SetLocked( theArc->IsLocked() );
471 retval->SetFlags( IS_NEW );
472 getView()->Add( retval );
473 }
474
475 return retval;
476 };
477
478 PCB_TRACK* trackOnStart = getUniqueTrackAtAnchorCollinear( theArc->GetStart(), tanStart);
479 PCB_TRACK* trackOnEnd = getUniqueTrackAtAnchorCollinear( theArc->GetEnd(), tanEnd );
480
481 // Make copies of items to be edited
482 PCB_ARC* theArcCopy = new PCB_ARC( *theArc );
483 PCB_TRACK* trackOnStartCopy = new PCB_TRACK( *trackOnStart );
484 PCB_TRACK* trackOnEndCopy = new PCB_TRACK( *trackOnEnd );
485
486 if( trackOnStart->GetLength() != 0 )
487 {
488 tanStart.A = trackOnStart->GetStart();
489 tanStart.B = trackOnStart->GetEnd();
490 }
491
492 if( trackOnEnd->GetLength() != 0 )
493 {
494 tanEnd.A = trackOnEnd->GetStart();
495 tanEnd.B = trackOnEnd->GetEnd();
496 }
497
498 // Recalculate intersection point
499 if( tanIntersect = tanStart.IntersectLines( tanEnd ); !tanIntersect )
500 return 0;
501
502 auto isTrackStartClosestToArcStart =
503 [&]( PCB_TRACK* aTrack ) -> bool
504 {
505 double trackStartToArcStart = GetLineLength( aTrack->GetStart(), theArc->GetStart() );
506 double trackEndToArcStart = GetLineLength( aTrack->GetEnd(), theArc->GetStart() );
507
508 return trackStartToArcStart < trackEndToArcStart;
509 };
510
511 bool isStartTrackOnStartPt = isTrackStartClosestToArcStart( trackOnStart );
512 bool isEndTrackOnStartPt = isTrackStartClosestToArcStart( trackOnEnd );
513
514 // Calculate constraints
515 //======================
516 // maxTanCircle is the circle with maximum radius that is tangent to the two adjacent straight
517 // tracks and whose tangent points are constrained within the original tracks and their
518 // projected intersection points.
519 //
520 // The cursor will be constrained first within the isosceles triangle formed by the segments
521 // cSegTanStart, cSegTanEnd and cSegChord. After that it will be constrained to be outside
522 // maxTanCircle.
523 //
524 //
525 // ____________ <-cSegTanStart
526 // / * . ' *
527 // cSegTanEnd-> / * . ' *
528 // /* . ' <-cSegChord *
529 // /. '
530 // /* *
531 //
532 // * c * <-maxTanCircle
533 //
534 // * *
535 //
536 // * *
537 // * *
538 // * *
539 //
540
541 auto getFurthestPointToTanInterstect =
542 [&]( VECTOR2I& aPointA, VECTOR2I& aPointB ) -> VECTOR2I
543 {
544 if( ( aPointA - *tanIntersect ).EuclideanNorm()
545 > ( aPointB - *tanIntersect ).EuclideanNorm() )
546 {
547 return aPointA;
548 }
549 else
550 {
551 return aPointB;
552 }
553 };
554
555 CIRCLE maxTanCircle;
556 VECTOR2I tanStartPoint = getFurthestPointToTanInterstect( tanStart.A, tanStart.B );
557 VECTOR2I tanEndPoint = getFurthestPointToTanInterstect( tanEnd.A, tanEnd.B );
558 VECTOR2I tempTangentPoint = tanEndPoint;
559
560 if( getFurthestPointToTanInterstect( tanStartPoint, tanEndPoint ) == tanEndPoint )
561 tempTangentPoint = tanStartPoint;
562
563 maxTanCircle.ConstructFromTanTanPt( tanStart, tanEnd, tempTangentPoint );
564 VECTOR2I maxTanPtStart = tanStart.LineProject( maxTanCircle.Center );
565 VECTOR2I maxTanPtEnd = tanEnd.LineProject( maxTanCircle.Center );
566
567 SEG cSegTanStart( maxTanPtStart, *tanIntersect );
568 SEG cSegTanEnd( maxTanPtEnd, *tanIntersect );
569 SEG cSegChord( maxTanPtStart, maxTanPtEnd );
570
571 int cSegTanStartSide = cSegTanStart.Side( theArc->GetMid() );
572 int cSegTanEndSide = cSegTanEnd.Side( theArc->GetMid() );
573 int cSegChordSide = cSegChord.Side( theArc->GetMid() );
574
575 bool eatFirstMouseUp = true;
576
577 // Start the tool loop
578 while( TOOL_EVENT* evt = Wait() )
579 {
581
582 // Constrain cursor within the isosceles triangle
583 if( cSegTanStartSide != cSegTanStart.Side( m_cursor )
584 || cSegTanEndSide != cSegTanEnd.Side( m_cursor )
585 || cSegChordSide != cSegChord.Side( m_cursor ) )
586 {
587 std::vector<VECTOR2I> possiblePoints;
588
589 possiblePoints.push_back( cSegTanEnd.NearestPoint( m_cursor ) );
590 possiblePoints.push_back( cSegChord.NearestPoint( m_cursor ) );
591
592 VECTOR2I closest = cSegTanStart.NearestPoint( m_cursor );
593
594 for( VECTOR2I candidate : possiblePoints )
595 {
596 if( ( candidate - m_cursor ).SquaredEuclideanNorm()
597 < ( closest - m_cursor ).SquaredEuclideanNorm() )
598 {
599 closest = candidate;
600 }
601 }
602
603 m_cursor = closest;
604 }
605
606 // Constrain cursor to be outside maxTanCircle
607 if( ( m_cursor - maxTanCircle.Center ).EuclideanNorm() < maxTanCircle.Radius )
608 m_cursor = maxTanCircle.NearestPoint( m_cursor );
609
611
612 // Calculate resulting object coordinates
613 CIRCLE circlehelper;
614 circlehelper.ConstructFromTanTanPt( cSegTanStart, cSegTanEnd, m_cursor );
615
616 VECTOR2I newCenter = circlehelper.Center;
617 VECTOR2I newStart = cSegTanStart.LineProject( newCenter );
618 VECTOR2I newEnd = cSegTanEnd.LineProject( newCenter );
619 VECTOR2I newMid = CalcArcMid( newStart, newEnd, newCenter );
620
621 // Update objects
622 theArc->SetStart( newStart );
623 theArc->SetEnd( newEnd );
624 theArc->SetMid( newMid );
625
626 if( isStartTrackOnStartPt )
627 trackOnStart->SetStart( newStart );
628 else
629 trackOnStart->SetEnd( newStart );
630
631 if( isEndTrackOnStartPt )
632 trackOnEnd->SetStart( newEnd );
633 else
634 trackOnEnd->SetEnd( newEnd );
635
636 // Update view
637 getView()->Update( trackOnStart );
638 getView()->Update( trackOnEnd );
639 getView()->Update( theArc );
640
641 // Handle events
642 if( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) )
643 {
644 eatFirstMouseUp = false;
645 }
646 else if( evt->IsCancelInteractive() || evt->IsActivate() )
647 {
648 restore_state = true; // Canceling the tool means that items have to be restored
649 break; // Finish
650 }
651 else if( evt->IsAction( &ACTIONS::undo ) )
652 {
653 restore_state = true; // Perform undo locally
654 break; // Finish
655 }
656 else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT )
657 || evt->IsDblClick( BUT_LEFT ) )
658 {
659 // Eat mouse-up/-click events that leaked through from the lock dialog
660 if( eatFirstMouseUp && evt->Parameter<intptr_t>() != ACTIONS::CURSOR_CLICK )
661 {
662 eatFirstMouseUp = false;
663 continue;
664 }
665
666 break; // Finish
667 }
668 }
669
670 // Ensure we only do one commit operation on each object
671 auto processTrack =
672 [&]( PCB_TRACK* aTrack, PCB_TRACK* aTrackCopy, int aMaxLengthIU ) -> bool
673 {
674 if( aTrack->IsNew() )
675 {
676 getView()->Remove( aTrack );
677
678 if( aTrack->GetLength() <= aMaxLengthIU )
679 {
680 delete aTrack;
681 delete aTrackCopy;
682 aTrack = nullptr;
683 aTrackCopy = nullptr;
684 return false;
685 }
686 else
687 {
688 m_commit->Add( aTrack );
689 delete aTrackCopy;
690 aTrackCopy = nullptr;
691 return true;
692 }
693 }
694 else if( aTrack->GetLength() <= aMaxLengthIU )
695 {
696 aTrack->SwapData( aTrackCopy ); //restore the original before notifying COMMIT
697 m_commit->Remove( aTrack );
698 delete aTrackCopy;
699 aTrackCopy = nullptr;
700 return false;
701 }
702 else
703 {
704 m_commit->Modified( aTrack, aTrackCopy );
705 }
706
707 return true;
708 };
709
710 // Amend the end points of the arc if we delete the joining tracks
711 VECTOR2I newStart = trackOnStart->GetStart();
712 VECTOR2I newEnd = trackOnEnd->GetStart();
713
714 if( isStartTrackOnStartPt )
715 newStart = trackOnStart->GetEnd();
716
717 if( isEndTrackOnStartPt )
718 newEnd = trackOnEnd->GetEnd();
719
720 int maxLengthIU =
721 KiROUND( ADVANCED_CFG::GetCfg().m_MaxTrackLengthToKeep * pcbIUScale.IU_PER_MM );
722
723 if( !processTrack( trackOnStart, trackOnStartCopy, maxLengthIU ) )
724 theArc->SetStart( newStart );
725
726 if( !processTrack( trackOnEnd, trackOnEndCopy, maxLengthIU ) )
727 theArc->SetEnd( newEnd );
728
729 processTrack( theArc, theArcCopy, 0 ); // only delete the arc if start and end points coincide
730
731 // Should we commit?
732 if( restore_state )
733 m_commit->Revert();
734 else
735 m_commit->Push( _( "Drag Arc Track" ) );
736
737 return 0;
738}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:109
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
NETINFO_ITEM * GetNet() const
Return #NET_INFO object for a given item.
void SetNet(NETINFO_ITEM *aNetInfo)
Set a NET_INFO object for the item.
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:169
virtual void SetLocked(bool aLocked)
Definition: board_item.h:243
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:203
virtual bool IsLocked() const
Definition: board_item.cpp:65
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:152
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:424
Represent basic circle geometry with utility geometry functions.
Definition: circle.h:33
VECTOR2I Center
Public to make access simpler.
Definition: circle.h:116
int Radius
Public to make access simpler.
Definition: circle.h:115
CIRCLE & ConstructFromTanTanPt(const SEG &aLineA, const SEG &aLineB, const VECTOR2I &aP)
Construct this circle such that it is tangent to the given segments and passes through the given poin...
Definition: circle.cpp:51
VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute the point on the circumference of the circle that is the closest to aP.
Definition: circle.cpp:197
void ShowInfoBarError(const wxString &aErrorMsg, bool aShowCloseButton=false, WX_INFOBAR::MESSAGE_TYPE aType=WX_INFOBAR::MESSAGE_TYPE::GENERIC)
Show the WX_INFOBAR displayed on the top of the canvas with a message and an error icon on the left o...
bool IsNew() const
Definition: eda_item.h:117
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:316
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp:346
void SetMid(const VECTOR2I &aMid)
Definition: pcb_track.h:273
EDA_ANGLE GetAngle() const
Definition: pcb_track.cpp:1100
const VECTOR2I & GetMid() const
Definition: pcb_track.h:274
virtual VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition: pcb_track.h:283
PCB_SELECTION & GetSelection()
virtual void SwapData(BOARD_ITEM *aImage) override
Swap data between aItem and aImage.
Definition: pcb_track.cpp:1066
virtual double GetLength() const
Function GetLength returns the length of the track using the hypotenuse calculation.
Definition: pcb_track.cpp:278
int GetWidth() const
Definition: pcb_track.h:105
void SetEnd(const VECTOR2I &aEnd)
Definition: pcb_track.h:107
void SetStart(const VECTOR2I &aStart)
Definition: pcb_track.h:110
Definition: seg.h:42
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50
OPT_VECTOR2I IntersectLines(const SEG &aSeg) const
Compute the intersection point of lines passing through ends of (this) and aSeg.
Definition: seg.h:210
VECTOR2I LineProject(const VECTOR2I &aP) const
Compute the perpendicular projection point of aP on a line passing through ends of the segment.
Definition: seg.cpp:302
SEG PerpendicularSeg(const VECTOR2I &aP) const
Compute a segment perpendicular to this one, passing through point aP.
Definition: seg.cpp:199
static constexpr EDA_ANGLE & ANGLE_180
Definition: eda_angle.h:416
@ DEGREES_T
Definition: eda_angle.h:31
#define IS_NEW
New item, just created.
wxString MessageTextFromValue(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, double aValue, bool aAddUnitsText=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
A helper to convert the double length aValue to a string in inches, millimeters, or unscaled units.
Definition: eda_units.cpp:323
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
std::optional< VECTOR2I > OPT_VECTOR2I
Definition: seg.h:39
const double IU_PER_MM
Definition: base_units.h:77
const VECTOR2I CalcArcMid(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCenter, bool aMinArcAngle=true)
Return the middle point of an arc, half-way between aStart and aEnd.
Definition: trigo.cpp:163
double GetLineLength(const VECTOR2I &aPointA, const VECTOR2I &aPointB)
Return the length of a line segment defined by aPointA and aPointB.
Definition: trigo.h:188
double EuclideanNorm(const VECTOR2I &vector)
Definition: trigo.h:129
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition: typeinfo.h:87
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:80

References _, SEG::A, TOOL_INTERACTIVE::Activate(), KIGFX::VIEW::Add(), SEG::Angle(), ANGLE_180, SEG::B, PCB_TOOL_BASE::board(), BUT_LEFT, CalcArcMid(), CIRCLE::Center, CIRCLE::ConstructFromTanTanPt(), PCB_TOOL_BASE::controls(), ACTIONS::CURSOR_CLICK, DEGREES_T, EuclideanNorm(), KIGFX::VIEW_CONTROLS::ForceCursorPosition(), Format(), PCB_TOOL_BASE::frame(), SELECTION::Front(), PCB_ARC::GetAngle(), PCB_ARC::GetCenter(), ADVANCED_CFG::GetCfg(), BOARD::GetConnectivity(), PCB_TRACK::GetEnd(), BOARD_ITEM::GetLayer(), PCB_TRACK::GetLength(), GetLineLength(), PCB_ARC::GetMid(), KIGFX::VIEW_CONTROLS::GetMousePosition(), BOARD_CONNECTED_ITEM::GetNet(), BOARD_ITEM::GetParent(), PCB_SELECTION_TOOL::GetSelection(), PCB_TRACK::GetStart(), TOOL_BASE::getView(), TOOL_BASE::getViewControls(), PCB_TRACK::GetWidth(), SEG::IntersectLines(), IS_NEW, BOARD_ITEM::IsLocked(), EDA_ITEM::IsNew(), EDA_IU_SCALE::IU_PER_MM, KiROUND(), SEG::LineProject(), m_commit, m_cursor, m_selectionTool, EDA_UNIT_UTILS::UI::MessageTextFromValue(), CIRCLE::NearestPoint(), SEG::NearestPoint(), PCB_ARC_T, PCB_PAD_T, PCB_TRACE_T, PCB_VIA_T, pcbIUScale, SEG::PerpendicularSeg(), CIRCLE::Radius, KIGFX::VIEW::Remove(), PCB_TOOL_BASE::selection(), KIGFX::VIEW_CONTROLS::SetAutoPan(), PCB_TRACK::SetEnd(), EDA_ITEM::SetFlags(), BOARD_ITEM::SetLayer(), BOARD_ITEM::SetLocked(), PCB_ARC::SetMid(), BOARD_CONNECTED_ITEM::SetNet(), PCB_TRACK::SetStart(), PCB_TRACK::SetWidth(), KIGFX::VIEW_CONTROLS::ShowCursor(), EDA_BASE_FRAME::ShowInfoBarError(), SEG::Side(), SELECTION::Size(), PCB_TRACK::SwapData(), EDA_ITEM::Type(), ACTIONS::undo, KIGFX::VIEW::Update(), and TOOL_INTERACTIVE::Wait().

◆ Duplicate()

int EDIT_TOOL::Duplicate ( const TOOL_EVENT aEvent)

Duplicate the current selection and starts a move action.

Definition at line 1849 of file edit_tool.cpp.

1850{
1851 if( isRouterActive() )
1852 {
1853 wxBell();
1854 return 0;
1855 }
1856
1857 bool increment = aEvent.IsAction( &PCB_ACTIONS::duplicateIncrement );
1858
1859 // Be sure that there is at least one item that we can modify
1861 []( const VECTOR2I&, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1862 {
1863 sTool->FilterCollectorForMarkers( aCollector );
1864 sTool->FilterCollectorForHierarchy( aCollector, true );
1865 } );
1866
1867 if( selection.Empty() )
1868 return 0;
1869
1870 // we have a selection to work on now, so start the tool process
1871 PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
1872
1873 // If the selection was given a hover, we do not keep the selection after completion
1874 bool is_hover = selection.IsHover();
1875
1876 std::vector<BOARD_ITEM*> new_items;
1877 new_items.reserve( selection.Size() );
1878
1879 // Each selected item is duplicated and pushed to new_items list
1880 // Old selection is cleared, and new items are then selected.
1881 for( EDA_ITEM* item : selection )
1882 {
1883 BOARD_ITEM* dupe_item = nullptr;
1884 BOARD_ITEM* orig_item = static_cast<BOARD_ITEM*>( item );
1885
1887 {
1888 FOOTPRINT* parentFootprint = editFrame->GetBoard()->GetFirstFootprint();
1889 dupe_item = parentFootprint->DuplicateItem( orig_item );
1890
1891 if( increment && dupe_item->Type() == PCB_PAD_T
1892 && static_cast<PAD*>( dupe_item )->CanHaveNumber() )
1893 {
1894 PAD_TOOL* padTool = m_toolMgr->GetTool<PAD_TOOL>();
1895 wxString padNumber = padTool->GetLastPadNumber();
1896 padNumber = parentFootprint->GetNextPadNumber( padNumber );
1897 padTool->SetLastPadNumber( padNumber );
1898 static_cast<PAD*>( dupe_item )->SetNumber( padNumber );
1899 }
1900 }
1901 else if( orig_item->GetParent() && orig_item->GetParent()->Type() == PCB_FOOTPRINT_T )
1902 {
1903 FOOTPRINT* parentFootprint = static_cast<FOOTPRINT*>( orig_item->GetParent() );
1904
1905 m_commit->Modify( parentFootprint );
1906 dupe_item = parentFootprint->DuplicateItem( orig_item, true /* add to parent */ );
1907 }
1908 else
1909 {
1910 switch( orig_item->Type() )
1911 {
1912 case PCB_FOOTPRINT_T:
1913 case PCB_TEXT_T:
1914 case PCB_TEXTBOX_T:
1915 case PCB_BITMAP_T:
1916 case PCB_SHAPE_T:
1917 case PCB_TRACE_T:
1918 case PCB_ARC_T:
1919 case PCB_VIA_T:
1920 case PCB_ZONE_T:
1921 case PCB_TARGET_T:
1922 case PCB_DIM_ALIGNED_T:
1923 case PCB_DIM_CENTER_T:
1924 case PCB_DIM_RADIAL_T:
1926 case PCB_DIM_LEADER_T:
1927 dupe_item = orig_item->Duplicate();
1928 break;
1929
1930 case PCB_GROUP_T:
1931 dupe_item = static_cast<PCB_GROUP*>( orig_item )->DeepDuplicate();
1932 break;
1933
1934 default:
1935 wxASSERT_MSG( false, wxString::Format( wxT( "Unhandled item type %d" ),
1936 orig_item->Type() ) );
1937 break;
1938 }
1939 }
1940
1941 if( dupe_item )
1942 {
1943 if( dupe_item->Type() == PCB_GROUP_T )
1944 {
1945 static_cast<PCB_GROUP*>( dupe_item )->RunOnDescendants(
1946 [&]( BOARD_ITEM* bItem )
1947 {
1948 m_commit->Add( bItem );
1949 });
1950 }
1951
1952 // Clear the selection flag here, otherwise the PCB_SELECTION_TOOL
1953 // will not properly select it later on
1954 dupe_item->ClearSelected();
1955
1956 new_items.push_back( dupe_item );
1957 m_commit->Add( dupe_item );
1958 }
1959 }
1960
1961 // Clear the old selection first
1963
1964 // Select the new items
1965 m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &new_items );
1966
1967 // record the new items as added
1968 if( !selection.Empty() )
1969 {
1970 editFrame->DisplayToolMsg( wxString::Format( _( "Duplicated %d item(s)" ),
1971 (int) new_items.size() ) );
1972
1973 // TODO(ISM): This line can't be used to activate the tool until we allow multiple
1974 // activations.
1975 // m_toolMgr->RunAction( PCB_ACTIONS::move, true );
1976 // Instead we have to create the event and call the tool's function
1977 // directly
1978
1979 // If items were duplicated, pick them up
1980 // this works well for "dropping" copies around and pushes the commit
1982 Move( evt );
1983
1984 // Deslect the duplicated item if we originally started as a hover selection
1985 if( is_hover )
1987 }
1988
1989 return 0;
1990}
virtual BOARD_ITEM * Duplicate() const
Create a copy of this BOARD_ITEM.
Definition: board_item.cpp:160
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition: board.h:397
void DisplayToolMsg(const wxString &msg) override
void ClearSelected()
Definition: eda_item.h:135
BOARD_ITEM * DuplicateItem(const BOARD_ITEM *aItem, bool aAddToFootprint=false)
Duplicate a given item within the footprint, optionally adding it to the board.
Definition: footprint.cpp:1832
wxString GetNextPadNumber(const wxString &aLastPadName) const
Return the next available pad number in the footprint.
Definition: footprint.cpp:1944
Tool relating to pads and pad settings.
Definition: pad_tool.h:37
void SetLastPadNumber(const wxString &aPadNumber)
Definition: pad_tool.h:66
wxString GetLastPadNumber() const
Definition: pad_tool.h:65
static TOOL_ACTION duplicateIncrement
Activation of the duplication tool with incrementing (e.g. pad number)
Definition: pcb_actions.h:148
TOOL_EVENT MakeEvent() const
Return the event associated with the action (i.e.
Definition: tool_action.cpp:72
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:88
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
Definition: typeinfo.h:110
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
Definition: typeinfo.h:107
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
Definition: typeinfo.h:108
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition: typeinfo.h:91
@ PCB_ZONE_T
class ZONE, a copper pour area
Definition: typeinfo.h:112
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition: typeinfo.h:90
@ PCB_TARGET_T
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:111
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
Definition: typeinfo.h:106
@ PCB_BITMAP_T
class PCB_BITMAP, bitmap on a layer
Definition: typeinfo.h:89
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
Definition: typeinfo.h:109

References _, EDA_ITEM::ClearSelected(), EDA_DRAW_FRAME::DisplayToolMsg(), BOARD_ITEM::Duplicate(), PCB_ACTIONS::duplicateIncrement, FOOTPRINT::DuplicateItem(), SELECTION::Empty(), PCB_SELECTION_TOOL::FilterCollectorForHierarchy(), PCB_SELECTION_TOOL::FilterCollectorForMarkers(), Format(), PCB_BASE_FRAME::GetBoard(), BOARD::GetFirstFootprint(), PAD_TOOL::GetLastPadNumber(), FOOTPRINT::GetNextPadNumber(), BOARD_ITEM::GetParent(), TOOL_MANAGER::GetTool(), TOOL_EVENT::IsAction(), SELECTION::IsHover(), isRouterActive(), m_commit, PCB_TOOL_BASE::m_isFootprintEditor, m_selectionTool, TOOL_BASE::m_toolMgr, TOOL_ACTION::MakeEvent(), Move(), PCB_ACTIONS::move, PCB_ARC_T, PCB_BITMAP_T, PCB_DIM_ALIGNED_T, PCB_DIM_CENTER_T, PCB_DIM_LEADER_T, PCB_DIM_ORTHOGONAL_T, PCB_DIM_RADIAL_T, PCB_FOOTPRINT_T, PCB_GROUP_T, PCB_PAD_T, PCB_SHAPE_T, PCB_TARGET_T, PCB_TEXT_T, PCB_TEXTBOX_T, PCB_TRACE_T, PCB_VIA_T, PCB_ZONE_T, PCB_SELECTION_TOOL::RequestSelection(), TOOL_MANAGER::RunAction(), PCB_TOOL_BASE::selection(), PCB_ACTIONS::selectionClear, PCB_ACTIONS::selectItems, PAD_TOOL::SetLastPadNumber(), SELECTION::Size(), and EDA_ITEM::Type().

Referenced by setTransitions().

◆ FilletTracks()

int EDIT_TOOL::FilletTracks ( const TOOL_EVENT aEvent)

Fillet (i.e.

adds an arc tangent to) all selected straight tracks by a user defined radius.

Definition at line 811 of file edit_tool.cpp.

812{
813 // Store last used fillet radius to allow pressing "enter" if repeat fillet is required
814 static long long filletRadiusIU = 0;
815
817 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
818 {
819 // Iterate from the back so we don't have to worry about removals.
820 for( int i = aCollector.GetCount() - 1; i >= 0; --i )
821 {
822 BOARD_ITEM* item = aCollector[i];
823
824 if( !dynamic_cast<PCB_TRACK*>( item ) )
825 aCollector.Remove( item );
826 }
827 },
828 true /* prompt user regarding locked items */ );
829
830 if( selection.Size() < 2 )
831 {
832 frame()->ShowInfoBarMsg( _( "At least two straight track segments must be selected." ) );
833 return 0;
834 }
835
836 WX_UNIT_ENTRY_DIALOG dia( frame(), _( "Enter fillet radius:" ), _( "Fillet Tracks" ),
837 filletRadiusIU );
838
839 if( dia.ShowModal() == wxID_CANCEL )
840 return 0;
841
842 filletRadiusIU = dia.GetValue();
843
844 if( filletRadiusIU == 0 )
845 {
846 frame()->ShowInfoBarMsg( _( "A radius of zero was entered.\n"
847 "The fillet operation was not performed." ) );
848 return 0;
849 }
850
851 struct FILLET_OP
852 {
853 PCB_TRACK* t1;
854 PCB_TRACK* t2;
855 // Start point of track is modified after PCB_ARC is added, otherwise the end point:
856 bool t1Start = true;
857 bool t2Start = true;
858 };
859
860 std::vector<FILLET_OP> filletOperations;
861 bool operationPerformedOnAtLeastOne = false;
862 bool didOneAttemptFail = false;
863 std::set<PCB_TRACK*> processedTracks;
864
865 for( EDA_ITEM* item : selection )
866 {
867 PCB_TRACK* track = dyn_cast<PCB_TRACK*>( item );
868
869 if( !track || track->Type() != PCB_TRACE_T || track->GetLength() == 0 )
870 {
871 continue;
872 }
873
874 auto processFilletOp =
875 [&]( bool aStartPoint )
876 {
877 std::shared_ptr<CONNECTIVITY_DATA> c = board()->GetConnectivity();
878 VECTOR2I anchor = aStartPoint ? track->GetStart()
879 : track->GetEnd();
880 std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
881
882 itemsOnAnchor = c->GetConnectedItemsAtAnchor( track, anchor,
885
886 if( itemsOnAnchor.size() > 0
887 && selection.Contains( itemsOnAnchor.at( 0 ) )
888 && itemsOnAnchor.at( 0 )->Type() == PCB_TRACE_T )
889 {
890 PCB_TRACK* trackOther = dyn_cast<PCB_TRACK*>( itemsOnAnchor.at( 0 ) );
891
892 // Make sure we don't fillet the same pair of tracks twice
893 if( processedTracks.find( trackOther ) == processedTracks.end() )
894 {
895 if( itemsOnAnchor.size() == 1 )
896 {
897 FILLET_OP filletOp;
898 filletOp.t1 = track;
899 filletOp.t2 = trackOther;
900 filletOp.t1Start = aStartPoint;
901 filletOp.t2Start = track->IsPointOnEnds( filletOp.t2->GetStart() );
902 filletOperations.push_back( filletOp );
903 }
904 else
905 {
906 // User requested to fillet these two tracks but not possible as
907 // there are other elements connected at that point
908 didOneAttemptFail = true;
909 }
910 }
911 }
912 };
913
914 processFilletOp( true ); // on the start point of track
915 processFilletOp( false ); // on the end point of track
916
917 processedTracks.insert( track );
918 }
919
920 std::vector<BOARD_ITEM*> itemsToAddToSelection;
921
922 for( FILLET_OP filletOp : filletOperations )
923 {
924 PCB_TRACK* track1 = filletOp.t1;
925 PCB_TRACK* track2 = filletOp.t2;
926
927 bool trackOnStart = track1->IsPointOnEnds( track2->GetStart() );
928 bool trackOnEnd = track1->IsPointOnEnds( track2->GetEnd() );
929
930 if( trackOnStart && trackOnEnd )
931 continue; // Ignore duplicate tracks
932
933 if( ( trackOnStart || trackOnEnd ) && track1->GetLayer() == track2->GetLayer() )
934 {
935 SEG t1Seg( track1->GetStart(), track1->GetEnd() );
936 SEG t2Seg( track2->GetStart(), track2->GetEnd() );
937
938 if( t1Seg.ApproxCollinear( t2Seg ) )
939 continue;
940
941 SHAPE_ARC sArc( t1Seg, t2Seg, filletRadiusIU );
942 VECTOR2I t1newPoint, t2newPoint;
943
944 auto setIfPointOnSeg =
945 []( VECTOR2I& aPointToSet, SEG aSegment, VECTOR2I aVecToTest )
946 {
947 VECTOR2I segToVec = aSegment.NearestPoint( aVecToTest ) - aVecToTest;
948
949 // Find out if we are on the segment (minimum precision)
951 {
952 aPointToSet.x = aVecToTest.x;
953 aPointToSet.y = aVecToTest.y;
954 return true;
955 }
956
957 return false;
958 };
959
960 //Do not draw a fillet if the end points of the arc are not within the track segments
961 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.GetP0() )
962 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.GetP0() ) )
963 {
964 didOneAttemptFail = true;
965 continue;
966 }
967
968 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.GetP1() )
969 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.GetP1() ) )
970 {
971 didOneAttemptFail = true;
972 continue;
973 }
974
975 PCB_ARC* tArc = new PCB_ARC( frame()->GetBoard(), &sArc );
976 tArc->SetLayer( track1->GetLayer() );
977 tArc->SetWidth( track1->GetWidth() );
978 tArc->SetNet( track1->GetNet() );
979 tArc->SetLocked( track1->IsLocked() );
980 m_commit->Add( tArc );
981 itemsToAddToSelection.push_back( tArc );
982
983 m_commit->Modify( track1 );
984 m_commit->Modify( track2 );
985
986 if( filletOp.t1Start )
987 track1->SetStart( t1newPoint );
988 else
989 track1->SetEnd( t1newPoint );
990
991 if( filletOp.t2Start )
992 track2->SetStart( t2newPoint );
993 else
994 track2->SetEnd( t2newPoint );
995
996 operationPerformedOnAtLeastOne = true;
997 }
998 }
999
1000 m_commit->Push( _( "Fillet Tracks" ) );
1001
1002 //select the newly created arcs
1003 for( BOARD_ITEM* item : itemsToAddToSelection )
1005
1006 if( !operationPerformedOnAtLeastOne )
1007 frame()->ShowInfoBarMsg( _( "Unable to fillet the selected track segments." ) );
1008 else if( didOneAttemptFail )
1009 frame()->ShowInfoBarMsg( _( "Some of the track segments could not be filleted." ) );
1010
1011 return 0;
1012}
void ShowInfoBarMsg(const wxString &aMsg, bool aShowCloseButton=false)
Show the WX_INFOBAR displayed on the top of the canvas with a message and an info icon on the left of...
EDA_ITEM_FLAGS IsPointOnEnds(const VECTOR2I &point, int min_dist=0) const
Function IsPointOnEnds returns STARTPOINT if point if near (dist = min_dist) start point,...
Definition: pcb_track.cpp:200
int AddItemToSel(const TOOL_EVENT &aEvent)
bool Contains(EDA_ITEM *aItem) const
Definition: selection.cpp:74
static const int MIN_PRECISION_IU
This is the minimum precision for all the points in a shape.
Definition: shape.h:128
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:293
An extension of WX_TEXT_ENTRY_DIALOG that uses UNIT_BINDER to request a dimension (e....
BOARD * GetBoard()

References _, SELECTION_TOOL::AddItemToSel(), anchor, SEG::ApproxCollinear(), PCB_TOOL_BASE::board(), SELECTION::Contains(), VECTOR2< T >::EuclideanNorm(), PCB_TOOL_BASE::frame(), GetBoard(), BOARD::GetConnectivity(), COLLECTOR::GetCount(), PCB_TRACK::GetEnd(), BOARD_ITEM::GetLayer(), PCB_TRACK::GetLength(), BOARD_CONNECTED_ITEM::GetNet(), SHAPE_ARC::GetP0(), SHAPE_ARC::GetP1(), PCB_TRACK::GetStart(), WX_UNIT_ENTRY_DIALOG::GetValue(), PCB_TRACK::GetWidth(), BOARD_ITEM::IsLocked(), PCB_TRACK::IsPointOnEnds(), m_commit, m_selectionTool, SHAPE::MIN_PRECISION_IU, PCB_ARC_T, PCB_PAD_T, PCB_TRACE_T, PCB_VIA_T, PCB_SELECTION_TOOL::RequestSelection(), PCB_TOOL_BASE::selection(), PCB_TRACK::SetEnd(), BOARD_ITEM::SetLayer(), BOARD_ITEM::SetLocked(), BOARD_CONNECTED_ITEM::SetNet(), PCB_TRACK::SetStart(), PCB_TRACK::SetWidth(), EDA_BASE_FRAME::ShowInfoBarMsg(), SELECTION::Size(), EDA_ITEM::Type(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by setTransitions().

◆ Flip()

int EDIT_TOOL::Flip ( const TOOL_EVENT aEvent)

Rotate currently selected items.

The rotation point is the current cursor position.

Definition at line 1410 of file edit_tool.cpp.

1411{
1412 if( isRouterActive() )
1413 {
1414 wxBell();
1415 return 0;
1416 }
1417
1419 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1420 {
1421 sTool->FilterCollectorForMarkers( aCollector );
1422 sTool->FilterCollectorForHierarchy( aCollector, true );
1423 sTool->FilterCollectorForFreePads( aCollector );
1424 },
1425 !m_dragging /* prompt user regarding locked items */ );
1426
1427 if( selection.Empty() )
1428 return 0;
1429
1430 std::optional<VECTOR2I> oldRefPt;
1431
1433 oldRefPt = selection.GetReferencePoint();
1434
1436
1437 // Flip around the anchor for footprints, and the bounding box center for board items
1438 VECTOR2I refPt = IsFootprintEditor() ? VECTOR2I( 0, 0 ) : selection.GetCenter();
1439
1440 // If only one item selected, flip around the selection or item anchor point (instead
1441 // of the bounding box center) to avoid moving the item anchor
1442 if( selection.GetSize() == 1 )
1443 {
1445 refPt = selection.GetReferencePoint();
1446 else
1447 refPt = static_cast<BOARD_ITEM*>( selection.GetItem( 0 ) )->GetPosition();
1448 }
1449
1450 bool leftRight = frame()->GetPcbNewSettings()->m_FlipLeftRight;
1451
1452 // When editing footprints, all items have the same parent
1453 if( IsFootprintEditor() )
1454 m_commit->Modify( selection.Front() );
1455
1456 for( EDA_ITEM* item : selection )
1457 {
1458 if( !item->IsNew() && !IsFootprintEditor() )
1459 m_commit->Modify( item );
1460
1461 if( item->Type() == PCB_GROUP_T )
1462 {
1463 static_cast<PCB_GROUP*>( item )->RunOnDescendants( [&]( BOARD_ITEM* bItem )
1464 {
1465 m_commit->Modify( bItem );
1466 });
1467 }
1468
1469 static_cast<BOARD_ITEM*>( item )->Flip( refPt, leftRight );
1470 }
1471
1472 if( !m_dragging )
1473 m_commit->Push( _( "Change Side / Flip" ) );
1474
1475 if( selection.IsHover() && !m_dragging )
1477
1479
1480 if( m_dragging )
1482
1483 // Restore the old reference so any mouse dragging that occurs doesn't make the selection jump
1484 // to this now invalid reference
1485 if( oldRefPt )
1486 selection.SetReferencePoint( *oldRefPt );
1487 else
1489
1490 return 0;
1491}
int Flip(const TOOL_EVENT &aEvent)
Rotate currently selected items.
Definition: edit_tool.cpp:1410
bool updateModificationPoint(PCB_SELECTION &aSelection)
Definition: edit_tool.cpp:2047
virtual KIGFX::VIEW_ITEM * GetItem(unsigned int aIdx) const override
Definition: selection.cpp:65
virtual unsigned int GetSize() const override
Return the number of stored items.
Definition: selection.h:97

References _, SELECTION::ClearReferencePoint(), SELECTION::Empty(), PCB_SELECTION_TOOL::FilterCollectorForFreePads(), PCB_SELECTION_TOOL::FilterCollectorForHierarchy(), PCB_SELECTION_TOOL::FilterCollectorForMarkers(), Flip(), PCB_TOOL_BASE::frame(), SELECTION::Front(), SELECTION::GetCenter(), SELECTION::GetItem(), PCB_BASE_FRAME::GetPcbNewSettings(), SELECTION::GetReferencePoint(), SELECTION::GetSize(), SELECTION::HasReferencePoint(), PCB_TOOL_BASE::IsFootprintEditor(), SELECTION::IsHover(), isRouterActive(), m_commit, m_dragging, PCBNEW_SETTINGS::m_FlipLeftRight, m_selectionTool, TOOL_BASE::m_toolMgr, PCB_GROUP_T, TOOL_MANAGER::ProcessEvent(), PCB_SELECTION_TOOL::RequestSelection(), TOOL_MANAGER::RunAction(), EVENTS::SelectedItemsModified, PCB_TOOL_BASE::selection(), PCB_ACTIONS::selectionClear, SELECTION::SetReferencePoint(), PCB_ACTIONS::updateLocalRatsnest, and updateModificationPoint().

Referenced by Flip(), and setTransitions().

◆ footprint()

◆ FootprintFilter()

void EDIT_TOOL::FootprintFilter ( const VECTOR2I ,
GENERAL_COLLECTOR aCollector,
PCB_SELECTION_TOOL sTool 
)
static

A selection filter which prunes the selection to contain only items of type #PCB_MODULE_T.

Definition at line 2034 of file edit_tool.cpp.

2036{
2037 for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
2038 {
2039 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aCollector[i] );
2040
2041 if( item->Type() != PCB_FOOTPRINT_T )
2042 aCollector.Remove( i );
2043 }
2044}

References COLLECTOR::GetCount(), PCB_FOOTPRINT_T, COLLECTOR::Remove(), and EDA_ITEM::Type().

Referenced by BOARD_EDITOR_CONTROL::EditFpInFpEditor(), GLOBAL_EDIT_TOOL::ExchangeFootprints(), and BOARD_INSPECTION_TOOL::LocalRatsnestTool().

◆ frame()

PCB_BASE_EDIT_FRAME * PCB_TOOL_BASE::frame ( ) const
inlineprotectedinherited

Definition at line 165 of file pcb_tool_base.h.

166 {
167 return getEditFrame<PCB_BASE_EDIT_FRAME>();
168 }

Referenced by PCB_POINT_EDITOR::addCorner(), AUTOPLACE_TOOL::autoplace(), PCB_TOOL_BASE::canvas(), ZONE_FILLER_TOOL::CheckAllZones(), PNS::TOOL_BASE::checkSnap(), PAD_TOOL::copyPadSettings(), copyToClipboard(), ROUTER_TOOL::CustomTrackWidthDialog(), FOOTPRINT_EDITOR_CONTROL::DeleteFootprint(), PCB_TOOL_BASE::displayOptions(), BOARD_EDITOR_CONTROL::doCrossProbePcbToSch(), PCB_TOOL_BASE::doInteractiveItemPlacement(), ROUTER_TOOL::DpDimensionsDialog(), DragArcTrack(), DRAWING_TOOL::drawArc(), DRAWING_TOOL::DrawDimension(), MICROWAVE_TOOL::drawMicrowaveInductor(), DRAWING_TOOL::drawShape(), DRAWING_TOOL::DrawVia(), DRAWING_TOOL::DrawZone(), PAD_TOOL::EditPad(), PAD_TOOL::EnumeratePads(), PAD_TOOL::explodePad(), BOARD_EDITOR_CONTROL::ExportSpecctraDSN(), ZONE_FILLER_TOOL::FillAllZones(), FilletTracks(), ROUTER_TOOL::finishInteractive(), Flip(), PCB_CONTROL::FlipPcbView(), GLOBAL_EDIT_TOOL::GlobalDeletions(), ROUTER_TOOL::handleLayerSwitch(), PCB_CONTROL::HighContrastMode(), PCB_CONTROL::HighContrastModeCycle(), BOARD_INSPECTION_TOOL::HighlightItem(), FOOTPRINT_EDITOR_CONTROL::ImportFootprint(), BOARD_EDITOR_CONTROL::ImportSpecctraSession(), SCRIPTING_TOOL::Init(), ROUTER_TOOL::Init(), Init(), ROUTER_TOOL::InlineBreakTrack(), ROUTER_TOOL::InlineDrag(), DRAWING_TOOL::InteractivePlaceWithPreview(), PCB_TOOL_BASE::Is45Limited(), PCB_PICKER_TOOL::Main(), LENGTH_TUNER_TOOL::MainLoop(), ROUTER_TOOL::MainLoop(), LENGTH_TUNER_TOOL::meanderSettingsDialog(), MoveExact(), PCB_CONTROL::NetColorModeCycle(), PCB_POINT_EDITOR::OnSelectionChange(), ROUTER_TOOL::onViaCommand(), PCB_CONTROL::Paste(), PAD_TOOL::pastePadProperties(), ROUTER_TOOL::performDragging(), ROUTER_TOOL::performRouting(), LENGTH_TUNER_TOOL::performTuning(), GROUP_TOOL::PickNewMember(), PNS::TOOL_BASE::pickSingleItem(), PCB_CONTROL::placeBoardItems(), BOARD_EDITOR_CONTROL::PlaceFootprint(), DRAWING_TOOL::PlaceText(), ROUTER_TOOL::prepareInteractive(), PAD_TOOL::pushPadSettings(), POSITION_RELATIVE_TOOL::RelativeItemSelectionMove(), SCRIPTING_TOOL::reloadPlugins(), Remove(), PCB_POINT_EDITOR::removeCorner(), PNS::TOOL_BASE::Reset(), PAD_TOOL::Reset(), Rotate(), ROUTER_TOOL::RouteSelected(), ROUTER_TOOL::SelectCopperLayerPair(), POSITION_RELATIVE_TOOL::SelectPositionRelativeItem(), PCB_POINT_EDITOR::setEditedPoint(), ROUTER_TOOL::SettingsDialog(), GLOBAL_EDIT_TOOL::swapBoardItem(), GLOBAL_EDIT_TOOL::SwapLayers(), ROUTER_TOOL::switchLayerOnViaPlacement(), DRAWING_TOOL::ToggleHV45Mode(), PCB_CONTROL::unfilledZoneCheck(), PCB_POINT_EDITOR::updateItem(), ROUTER_TOOL::UpdateMessagePanel(), updateModificationPoint(), BOARD_EDITOR_CONTROL::UpdateSchematicFromPCB(), PCB_CONTROL::ZoneDisplayMode(), ZONE_FILLER_TOOL::ZoneFill(), ZONE_FILLER_TOOL::ZoneFillAll(), and ZONE_FILLER_TOOL::ZoneFillDirty().

◆ GetAndPlace()

int EDIT_TOOL::GetAndPlace ( const TOOL_EVENT aEvent)

Definition at line 241 of file edit_tool.cpp.

242{
243 // GetAndPlace makes sense only in board editor, although it is also called
244 // in fpeditor, that shares the same EDIT_TOOL list
245 if( !getEditFrame<PCB_BASE_FRAME>()->IsType( FRAME_PCB_EDITOR ) )
246 return 0;
247
249 FOOTPRINT* fp = getEditFrame<PCB_BASE_FRAME>()->GetFootprintFromBoardByReference();
250
251 if( fp )
252 {
254 m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, (void*) fp );
255
256 selectionTool->GetSelection().SetReferencePoint( fp->GetPosition() );
258 }
259
260 return 0;
261}
static TOOL_ACTION selectItem
Select an item (specified as the event parameter).
Definition: pcb_actions.h:62
@ FRAME_PCB_EDITOR
Definition: frame_type.h:40

References FRAME_PCB_EDITOR, PCB_SELECTION_TOOL::GetSelection(), TOOL_MANAGER::GetTool(), TOOL_BASE::m_toolMgr, PCB_ACTIONS::move, TOOL_MANAGER::RunAction(), PCB_ACTIONS::selectionClear, PCB_ACTIONS::selectItem, and SELECTION::SetReferencePoint().

Referenced by setTransitions().

◆ GetCurrentCommit()

BOARD_COMMIT * EDIT_TOOL::GetCurrentCommit ( ) const
inline

Definition at line 168 of file edit_tool.h.

168{ return m_commit.get(); }

References m_commit.

◆ getEditFrame()

template<typename T >
T * TOOL_BASE::getEditFrame ( ) const
inlineprotectedinherited

Return the application window object, casted to requested user type.

Definition at line 184 of file tool_base.h.

185 {
186#if !defined( QA_TEST ) // Dynamic casts give the linker a seizure in the test framework
187 wxASSERT( dynamic_cast<T*>( getToolHolderInt() ) );
188#endif
189 return static_cast<T*>( getToolHolderInt() );
190 }
TOOLS_HOLDER * getToolHolderInt() const
Definition: tool_base.cpp:48

References TOOL_BASE::getToolHolderInt().

Referenced by ZONE_CREATE_HELPER::createNewZone(), and ZONE_CREATE_HELPER::setUniquePriority().

◆ GetId()

TOOL_ID TOOL_BASE::GetId ( ) const
inlineinherited

Return the unique identifier of the tool.

The identifier is set by an instance of TOOL_MANAGER.

Returns
Identifier of the tool.

Definition at line 120 of file tool_base.h.

121 {
122 return m_toolId;
123 }

References TOOL_BASE::m_toolId.

Referenced by TOOL_MANAGER::finishTool(), TOOL_MANAGER::InitTools(), TOOL_MANAGER::isActive(), TOOL_MANAGER::RegisterTool(), ACTION_MANAGER::RunHotKey(), TOOL_MANAGER::runTool(), TOOL_MANAGER::saveViewControls(), and TOOL_MANAGER::ShutdownTool().

◆ GetManager()

TOOL_MANAGER * TOOL_BASE::GetManager ( ) const
inlineinherited

◆ getModel()

template<typename T >
T * TOOL_BASE::getModel ( ) const
inlineprotectedinherited

Return the model object if it matches the requested type.

Store the type of the tool.

Definition at line 196 of file tool_base.h.

References TOOL_BASE::getModelInt().

Referenced by ZONE_CREATE_HELPER::commitZone(), and ZONE_CREATE_HELPER::createZoneFromExisting().

◆ getModelInt()

EDA_ITEM * TOOL_BASE::getModelInt ( ) const
privateinherited

Definition at line 54 of file tool_base.cpp.

55{
56 return m_toolMgr->GetModel();
57}
EDA_ITEM * GetModel() const
Definition: tool_manager.h:292

References TOOL_MANAGER::GetModel(), and TOOL_BASE::m_toolMgr.

Referenced by TOOL_BASE::getModel().

◆ GetName()

const std::string & TOOL_BASE::GetName ( void  ) const
inlineinherited

Return the name of the tool.

Tool names are expected to obey the format: application.ToolName (eg. pcbnew.InteractiveSelection).

Returns
The name of the tool.

Definition at line 133 of file tool_base.h.

134 {
135 return m_toolName;
136 }
std::string m_toolName
Definition: tool_base.h:213

References TOOL_BASE::m_toolName.

Referenced by TOOL_MANAGER::dispatchInternal(), TOOL_MANAGER::InitTools(), TOOL_MANAGER::invokeTool(), TOOL_MANAGER::RegisterTool(), TOOL_MANAGER::runTool(), and TOOL_MANAGER::ShutdownTool().

◆ getSafeMovement()

VECTOR2I EDIT_TOOL::getSafeMovement ( const VECTOR2I aMovement,
const BOX2I aSourceBBox,
const VECTOR2D aBBoxOffset 
)
private

Definition at line 435 of file edit_tool_move_fct.cpp.

437{
438 typedef std::numeric_limits<int> coord_limits;
439
440 int max = coord_limits::max();
441 int min = -max;
442
443 double left = aBBoxOffset.x + aSourceBBox.GetPosition().x;
444 double top = aBBoxOffset.y + aSourceBBox.GetPosition().y;
445
446 double right = left + aSourceBBox.GetSize().x;
447 double bottom = top + aSourceBBox.GetSize().y;
448
449 // Do not restrict movement if bounding box is already out of bounds
450 if( left < min || top < min || right > max || bottom > max )
451 return aMovement;
452
453 // Constrain moving bounding box to coordinates limits
454 VECTOR2D tryMovement( aMovement );
455
456 VECTOR2D clampedBBoxOrigin = GetClampedCoords(
457 VECTOR2D( aSourceBBox.GetPosition() ) + aBBoxOffset + tryMovement, COORDS_PADDING );
458
459 tryMovement = clampedBBoxOrigin - aBBoxOffset - aSourceBBox.GetPosition();
460
461 VECTOR2D clampedBBoxEnd = GetClampedCoords(
462 VECTOR2D( aSourceBBox.GetEnd() ) + aBBoxOffset + tryMovement, COORDS_PADDING );
463
464 tryMovement = clampedBBoxEnd - aBBoxOffset - aSourceBBox.GetEnd();
465
466 return GetClampedCoords<double, int>( tryMovement );
467}
const Vec & GetPosition() const
Definition: box2.h:184
const Vec GetEnd() const
Definition: box2.h:185
const Vec & GetSize() const
Definition: box2.h:179
static const unsigned int COORDS_PADDING
Definition: edit_tool.h:209
VECTOR2< ret_type > GetClampedCoords(const VECTOR2< in_type > &aCoords, pad_type aPadding=0u)
Clamps a vector to values that can be negated, respecting numeric limits of coordinates data type wit...

References COORDS_PADDING, GetClampedCoords(), BOX2< Vec >::GetEnd(), BOX2< Vec >::GetPosition(), BOX2< Vec >::GetSize(), left, right, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by doMoveSelection().

◆ getToolHolderInt()

TOOLS_HOLDER * TOOL_BASE::getToolHolderInt ( ) const
privateinherited

Definition at line 48 of file tool_base.cpp.

49{
50 return m_toolMgr->GetToolHolder();
51}
TOOLS_HOLDER * GetToolHolder() const
Definition: tool_manager.h:296

References TOOL_MANAGER::GetToolHolder(), and TOOL_BASE::m_toolMgr.

Referenced by TOOL_BASE::getEditFrame().

◆ GetToolMenu()

◆ GetType()

TOOL_TYPE TOOL_BASE::GetType ( ) const
inlineinherited

Return the type of the tool.

Returns
The type of the tool.

Definition at line 108 of file tool_base.h.

109 {
110 return m_type;
111 }
TOOL_TYPE m_type
Unique identifier for the tool, assigned by a TOOL_MANAGER instance.
Definition: tool_base.h:206

References TOOL_BASE::m_type.

Referenced by TOOL_MANAGER::finishTool(), TOOL_MANAGER::InvokeTool(), TOOL_MANAGER::ResetTools(), TOOL_MANAGER::runTool(), and TOOL_MANAGER::ShutdownTool().

◆ getView()

KIGFX::VIEW * TOOL_BASE::getView ( ) const
protectedinherited

Returns the instance of #VIEW object used in the application.

It allows tools to draw.

Returns
The instance of VIEW.

Definition at line 36 of file tool_base.cpp.

37{
38 return m_toolMgr->GetView();
39}

References TOOL_MANAGER::GetView(), and TOOL_BASE::m_toolMgr.

Referenced by EE_POINT_EDITOR::addCornerCondition(), ALIGN_DISTRIBUTE_TOOL::AlignLeft(), ALIGN_DISTRIBUTE_TOOL::AlignRight(), COMMON_TOOLS::CenterContents(), SCH_EDIT_TOOL::ChangeTextType(), EE_INSPECTION_TOOL::CheckSymbol(), GERBVIEW_CONTROL::ClearAllLayers(), PL_SELECTION_TOOL::ClearSelection(), EE_SELECTION_TOOL::ClearSelection(), EE_SELECTION_TOOL::CollectHits(), SCH_LINE_WIRE_BUS_TOOL::computeBreakPoint(), COMMON_TOOLS::CursorControl(), SCH_EDIT_TOOL::DeleteItemCursor(), PL_EDIT_TOOL::DeleteItemCursor(), PCB_CONTROL::DeleteItemCursor(), PL_EDIT_TOOL::DoDelete(), SCH_LINE_WIRE_BUS_TOOL::doDrawSegments(), PCB_TOOL_BASE::doInteractiveItemPlacement(), doMoveSelection(), SELECTION_TOOL::doSelectionMenu(), COMMON_TOOLS::doZoomFit(), COMMON_TOOLS::doZoomInOut(), COMMON_TOOLS::doZoomToPreset(), DragArcTrack(), DRAWING_TOOL::drawArc(), DRAWING_TOOL::DrawDimension(), MICROWAVE_TOOL::drawMicrowaveInductor(), SCH_LINE_WIRE_BUS_TOOL::DrawSegments(), PL_DRAWING_TOOLS::DrawShape(), DRAWING_TOOL::drawShape(), DRAWING_TOOL::DrawZone(), BOARD_EDITOR_CONTROL::DrillOrigin(), SYMBOL_EDITOR_EDIT_TOOL::Duplicate(), PAD_TOOL::EnumeratePads(), EE_SELECTION_TOOL::GetNode(), ROUTER_TOOL::getStartLayer(), PCB_CONTROL::GridResetOrigin(), PCB_CONTROL::GridSetOrigin(), EE_SELECTION_TOOL::GuessSelectionCandidates(), ROUTER_TOOL::handleCommonEvents(), EE_SELECTION_TOOL::highlight(), PL_SELECTION_TOOL::highlight(), PCB_SELECTION_TOOL::highlight(), GERBVIEW_CONTROL::HighlightControl(), PNS::TOOL_BASE::highlightNet(), BOARD_INSPECTION_TOOL::highlightNet(), PCB_SELECTION_TOOL::hitTestDistance(), SCH_EDIT_TOOL::Init(), Init(), ROUTER_TOOL::InlineDrag(), EE_POINT_EDITOR::Main(), SCH_MOVE_TOOL::Main(), PL_POINT_EDITOR::Main(), PCB_PICKER_TOOL::Main(), GERBVIEW_INSPECTION_TOOL::MeasureTool(), PCB_VIEWER_TOOLS::MeasureTool(), SCH_EDIT_TOOL::Mirror(), MoveExact(), PL_EDIT_TOOL::moveItem(), SCH_MOVE_TOOL::moveItem(), COMMON_TOOLS::OnGridChanged(), PCB_POINT_EDITOR::OnSelectionChange(), COMMON_TOOLS::PanControl(), SCH_EDITOR_CONTROL::Paste(), SYMBOL_EDITOR_EDIT_TOOL::Paste(), PL_EDIT_TOOL::Paste(), ROUTER_TOOL::performRouting(), PNS::TOOL_BASE::pickSingleItem(), BOARD_EDITOR_CONTROL::PlaceFootprint(), PL_DRAWING_TOOLS::PlaceItem(), SCH_DRAWING_TOOLS::PlaceSymbol(), ROUTER_TOOL::prepareInteractive(), SCH_EDIT_TOOL::Properties(), Properties(), Remove(), EE_SELECTION_TOOL::Reset(), EE_TOOL_BASE< T >::Reset(), GERBVIEW_SELECTION_TOOL::Reset(), PNS::TOOL_BASE::Reset(), BOARD_EDITOR_CONTROL::Reset(), DRAWING_TOOL::Reset(), PCB_CONTROL::Reset(), PCB_SELECTION_TOOL::Reset(), SCH_EDIT_TOOL::Rotate(), GERBVIEW_SELECTION_TOOL::select(), PCB_SELECTION_TOOL::Selectable(), EE_SELECTION_TOOL::SelectAll(), PCB_SELECTION_TOOL::SelectAll(), EE_SELECTION_TOOL::selectionContains(), PL_SELECTION_TOOL::selectionContains(), EE_SELECTION_TOOL::selectMultiple(), PL_SELECTION_TOOL::selectMultiple(), PCB_SELECTION_TOOL::selectMultiple(), PL_SELECTION_TOOL::SelectPoint(), ZOOM_TOOL::selectRegion(), GERBVIEW_SELECTION_TOOL::selectVisually(), DRAWING_TOOL::SetAnchor(), SCH_DRAWING_TOOLS::SingleClickPlace(), SCH_EDITOR_CONTROL::ToggleERCErrors(), SCH_EDITOR_CONTROL::ToggleERCExclusions(), SCH_EDITOR_CONTROL::ToggleERCWarnings(), SCH_EDITOR_CONTROL::ToggleHiddenFields(), SCH_EDITOR_CONTROL::ToggleHiddenPins(), SCH_DRAWING_TOOLS::TwoClickPlace(), SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace(), EE_SELECTION_TOOL::unhighlight(), PL_SELECTION_TOOL::unhighlight(), PCB_SELECTION_TOOL::unhighlight(), GERBVIEW_SELECTION_TOOL::unselect(), GERBVIEW_SELECTION_TOOL::unselectVisually(), EE_POINT_EDITOR::updateEditedPoint(), PL_POINT_EDITOR::updateEditedPoint(), PCB_POINT_EDITOR::updateEditedPoint(), SCH_EDITOR_CONTROL::UpdateFind(), PL_POINT_EDITOR::updateItem(), PCB_POINT_EDITOR::updateItem(), EE_TOOL_BASE< T >::updateItem(), SCH_EDITOR_CONTROL::UpdateNetHighlighting(), EE_POINT_EDITOR::updatePoints(), PL_POINT_EDITOR::updatePoints(), PCB_POINT_EDITOR::updatePoints(), PCB_SELECTION_TOOL::updateSelection(), PNS::TOOL_BASE::updateStartItem(), PCB_SELECTION_TOOL::view(), PCB_TOOL_BASE::view(), PCB_VIEWER_TOOLS::view(), EE_SELECTION_TOOL::ZoomFitCrossProbeBBox(), PCB_SELECTION_TOOL::ZoomFitCrossProbeBBox(), PCB_SELECTION_TOOL::zoomFitSelection(), EE_SELECTION_TOOL::~EE_SELECTION_TOOL(), GERBVIEW_SELECTION_TOOL::~GERBVIEW_SELECTION_TOOL(), and PCB_SELECTION_TOOL::~PCB_SELECTION_TOOL().

◆ getViewControls()

KIGFX::VIEW_CONTROLS * TOOL_BASE::getViewControls ( ) const
protectedinherited

Return the instance of VIEW_CONTROLS object used in the application.

It allows tools to read & modify user input and its settings (eg. show cursor, enable snapping to grid, etc.).

Returns
The instance of VIEW_CONTROLS.

Definition at line 42 of file tool_base.cpp.

43{
44 return m_toolMgr->GetViewControls();
45}
KIGFX::VIEW_CONTROLS * GetViewControls() const
Definition: tool_manager.h:287

References TOOL_MANAGER::GetViewControls(), and TOOL_BASE::m_toolMgr.

Referenced by EE_POINT_EDITOR::addCorner(), PCB_POINT_EDITOR::addCorner(), EE_POINT_EDITOR::addCornerCondition(), SCH_EDITOR_CONTROL::AssignNetclass(), EE_SELECTION_TOOL::autostartEvent(), SCH_EDIT_TOOL::BreakWire(), PCB_SELECTION_TOOL::controls(), PCB_TOOL_BASE::controls(), copyToClipboard(), SCH_DRAWING_TOOLS::createSheetPin(), COMMON_TOOLS::CursorControl(), SCH_LINE_WIRE_BUS_TOOL::doDrawSegments(), doMoveSelection(), SCH_LINE_WIRE_BUS_TOOL::doUnfoldBus(), COMMON_TOOLS::doZoomToPreset(), DragArcTrack(), DRAWING_TOOL::DrawCircle(), DRAWING_TOOL::DrawLine(), MICROWAVE_TOOL::drawMicrowaveInductor(), DRAWING_TOOL::DrawRectangle(), SCH_DRAWING_TOOLS::DrawShape(), SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape(), PL_DRAWING_TOOLS::DrawShape(), SCH_DRAWING_TOOLS::DrawSheet(), SYMBOL_EDITOR_EDIT_TOOL::Duplicate(), PAD_TOOL::EnumeratePads(), SCH_LINE_WIRE_BUS_TOOL::finishSegments(), SCH_EDITOR_CONTROL::HighlightNet(), BOARD_INSPECTION_TOOL::HighlightNet(), FOOTPRINT_EDITOR_CONTROL::ImportFootprint(), SCH_EDIT_TOOL::Init(), Init(), EE_POINT_EDITOR::Main(), EE_SELECTION_TOOL::Main(), SCH_MOVE_TOOL::Main(), SYMBOL_EDITOR_MOVE_TOOL::Main(), PICKER_TOOL::Main(), PL_EDIT_TOOL::Main(), PL_POINT_EDITOR::Main(), PCB_PICKER_TOOL::Main(), ROUTER_TOOL::MainLoop(), GERBVIEW_INSPECTION_TOOL::MeasureTool(), PCB_VIEWER_TOOLS::MeasureTool(), COMMON_TOOLS::OnGridChanged(), PCB_POINT_EDITOR::OnSelectionChange(), SYMBOL_EDITOR_EDIT_TOOL::Paste(), ROUTER_TOOL::performDragging(), LENGTH_TUNER_TOOL::performTuning(), SYMBOL_EDITOR_DRAWING_TOOLS::PlaceAnchor(), PCB_CONTROL::placeBoardItems(), BOARD_EDITOR_CONTROL::PlaceFootprint(), SCH_DRAWING_TOOLS::PlaceImage(), DRAWING_TOOL::PlaceImage(), PL_DRAWING_TOOLS::PlaceItem(), SCH_DRAWING_TOOLS::PlaceSymbol(), SCH_EDIT_TOOL::Properties(), Properties(), Remove(), SCH_EDIT_TOOL::RepeatDrawItem(), PL_SELECTION_TOOL::RequestSelection(), EE_SELECTION_TOOL::RequestSelection(), DRAWING_TOOL::Reset(), PCB_POINT_EDITOR::Reset(), COMMON_TOOLS::ResetLocalCoords(), ROUTER_TOOL::RouteSelected(), PCB_SELECTION_TOOL::selectCursor(), EE_SELECTION_TOOL::selectMultiple(), PL_SELECTION_TOOL::selectMultiple(), PCB_SELECTION_TOOL::selectMultiple(), EE_SELECTION_TOOL::SelectNode(), ZOOM_TOOL::selectRegion(), ALIGN_DISTRIBUTE_TOOL::selectTarget(), PICKER_TOOL::setControls(), PCB_PICKER_TOOL::setControls(), EE_POINT_EDITOR::setEditedPoint(), PL_POINT_EDITOR::setEditedPoint(), PCB_POINT_EDITOR::setEditedPoint(), SCH_DRAWING_TOOLS::SingleClickPlace(), SCH_DRAWING_TOOLS::TwoClickPlace(), SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace(), EE_POINT_EDITOR::updateEditedPoint(), PL_POINT_EDITOR::updateEditedPoint(), PCB_POINT_EDITOR::updateEditedPoint(), PCB_POINT_EDITOR::updateItem(), PL_EDIT_TOOL::updateModificationPoint(), and COMMON_TOOLS::ZoomCenter().

◆ Go()

template<class T >
void TOOL_INTERACTIVE::Go ( int(T::*)(const TOOL_EVENT &)  aStateFunc,
const TOOL_EVENT_LIST aConditions = TOOL_EVENTTC_ANYTA_ANY ) 
)
inherited

Define which state (aStateFunc) to go when a certain event arrives (aConditions).

No conditions means any event.

Definition at line 147 of file tool_interactive.h.

149{
150 TOOL_STATE_FUNC sptr = std::bind( aStateFunc, static_cast<T*>( this ), std::placeholders::_1 );
151
152 goInternal( sptr, aConditions );
153}
void goInternal(TOOL_STATE_FUNC &aState, const TOOL_EVENT_LIST &aConditions)
std::function< int(const TOOL_EVENT &)> TOOL_STATE_FUNC
Definition: tool_base.h:58

References TOOL_INTERACTIVE::goInternal().

Referenced by EDA_3D_CONTROLLER::setTransitions(), CVPCB_ASSOCIATION_TOOL::setTransitions(), CVPCB_CONTROL::setTransitions(), CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL::setTransitions(), EE_INSPECTION_TOOL::setTransitions(), EE_POINT_EDITOR::setTransitions(), EE_SELECTION_TOOL::setTransitions(), SCH_DRAWING_TOOLS::setTransitions(), SCH_EDIT_TOOL::setTransitions(), SCH_EDITOR_CONTROL::setTransitions(), SCH_LINE_WIRE_BUS_TOOL::setTransitions(), SCH_MOVE_TOOL::setTransitions(), SCH_NAVIGATE_TOOL::setTransitions(), SYMBOL_EDITOR_CONTROL::setTransitions(), SYMBOL_EDITOR_DRAWING_TOOLS::setTransitions(), SYMBOL_EDITOR_EDIT_TOOL::setTransitions(), SYMBOL_EDITOR_MOVE_TOOL::setTransitions(), SYMBOL_EDITOR_PIN_TOOL::setTransitions(), GERBVIEW_CONTROL::setTransitions(), GERBVIEW_INSPECTION_TOOL::setTransitions(), GERBVIEW_SELECTION_TOOL::setTransitions(), COMMON_CONTROL::setTransitions(), COMMON_TOOLS::setTransitions(), PICKER_TOOL::setTransitions(), ZOOM_TOOL::setTransitions(), KICAD_MANAGER_CONTROL::setTransitions(), PL_DRAWING_TOOLS::setTransitions(), PL_EDIT_TOOL::setTransitions(), PL_EDITOR_CONTROL::setTransitions(), PL_POINT_EDITOR::setTransitions(), PL_SELECTION_TOOL::setTransitions(), AUTOPLACE_TOOL::setTransitions(), MICROWAVE_TOOL::setTransitions(), SCRIPTING_TOOL::setTransitions(), LENGTH_TUNER_TOOL::setTransitions(), ROUTER_TOOL::setTransitions(), BOARD_EDITOR_CONTROL::setTransitions(), BOARD_INSPECTION_TOOL::setTransitions(), BOARD_REANNOTATE_TOOL::setTransitions(), CONVERT_TOOL::setTransitions(), DRAWING_TOOL::setTransitions(), DRC_TOOL::setTransitions(), setTransitions(), FOOTPRINT_EDITOR_CONTROL::setTransitions(), GLOBAL_EDIT_TOOL::setTransitions(), GROUP_TOOL::setTransitions(), PAD_TOOL::setTransitions(), PCB_CONTROL::setTransitions(), PCB_PICKER_TOOL::setTransitions(), PCB_POINT_EDITOR::setTransitions(), PCB_SELECTION_TOOL::setTransitions(), PCB_VIEWER_TOOLS::setTransitions(), ALIGN_DISTRIBUTE_TOOL::setTransitions(), POSITION_RELATIVE_TOOL::setTransitions(), PROPERTIES_TOOL::setTransitions(), and ZONE_FILLER_TOOL::setTransitions().

◆ goInternal()

void TOOL_INTERACTIVE::goInternal ( TOOL_STATE_FUNC aState,
const TOOL_EVENT_LIST aConditions 
)
privateinherited

Definition at line 70 of file tool_interactive.cpp.

71{
72 m_toolMgr->ScheduleNextState( this, aState, aConditions );
73}
void ScheduleNextState(TOOL_BASE *aTool, TOOL_STATE_FUNC &aHandler, const TOOL_EVENT_LIST &aConditions)
Define a state transition.

References TOOL_BASE::m_toolMgr, and TOOL_MANAGER::ScheduleNextState().

Referenced by TOOL_INTERACTIVE::Go().

◆ Init()

bool EDIT_TOOL::Init ( )
overridevirtual

Init() is called once upon a registration of the tool.

Returns
True if the initialization went fine, false - otherwise. Find an item and start moving.

Reimplemented from PCB_TOOL_BASE.

Definition at line 102 of file edit_tool.cpp.

103{
104 // Find the selection tool, so they can cooperate
106
107 auto positioningToolsSubMenu = std::make_shared<POSITIONING_TOOLS_MENU>( this );
108 m_selectionTool->GetToolMenu().RegisterSubMenu( positioningToolsSubMenu );
109
110 auto propertiesCondition =
111 [&]( const SELECTION& aSel )
112 {
113 if( aSel.GetSize() == 0 )
114 {
116 {
119
120 if( ds && ds->HitTestDrawingSheetItems( getView(), cursor ) )
121 return true;
122 }
123
124 return false;
125 }
126
127 if( aSel.GetSize() == 1 )
128 return true;
129
130 for( EDA_ITEM* item : aSel )
131 {
132 if( !dynamic_cast<PCB_TRACK*>( item ) )
133 return false;
134 }
135
136 return true;
137 };
138
139 auto inFootprintEditor =
140 [ this ]( const SELECTION& aSelection )
141 {
142 return m_isFootprintEditor;
143 };
144
145 auto singleFootprintCondition = SELECTION_CONDITIONS::OnlyTypes( { PCB_FOOTPRINT_T } )
147
148 auto noActiveToolCondition =
149 [ this ]( const SELECTION& aSelection )
150 {
151 return frame()->ToolStackIsEmpty();
152 };
153
154 auto notMovingCondition =
155 [ this ]( const SELECTION& aSelection )
156 {
159 };
160
161 auto noItemsCondition =
162 [ this ]( const SELECTION& aSelections ) -> bool
163 {
164 return frame()->GetBoard() && !frame()->GetBoard()->IsEmpty();
165 };
166
167 static std::vector<KICAD_T> connectedTypes = { PCB_TRACE_T,
168 PCB_ARC_T,
169 PCB_VIA_T,
170 PCB_PAD_T,
171 PCB_ZONE_T };
172
173 static std::vector<KICAD_T> unroutableTypes = { PCB_TRACE_T,
174 PCB_ARC_T,
175 PCB_VIA_T,
176 PCB_PAD_T,
178
179 static std::vector<KICAD_T> trackTypes = { PCB_TRACE_T,
180 PCB_ARC_T,
181 PCB_VIA_T };
182
183
184 // Add context menu entries that are displayed when selection tool is active
186
188 && notMovingCondition );
190 && SELECTION_CONDITIONS::OnlyTypes( unroutableTypes ) );
192 && notMovingCondition );
194 && SELECTION_CONDITIONS::OnlyTypes( trackTypes ) );
207
208 menu.AddItem( PCB_ACTIONS::properties, propertiesCondition );
209
212
213 // Footprint actions
214 menu.AddSeparator();
215 menu.AddItem( PCB_ACTIONS::editFpInFpEditor, singleFootprintCondition );
216 menu.AddItem( PCB_ACTIONS::updateFootprint, singleFootprintCondition );
217 menu.AddItem( PCB_ACTIONS::changeFootprint, singleFootprintCondition );
218
219 // Add the submenu for the special positioning tools
220 menu.AddSeparator( 100 );
221 menu.AddMenu( positioningToolsSubMenu.get(), SELECTION_CONDITIONS::NotEmpty, 100 );
222
223 menu.AddSeparator( 150 );
226
227 // Selection tool handles the context menu for some other tools, such as the Picker.
228 // Don't add things like Paste when another tool is active.
229 menu.AddItem( ACTIONS::paste, noActiveToolCondition, 150 );
230 menu.AddItem( ACTIONS::pasteSpecial, noActiveToolCondition && !inFootprintEditor, 150 );
233
234 menu.AddSeparator( 150 );
235 menu.AddItem( ACTIONS::selectAll, noItemsCondition, 150 );
236
237 return true;
238}
static TOOL_ACTION paste
Definition: actions.h:69
static TOOL_ACTION copy
Definition: actions.h:68
static TOOL_ACTION pasteSpecial
Definition: actions.h:70
static TOOL_ACTION selectAll
Definition: actions.h:71
bool IsEmpty() const
Definition: board.h:355
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 AddSeparator(int aOrder=ANY_ORDER)
Add a separator to the menu.
void AddMenu(ACTION_MENU *aMenu, const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Add a submenu to the menu.
bool HitTestDrawingSheetItems(KIGFX::VIEW *aView, const VECTOR2I &aPosition)
static const std::vector< KICAD_T > DraggableItems
A scan list for items that can be dragged.
Definition: collectors.h:270
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:410
static TOOL_ACTION drag45Degree
Definition: pcb_actions.h:159
static TOOL_ACTION unrouteSelected
Removes all tracks from the selected items to the first pad.
Definition: pcb_actions.h:83
static TOOL_ACTION updateFootprint
Definition: pcb_actions.h:353
static TOOL_ACTION breakTrack
Break a single track into two segments at the cursor.
Definition: pcb_actions.h:157
static TOOL_ACTION editFpInFpEditor
Definition: pcb_actions.h:375
static TOOL_ACTION swap
Swapping of selected items.
Definition: pcb_actions.h:133
static TOOL_ACTION assignNetClass
Definition: pcb_actions.h:329
static TOOL_ACTION inspectClearance
Definition: pcb_actions.h:481
static TOOL_ACTION filletTracks
Fillet (i.e. adds an arc tangent to) all selected straight tracks by a user defined radius.
Definition: pcb_actions.h:139
static TOOL_ACTION changeFootprint
Definition: pcb_actions.h:355
DS_PROXY_VIEW_ITEM * GetDrawingSheet() const
PCB_DRAW_PANEL_GAL * canvas() const
static bool NotEmpty(const SELECTION &aSelection)
Test if there are any items selected.
static SELECTION_CONDITION MoreThan(int aNumber)
Create a functor that tests if the number of selected items is greater than the value given as parame...
static SELECTION_CONDITION Count(int aNumber)
Create a functor that tests if the number of selected items is equal to the value given as parameter.
static SELECTION_CONDITION OnlyTypes(std::vector< KICAD_T > aTypes)
Create a functor that tests if the selected items are only of given types.
bool ToolStackIsEmpty()
Definition: tools_holder.h:128
bool IsCurrentTool(const TOOL_ACTION &aAction) const
TOOL_MENU & GetToolMenu()
CONDITIONAL_MENU & GetMenu()
Definition: tool_menu.cpp:44
void RegisterSubMenu(std::shared_ptr< ACTION_MENU > aSubMenu)
Store a submenu of this menu model.
Definition: tool_menu.cpp:50
static std::vector< KICAD_T > connectedTypes
@ LAYER_SCHEMATIC_DRAWINGSHEET
Definition: layer_ids.h:382

References CONDITIONAL_MENU::AddItem(), CONDITIONAL_MENU::AddMenu(), CONDITIONAL_MENU::AddSeparator(), PCB_ACTIONS::assignNetClass, PCB_ACTIONS::breakTrack, PCB_TOOL_BASE::canvas(), PCB_ACTIONS::changeFootprint, connectedTypes, ACTIONS::copy, SELECTION_CONDITIONS::Count(), cursor, ACTIONS::cut, ACTIONS::doDelete, PCB_ACTIONS::drag45Degree, PCB_ACTIONS::dragFreeAngle, GENERAL_COLLECTOR::DraggableItems, ACTIONS::duplicate, PCB_ACTIONS::editFpInFpEditor, PCB_ACTIONS::filletTracks, PCB_ACTIONS::flip, PCB_TOOL_BASE::frame(), PCB_BASE_FRAME::GetBoard(), KIGFX::VIEW_CONTROLS::GetCursorPosition(), PCB_DRAW_PANEL_GAL::GetDrawingSheet(), TOOL_MENU::GetMenu(), TOOL_MANAGER::GetTool(), TOOL_INTERACTIVE::GetToolMenu(), TOOL_BASE::getView(), TOOL_BASE::getViewControls(), DS_PROXY_VIEW_ITEM::HitTestDrawingSheetItems(), PCB_ACTIONS::inspectClearance, TOOLS_HOLDER::IsCurrentTool(), BOARD::IsEmpty(), KIGFX::VIEW::IsLayerVisible(), LAYER_SCHEMATIC_DRAWINGSHEET, PCB_TOOL_BASE::m_isFootprintEditor, m_selectionTool, TOOL_BASE::m_toolMgr, PCB_ACTIONS::mirrorH, PCB_ACTIONS::mirrorV, SELECTION_CONDITIONS::MoreThan(), PCB_ACTIONS::move, PCB_ACTIONS::moveIndividually, PCB_ACTIONS::moveWithReference, SELECTION_CONDITIONS::NotEmpty(), SELECTION_CONDITIONS::OnlyTypes(), ACTIONS::paste, ACTIONS::pasteSpecial, PCB_ARC_T, PCB_FOOTPRINT_T, PCB_PAD_T, PCB_TRACE_T, PCB_VIA_T, PCB_ZONE_T, PCB_ACTIONS::properties, TOOL_MENU::RegisterSubMenu(), PCB_ACTIONS::rotateCcw, PCB_ACTIONS::rotateCw, ACTIONS::selectAll, PCB_ACTIONS::swap, TOOLS_HOLDER::ToolStackIsEmpty(), PCB_ACTIONS::unrouteSelected, and PCB_ACTIONS::updateFootprint.

◆ invokeInlineRouter()

bool EDIT_TOOL::invokeInlineRouter ( int  aDragMode)
private

Definition at line 264 of file edit_tool.cpp.

265{
267
268 if( !theRouter )
269 return false;
270
271 // don't allow switch from moving to dragging
272 if( m_dragging )
273 {
274 wxBell();
275 return false;
276 }
277
278 // make sure we don't accidentally invoke inline routing mode while the router is already
279 // active!
280 if( theRouter->IsToolActive() )
281 return false;
282
283 if( theRouter->CanInlineDrag( aDragMode ) )
284 {
286 static_cast<intptr_t>( aDragMode ) );
287 return true;
288 }
289
290 return false;
291}
static TOOL_ACTION routerInlineDrag
Activation of the Push and Shove router (inline dragging mode)
Definition: pcb_actions.h:235
static ROUTER * theRouter
Definition: pns_router.cpp:58

References TOOL_MANAGER::GetTool(), m_dragging, TOOL_BASE::m_toolMgr, PCB_ACTIONS::routerInlineDrag, TOOL_MANAGER::RunAction(), and PNS::theRouter.

Referenced by doMoveSelection().

◆ Is45Limited()

bool PCB_TOOL_BASE::Is45Limited ( ) const
virtualinherited

Should the tool use its 45° mode option?

Returns
True if set to use 45°

Definition at line 328 of file pcb_tool_base.cpp.

329{
330 SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
331
332 if( frame()->IsType( FRAME_PCB_EDITOR ) )
333 return mgr.GetAppSettings<PCBNEW_SETTINGS>()->m_Use45DegreeLimit;
334 else
335 return mgr.GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>()->m_Use45Limit;
336}
T * GetAppSettings(bool aLoadNow=true)
Returns a handle to the a given settings by type If the settings have already been loaded,...
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:111

References PCB_TOOL_BASE::frame(), FRAME_PCB_EDITOR, SETTINGS_MANAGER::GetAppSettings(), and Pgm().

Referenced by DRAWING_TOOL::drawArc(), DRAWING_TOOL::DrawDimension(), MICROWAVE_TOOL::drawMicrowaveInductor(), DRAWING_TOOL::drawShape(), DRAWING_TOOL::DrawZone(), and ZONE_CREATE_HELPER::OnFirstPoint().

◆ IsBoardEditor()

bool PCB_TOOL_BASE::IsBoardEditor ( ) const
inlineinherited

Definition at line 109 of file pcb_tool_base.h.

109{ return m_isBoardEditor; }

References PCB_TOOL_BASE::m_isBoardEditor.

Referenced by BOARD_COMMIT::BOARD_COMMIT().

◆ IsFootprintEditor()

bool PCB_TOOL_BASE::IsFootprintEditor ( ) const
inlineinherited

◆ isRouterActive()

bool EDIT_TOOL::isRouterActive ( ) const
private

Definition at line 294 of file edit_tool.cpp.

295{
297
298 return router && router->RoutingInProgress();
299}
bool RoutingInProgress()
Returns whether routing is currently active.

References TOOL_MANAGER::GetTool(), TOOL_BASE::m_toolMgr, and ROUTER_TOOL::RoutingInProgress().

Referenced by CreateArray(), Duplicate(), Flip(), Mirror(), Move(), MoveExact(), MoveIndividually(), MoveWithReference(), Remove(), Rotate(), and Swap().

◆ IsToolActive()

bool TOOL_BASE::IsToolActive ( ) const
inherited

Definition at line 31 of file tool_base.cpp.

32{
34}
bool IsToolActive(TOOL_ID aId) const
Return true if a tool with given id is active (executing)

References TOOL_MANAGER::IsToolActive(), TOOL_BASE::m_toolId, and TOOL_BASE::m_toolMgr.

Referenced by Drag(), ROUTER_TOOL::handleLayerSwitch(), PCB_SELECTION_TOOL::Main(), BOARD_EDITOR_CONTROL::TrackWidthDec(), and BOARD_EDITOR_CONTROL::TrackWidthInc().

◆ Mirror()

int EDIT_TOOL::Mirror ( const TOOL_EVENT aEvent)

Mirror the current selection.

The mirror axis passes through the current point.

Definition at line 1279 of file edit_tool.cpp.

1280{
1281 if( isRouterActive() )
1282 {
1283 wxBell();
1284 return 0;
1285 }
1286
1288 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1289 {
1290 sTool->FilterCollectorForMarkers( aCollector );
1291 sTool->FilterCollectorForHierarchy( aCollector, true );
1292 sTool->FilterCollectorForFreePads( aCollector );
1293 },
1294 !m_dragging /* prompt user regarding locked items */ );
1295
1296 if( selection.Empty() )
1297 return 0;
1298
1300 VECTOR2I mirrorPoint = selection.GetReferencePoint();
1301
1302 // When editing footprints, all items have the same parent
1303 if( IsFootprintEditor() )
1304 m_commit->Modify( selection.Front() );
1305
1306 // Set the mirroring options.
1307 // Unfortunately, the mirror function do not have the same parameter for all items
1308 // So we need these 2 parameters to avoid mistakes
1309 bool mirrorLeftRight = true;
1310 bool mirrorAroundXaxis = false;
1311
1312 if( aEvent.IsAction( &PCB_ACTIONS::mirrorV ) )
1313 {
1314 mirrorLeftRight = false;
1315 mirrorAroundXaxis = true;
1316 }
1317
1318 for( EDA_ITEM* item : selection )
1319 {
1320 // only modify items we can mirror
1321 switch( item->Type() )
1322 {
1323 case PCB_FP_SHAPE_T:
1324 case PCB_SHAPE_T:
1325 case PCB_FP_TEXT_T:
1326 case PCB_TEXT_T:
1327 case PCB_FP_TEXTBOX_T:
1328 case PCB_TEXTBOX_T:
1329 case PCB_FP_ZONE_T:
1330 case PCB_ZONE_T:
1331 case PCB_PAD_T:
1332 case PCB_TRACE_T:
1333 case PCB_ARC_T:
1334 case PCB_VIA_T:
1335 if( !item->IsNew() && !IsFootprintEditor() )
1336 m_commit->Modify( item );
1337
1338 break;
1339
1340 default:
1341 continue;
1342 }
1343
1344 // modify each object as necessary
1345 switch( item->Type() )
1346 {
1347 case PCB_FP_SHAPE_T:
1348 case PCB_SHAPE_T:
1349 static_cast<PCB_SHAPE*>( item )->Mirror( mirrorPoint, mirrorAroundXaxis );
1350 break;
1351
1352 case PCB_FP_ZONE_T:
1353 case PCB_ZONE_T:
1354 static_cast<FP_ZONE*>( item )->Mirror( mirrorPoint, mirrorLeftRight );
1355 break;
1356
1357 case PCB_FP_TEXT_T:
1358 static_cast<FP_TEXT*>( item )->Mirror( mirrorPoint, mirrorAroundXaxis );
1359 break;
1360
1361 case PCB_TEXT_T:
1362 static_cast<PCB_TEXT*>( item )->Mirror( mirrorPoint, mirrorAroundXaxis );
1363 break;
1364
1365 case PCB_FP_TEXTBOX_T:
1366 static_cast<FP_TEXTBOX*>( item )->Mirror( mirrorPoint, mirrorAroundXaxis );
1367 break;
1368
1369 case PCB_TEXTBOX_T:
1370 static_cast<PCB_TEXTBOX*>( item )->Mirror( mirrorPoint, mirrorAroundXaxis );
1371 break;
1372
1373 case PCB_PAD_T:
1374 if( mirrorLeftRight )
1375 mirrorPadX( *static_cast<PAD*>( item ), mirrorPoint );
1376 else
1377 mirrorPadY( *static_cast<PAD*>( item ), mirrorPoint );
1378
1379 break;
1380
1381 case PCB_TRACE_T:
1382 case PCB_ARC_T:
1383 case PCB_VIA_T:
1384 static_cast<PCB_TRACK*>( item )->Mirror( mirrorPoint, mirrorAroundXaxis );
1385 break;
1386
1387 default:
1388 // it's likely the commit object is wrong if you get here
1389 // Unsure if PCB_GROUP_T needs special attention here.
1390 assert( false );
1391 break;
1392 }
1393 }
1394
1395 if( !m_dragging )
1396 m_commit->Push( _( "Mirror" ) );
1397
1398 if( selection.IsHover() && !m_dragging )
1400
1402
1403 if( m_dragging )
1405
1406 return 0;
1407}
int Mirror(const TOOL_EVENT &aEvent)
Mirror the current selection.
Definition: edit_tool.cpp:1279
A specialization of ZONE for use in footprints.
Definition: zone.h:897
static void mirrorPadX(PAD &aPad, const VECTOR2I &aMirrorPoint)
Mirror a pad in the vertical axis passing through a point (mirror left to right).
Definition: edit_tool.cpp:1232
static void mirrorPadY(PAD &aPad, const VECTOR2I &aMirrorPoint)
Mirror a pad in the vertical axis passing through a point (mirror left to right).
Definition: edit_tool.cpp:1257
@ PCB_FP_SHAPE_T
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:94
@ PCB_FP_TEXTBOX_T
class FP_TEXTBOX, wrapped text in a footprint
Definition: typeinfo.h:93
@ PCB_FP_ZONE_T
class ZONE, managed by a footprint
Definition: typeinfo.h:100
@ PCB_FP_TEXT_T
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92

References _, SELECTION::Empty(), PCB_SELECTION_TOOL::FilterCollectorForFreePads(), PCB_SELECTION_TOOL::FilterCollectorForHierarchy(), PCB_SELECTION_TOOL::FilterCollectorForMarkers(), SELECTION::Front(), SELECTION::GetReferencePoint(), TOOL_EVENT::IsAction(), PCB_TOOL_BASE::IsFootprintEditor(), SELECTION::IsHover(), isRouterActive(), m_commit, m_dragging, m_selectionTool, TOOL_BASE::m_toolMgr, Mirror(), mirrorPadX(), mirrorPadY(), PCB_ACTIONS::mirrorV, PCB_ARC_T, PCB_FP_SHAPE_T, PCB_FP_TEXT_T, PCB_FP_TEXTBOX_T, PCB_FP_ZONE_T, PCB_PAD_T, PCB_SHAPE_T, PCB_TEXT_T, PCB_TEXTBOX_T, PCB_TRACE_T, PCB_VIA_T, PCB_ZONE_T, TOOL_MANAGER::ProcessEvent(), PCB_SELECTION_TOOL::RequestSelection(), TOOL_MANAGER::RunAction(), EVENTS::SelectedItemsModified, PCB_TOOL_BASE::selection(), PCB_ACTIONS::selectionClear, PCB_ACTIONS::updateLocalRatsnest, and updateModificationPoint().

Referenced by Mirror(), and setTransitions().

◆ Move()

int EDIT_TOOL::Move ( const TOOL_EVENT aEvent)

Main loop in which events are handled.

Definition at line 383 of file edit_tool_move_fct.cpp.

384{
385 if( isRouterActive() )
386 {
387 wxBell();
388 return 0;
389 }
390
391 return doMoveSelection( aEvent );
392}
int doMoveSelection(const TOOL_EVENT &aEvent, bool aPickReference=false)

References doMoveSelection(), and isRouterActive().

Referenced by doMoveSelection(), Duplicate(), and setTransitions().

◆ MoveExact()

int EDIT_TOOL::MoveExact ( const TOOL_EVENT aEvent)

Invoke a dialog box to allow moving of the item by an exact amount.

Definition at line 1746 of file edit_tool.cpp.

1747{
1748 if( isRouterActive() )
1749 {
1750 wxBell();
1751 return 0;
1752 }
1753
1755 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1756 {
1757 sTool->FilterCollectorForMarkers( aCollector );
1758 sTool->FilterCollectorForHierarchy( aCollector, true );
1759 },
1760 true /* prompt user regarding locked items */ );
1761
1762 if( selection.Empty() )
1763 return 0;
1764
1765 VECTOR2I translation;
1766 EDA_ANGLE rotation;
1769
1770 // TODO: Implement a visible bounding border at the edge
1771 BOX2I sel_box = selection.GetBoundingBox();
1772
1773 DIALOG_MOVE_EXACT dialog( frame(), translation, rotation, rotationAnchor, sel_box );
1774 int ret = dialog.ShowModal();
1775
1776 if( ret == wxID_OK )
1777 {
1778 EDA_ANGLE angle = rotation;
1780 VECTOR2I selCenter( rp.x, rp.y );
1781
1782 // Make sure the rotation is from the right reference point
1783 selCenter += translation;
1784
1785 if( !frame()->GetPcbNewSettings()->m_Display.m_DisplayInvertYAxis )
1786 rotation = -rotation;
1787
1788 // When editing footprints, all items have the same parent
1789 if( IsFootprintEditor() )
1790 m_commit->Modify( selection.Front() );
1791
1792 for( EDA_ITEM* selItem : selection )
1793 {
1794 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selItem );
1795
1796 if( !item->IsNew() && !IsFootprintEditor() )
1797 {
1798 m_commit->Modify( item );
1799
1800 if( item->Type() == PCB_GROUP_T )
1801 {
1802 PCB_GROUP* group = static_cast<PCB_GROUP*>( item );
1803
1804 group->RunOnDescendants( [&]( BOARD_ITEM* bItem )
1805 {
1806 m_commit->Modify( bItem );
1807 });
1808 }
1809 }
1810
1811 if( !item->GetParent() || !item->GetParent()->IsSelected() )
1812 item->Move( translation );
1813
1814 switch( rotationAnchor )
1815 {
1817 item->Rotate( item->GetPosition(), angle );
1818 break;
1820 item->Rotate( selCenter, angle );
1821 break;
1823 item->Rotate( frame()->GetScreen()->m_LocalOrigin, angle );
1824 break;
1827 break;
1828 }
1829
1830 if( !m_dragging )
1831 getView()->Update( item );
1832 }
1833
1834 m_commit->Push( _( "Move exact" ) );
1835
1836 if( selection.IsHover() )
1838
1840
1841 if( m_dragging )
1843 }
1844
1845 return 0;
1846}
VECTOR2D m_LocalOrigin
Relative Screen cursor coordinate (on grid) in user units.
Definition: base_screen.h:90
const VECTOR2I & GetAuxOrigin()
virtual void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle)
Rotate this object.
Definition: board_item.cpp:228
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:263
bool IsSelected() const
Definition: eda_item.h:121
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
virtual VECTOR2I GetCenter() const
Returns the center point of the selection area bounding box.
Definition: selection.cpp:83
virtual BOX2I GetBoundingBox() const
Definition: selection.cpp:123
ROTATION_ANCHOR
@ ROTATE_AROUND_USER_ORIGIN
@ ROTATE_AROUND_SEL_CENTER
@ ROTATE_AROUND_AUX_ORIGIN
@ ROTATE_AROUND_ITEM_ANCHOR
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)

References _, PNS::angle(), PCB_TOOL_BASE::board(), SELECTION::Empty(), PCB_SELECTION_TOOL::FilterCollectorForHierarchy(), PCB_SELECTION_TOOL::FilterCollectorForMarkers(), PCB_TOOL_BASE::frame(), SELECTION::Front(), BOARD_DESIGN_SETTINGS::GetAuxOrigin(), SELECTION::GetBoundingBox(), SELECTION::GetCenter(), BOARD::GetDesignSettings(), BOARD_ITEM::GetParent(), EDA_ITEM::GetPosition(), PCB_BASE_FRAME::GetScreen(), TOOL_BASE::getView(), group, PCB_TOOL_BASE::IsFootprintEditor(), SELECTION::IsHover(), EDA_ITEM::IsNew(), isRouterActive(), EDA_ITEM::IsSelected(), m_commit, m_dragging, BASE_SCREEN::m_LocalOrigin, m_selectionTool, TOOL_BASE::m_toolMgr, BOARD_ITEM::Move(), PCB_GROUP_T, TOOL_MANAGER::ProcessEvent(), PCB_SELECTION_TOOL::RequestSelection(), BOARD_ITEM::Rotate(), ROTATE_AROUND_AUX_ORIGIN, ROTATE_AROUND_ITEM_ANCHOR, ROTATE_AROUND_SEL_CENTER, ROTATE_AROUND_USER_ORIGIN, TOOL_MANAGER::RunAction(), EVENTS::SelectedItemsModified, PCB_TOOL_BASE::selection(), PCB_ACTIONS::selectionClear, SELECTION::Size(), EDA_ITEM::Type(), KIGFX::VIEW::Update(), PCB_ACTIONS::updateLocalRatsnest, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by setTransitions().

◆ MoveIndividually()

int EDIT_TOOL::MoveIndividually ( const TOOL_EVENT aEvent)

Move a selection of items one-at-a-time.

Definition at line 395 of file edit_tool_move_fct.cpp.

396{
398
399 if( isRouterActive() )
400 {
401 wxBell();
402 return 0;
403 }
404
405 EDA_ITEMS sortedItems = selTool->GetSelection().GetItemsSortedBySelectionOrder();
406
407 if( sortedItems.size() == 0 )
408 return 0;
409
410 for( EDA_ITEM* item : sortedItems )
411 {
412 selTool->ClearSelection();
413 selTool->AddItemToSel( item );
414 doMoveSelection( aEvent );
415 }
416
417 selTool->AddItemsToSel( &sortedItems );
418
419 return 0;
420}
int ClearSelection(const TOOL_EVENT &aEvent)
int AddItemsToSel(const TOOL_EVENT &aEvent)
const std::vector< EDA_ITEM * > GetItemsSortedBySelectionOrder() const
Definition: selection.cpp:202
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
Definition: eda_item.h:538

References SELECTION_TOOL::AddItemsToSel(), SELECTION_TOOL::AddItemToSel(), PCB_SELECTION_TOOL::ClearSelection(), doMoveSelection(), SELECTION::GetItemsSortedBySelectionOrder(), PCB_SELECTION_TOOL::GetSelection(), TOOL_MANAGER::GetTool(), isRouterActive(), and TOOL_BASE::m_toolMgr.

Referenced by setTransitions().

◆ MoveWithReference()

int EDIT_TOOL::MoveWithReference ( const TOOL_EVENT aEvent)

Move an item but with a reference point selected first.

Definition at line 423 of file edit_tool_move_fct.cpp.

424{
425 if( isRouterActive() )
426 {
427 wxBell();
428 return 0;
429 }
430
431 return doMoveSelection( aEvent, true );
432}

References doMoveSelection(), and isRouterActive().

Referenced by setTransitions().

◆ PadFilter()

void EDIT_TOOL::PadFilter ( const VECTOR2I ,
GENERAL_COLLECTOR aCollector,
PCB_SELECTION_TOOL sTool 
)
static

A selection filter which prunes the selection to contain only items of type PCB_PAD_T.

Definition at line 2021 of file edit_tool.cpp.

2023{
2024 for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
2025 {
2026 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aCollector[i] );
2027
2028 if( item->Type() != PCB_PAD_T )
2029 aCollector.Remove( i );
2030 }
2031}

References COLLECTOR::GetCount(), PCB_PAD_T, COLLECTOR::Remove(), and EDA_ITEM::Type().

Referenced by BOARD_INSPECTION_TOOL::LocalRatsnestTool().

◆ pickReferencePoint()

bool EDIT_TOOL::pickReferencePoint ( const wxString &  aTooltip,
const wxString &  aSuccessMessage,
const wxString &  aCanceledMessage,
VECTOR2I aReferencePoint 
)
private

This allow the option of snapping in the tool

Definition at line 2074 of file edit_tool.cpp.

2076{
2078 std::optional<VECTOR2I> pickedPoint;
2079 bool done = false;
2080
2081 m_statusPopup->SetText( aTooltip );
2082
2084 picker->SetSnapping( true );
2085
2086 picker->SetClickHandler(
2087 [&]( const VECTOR2D& aPoint ) -> bool
2088 {
2089 pickedPoint = aPoint;
2090
2091 if( !aSuccessMessage.empty() )
2092 {
2093 m_statusPopup->SetText( aSuccessMessage );
2094 m_statusPopup->Expire( 800 );
2095 }
2096 else
2097 {
2098 m_statusPopup->Hide();
2099 }
2100
2101 return false; // we don't need any more points
2102 } );
2103
2104 picker->SetMotionHandler(
2105 [&]( const VECTOR2D& aPos )
2106 {
2107 m_statusPopup->Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
2108 } );
2109
2110 picker->SetCancelHandler(
2111 [&]()
2112 {
2113 if( !aCanceledMessage.empty() )
2114 {
2115 m_statusPopup->SetText( aCanceledMessage );
2116 m_statusPopup->Expire( 800 );
2117 }
2118 else
2119 {
2120 m_statusPopup->Hide();
2121 }
2122 } );
2123
2124 picker->SetFinalizeHandler(
2125 [&]( const int& aFinalState )
2126 {
2127 done = true;
2128 } );
2129
2130 m_statusPopup->Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
2131 m_statusPopup->Popup();
2132 canvas()->SetStatusPopup( m_statusPopup->GetPanel() );
2133
2134 std::string tool = "";
2135 m_toolMgr->RunAction( ACTIONS::pickerTool, true, &tool );
2136
2137 while( !done )
2138 {
2139 // Pass events unless we receive a null event, then we must shut down
2140 if( TOOL_EVENT* evt = Wait() )
2141 evt->SetPassEvent();
2142 else
2143 break;
2144 }
2145
2146 // Ensure statusPopup is hidden after use and before deleting it:
2147 canvas()->SetStatusPopup( nullptr );
2148 m_statusPopup->Hide();
2149
2150 if( pickedPoint )
2151 aReferencePoint = *pickedPoint;
2152
2153 return pickedPoint.has_value();
2154}
static TOOL_ACTION pickerTool
Definition: actions.h:158
void SetStatusPopup(wxWindow *aPopup)
std::unique_ptr< STATUS_TEXT_POPUP > m_statusPopup
Definition: edit_tool.h:207
Generic tool for picking an item.
void SetMotionHandler(MOTION_HANDLER aHandler)
Set a handler for mouse motion.
Definition: picker_tool.h:82
void SetClickHandler(CLICK_HANDLER aHandler)
Set a handler for mouse click event.
Definition: picker_tool.h:71
void SetSnapping(bool aSnap)
Definition: picker_tool.h:64
void SetCancelHandler(CANCEL_HANDLER aHandler)
Set a handler for cancel events (ESC or context-menu Cancel).
Definition: picker_tool.h:91
void SetFinalizeHandler(FINALIZE_HANDLER aHandler)
Set a handler for the finalize event.
Definition: picker_tool.h:102

References PCB_TOOL_BASE::canvas(), TOOL_MANAGER::GetTool(), m_statusPopup, TOOL_BASE::m_toolMgr, ACTIONS::pickerTool, TOOL_MANAGER::RunAction(), PICKER_TOOL_BASE::SetCancelHandler(), PICKER_TOOL_BASE::SetClickHandler(), PICKER_TOOL_BASE::SetFinalizeHandler(), PICKER_TOOL_BASE::SetMotionHandler(), PICKER_TOOL_BASE::SetSnapping(), EDA_DRAW_PANEL_GAL::SetStatusPopup(), and TOOL_INTERACTIVE::Wait().

Referenced by copyToClipboard(), and doMoveSelection().

◆ Properties()

int EDIT_TOOL::Properties ( const TOOL_EVENT aEvent)

Display properties window for the selected object.

Definition at line 1015 of file edit_tool.cpp.

1016{
1017 PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
1019 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1020 {
1021 } );
1022
1023 // Tracks & vias are treated in a special way:
1025 {
1027 dlg.ShowQuasiModal(); // QuasiModal required for NET_SELECTOR
1028 }
1029 else if( selection.Size() == 1 )
1030 {
1031 // Display properties dialog
1032 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.Front() );
1033
1034 // Do not handle undo buffer, it is done by the properties dialogs
1035 editFrame->OnEditItemRequest( item );
1036
1037 // Notify other tools of the changes
1039 }
1040 else if( selection.Size() == 0 && getView()->IsLayerVisible( LAYER_DRAWINGSHEET ) )
1041 {
1042 DS_PROXY_VIEW_ITEM* ds = editFrame->GetCanvas()->GetDrawingSheet();
1043 VECTOR2D cursorPos = getViewControls()->GetCursorPosition( false );
1044
1045 if( ds && ds->HitTestDrawingSheetItems( getView(), cursorPos ) )
1047 else
1049 }
1050
1051 if( selection.IsHover() )
1052 {
1054 }
1055 else
1056 {
1057 // Check for items becoming invisible and drop them from the selection.
1058
1059 PCB_SELECTION selCopy = selection;
1060 LSET visible = editFrame->GetBoard()->GetVisibleLayers();
1061
1062 for( EDA_ITEM* eda_item : selCopy )
1063 {
1064 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( eda_item );
1065
1066 if( !( item->GetLayerSet() & visible ).any() )
1068 }
1069 }
1070
1071 return 0;
1072}
static TOOL_ACTION pageSettings
Definition: actions.h:56
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition: board_item.h:174
LSET GetVisibleLayers() const
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:499
static TOOL_ACTION footprintProperties
Definition: pcb_actions.h:409
int RemoveItemFromSel(const TOOL_EVENT &aEvent)
@ LAYER_DRAWINGSHEET
drawingsheet frame and titleblock
Definition: layer_ids.h:217

References PCB_ACTIONS::footprintProperties, SELECTION::Front(), PCB_BASE_FRAME::GetBoard(), PCB_BASE_FRAME::GetCanvas(), KIGFX::VIEW_CONTROLS::GetCursorPosition(), PCB_DRAW_PANEL_GAL::GetDrawingSheet(), BOARD_ITEM::GetLayerSet(), TOOL_BASE::getView(), TOOL_BASE::getViewControls(), BOARD::GetVisibleLayers(), DS_PROXY_VIEW_ITEM::HitTestDrawingSheetItems(), SELECTION::IsHover(), KIGFX::VIEW::IsLayerVisible(), LAYER_DRAWINGSHEET, m_commit, m_selectionTool, TOOL_BASE::m_toolMgr, PCB_BASE_EDIT_FRAME::OnEditItemRequest(), SELECTION_CONDITIONS::OnlyTypes(), ACTIONS::pageSettings, PCB_ARC_T, PCB_TRACE_T, PCB_VIA_T, TOOL_MANAGER::ProcessEvent(), SELECTION_TOOL::RemoveItemFromSel(), PCB_SELECTION_TOOL::RequestSelection(), TOOL_MANAGER::RunAction(), EVENTS::SelectedItemsModified, PCB_TOOL_BASE::selection(), PCB_ACTIONS::selectionClear, DIALOG_SHIM::ShowQuasiModal(), and SELECTION::Size().

Referenced by setTransitions().

◆ Remove()

int EDIT_TOOL::Remove ( const TOOL_EVENT aEvent)

Delete currently selected items.

Definition at line 1494 of file edit_tool.cpp.

1495{
1496 PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
1497
1498 if( isRouterActive() )
1499 {
1501 return 0;
1502 }
1503
1504 editFrame->PushTool( aEvent );
1505
1506 std::vector<BOARD_ITEM*> lockedItems;
1507 Activate();
1508
1509 // get a copy instead of reference (as we're going to clear the selection before removing items)
1510 PCB_SELECTION selectionCopy;
1513
1514 // If we are in a "Cut" operation, then the copied selection exists already and we want to
1515 // delete exactly that; no more, no fewer. Any filtering for locked items must be done in
1516 // the copyToClipboard() routine.
1517 if( isCut )
1518 {
1519 selectionCopy = m_selectionTool->GetSelection();
1520 }
1521 else
1522 {
1523 // When not in free-pad mode we normally auto-promote selected pads to their parent
1524 // footprints. But this is probably a little too dangerous for a destructive operation,
1525 // so we just do the promotion but not the deletion (allowing for a second delete to do
1526 // it if that's what the user wanted).
1527 selectionCopy = m_selectionTool->RequestSelection(
1528 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1529 {
1530 } );
1531
1532 size_t beforeFPCount = selectionCopy.CountType( PCB_FOOTPRINT_T );
1533
1535 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1536 {
1537 sTool->FilterCollectorForFreePads( aCollector );
1538 } );
1539
1540 if( !selectionCopy.IsHover()
1541 && m_selectionTool->GetSelection().CountType( PCB_FOOTPRINT_T ) > beforeFPCount )
1542 {
1543 wxBell();
1544 canvas()->Refresh();
1545 editFrame->PopTool( aEvent );
1546 return 0;
1547 }
1548
1549 // In "alternative" mode, we expand selected track items to their full connection.
1550 if( isAlt && ( selectionCopy.HasType( PCB_TRACE_T ) || selectionCopy.HasType( PCB_VIA_T ) ) )
1551 {
1553 }
1554
1555 // Finally run RequestSelection() one more time to find out what user wants to do about
1556 // locked objects.
1557 selectionCopy = m_selectionTool->RequestSelection(
1558 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1559 {
1560 sTool->FilterCollectorForFreePads( aCollector );
1561 },
1562 true /* prompt user regarding locked items */ );
1563 }
1564
1565 // As we are about to remove items, they have to be removed from the selection first
1567
1568 for( EDA_ITEM* item : selectionCopy )
1569 {
1570 PCB_GROUP* parentGroup = static_cast<BOARD_ITEM*>( item )->GetParentGroup();
1571
1572 if( parentGroup )
1573 {
1574 m_commit->Modify( parentGroup );
1575 parentGroup->RemoveItem( static_cast<BOARD_ITEM*>( item ) );
1576 }
1577
1578 switch( item->Type() )
1579 {
1580 case PCB_FP_TEXT_T:
1581 {
1582 FP_TEXT* text = static_cast<FP_TEXT*>( item );
1583 FOOTPRINT* parent = static_cast<FOOTPRINT*>( item->GetParent() );
1584
1585 switch( text->GetType() )
1586 {
1589 m_commit->Modify( parent );
1590 text->SetVisible( false );
1591 getView()->Update( text );
1592 break;
1594 m_commit->Modify( parent );
1595 getView()->Remove( text );
1596 parent->Remove( text );
1597 break;
1598 default:
1599 wxFAIL; // Shouldn't get here
1600 break;
1601 }
1602
1603 break;
1604 }
1605
1606 case PCB_FP_TEXTBOX_T:
1607 {
1608 FP_TEXTBOX* textbox = static_cast<FP_TEXTBOX*>( item );
1609 FOOTPRINT* parent = static_cast<FOOTPRINT*>( item->GetParent() );
1610
1611 m_commit->Modify( parent );
1612 getView()->Remove( textbox );
1613 parent->Remove( textbox );
1614 break;
1615 }
1616
1617 case PCB_PAD_T:
1618 if( IsFootprintEditor() || frame()->GetPcbNewSettings()->m_AllowFreePads )
1619 {
1620 PAD* pad = static_cast<PAD*>( item );
1621 FOOTPRINT* parent = static_cast<FOOTPRINT*>( item->GetParent() );
1622
1623 m_commit->Modify( parent );
1624 getView()->Remove( pad );
1625 parent->Remove( pad );
1626 }
1627
1628 break;
1629
1630 case PCB_FP_ZONE_T:
1631 {
1632 FP_ZONE* zone = static_cast<FP_ZONE*>( item );
1633 FOOTPRINT* parent = static_cast<FOOTPRINT*>( item->GetParent() );
1634
1635 m_commit->Modify( parent );
1636 getView()->Remove( zone );
1637 parent->Remove( zone );
1638 break;
1639 }
1640
1641 case PCB_ZONE_T:
1642 // We process the zones special so that cutouts can be deleted when the delete tool
1643 // is called from inside a cutout when the zone is selected.
1644 {
1645 // Only interact with cutouts when deleting and a single item is selected
1646 if( !isCut && selectionCopy.GetSize() == 1 )
1647 {
1649 ZONE* zone = static_cast<ZONE*>( item );
1650
1651 int outlineIdx, holeIdx;
1652
1653 if( zone->HitTestCutout( curPos, &outlineIdx, &holeIdx ) )
1654 {
1655 // Remove the cutout
1656 m_commit->Modify( zone );
1657 zone->RemoveCutout( outlineIdx, holeIdx );
1658 zone->UnFill();
1659
1660 // TODO Refill zone when KiCad supports auto re-fill
1661
1662 // Update the display
1663 zone->HatchBorder();
1664 canvas()->Refresh();
1665
1666 // Restore the selection on the original zone
1668
1669 break;
1670 }
1671 }
1672
1673 // Remove the entire zone otherwise
1674 m_commit->Remove( item );
1675 break;
1676 }
1677
1678 case PCB_GROUP_T:
1679 {
1680 PCB_GROUP* group = static_cast<PCB_GROUP*>( item );
1681
1682 auto removeItem =
1683 [&]( BOARD_ITEM* bItem )
1684 {
1685 if( bItem->GetParent() && bItem->GetParent()->Type() == PCB_FOOTPRINT_T )
1686 {
1687 // Silently ignore delete of Reference or Value if they happen to be
1688 // in group.
1689 if( bItem->Type() == PCB_FP_TEXT_T )
1690 {
1691 FP_TEXT* textItem = static_cast<FP_TEXT*>( bItem );
1692
1693 if( textItem->GetType() != FP_TEXT::TEXT_is_DIVERS )
1694 return;
1695 }
1696 else if( bItem->Type() == PCB_PAD_T )
1697 {
1698 if( !IsFootprintEditor()
1700 {
1701 return;
1702 }
1703 }
1704
1705 m_commit->Modify( bItem->GetParent() );
1706 getView()->Remove( bItem );
1707 bItem->GetParent()->Remove( bItem );
1708 }
1709 else
1710 {
1711 m_commit->Remove( bItem );
1712 }
1713 };
1714
1715 removeItem( group );
1716
1717 group->RunOnDescendants( [&]( BOARD_ITEM* aDescendant )
1718 {
1719 removeItem( aDescendant );
1720 });
1721 break;
1722 }
1723
1724 default:
1725 m_commit->Remove( item );
1726 break;
1727 }
1728 }
1729
1730 // If the entered group has been emptied then leave it.
1731 PCB_GROUP* enteredGroup = m_selectionTool->GetEnteredGroup();
1732
1733 if( enteredGroup && enteredGroup->GetItems().empty() )
1735
1736 if( isCut )
1737 m_commit->Push( _( "Cut" ) );
1738 else
1739 m_commit->Push( _( "Delete" ) );
1740
1741 editFrame->PopTool( aEvent );
1742 return 0;
1743}
REMOVE_FLAGS
Definition: actions.h:194
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...
void Remove(BOARD_ITEM *aItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
Definition: footprint.cpp:609
@ TEXT_is_REFERENCE
Definition: fp_text.h:49
@ TEXT_is_DIVERS
Definition: fp_text.h:51
@ TEXT_is_VALUE
Definition: fp_text.h:50
TEXT_TYPE GetType() const
Definition: fp_text.h:120
static TOOL_ACTION routerUndoLastSegment
Definition: pcb_actions.h:215
static TOOL_ACTION selectConnection
Select tracks between junctions or expands an existing selection to pads or the entire connection.
Definition: pcb_actions.h:80
std::unordered_set< BOARD_ITEM * > & GetItems()
Definition: pcb_group.h:68
bool RemoveItem(BOARD_ITEM *aItem)
Remove item from group.
Definition: pcb_group.cpp:51
PCB_GROUP * GetEnteredGroup()
void ExitGroup(bool aSelectGroup=false)
Leave the currently-entered group.
bool HasType(KICAD_T aType) const
Checks if there is at least one item of requested kind.
Definition: selection.cpp:134
size_t CountType(KICAD_T aType) const
Definition: selection.cpp:146
Handle a list of polygons defining a copper zone.
Definition: zone.h:57
bool UnFill()
Removes the zone filling.
Definition: zone.cpp:206
bool HitTestCutout(const VECTOR2I &aRefPos, int *aOutlineIdx=nullptr, int *aHoleIdx=nullptr) const
Test if the given point is contained within a cutout of the zone.
Definition: zone.cpp:451
void HatchBorder()
Compute the hatch lines depending on the hatch parameters and stores it in the zone's attribute m_bor...
Definition: zone.cpp:791
void RemoveCutout(int aOutlineIdx, int aHoleIdx)
Remove a cutout from the zone.
Definition: zone.cpp:650

References _, TOOL_INTERACTIVE::Activate(), ACTIONS::ALT, PCB_TOOL_BASE::canvas(), SELECTION::CountType(), ACTIONS::CUT, PCB_SELECTION_TOOL::ExitGroup(), PCB_SELECTION_TOOL::FilterCollectorForFreePads(), PCB_TOOL_BASE::frame(), KIGFX::VIEW_CONTROLS::GetCursorPosition(), PCB_SELECTION_TOOL::GetEnteredGroup(), PCB_GROUP::GetItems(), PCB_BASE_FRAME::GetPcbNewSettings(), PCB_SELECTION_TOOL::GetSelection(), SELECTION::GetSize(), FP_TEXT::GetType(), TOOL_BASE::getView(), TOOL_BASE::getViewControls(), group, SELECTION::HasType(), ZONE::HatchBorder(), ZONE::HitTestCutout(), PCB_TOOL_BASE::IsFootprintEditor(), SELECTION::IsHover(), isRouterActive(), PCBNEW_SETTINGS::m_AllowFreePads, m_commit, m_selectionTool, TOOL_BASE::m_toolMgr, pad, TOOL_EVENT::Parameter(), PCB_FOOTPRINT_T, PCB_FP_TEXT_T, PCB_FP_TEXTBOX_T, PCB_FP_ZONE_T, PCB_GROUP_T, PCB_PAD_T, PCB_TRACE_T, PCB_VIA_T, PCB_ZONE_T, TOOLS_HOLDER::PopTool(), TOOLS_HOLDER::PushTool(), EDA_DRAW_PANEL_GAL::Refresh(), FOOTPRINT::Remove(), KIGFX::VIEW::Remove(), ZONE::RemoveCutout(), PCB_GROUP::RemoveItem(), PCB_SELECTION_TOOL::RequestSelection(), PCB_ACTIONS::routerUndoLastSegment, TOOL_MANAGER::RunAction(), PCB_ACTIONS::selectConnection, PCB_ACTIONS::selectionClear, PCB_ACTIONS::selectItem, text, FP_TEXT::TEXT_is_DIVERS, FP_TEXT::TEXT_is_REFERENCE, FP_TEXT::TEXT_is_VALUE, ZONE::UnFill(), and KIGFX::VIEW::Update().

Referenced by cutToClipboard(), and setTransitions().

◆ Reset()

void EDIT_TOOL::Reset ( RESET_REASON  aReason)
overridevirtual

Bring the tool to a known, initial state.

If the tool claimed anything from the model or the view, it must release it when its reset.

Parameters
aReasoncontains information about the reason of tool reset.

Reimplemented from PCB_TOOL_BASE.

Definition at line 79 of file edit_tool.cpp.

80{
81 m_dragging = false;
82
83 m_statusPopup = std::make_unique<STATUS_TEXT_POPUP>( getEditFrame<PCB_BASE_EDIT_FRAME>() );
84
85 if( aReason != RUN )
86 m_commit.reset( new BOARD_COMMIT( this ) );
87}

References m_commit, m_dragging, m_statusPopup, and TOOL_BASE::RUN.

◆ resetTransitions()

void TOOL_INTERACTIVE::resetTransitions ( )
privateinherited

Clear the current transition map and restores the default one created by setTransitions().

Definition at line 63 of file tool_interactive.cpp.

64{
67}
virtual void setTransitions()=0
This method is meant to be overridden in order to specify handlers for events.
void ClearTransitions(TOOL_BASE *aTool)
Clear the state transition map for a tool.

References TOOL_MANAGER::ClearTransitions(), TOOL_BASE::m_toolMgr, and TOOL_INTERACTIVE::setTransitions().

◆ Rotate()

int EDIT_TOOL::Rotate ( const TOOL_EVENT aEvent)

Rotate currently selected items.

Definition at line 1075 of file edit_tool.cpp.

1076{
1077 if( isRouterActive() )
1078 {
1079 wxBell();
1080 return 0;
1081 }
1082
1083 PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
1084
1085 // Be sure that there is at least one item that we can modify. If nothing was selected before,
1086 // try looking for the stuff under mouse cursor (i.e. KiCad old-style hover selection)
1088 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1089 {
1090 sTool->FilterCollectorForHierarchy( aCollector, true );
1091 sTool->FilterCollectorForMarkers( aCollector );
1092 },
1093 // Prompt user regarding locked items if in board editor and in free-pad-mode (if
1094 // we're not in free-pad mode we delay this until the second RequestSelection()).
1096
1097 if( selection.Empty() )
1098 return 0;
1099
1100 std::optional<VECTOR2I> oldRefPt;
1101 bool is_hover = selection.IsHover(); // N.B. This must be saved before the second
1102 // call to RequestSelection() below
1103
1105 oldRefPt = selection.GetReferencePoint();
1106
1107 // Now filter out pads if not in free pads mode. We cannot do this in the first
1108 // RequestSelection() as we need the reference point when a pad is the selection front.
1110 {
1112 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1113 {
1114 sTool->FilterCollectorForMarkers( aCollector );
1115 sTool->FilterCollectorForHierarchy( aCollector, true );
1116 sTool->FilterCollectorForFreePads( aCollector );
1117 },
1118 true /* prompt user regarding locked items */ );
1119 }
1120
1121 // Did we filter everything out? If so, don't try to operate further
1122 if( selection.Empty() )
1123 return 0;
1124
1126
1128 EDA_ANGLE rotateAngle = TOOL_EVT_UTILS::GetEventRotationAngle( *editFrame, aEvent );
1129
1130 // Calculate view bounding box
1131 BOX2I viewBBox = selection.Front()->ViewBBox();
1132
1133 for( EDA_ITEM* item : selection )
1134 viewBBox.Merge( item->ViewBBox() );
1135
1136 // Check if the view bounding box will go out of bounds
1137 VECTOR2D rotPos = viewBBox.GetPosition();
1138 VECTOR2D rotEnd = viewBBox.GetEnd();
1139
1140 RotatePoint( &rotPos.x, &rotPos.y, refPt.x, refPt.y, rotateAngle );
1141 RotatePoint( &rotEnd.x, &rotEnd.y, refPt.x, refPt.y, rotateAngle );
1142
1143 typedef std::numeric_limits<int> coord_limits;
1144
1145 int max = coord_limits::max() - COORDS_PADDING;
1146 int min = -max;
1147
1148 bool outOfBounds = rotPos.x < min || rotPos.x > max || rotPos.y < min || rotPos.y > max
1149 || rotEnd.x < min || rotEnd.x > max || rotEnd.y < min || rotEnd.y > max;
1150
1151 if( !outOfBounds )
1152 {
1153 // When editing footprints, all items have the same parent
1154 if( IsFootprintEditor() )
1155 m_commit->Modify( selection.Front() );
1156
1157 for( EDA_ITEM* item : selection )
1158 {
1159 if( !item->IsNew() && !IsFootprintEditor() )
1160 {
1161 m_commit->Modify( item );
1162
1163 // If rotating a group, record position of all the descendants for undo
1164 if( item->Type() == PCB_GROUP_T )
1165 {
1166 static_cast<PCB_GROUP*>( item )->RunOnDescendants( [&]( BOARD_ITEM* bItem )
1167 {
1168 m_commit->Modify( bItem );
1169 });
1170 }
1171 }
1172
1173 static_cast<BOARD_ITEM*>( item )->Rotate( refPt, rotateAngle );
1174 }
1175
1176 if( !m_dragging )
1177 m_commit->Push( _( "Rotate" ) );
1178
1179 if( is_hover && !m_dragging )
1181
1183
1184 if( m_dragging )
1186 }
1187
1188 // Restore the old reference so any mouse dragging that occurs doesn't make the selection jump
1189 // to this now invalid reference
1190 if( oldRefPt )
1191 selection.SetReferencePoint( *oldRefPt );
1192 else
1194
1195 return 0;
1196}
virtual const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
Definition: eda_item.cpp:254
int Rotate(const TOOL_EVENT &aEvent)
Rotate currently selected items.
Definition: edit_tool.cpp:1075
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Definition: trigo.cpp:183

References _, SELECTION::ClearReferencePoint(), COORDS_PADDING, SELECTION::Empty(), PCB_SELECTION_TOOL::FilterCollectorForFreePads(), PCB_SELECTION_TOOL::FilterCollectorForHierarchy(), PCB_SELECTION_TOOL::FilterCollectorForMarkers(), PCB_TOOL_BASE::frame(), SELECTION::Front(), BOX2< Vec >::GetEnd(), TOOL_EVT_UTILS::GetEventRotationAngle(), PCB_BASE_FRAME::GetPcbNewSettings(), BOX2< Vec >::GetPosition(), SELECTION::GetReferencePoint(), SELECTION::HasReferencePoint(), PCB_TOOL_BASE::IsFootprintEditor(), SELECTION::IsHover(), isRouterActive(), PCBNEW_SETTINGS::m_AllowFreePads, m_commit, m_dragging, PCB_TOOL_BASE::m_isFootprintEditor, m_selectionTool, TOOL_BASE::m_toolMgr, BOX2< Vec >::Merge(), PCB_GROUP_T, TOOL_MANAGER::ProcessEvent(), PCB_SELECTION_TOOL::RequestSelection(), Rotate(), RotatePoint(), TOOL_MANAGER::RunAction(), EVENTS::SelectedItemsModified, PCB_TOOL_BASE::selection(), PCB_ACTIONS::selectionClear, SELECTION::SetReferencePoint(), PCB_ACTIONS::updateLocalRatsnest, updateModificationPoint(), EDA_ITEM::ViewBBox(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by Rotate(), and setTransitions().

◆ RunMainStack()

void TOOL_INTERACTIVE::RunMainStack ( std::function< void()>  aFunc)
inherited

Call a function using the main stack.

Parameters
aFuncis the function to be calls.

Definition at line 87 of file tool_interactive.cpp.

88{
89 m_toolMgr->RunMainStack( this, std::move( aFunc ) );
90}
void RunMainStack(TOOL_BASE *aTool, std::function< void()> aFunc)

References TOOL_BASE::m_toolMgr, and TOOL_MANAGER::RunMainStack().

Referenced by DRAWING_TOOL::PlaceText().

◆ selection() [1/2]

PCB_SELECTION & PCB_TOOL_BASE::selection ( )
protectedinherited

Definition at line 320 of file pcb_tool_base.cpp.

321{
323
324 return selTool->GetSelection();
325}

References PCB_SELECTION_TOOL::GetSelection(), TOOL_MANAGER::GetTool(), and TOOL_BASE::m_toolMgr.

◆ selection() [2/2]

const PCB_SELECTION & PCB_TOOL_BASE::selection ( ) const
protectedinherited

Definition at line 312 of file pcb_tool_base.cpp.

313{
315
316 return selTool->GetSelection();
317}

References PCB_SELECTION_TOOL::GetSelection(), TOOL_MANAGER::GetTool(), and TOOL_BASE::m_toolMgr.

Referenced by BOARD_EDITOR_CONTROL::AssignNetclass(), AUTOPLACE_TOOL::autoplaceSelected(), BOARD_INSPECTION_TOOL::calculateSelectionRatsnest(), ROUTER_TOOL::CanInlineDrag(), ChangeTrackWidth(), PAD_TOOL::copyPadSettings(), copyToClipboard(), CreateArray(), DRC_TOOL::CrossProbe(), BOARD_EDITOR_CONTROL::doCrossProbePcbToSch(), BOARD_INSPECTION_TOOL::doHideRatsnestNet(), PCB_TOOL_BASE::doInteractiveItemPlacement(), doMoveSelection(), Drag(), DragArcTrack(), DRAWING_TOOL::drawArc(), DRAWING_TOOL::DrawDimension(), MICROWAVE_TOOL::drawMicrowaveInductor(), DRAWING_TOOL::drawShape(), DRAWING_TOOL::DrawZone(), Duplicate(), BOARD_EDITOR_CONTROL::EditFpInFpEditor(), PAD_TOOL::EditPad(), GROUP_TOOL::EnterGroup(), PAD_TOOL::EnumeratePads(), GLOBAL_EDIT_TOOL::ExchangeFootprints(), FilletTracks(), Flip(), DRAWING_TOOL::getSourceZoneForAction(), GROUP_TOOL::Group(), BOARD_INSPECTION_TOOL::highlightNet(), ROUTER_TOOL::InlineBreakTrack(), ROUTER_TOOL::InlineDrag(), BOARD_INSPECTION_TOOL::InspectClearance(), BOARD_INSPECTION_TOOL::InspectConstraints(), DRAWING_TOOL::InteractivePlaceWithPreview(), BOARD_INSPECTION_TOOL::LocalRatsnestTool(), LENGTH_TUNER_TOOL::MainLoop(), ROUTER_TOOL::MainLoop(), Mirror(), BOARD_EDITOR_CONTROL::modifyLockSelected(), MoveExact(), PCB_POINT_EDITOR::OnSelectionChange(), PAD_TOOL::pastePadProperties(), ROUTER_TOOL::performDragging(), ROUTER_TOOL::performRouting(), LENGTH_TUNER_TOOL::performTuning(), PCB_CONTROL::placeBoardItems(), BOARD_EDITOR_CONTROL::PlaceFootprint(), DRAWING_TOOL::PlaceImportedGraphics(), DRAWING_TOOL::PlaceText(), POSITION_RELATIVE_TOOL::PositionRelative(), Properties(), PAD_TOOL::pushPadSettings(), BOARD_REANNOTATE_TOOL::ReannotateDuplicatesInSelection(), GROUP_TOOL::RemoveFromGroup(), GLOBAL_EDIT_TOOL::RemoveUnusedPads(), Rotate(), ROUTER_TOOL::RouteSelected(), DRAWING_TOOL::SetAnchor(), Swap(), BOARD_EDITOR_CONTROL::TrackWidthDec(), BOARD_EDITOR_CONTROL::TrackWidthInc(), GROUP_TOOL::Ungroup(), BOARD_INSPECTION_TOOL::UpdateLocalRatsnest(), PCB_CONTROL::UpdateMessagePanel(), BOARD_EDITOR_CONTROL::ViaSizeDec(), BOARD_EDITOR_CONTROL::ViaSizeInc(), BOARD_EDITOR_CONTROL::ZoneDuplicate(), ZONE_FILLER_TOOL::ZoneFill(), BOARD_EDITOR_CONTROL::ZoneMerge(), and ZONE_FILLER_TOOL::ZoneUnfill().

◆ SetContextMenu()

void TOOL_INTERACTIVE::SetContextMenu ( ACTION_MENU aMenu,
CONTEXT_MENU_TRIGGER  aTrigger = CMENU_BUTTON 
)
inherited

Assign a context menu and tells when it should be activated.

Parameters
aMenuis the menu to be assigned.
aTriggerdetermines conditions upon which the context menu is activated.

Definition at line 76 of file tool_interactive.cpp.

77{
78 if( aMenu )
79 aMenu->SetTool( this );
80 else
81 aTrigger = CMENU_OFF;
82
83 m_toolMgr->ScheduleContextMenu( this, aMenu, aTrigger );
84}
void SetTool(TOOL_INTERACTIVE *aTool)
Set a tool that is the creator of the menu.
void ScheduleContextMenu(TOOL_BASE *aTool, ACTION_MENU *aMenu, CONTEXT_MENU_TRIGGER aTrigger)
Set behavior of the tool's context popup menu.
@ CMENU_OFF
Definition: tool_event.h:149

References CMENU_OFF, TOOL_BASE::m_toolMgr, TOOL_MANAGER::ScheduleContextMenu(), and ACTION_MENU::SetTool().

Referenced by SELECTION_TOOL::doSelectionMenu(), TOOL_MENU::ShowContextMenu(), and SCH_LINE_WIRE_BUS_TOOL::UnfoldBus().

◆ SetIsBoardEditor()

void PCB_TOOL_BASE::SetIsBoardEditor ( bool  aEnabled)
inlineinherited

Definition at line 108 of file pcb_tool_base.h.

108{ m_isBoardEditor = aEnabled; }

References PCB_TOOL_BASE::m_isBoardEditor.

◆ SetIsFootprintEditor()

void PCB_TOOL_BASE::SetIsFootprintEditor ( bool  aEnabled)
inlineinherited

Function SetIsFootprintEditor()

Toggles edit footprint mode. When enabled, one may select parts of footprints individually (graphics, pads, etc.), so they can be modified.

Parameters
aEnableddecides if the mode should be enabled.

Definition at line 105 of file pcb_tool_base.h.

105{ m_isFootprintEditor = aEnabled; }

References PCB_TOOL_BASE::m_isFootprintEditor.

◆ setTransitions()

void EDIT_TOOL::setTransitions ( )
overrideprivatevirtual

< Set up handlers for various events.

Reimplemented from PCB_TOOL_BASE.

Definition at line 2240 of file edit_tool.cpp.

2241{
2243 Go( &EDIT_TOOL::Move, PCB_ACTIONS::move.MakeEvent() );
2249 Go( &EDIT_TOOL::Flip, PCB_ACTIONS::flip.MakeEvent() );
2250 Go( &EDIT_TOOL::Remove, ACTIONS::doDelete.MakeEvent() );
2258 Go( &EDIT_TOOL::Mirror, PCB_ACTIONS::mirrorH.MakeEvent() );
2259 Go( &EDIT_TOOL::Mirror, PCB_ACTIONS::mirrorV.MakeEvent() );
2260 Go( &EDIT_TOOL::Swap, PCB_ACTIONS::swap.MakeEvent() );
2263
2266 Go( &EDIT_TOOL::cutToClipboard, ACTIONS::cut.MakeEvent() );
2267}
int Drag(const TOOL_EVENT &aEvent)
Invoke the PNS router to drag tracks or do an offline resizing of an arc track if a single arc track ...
Definition: edit_tool.cpp:302
int Duplicate(const TOOL_EVENT &aEvent)
Duplicate the current selection and starts a move action.
Definition: edit_tool.cpp:1849
int Swap(const TOOL_EVENT &aEvent)
Swap currently selected items' positions.
int MoveWithReference(const TOOL_EVENT &aEvent)
Move an item but with a reference point selected first.
int CreateArray(const TOOL_EVENT &aEvent)
Create an array of the selected items, invoking the array editor dialog to set the options.
Definition: edit_tool.cpp:1993
int MoveExact(const TOOL_EVENT &aEvent)
Invoke a dialog box to allow moving of the item by an exact amount.
Definition: edit_tool.cpp:1746
int cutToClipboard(const TOOL_EVENT &aEvent)
Cut the current selection to the clipboard by formatting it as a fake pcb see #AppendBoardFromClipboa...
Definition: edit_tool.cpp:2224
int ChangeTrackWidth(const TOOL_EVENT &aEvent)
Definition: edit_tool.cpp:741
int GetAndPlace(const TOOL_EVENT &aEvent)
Definition: edit_tool.cpp:241
int FilletTracks(const TOOL_EVENT &aEvent)
Fillet (i.e.
Definition: edit_tool.cpp:811
int MoveIndividually(const TOOL_EVENT &aEvent)
Move a selection of items one-at-a-time.
int Properties(const TOOL_EVENT &aEvent)
Display properties window for the selected object.
Definition: edit_tool.cpp:1015
static TOOL_ACTION changeTrackWidth
Update selected tracks & vias to the current track & via dimensions.
Definition: pcb_actions.h:136
static TOOL_ACTION getAndPlace
Find an item and start moving.
Definition: pcb_actions.h:503
static TOOL_ACTION deleteFull
Definition: pcb_actions.h:152
static TOOL_ACTION createArray
Tool for creating an array of objects.
Definition: pcb_actions.h:424
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).

References ChangeTrackWidth(), PCB_ACTIONS::changeTrackWidth, ACTIONS::copy, copyToClipboard(), PCB_ACTIONS::copyWithReference, CreateArray(), PCB_ACTIONS::createArray, ACTIONS::cut, cutToClipboard(), PCB_ACTIONS::deleteFull, ACTIONS::doDelete, Drag(), PCB_ACTIONS::drag45Degree, PCB_ACTIONS::dragFreeAngle, ACTIONS::duplicate, Duplicate(), PCB_ACTIONS::duplicateIncrement, FilletTracks(), PCB_ACTIONS::filletTracks, Flip(), PCB_ACTIONS::flip, GetAndPlace(), PCB_ACTIONS::getAndPlace, TOOL_INTERACTIVE::Go(), Mirror(), PCB_ACTIONS::mirrorH, PCB_ACTIONS::mirrorV, Move(), PCB_ACTIONS::move, MoveExact(), PCB_ACTIONS::moveExact, MoveIndividually(), PCB_ACTIONS::moveIndividually, MoveWithReference(), PCB_ACTIONS::moveWithReference, Properties(), PCB_ACTIONS::properties, Remove(), Rotate(), PCB_ACTIONS::rotateCcw, PCB_ACTIONS::rotateCw, Swap(), and PCB_ACTIONS::swap.

◆ Swap()

int EDIT_TOOL::Swap ( const TOOL_EVENT aEvent)

Swap currently selected items' positions.

Changes position of each item to the next.

Definition at line 273 of file edit_tool_move_fct.cpp.

274{
275 if( isRouterActive() || m_dragging )
276 {
277 wxBell();
278 return 0;
279 }
280
282 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
283 {
284 sTool->FilterCollectorForMarkers( aCollector );
285 sTool->FilterCollectorForHierarchy( aCollector, true );
286 sTool->FilterCollectorForFreePads( aCollector );
287 },
288 true /* prompt user regarding locked items */ );
289
290 if( selection.Size() < 2 )
291 return 0;
292
293 std::vector<EDA_ITEM*> sorted = selection.GetItemsSortedBySelectionOrder();
294
295 // When editing footprints, all items have the same parent
296 if( IsFootprintEditor() )
297 {
298 m_commit->Modify( selection.Front() );
299 }
300 else
301 {
302 // Save items, so changes can be undone
303 for( EDA_ITEM* item : selection )
304 {
305 // Don't double move footprint pads, fields, etc.
306 //
307 // For PCB_GROUP_T, the parent is the board.
308 if( item->GetParent() && item->GetParent()->IsSelected() )
309 continue;
310
311 m_commit->Modify( item );
312
313 // If moving a group, record position of all the descendants for undo
314 if( item->Type() == PCB_GROUP_T )
315 {
316 PCB_GROUP* group = static_cast<PCB_GROUP*>( item );
317 group->RunOnDescendants( [&]( BOARD_ITEM* bItem )
318 {
319 m_commit->Modify( bItem );
320 });
321 }
322 }
323 }
324
325 for( size_t i = 0; i < sorted.size() - 1; i++ )
326 {
327 BOARD_ITEM* a = static_cast<BOARD_ITEM*>( sorted[i] );
328 BOARD_ITEM* b = static_cast<BOARD_ITEM*>( sorted[( i + 1 ) % sorted.size()] );
329
330 // Swap X,Y position
331 VECTOR2I aPos = a->GetPosition(), bPos = b->GetPosition();
332 std::swap( aPos, bPos );
333 a->SetPosition( aPos );
334 b->SetPosition( bPos );
335
336 // Pads need special handling to keep their offset from their parent
337 if( a->Type() == PCB_PAD_T )
338 static_cast<PAD*>( a )->SetLocalCoord();
339
340 if( b->Type() == PCB_PAD_T )
341 static_cast<PAD*>( b )->SetLocalCoord();
342
343 // Handle footprints specially. They can be flipped to the back of the board which
344 // requires a special transformation.
345 if( a->Type() == PCB_FOOTPRINT_T && b->Type() == PCB_FOOTPRINT_T )
346 {
347 FOOTPRINT* aFP = static_cast<FOOTPRINT*>( a );
348 FOOTPRINT* bFP = static_cast<FOOTPRINT*>( b );
349
350 // Flip both if needed
351 if( aFP->IsFlipped() != bFP->IsFlipped() )
352 {
353 aFP->Flip( aPos, false );
354 bFP->Flip( bPos, false );
355 }
356
357 // Set orientation
358 EDA_ANGLE aAngle = aFP->GetOrientation(), bAngle = bFP->GetOrientation();
359 std::swap( aAngle, bAngle );
360 aFP->SetOrientation( aAngle );
361 bFP->SetOrientation( bAngle );
362 }
363 // We can also do a layer swap safely for two objects of the same type,
364 // except groups which don't support layer swaps.
365 else if( a->Type() == b->Type() && a->Type() != PCB_GROUP_T )
366 {
367 // Swap layers
368 PCB_LAYER_ID aLayer = a->GetLayer(), bLayer = b->GetLayer();
369 std::swap( aLayer, bLayer );
370 a->SetLayer( aLayer );
371 b->SetLayer( bLayer );
372 }
373 }
374
375 m_commit->Push( _( "Swap" ) );
376
378
379 return 0;
380}
virtual void SetPosition(const VECTOR2I &aPos)
Definition: eda_item.h:264
EDA_ANGLE GetOrientation() const
Definition: footprint.h:195
void SetOrientation(const EDA_ANGLE &aNewAngle)
Definition: footprint.cpp:1766
bool IsFlipped() const
Definition: footprint.h:319
void Flip(const VECTOR2I &aCentre, bool aFlipLeftRight) override
Flip this object, i.e.
Definition: footprint.cpp:1553
void SetLocalCoord()
< Set relative coordinates.
Definition: pad.cpp:638
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:59

References _, PCB_SELECTION_TOOL::FilterCollectorForFreePads(), PCB_SELECTION_TOOL::FilterCollectorForHierarchy(), PCB_SELECTION_TOOL::FilterCollectorForMarkers(), FOOTPRINT::Flip(), SELECTION::Front(), SELECTION::GetItemsSortedBySelectionOrder(), BOARD_ITEM::GetLayer(), FOOTPRINT::GetOrientation(), EDA_ITEM::GetPosition(), group, FOOTPRINT::IsFlipped(), PCB_TOOL_BASE::IsFootprintEditor(), isRouterActive(), m_commit, m_dragging, m_selectionTool, TOOL_BASE::m_toolMgr, PCB_FOOTPRINT_T, PCB_GROUP_T, PCB_PAD_T, TOOL_MANAGER::ProcessEvent(), PCB_SELECTION_TOOL::RequestSelection(), EVENTS::SelectedItemsModified, PCB_TOOL_BASE::selection(), BOARD_ITEM::SetLayer(), PAD::SetLocalCoord(), FOOTPRINT::SetOrientation(), EDA_ITEM::SetPosition(), SELECTION::Size(), and EDA_ITEM::Type().

Referenced by setTransitions().

◆ updateModificationPoint()

bool EDIT_TOOL::updateModificationPoint ( PCB_SELECTION aSelection)
private

Definition at line 2047 of file edit_tool.cpp.

2048{
2049 if( m_dragging && aSelection.HasReferencePoint() )
2050 return false;
2051
2052 // Can't modify an empty group
2053 if( aSelection.Empty() )
2054 return false;
2055
2056 // When there is only one item selected, the reference point is its position...
2057 if( aSelection.Size() == 1 )
2058 {
2059 auto item = static_cast<BOARD_ITEM*>( aSelection.Front() );
2060 auto pos = item->GetPosition();
2061 aSelection.SetReferencePoint( VECTOR2I( pos.x, pos.y ) );
2062 }
2063 // ...otherwise modify items with regard to the grid-snapped center position
2064 else
2065 {
2066 PCB_GRID_HELPER grid( m_toolMgr, frame()->GetMagneticItemsSettings() );
2067 aSelection.SetReferencePoint( grid.BestSnapAnchor( aSelection.GetCenter(), nullptr ) );
2068 }
2069
2070 return true;
2071}

References SELECTION::Empty(), PCB_TOOL_BASE::frame(), SELECTION::Front(), SELECTION::GetCenter(), EDA_ITEM::GetPosition(), grid, SELECTION::HasReferencePoint(), m_dragging, TOOL_BASE::m_toolMgr, SELECTION::SetReferencePoint(), and SELECTION::Size().

Referenced by Flip(), Mirror(), and Rotate().

◆ view()

◆ Wait()

TOOL_EVENT * TOOL_INTERACTIVE::Wait ( const TOOL_EVENT_LIST aEventList = TOOL_EVENTTC_ANYTA_ANY ))
inherited

Suspend execution of the tool until an event specified in aEventList arrives.

No parameters means waiting for any event.

Definition at line 57 of file tool_interactive.cpp.

58{
59 return m_toolMgr->ScheduleWait( this, aEventList );
60}
TOOL_EVENT * ScheduleWait(TOOL_BASE *aTool, const TOOL_EVENT_LIST &aConditions)
Pause execution of a given tool until one or more events matching aConditions arrives.

References TOOL_BASE::m_toolMgr, and TOOL_MANAGER::ScheduleWait().

Referenced by SCH_LINE_WIRE_BUS_TOOL::doDrawSegments(), PCB_TOOL_BASE::doInteractiveItemPlacement(), doMoveSelection(), SELECTION_TOOL::doSelectionMenu(), DragArcTrack(), DRAWING_TOOL::drawArc(), DRAWING_TOOL::DrawDimension(), MICROWAVE_TOOL::drawMicrowaveInductor(), SCH_DRAWING_TOOLS::DrawShape(), SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape(), PL_DRAWING_TOOLS::DrawShape(), DRAWING_TOOL::drawShape(), SCH_DRAWING_TOOLS::DrawSheet(), DRAWING_TOOL::DrawZone(), PAD_TOOL::EnumeratePads(), ROUTER_TOOL::InlineDrag(), DRAWING_TOOL::InteractivePlaceWithPreview(), EDA_3D_CONTROLLER::Main(), CVPCB_CONTROL::Main(), CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL::Main(), EE_POINT_EDITOR::Main(), EE_SELECTION_TOOL::Main(), SCH_MOVE_TOOL::Main(), SYMBOL_EDITOR_MOVE_TOOL::Main(), GERBVIEW_SELECTION_TOOL::Main(), PICKER_TOOL::Main(), ZOOM_TOOL::Main(), PL_EDIT_TOOL::Main(), PL_POINT_EDITOR::Main(), PL_SELECTION_TOOL::Main(), PCB_PICKER_TOOL::Main(), PCB_SELECTION_TOOL::Main(), LENGTH_TUNER_TOOL::MainLoop(), ROUTER_TOOL::MainLoop(), GERBVIEW_INSPECTION_TOOL::MeasureTool(), PCB_VIEWER_TOOLS::MeasureTool(), PCB_POINT_EDITOR::OnSelectionChange(), ROUTER_TOOL::performDragging(), ROUTER_TOOL::performRouting(), LENGTH_TUNER_TOOL::performTuning(), GROUP_TOOL::PickNewMember(), pickReferencePoint(), SYMBOL_EDITOR_DRAWING_TOOLS::PlaceAnchor(), BOARD_EDITOR_CONTROL::PlaceFootprint(), SCH_DRAWING_TOOLS::PlaceImage(), DRAWING_TOOL::PlaceImage(), DRAWING_TOOL::PlaceImportedGraphics(), PL_DRAWING_TOOLS::PlaceItem(), SCH_DRAWING_TOOLS::PlaceSymbol(), DRAWING_TOOL::PlaceText(), EE_SELECTION_TOOL::selectMultiple(), PL_SELECTION_TOOL::selectMultiple(), PCB_SELECTION_TOOL::selectMultiple(), PCB_SELECTION_TOOL::selectPoint(), POSITION_RELATIVE_TOOL::SelectPositionRelativeItem(), ZOOM_TOOL::selectRegion(), DRAWING_TOOL::SetAnchor(), SCH_DRAWING_TOOLS::SingleClickPlace(), SCH_DRAWING_TOOLS::TwoClickPlace(), SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace(), and SCH_LINE_WIRE_BUS_TOOL::UnfoldBus().

Member Data Documentation

◆ COORDS_PADDING

const unsigned int EDIT_TOOL::COORDS_PADDING = pcbIUScale.mmToIU( 20 )
staticprivate

Definition at line 209 of file edit_tool.h.

Referenced by getSafeMovement(), and Rotate().

◆ m_commit

std::unique_ptr<BOARD_COMMIT> EDIT_TOOL::m_commit
private

◆ m_cursor

VECTOR2I EDIT_TOOL::m_cursor
private

Definition at line 205 of file edit_tool.h.

Referenced by doMoveSelection(), and DragArcTrack().

◆ m_dragging

bool EDIT_TOOL::m_dragging
private

◆ m_isBoardEditor

bool PCB_TOOL_BASE::m_isBoardEditor
protectedinherited

◆ m_isFootprintEditor

◆ m_menu

TOOL_MENU TOOL_INTERACTIVE::m_menu
protectedinherited

The functions below are not yet implemented - their interface may change.

Definition at line 125 of file tool_interactive.h.

Referenced by SCH_LINE_WIRE_BUS_TOOL::doDrawSegments(), PCB_TOOL_BASE::doInteractiveItemPlacement(), DRAWING_TOOL::drawArc(), DRAWING_TOOL::DrawDimension(), MICROWAVE_TOOL::drawMicrowaveInductor(), SCH_DRAWING_TOOLS::DrawShape(), SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape(), PL_DRAWING_TOOLS::DrawShape(), DRAWING_TOOL::drawShape(), SCH_DRAWING_TOOLS::DrawSheet(), DRAWING_TOOL::DrawZone(), PAD_TOOL::EnumeratePads(), TOOL_INTERACTIVE::GetToolMenu(), EDA_3D_CONTROLLER::Init(), CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL::Init(), EE_SELECTION_TOOL::Init(), EE_TOOL_BASE< T >::Init(), SCH_DRAWING_TOOLS::Init(), SCH_EDIT_TOOL::Init(), SCH_LINE_WIRE_BUS_TOOL::Init(), SYMBOL_EDITOR_CONTROL::Init(), SYMBOL_EDITOR_DRAWING_TOOLS::Init(), GERBVIEW_SELECTION_TOOL::Init(), PICKER_TOOL::Init(), ZOOM_TOOL::Init(), PL_DRAWING_TOOLS::Init(), PL_EDIT_TOOL::Init(), PL_SELECTION_TOOL::Init(), LENGTH_TUNER_TOOL::Init(), ROUTER_TOOL::Init(), BOARD_EDITOR_CONTROL::Init(), DRAWING_TOOL::Init(), FOOTPRINT_EDITOR_CONTROL::Init(), PAD_TOOL::Init(), PCB_SELECTION_TOOL::Init(), PCB_TOOL_BASE::Init(), PCB_VIEWER_TOOLS::Init(), DRAWING_TOOL::InteractivePlaceWithPreview(), EDA_3D_CONTROLLER::Main(), CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL::Main(), EE_SELECTION_TOOL::Main(), SCH_MOVE_TOOL::Main(), SYMBOL_EDITOR_MOVE_TOOL::Main(), GERBVIEW_SELECTION_TOOL::Main(), PICKER_TOOL::Main(), ZOOM_TOOL::Main(), PL_EDIT_TOOL::Main(), PL_SELECTION_TOOL::Main(), PCB_PICKER_TOOL::Main(), PCB_SELECTION_TOOL::Main(), LENGTH_TUNER_TOOL::MainLoop(), ROUTER_TOOL::MainLoop(), GERBVIEW_INSPECTION_TOOL::MeasureTool(), PCB_VIEWER_TOOLS::MeasureTool(), ROUTER_TOOL::performDragging(), ROUTER_TOOL::performRouting(), LENGTH_TUNER_TOOL::performTuning(), SYMBOL_EDITOR_DRAWING_TOOLS::PlaceAnchor(), BOARD_EDITOR_CONTROL::PlaceFootprint(), SCH_DRAWING_TOOLS::PlaceImage(), DRAWING_TOOL::PlaceImage(), DRAWING_TOOL::PlaceImportedGraphics(), PL_DRAWING_TOOLS::PlaceItem(), SCH_DRAWING_TOOLS::PlaceSymbol(), DRAWING_TOOL::PlaceText(), DRAWING_TOOL::SetAnchor(), SCH_DRAWING_TOOLS::SingleClickPlace(), SCH_DRAWING_TOOLS::TwoClickPlace(), and SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace().

◆ m_selectionTool

◆ m_statusPopup

std::unique_ptr<STATUS_TEXT_POPUP> EDIT_TOOL::m_statusPopup
private

Definition at line 207 of file edit_tool.h.

Referenced by pickReferencePoint(), and Reset().

◆ m_toolId

TOOL_ID TOOL_BASE::m_toolId
protectedinherited

Name of the tool.

Names are expected to obey the format application.ToolName (eg. pcbnew.InteractiveSelection).

Definition at line 209 of file tool_base.h.

Referenced by TOOL_INTERACTIVE::Activate(), TOOL_BASE::GetId(), and TOOL_BASE::IsToolActive().

◆ m_toolMgr

TOOL_MANAGER* TOOL_BASE::m_toolMgr
protectedinherited

Definition at line 214 of file tool_base.h.

Referenced by TOOL_INTERACTIVE::Activate(), SELECTION_TOOL::AddItemsToSel(), SELECTION_TOOL::AddItemToSel(), SCH_MOVE_TOOL::AlignElements(), SCH_EDITOR_CONTROL::AssignNetclass(), BOARD_EDITOR_CONTROL::AssignNetclass(), CVPCB_ASSOCIATION_TOOL::Associate(), TOOL_BASE::attachManager(), SCH_EDIT_TOOL::AutoplaceFields(), EE_SELECTION_TOOL::autostartEvent(), SCH_EDIT_TOOL::BreakWire(), BOARD_INSPECTION_TOOL::calculateSelectionRatsnest(), ROUTER_TOOL::CanInlineDrag(), SCH_EDITOR_CONTROL::ChangeLineMode(), SCH_EDIT_TOOL::ChangeTextType(), ChangeTrackWidth(), SCH_EDIT_TOOL::CleanupSheetPins(), GERBVIEW_CONTROL::ClearAllLayers(), SCH_EDITOR_CONTROL::ClearHighlight(), BOARD_INSPECTION_TOOL::ClearHighlight(), GERBVIEW_SELECTION_TOOL::clearSelection(), PL_SELECTION_TOOL::ClearSelection(), EE_SELECTION_TOOL::ClearSelection(), PCB_SELECTION_TOOL::ClearSelection(), SCH_EDIT_TOOL::ConvertDeMorgan(), SYMBOL_EDITOR_EDIT_TOOL::Copy(), PL_EDIT_TOOL::Copy(), PAD_TOOL::copyPadSettings(), copyToClipboard(), CreateArray(), MICROWAVE_TOOL::createInductorBetween(), EE_INSPECTION_TOOL::CrossProbe(), DRC_TOOL::CrossProbe(), COMMON_TOOLS::CursorControl(), SCH_EDITOR_CONTROL::Cut(), SCH_EDIT_TOOL::DeleteItemCursor(), SYMBOL_EDITOR_EDIT_TOOL::DeleteItemCursor(), PL_EDIT_TOOL::DeleteItemCursor(), PCB_CONTROL::DeleteItemCursor(), SCH_EDITOR_CONTROL::doCopy(), BOARD_EDITOR_CONTROL::doCrossProbePcbToSch(), SCH_EDITOR_CONTROL::doCrossProbeSchToPcb(), SCH_EDIT_TOOL::DoDelete(), SYMBOL_EDITOR_EDIT_TOOL::DoDelete(), SCH_LINE_WIRE_BUS_TOOL::doDrawSegments(), BOARD_INSPECTION_TOOL::doHideRatsnestNet(), PCB_TOOL_BASE::doInteractiveItemPlacement(), doMoveSelection(), PCB_SELECTION_TOOL::doSyncSelection(), SCH_LINE_WIRE_BUS_TOOL::doUnfoldBus(), COMMON_TOOLS::doZoomInOut(), COMMON_TOOLS::doZoomToPreset(), Drag(), DRAWING_TOOL::DrawArc(), DRAWING_TOOL::drawArc(), DRAWING_TOOL::DrawCircle(), DRAWING_TOOL::DrawDimension(), DRAWING_TOOL::DrawRectangle(), SCH_LINE_WIRE_BUS_TOOL::DrawSegments(), SCH_DRAWING_TOOLS::DrawShape(), SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape(), PL_DRAWING_TOOLS::DrawShape(), DRAWING_TOOL::drawShape(), SCH_DRAWING_TOOLS::DrawSheet(), DRAWING_TOOL::DrawZone(), BOARD_EDITOR_CONTROL::DrillOrigin(), SYMBOL_EDITOR_EDIT_TOOL::Duplicate(), Duplicate(), SCH_EDIT_TOOL::EditField(), SCH_EDIT_TOOL::editFieldText(), BOARD_EDITOR_CONTROL::EditFpInFpEditor(), PAD_TOOL::EditPad(), SYMBOL_EDITOR_EDIT_TOOL::editShapeProperties(), SYMBOL_EDITOR_EDIT_TOOL::editSymbolProperties(), SCH_EDITOR_CONTROL::EditWithSymbolEditor(), GROUP_TOOL::EnterGroup(), SCH_NAVIGATE_TOOL::EnterSheet(), PAD_TOOL::EnumeratePads(), EE_INSPECTION_TOOL::ExcludeMarker(), PCB_SELECTION_TOOL: